Argilla 记录检索指南:使用 rg.Query、rg.Filter 与 rg.Similar 构建数据集搜索与过滤
2026/9/18 13:38:56 网站建设 项目流程

Argilla 记录检索指南:使用 rg.Query、rg.Filter 与 rg.Similar 构建数据集搜索与过滤

【免费下载链接】argillaArgilla is a collaboration tool for AI engineers and domain experts to build high-quality datasets项目地址: https://gitcode.com/GitHub_Trending/ar/argilla

Argilla 提供了一套声明式的 Python 检索 API,用于按文本词条、结构化条件与向量相似度从数据集中获取记录。本文以 search.md 为骨架,结合 查询实操指南 与 Python 客户端源码,完整讲解rg.Queryrg.Filterrg.Similar三大类的用法、支持的字段与操作符、底层请求模型,并给出可直接复制运行的代码示例。读完本文,你将掌握在 Argilla 中组合全文搜索、条件过滤与向量相似度检索的完整实战方案。

核心类概览:Query、Filter 与 Similar

在 Argilla 的 Python SDK 中,记录检索由三个类协作完成:

  • rg.Query:定义一次检索的完整条件。它既可以只携带一个文本查询串(query),也可以携带一个Filter对象(filter),还可以携带一个Similar向量检索对象(similar),三者可以任意组合。
  • rg.Filter:定义结构化的过滤条件集合,每个条件是一个(字段, 操作符, 值)三元组。Filter会被传入Query,多个条件之间按AND(与)关系组合。
  • rg.Similar:定义基于向量字段的相似度检索,支持"最相似"与"最不相似"两种排序方向。

三者最终都会被转换为内部的 Pydantic 模型(见 argilla/src/argilla/_models/_search.py),并通过Dataset.records(query=...)发送到 Argilla Server 执行。

Query 的构造参数

从 Query 源码 可以看到,Query支持三个关键字参数:

参数类型说明
queryUnion[str, None]文本查询串,用于在记录文本字段中搜索词条
similarUnion[Similar, None]相似度检索对象,基于向量字段查找相似记录
filterUnion[Filter, Conditions, None]过滤条件,可以是Filter对象、单个(字段, 操作符, 值)元组,或元组列表

其中filter参数非常灵活:直接传一个元组("label", "==", "positive"),或一个元组列表[("a", "==", 1), ("b", "in", [2, 3])],都会被自动包装成Filter对象。

Filter 的构造方式

Filter接受单个条件元组或条件元组列表:

import argilla as rg # 单个条件 single = rg.Filter(("label", "==", "positive")) # 多个条件(AND 组合) multiple = rg.Filter( [ ("metadata.count", ">=", 10), ("metadata.count", "<=", 20), ] )

每个条件的结构为(field, operator, value),其中field支持点号(dot notation)语法,可以深入到记录的 metadata、suggestion 或 response 属性(详见下文"支持的过滤字段")。

按搜索词检索记录

最直接的检索方式是向Dataset.records传入一个查询字符串。该字符串会在记录的文本字段中进行全文匹配,支持单个词条与多个词条(多个词条必须全部出现在记录中才会被命中):

import argilla as rg client = rg.Argilla(api_url="<api_url>", api_key="<api_key>") dataset = client.datasets(name="my_dataset", workspace="my_workspace") # 单词条搜索 for record in dataset.records(query="paris"): print(record) # 多词条搜索(全部词条需同时出现) query = rg.Query(query="my_term1 my_term2") records = dataset.records(query=query).to_list(flatten=True)

需要说明的是,直接传入字符串时,DatasetRecords.call会将其自动包装为Query(query=...),因此dataset.records(query="paris")dataset.records(query=rg.Query(query="paris"))完全等价。

说明:dataset.records(...)返回的是一个惰性迭代器,只有真正开始迭代(如for循环或调用.to_list())时才会向服务器分批拉取记录。默认批大小为 256,可通过batch_size参数调整(见 DatasetRecords.call)。

高级文本查询语法

当需要更复杂的文本检索时,query字符串支持 Elasticsearch 的 simple query string 语法。下表总结了常用操作符(详见 query.md):

