首页
/ CrewAI XMLSearchTool 实战指南:为 Agent 赋予 XML 文件的 RAG 语义检索能力

CrewAI XMLSearchTool 实战指南:为 Agent 赋予 XML 文件的 RAG 语义检索能力

2026-09-07 09:11:39作者:明树来

XMLSearchTool 是 crewai-tools 中面向 XML 文件的 RAG(检索增强生成)语义搜索工具,可让 CrewAI Agent 直接在本地 .xml 文件内容上按语义提问并获取相关片段,而无需手写解析逻辑。本指南将从工具的设计定位、安装接入、两种初始化模式与运行期参数、底层 RAG 执行链路,一路深入到源码实现与测试用例,帮助你掌握如何在 Crew 中正确配置并复用该工具。

XMLSearchTool 是什么:从"标签解析"到"语义搜索"

传统读取 XML 需要 XPath 或 xml.etree.ElementTree 等解析手段,而 XMLSearchTool 的思路完全不同:它是一个 RAG 工具,核心工作是把 XML 文件内容加载后切块、向量化,建立索引,再基于用户输入的查询做语义相似度检索(而非关键词匹配)。这意味着即使用户提问的措辞与原文并不逐字相同,只要语义相关,也能命中并返回对应内容片段,见 官方文档

从源码类定义看,xml_search_tool.pyXMLSearchTool 直接继承自通用 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.pyrag_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.6limit=5 这两个默认值不仅在 RagTool 类字段上定义,还在集成测试中被断言:在 test_search_tools.pytest_xml_search_tool 中,mock 的 adapter 被期望以 similarity_threshold=0.6, limit=5 调用查询,是稳定可预期的行为。

底层执行链路:一次 XML 语义搜索是如何完成的

结合源码,一次典型的调用会走通如下链路:

  1. 入口:Agent 调用工具的 _run(search_query, xml=None, similarity_threshold=None, limit=None)。若本次运行提供了 xml,则先执行 self.add(xml) 把新文件加入知识库,再调用基类逻辑,见 xml_search_tool.py
  2. 加载与切块add 最终落到 CrewAIRagAdapter.add。这里会根据扩展名自动判定文档类型:.xml 会被识别为 DataType.XML(映射关系见 data_types.py),随后通过 XMLLoader 加载、XmlChunker 结构化切块,并为每个片段写入 data_typechunk_indextotal_chunkssource 等元数据,见 crewai_rag_adapter.py
  3. 入库向量化:切块结果经元数据清洗后,通过 RAG 客户端写入指定集合 rag_tool_collectioncrewai_rag_adapter.py)。文件路径不可达时(且非 URL)会抛出 FileNotFoundError,见 crewai_rag_adapter.py
  4. 语义查询_run 调用 self.adapter.query(...),内部执行 client.search,带入 score_threshold(默认 0.6)与 limit(默认 5),无命中时返回 "No relevant content found.",见 crewai_rag_adapter.py
  5. 结果组装:基类把查询结果包装成 Relevant Content:\n<结果内容> 返回给 Agent,见 rag_tool.py。返回的内容片段通常是多条相关内容以空行拼接的形式。

默认情况下,adapter 由 RagTool 的模型校验器 _ensure_adapter 自动构造为 CrewAIRagAdapterrag_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.addSourceContent 会区分 URL 与本地路径,并通过 data_type in [..., DataType.XML, ...] 分支做文件存在性校验,见 crewai_rag_adapter.py

自定义模型与 Embedding

官方文档说明了两种接入方式下的模型自定义入口。工具默认使用 OpenAI 同时承担 embedding 与摘要(summary)职责;若希望更换底层模型,可以在初始化时以 config 字典的方式注入 llmembedder 配置,例如切到 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 等多家大模型服务,temperaturetop_pstream 等推理参数可作为可选项随 config 一并下发。

补充一点源码层面的演进信息:从当前仓库看,RagTool 的配置结构定义在 rag/types.pyRagToolConfig 中,其两个顶层键是 embedding_model(对应 ProviderSpec,用于驱动 embedding 向量化)与 vectordb(向量库配置,provider 支持 "chromadb""qdrant",见 rag/types.py)。RagTool._parse_config 解析时若不带任何配置,会默认回退到 chromadbrag_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 会对位置参数与关键字参数(pathfile_pathurlwebsite 等)逐一调用 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.6limit=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.pyRagToolConfig 结构为准编写,确保参数真正生效。

结语

XMLSearchTool 的价值在于把"读 XML"从需要编写解析代码的工程任务,变成了 Agent 可以直接使用的语义检索能力:绑定文件、提交查询、得到相关片段,仅此而已。而这一切都建立在 crewai-tools 通用 RagTool 之上——加载、切块、向量化、阈值过滤、结果拼装的完整链路都清晰可查。若你的 Crew 需要从配置型或数据型 XML 中快速提取信息,建议直接照本文"初始化绑定 + Agent 注入"的方式接入,再依据实际命中率微调阈值与返回条数即可。

相关源码与文档参考:工具说明 README.md|工具实现 xml_search_tool.py|基类与配置 rag_tool.pyrag/types.py|适配器 crewai_rag_adapter.py|文件类型映射 rag/data_types.py|集成测试 test_search_tools.py

登录后查看全文
热门项目推荐
相关项目推荐