招聘数据是模糊的,但招聘约束条件不是。
为大规模人才平台提供职位搜索、候选人匹配和推荐系统支持。
result = client.query_points(
collection_name="jobs",
prefetch=[
models.Prefetch(
query=dense_emb, using="dense",
),
models.Prefetch(
query=sparse_vec, using="sparse",
),
],
query=models.FusionQuery(
fusion=models.Fusion.RRF),
query_filter=models.Filter(must=[
models.FieldCondition(
key="location",
match=models.MatchAny(any=["london", "remote"]),
),
models.FieldCondition(
key="salary_max",
range=models.Range(gte=60000),
),
]),
limit=20,
)
步骤 1
嵌入 - 解析 + 嵌入简历 / 职位描述
步骤 2
搜索 - 语义搜索 + 严格过滤
步骤 3
排名 - 排名 + 重排(可选)
步骤 4
结果 - 基于证据的匹配
“Qdrant 是我最不用担心会出问题的地方。”
Elvis Moraa
Pariti 工程负责人
2.4 倍
招聘填充率提升
70%
候选人筛选时间缩短
为什么团队选择 Qdrant
大规模招聘搜索效率低下
许多人力资源科技团队起初并未使用向量搜索。他们选择 Elasticsearch、PGVector 或托管 API,但在产品需要大规模组合过滤、多语言支持或百万级向量下的亚秒级延迟时,往往会遇到瓶颈。这些就是浮现出来的工程难题,也是我们从转向 Qdrant 的团队那里听到的痛点。
分类体系不一致
“高级软件工程师”、“Staff Dev”和“Lead SWE”可能是同一个职位。关键词搜索会漏掉这些,但语义搜索不会,嵌入(Embedding)可以捕捉到它们。
带有约束的模糊数据
简历中的技能和职称不一致,但地点、工作许可和认证是严格的硬性约束。你需要对同一个查询同时进行语义相似度搜索和硬性过滤。
考虑迁移?
我们的解决方案工程师每周都会与人力资源科技团队进行深入的技术交流。
您可以使用 Qdrant 构建什么
底层原理
针对上述问题的架构模式及 API 示例。
带有硬性招聘约束的语义匹配
嵌入职位描述或简历,然后为不可协商的约束条件应用“必须匹配”的负载过滤器。过滤器在 HNSW 遍历期间应用,而非遍历后,因此召回率不会下降。
图遍历期间的预过滤
地点、薪资、类别的复合过滤不会导致延迟激增。
混合搜索
在单次查询中结合密集向量 + 稀疏向量,并使用倒数排名融合(RRF)。
原生推理
使用 Qdrant 云推理简化您的数据管道。
# Pattern: hybrid semantic + keyword with filters
# → see docs for complete example
result = client.query_points(
collection_name="jobs",
prefetch=[
models.Prefetch(
query=dense_emb, using="dense",
limit=100),
models.Prefetch(
query=sparse_vec, using="sparse",
limit=100),
],
query=models.FusionQuery(
fusion=models.Fusion.RRF),
query_filter=models.Filter(must=[
models.FieldCondition(
key="location",
match=models.MatchAny(any=["london", "remote"]),
),
models.FieldCondition(
key="salary_max",
range=models.Range(gte=60000),
),
]),
limit=20,
)
针对 1000 万+ 向量的量化
标量和二进制量化可将内存中的向量压缩 4-32 倍。适用于 1000 万+ 候选人或职位向量。
标量量化
在极小的召回率损失下实现 4 倍内存缩减。仅需一个配置标志。
可预测的成本
固定的向量搜索基础设施成本,意味着可在管道的多个阶段进行检索,而不会侵蚀利润空间。
# Pattern: quantized collection for scale
# → see docs for complete example
client.create_collection(
collection_name="candidates_quantized",
vectors_config={
"dense": models.VectorParams(
size=1536,
distance=models.Distance.COSINE,
),
},
sparse_vectors_config={
"sparse": models.SparseVectorParams(
modifier=models.Modifier.IDF,
),
},
quantization_config=models.ScalarQuantization(
scalar=models.ScalarQuantizationConfig(
type=models.ScalarType.INT8,
quantile=0.99,
always_ram=True,
)
),
)
“相似职位”与候选人发现
使用现有数据点作为查询输入的推荐式检索。传入正面和负面示例,查询端无需额外的嵌入步骤。
按点 ID 推荐
无需重新嵌入。只需传入职位或候选人 ID。
正面 + 负面示例
“寻找更像这 3 个的,而不像那一个的”:无需重新训练即可进行优化。
# Pattern: recommend by point ID
# → see docs for complete example
result = client.query_points(
collection_name="jobs",
query=models.RecommendQuery(
recommend=models.RecommendInput(
positive=[0], # job_id_0
negative=[1], # job_id_1
)
),
using="dense",
query_filter=models.Filter(
must=[
models.FieldCondition(
key="category",
match=models.MatchValue(value="engineering"),
),
models.FieldCondition(
key="remote",
match=models.MatchValue(value=True),
),
]
),
limit=20,
)