操作符含义示例
+或空格AND:两个词条都出现argilla + distilabel
\|OR:任一词条出现argilla \| distilabel
-否定:排除词条argilla -distilabel
*前缀匹配arg*匹配所有以 "arg" 开头的词
"短语精确匹配"argilla and distilabel"
()分组与优先级(argilla \| distilabel) rules
~N编辑距离模糊匹配argilla~1可匹配 "argila"

若需按字面匹配这些特殊字符,可用反斜杠转义,例如"1 \+ 2"匹配包含短语 "1 + 2" 的记录。

按条件过滤记录

Filter支持四种比较操作符(见 query.md):

操作符含义
==字段值等于给定值
>=字段值大于等于给定值
<=字段值小于等于给定值
in字段值在给定列表中

文档中的经典示例——按 metadata 数值区间过滤并叠加文本搜索:

import argilla as rg # 构造 10 到 20 的数值区间过滤 range_filter = rg.Filter( [ ("metadata.count", ">=", 10), ("metadata.count", "<=", 20), ] ) # 组合文本搜索与过滤:命中 "paris" 且 count 落在 [10, 20] 的记录 query = rg.Query(filters=range_filter, query="paris") # 迭代结果 for record in dataset.records(query=query): print(record)

多个条件同时出现时按AND语义组合。这一点在 Filter.api_model 中体现得很清楚——所有条件会被打包进一个AndFilterModel。也就是说,("label", "==", "positive")("label", "==", "negative")同时出现时,结果为空(没有任何记录同时等于两个值),这一点由集成测试 test_query_records.py 明确验证。

支持的过滤字段

Filter的字段名支持点号语法,可以深入记录的不同实体。字段名到内部过滤作用域(filter scope)的映射实现在 Condition._extract_filter_scope,支持的字段如下:

