CrewAI XMLSearchTool 实战指南:为 Agent 赋予 XML 文件的 RAG 语义检索能力
XMLSearchTool 是 crewai-tools 中面向 XML 文件的 RAG(检索增强生成)语义搜索工具,可让 CrewAI Agent 直接在本地 .xml 文件内容上按语义提问并获取相关片段,而无需手写解析逻辑。本指南将从工具的设计定位、安装接入、两种初始化模式与运行期参数、底层 RAG 执行链路,一路深入到源码实现与测试用例,帮助你掌握如何在 Crew 中正确配置并复用该工具。
XMLSearchTool 是什么:从"标签解析"到"语义搜索"
传统读取 XML 需要 XPath 或 xml.etree.ElementTree 等解析手段,而 XMLSearchTool 的思路完全不同:它是一个 RAG 工具,核心工作是把 XML 文件内容加载后切块、向量化,建立索引,再基于用户输入的查询做语义相似度检索(而非关键词匹配)。这意味着即使用户提问的措辞与原文并不逐字相同,只要语义相关,也能命中并返回对应内容片段,见 官方文档。
从源码类定义看,xml_search_tool.py 中 XMLSearchTool 直接继承自通用 RAG 工具基类 RagTool,其默认 name 为 "Search a XML's content"、description 为 "A tool that can be used to semantic search a query from a XML's content."。当 Agent 被注入该工具时,正是靠这段描述理解"可以用它在 XML 内容里做语义搜索"。
安装与导入
XMLSearchTool 随 crewai-tools 一起发布,安装时使用带 tools extra 的 crewai 包即可:
pip install 'crewai[tools]'
代码中既可以直接从子模块导入,也可以从包级入口导入(后者在 tools/init.py 中做了统一导出,并登记于 __all__,见 同文件第 319 行):
from crewai_tools.tools.xml_search_tool import XMLSearchTool
# 或者
from crewai_tools.tools import XMLSearchTool
两种初始化模式:固定文件与运行时发现
官方文档给出的两个示例对应工具的两种典型用法——在初始化时绑定具体 XML 文件,或不绑定任何文件、把文件路径留给运行阶段由 Agent 自行传入。
from crewai_tools.tools.xml_search_tool import XMLSearchTool
# 模式一:不预先指定 xml,允许 Agent 在执行过程中按需学习并搜索任何 XML 文件的内容
tool = XMLSearchTool()
# 模式二:绑定一个具体的 XML 文件路径,仅在该文件内进行搜索
tool = XMLSearchTool(xml='path/to/your/xmlfile.xml')
两种模式在源码层面对应不同的参数 Schema,这是理解工具行为差异的关键,见 xml_search_tool.py:
- 不传
xml(模式一):工具使用XMLSearchToolSchema,其字段除必填的search_query外,还包含必填的xml字段(描述为 "File path or URL of a XML file to be searched")。也就是说,LLM 每次调用工具时都必须同时给出查询词和 xml 路径/URL,工具会在运行时加载该文件再搜索。 - 初始化时传入
xml(模式二):构造器里会先执行self.add(xml)把该文件加入知识库,同时把description动态改写为包含该文件路径的描述,并将args_schema收紧为FixedXMLSearchToolSchema——此 Schema 只剩search_query一个必填字段。这样 Agent 无需再关心文件路径,每次只需提交查询词即可。
两种模式各有用武之地:模式一灵活,适合 Agent 会在多份 XML 间自行挑选的场景;模式二精确,把搜索范围锁定在单一文档上,也能减少重复的加载与索引开销。
参数速览与默认行为
以仓库当前的 rag/types.py 与 rag_tool.py 为准,XMLSearchTool 继承自 RagTool,因此在使用时涉及如下参数:
| 参数 | 位置 | 类型/默认值 | 说明 |
|---|---|---|---|
xml |
初始化参数 / _run 参数 |
str | None,默认 None |
待搜索 XML 文件的本地路径或 URL;初始化与运行时至少提供一处,见 官方 Arguments 说明 |
search_query |
_run 参数 |
str(必填) |
用于检索 XML 内容的语义查询词 |
similarity_threshold |
初始化 / _run 参数 |
float,默认 0.6 |
相似度阈值,低于该阈值的检索结果将被丢弃 |
limit |
初始化 / _run 参数 |
int,默认 5 |
返回的相关内容片段数量上限 |
collection_name |
初始化参数 | str,默认 "rag_tool_collection" |
向量库中的集合名称,不同工具/不同数据建议区分 |
summarize |
初始化参数 | bool,默认 False |
是否在检索后对结果做摘要汇总 |
config |
初始化参数 | RagToolConfig |
用于自定义 embedding 模型与向量库的配置字典(详见下文"自定义模型与 Embedding") |
similarity_threshold=0.6 与 limit=5 这两个默认值不仅在 RagTool 类字段上定义,还在集成测试中被断言:在 test_search_tools.py 的 test_xml_search_tool 中,mock 的 adapter 被期望以 similarity_threshold=0.6, limit=5 调用查询,是稳定可预期的行为。
底层执行链路:一次 XML 语义搜索是如何完成的
结合源码,一次典型的调用会走通如下链路:
- 入口:Agent 调用工具的
_run(search_query, xml=None, similarity_threshold=None, limit=None)。若本次运行提供了xml,则先执行self.add(xml)把新文件加入知识库,再调用基类逻辑,见 xml_search_tool.py。 - 加载与切块:
add最终落到CrewAIRagAdapter.add。这里会根据扩展名自动判定文档类型:.xml会被识别为DataType.XML(映射关系见 data_types.py),随后通过XMLLoader加载、XmlChunker结构化切块,并为每个片段写入data_type、chunk_index、total_chunks、source等元数据,见 crewai_rag_adapter.py。 - 入库向量化:切块结果经元数据清洗后,通过 RAG 客户端写入指定集合
rag_tool_collection(crewai_rag_adapter.py)。文件路径不可达时(且非 URL)会抛出FileNotFoundError,见 crewai_rag_adapter.py。 - 语义查询:
_run调用self.adapter.query(...),内部执行client.search,带入score_threshold(默认 0.6)与limit(默认 5),无命中时返回"No relevant content found.",见 crewai_rag_adapter.py。 - 结果组装:基类把查询结果包装成
Relevant Content:\n<结果内容>返回给 Agent,见 rag_tool.py。返回的内容片段通常是多条相关内容以空行拼接的形式。
默认情况下,adapter 由 RagTool 的模型校验器 _ensure_adapter 自动构造为 CrewAIRagAdapter(rag_tool.py)。它使用的 embedding 模型来自 config 中指定的 provider,向量库默认为 ChromaDB;用户也可以显式传入自定义 adapter 以便在测试中注入 mock。
支持的来源形式:路径与 URL
需要留意的是,虽然工具名叫"XML Search",但 Schema 中 xml 字段的描述明确写着 "File path or URL of a XML file to be searched"——即除了本地文件路径,也可以传 XML 的 URL。CrewAIRagAdapter.add 中 SourceContent 会区分 URL 与本地路径,并通过 data_type in [..., DataType.XML, ...] 分支做文件存在性校验,见 crewai_rag_adapter.py。
自定义模型与 Embedding
官方文档说明了两种接入方式下的模型自定义入口。工具默认使用 OpenAI 同时承担 embedding 与摘要(summary)职责;若希望更换底层模型,可以在初始化时以 config 字典的方式注入 llm 与 embedder 配置,例如切到 Ollama 本地模型与 Google embedding:
tool = XMLSearchTool(
config=dict(
llm=dict(
provider="ollama", # or google, openai, anthropic, llama2, ...
config=dict(
model="llama2",
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google",
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
# title="Embeddings",
),
),
)
)
文档中 provider 的取值覆盖 ollama、google、openai、anthropic、llama2 等多家大模型服务,temperature、top_p、stream 等推理参数可作为可选项随 config 一并下发。
补充一点源码层面的演进信息:从当前仓库看,RagTool 的配置结构定义在 rag/types.py 的 RagToolConfig 中,其两个顶层键是 embedding_model(对应 ProviderSpec,用于驱动 embedding 向量化)与 vectordb(向量库配置,provider 支持 "chromadb" 与 "qdrant",见 rag/types.py)。RagTool._parse_config 解析时若不带任何配置,会默认回退到 chromadb(rag_tool.py)。embedding provider 配置会经过专门校验并给出针对单一 provider 的清晰报错(rag_tool.py),若以字典传入,建议对照当前 RagToolConfig 的键名编写配置,以获得最佳兼容性。
在 Crew 中挂载到 Agent
XMLSearchTool 本质是 crewai-tools 标准工具,因此可以像其他工具一样挂载到 Agent 上:
from crewai import Agent, Crew, Process, Task
from crewai_tools.tools.xml_search_tool import XMLSearchTool
# 建议模式二:在初始化阶段绑定唯一数据源,Agent 只需提交查询
xml_tool = XMLSearchTool(xml='data/config.xml')
analyst = Agent(
role='XML 配置分析员',
goal='基于 XML 配置内容回答技术问题',
backstory='擅长从结构化 XML 中检索信息',
tools=[xml_tool],
)
task = Task(
description='查询 data/config.xml 中与数据库连接超时相关的配置项',
expected_output='给出相关配置项的名称、默认值及其所在层级',
agent=analyst,
)
crew = Crew(agents=[analyst], tasks=[task], process=Process.sequential)
result = crew.kickoff()
这里建议优先采用"初始化时绑定 xml"的模式:args_schema 会自动收窄为只要求 search_query,Agent 交互更简单、输出更可控;若业务上需要在多份 XML 之间动态切换,再改用不传 xml 的模式一,把路径交给 Agent 自行判断。
安全与路径校验
XMLSearchTool 传入路径的安全性由基类 RagTool.add 统一把关。在真正进入 adapter 之前,add 会对位置参数与关键字参数(path、file_path、url、website 等)逐一调用 safe_path 模块 中的 validate_file_path / validate_url 做校验,并解决符号链接后使用规范化路径,防止越权读文件与 SSRF,见 rag_tool.py。校验失败会抛出形如 Blocked unsafe file path: ... 的异常。测试环境下允许临时目录等绝对路径需显式设置环境变量 CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true,这一点在 test_search_tools.py 中有体现,也侧面说明该工具默认只接受安全范围内的路径。
测试与可验证性
仓库已为 XMLSearchTool 提供单元级集成测试,可作为理解调用语义的参考,见 test_search_tools.py:
def test_xml_search_tool(mock_adapter):
mock_adapter.query.return_value = "this is a test"
tool = XMLSearchTool(adapter=mock_adapter)
result = tool._run(search_query="test XML", xml="test.xml")
assert "this is a test" in result.lower()
mock_adapter.add.assert_called_once_with("test.xml")
mock_adapter.query.assert_called_once_with(
"test XML", similarity_threshold=0.6, limit=5
)
该测试确认了三件事:其一,xml 可以在运行时通过 _run 传入(印证模式一);其二,传入后会先触发一次 add("test.xml") 完成文件索引;其三,查询默认以 similarity_threshold=0.6、limit=5 执行,返回结果直接透传。如果你在本仓库之外自行扩展类似 RAG 工具,这一测试模式可以直接套用。
使用建议与注意事项
- 索引时机:
add只发生在初始化(模式二)或首次运行传入 xml 时(模式一)。同一实例后续查询复用已建好的集合,若 XML 文件被修改,应重建工具实例或换用新的collection_name,避免检索到旧内容。 - 阈值调优:默认
similarity_threshold=0.6偏严格,检索不到结果时返回"No relevant content found.";若命中率过低,可在初始化和_run中显式调低阈值,同时注意提升查询词与原文的语义贴合度。 - 结果范围:返回的是相关内容片段而非整份文档,适合作为上下文喂给 LLM 做二次推理;需要全文时请考虑搭配 XML 加载器或其他工具。
- 多文件与多格式:XMLSearchTool 聚焦 XML,同一工具类族还提供 CSV、JSON、PDF、DOCX、MDX、网页等搜索工具,见 test_search_tools.py 的导入清单;当数据源横跨多种格式时,可组合多个对应搜索工具一并注入 Agent。
- 配置兼容:embedding 与向量库的自定义配置请以当前仓库 rag/types.py 的
RagToolConfig结构为准编写,确保参数真正生效。
结语
XMLSearchTool 的价值在于把"读 XML"从需要编写解析代码的工程任务,变成了 Agent 可以直接使用的语义检索能力:绑定文件、提交查询、得到相关片段,仅此而已。而这一切都建立在 crewai-tools 通用 RagTool 之上——加载、切块、向量化、阈值过滤、结果拼装的完整链路都清晰可查。若你的 Crew 需要从配置型或数据型 XML 中快速提取信息,建议直接照本文"初始化绑定 + Agent 注入"的方式接入,再依据实际命中率微调阈值与返回条数即可。
相关源码与文档参考:工具说明 README.md|工具实现 xml_search_tool.py|基类与配置 rag_tool.py、rag/types.py|适配器 crewai_rag_adapter.py|文件类型映射 rag/data_types.py|集成测试 test_search_tools.py
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00