字段说明示例
id记录的外部 ID("id", "in", ["1", "2", "3"])
_server_id服务器内部记录 ID(UUID)("_server_id", "==", "ba69a996-85c2-4af0-a473-23138929641b")
inserted_at记录插入时间(datetime 或字符串)("inserted_at", ">=", "2024-10-10")
updated_at记录更新时间("updated_at", ">=", "2024-10-10")
status记录状态:pending/completed("status", "==", "completed")
response.status响应状态:draft/submitted/discarded("response.status", "==", "submitted")
metadata.<name>元数据属性("metadata.split", "==", "train")
<question>.suggestion问题建议值("label.suggestion", "==", "positive")
<question>.score建议分数("label.score", "<=", 0.9)
<question>.agent建议来源 Agent("label.agent", "==", "ChatGPT4.0")
<question>.type建议类型(如human/model("label.type", "==", "human")
<question>.response问题响应值("label.response", "==", "negative")

从 ScopeModel 定义 可以看到,过滤作用域共分四类实体:record(记录属性)、response(响应)、suggestion(建议)、metadata(元数据)。例如字段label.suggestion会被解析为以label为 question 的SuggestionFilterScopeModel,而metadata.count会被解析为MetadataFilterScopeModel

一个综合运用多字段条件的示例:

filters = rg.Filter( [ ("label.suggestion", "==", "positive"), ("metadata.count", ">=", 10), ("metadata.count", "<=", 20), ("label", "in", ["positive", "negative"]), ] ) filtered_records = dataset.records(query=rg.Query(filter=filters), with_suggestions=True).to_list(flatten=True)

按状态过滤记录

记录状态与响应状态是标注工作流中非常常用的过滤维度:

status_filter = rg.Query( filter=rg.Filter( [ ("status", "==", "completed"), # 记录状态:pending / completed ("response.status", "==", "discarded") # 响应状态:draft / submitted / discarded ] ) ) filtered_records = dataset.records(status_filter).to_list(flatten=True)

该用法同样在源码层面得到印证:status字段映射到RecordFilterScopeModel(property="status")response.status映射到ResponseFilterScopeModel(property="status")(见 Condition._extract_filter_scope)。

向量相似度检索(Similar)

当数据集配置了向量字段(VectorField)时,可以使用Similar进行语义相似检索。Similar的构造参数如下(见 Similar 源码):

参数类型说明
namestr向量字段名称
valueIterable[float]Record向量值,或一个已有的Record对象(此时以其向量作为查询向量)
most_similarboolTrue查找最相似的记录,False查找最不相似的记录
# 按向量值检索最相似记录 similar_query = rg.Query( similar=rg.Similar( name="vector", value=[0.1, 0.2, 0.3], ) ) records = dataset.records(similar_query).to_list(flatten=True) # 以现有记录作为查询向量,检索最不相似记录 record = next(iter(dataset.records(limit=1, with_vectors=False))) least_similar = dataset.records( query=rg.Query(similar=rg.Similar(name="vector", value=record, most_similar=False)) ).to_list(flatten=True)

当以Record作为value时,SDK 会提取该记录的服务端 ID(_server_id),生成VectorQueryModel(record_id=...);当提供原始向量列表时则生成VectorQueryModel(value=...)(见 Similar.api_model)。排序方向由order字段表达,取值most_similarleast_similar(见 VectorQueryModel)。

注意:相似度检索要求数据集设置中必须包含对应的向量字段定义,否则服务器会返回错误。向量字段的定义方式可参考 dataset.md 中的 Vectors 章节。

使用相似度检索时,迭代器返回的元素是(Record, score)元组,其中score是服务器返回的查询得分——这一点可以从 DatasetRecordsIterator._list 的实现看到。

组合检索:搜索词 + 过滤条件

Query的核心价值在于把全文搜索与结构化过滤组合成一次检索请求:

query_filter = rg.Query( query="my_term", filter=rg.Filter( [ ("label.suggestion", "==", "positive"), ("metadata.count", ">=", 10), ] ) ) records = dataset.records(query=query_filter, with_suggestions=True).to_list(flatten=True)

底层调用链

一次组合检索在 SDK 内部的完整路径如下:

  1. Dataset.records(query=...)创建 DatasetRecordsIterator,并通过Query.has_search()判断是否走搜索接口(见 _is_search_query);
  2. Query.api_model()将文本、向量与过滤条件组装为SearchQueryModel:文本部分包装为TextQueryModel(q=...),向量部分包装为VectorQueryModel,过滤部分包装为AndFilterModel(见 Query.api_model);
  3. 客户端调用RecordsAPI.search,向POST /api/v1/datasets/{dataset_id}/records/search发起请求,并在响应中解析出每条记录的query_score与命中总数total(见 argilla/src/argilla/_api/_records.py#L105-L138)。

值得注意的是,Query的 API 模型(SearchQueryModel)是可选结构的:没有文本搜索也没有向量检索时,query部分为空;没有过滤条件时,filters部分为空。这意味着你完全可以只传filter不传query,或反过来。

测试验证:检索行为的可靠依据

仓库中的集成测试为上述用法提供了可复现的行为依据:

  • test_query_records.py:验证了按文本词条检索(query="first"只命中 1 条)、按建议值过滤(("label", "==", "positive")命中 2 条)、in操作符与 AND 语义;
  • test_search_records.py:覆盖了按id_server_idinserted_atupdated_at过滤,按sentiment.agent/sentiment.type过滤,以及Similar的最相似 / 最不相似 / 以记录为查询向量的全部场景;
  • test_export_records.py:验证了带rg.Query(query="hello")检索结果的导出链路。

这些测试同时展示了Filter的三种等价写法:元组、元组列表、以及直接嵌入Query(filter=...),实际使用时可按可读性任选其一。

小结

Argilla 的检索 API 设计简洁且组合能力强:文本搜索解决"内容里有什么"的问题,条件过滤解决"结构上满足什么"的问题,向量相似度解决"语义上像什么"的问题。三者通过一个rg.Query对象即可任意组合,并由 SDK 自动转换为服务器可执行的检索模型。若需进一步了解向量字段配置、记录导出等相邻能力,可继续阅读 query.md、dataset.md 与 record.md;若需查看完整 API 签名,可参考 search.md 中对QueryFilterSimilar三类对象的逐项说明。

【免费下载链接】argillaArgilla is a collaboration tool for AI engineers and domain experts to build high-quality datasets项目地址: https://gitcode.com/GitHub_Trending/ar/argilla

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询