十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

smolagents Agentic RAG 实战:用 CodeAgent 打造可推理、可迭代检索的知识库问答系统

smolagents Agentic RAG 实战:用 CodeAgent 打造可推理、可迭代检索的知识库问答系统 smolagents Agentic RAG 实战用 CodeAgent 打造可推理、可迭代检索的知识库问答系统【免费下载链接】smolagents smolagents: a barebones library for agents that think in code.项目地址: https://gitcode.com/gh_mirrors/smo/smolagents导读本文基于 smolagents 官方示例 docs/source/en/examples/rag.md 与仓库内完整可运行的 examples/rag.py讲解如何把传统 RAG检索增强生成升级为Agentic RAG即以 smolagents 的CodeAgent为核心通过自定义Tool把 BM25 检索器包装成语义检索工具让大模型自主优化查询、多轮检索、交叉验证并最终作答。读完本文你将掌握在 smolagents 中定义检索工具、配置InferenceClientModel模型、驱动CodeAgent完成知识库问答的完整套路并理解其底层工具校验与执行机制。一、RAG 是什么把答案建立在检索到的事实之上Retrieval-Augmented Generation检索增强生成RAG的核心思想可以概括为一句话用 LLM 回答用户问题但回答的依据是从知识库中检索到的信息。它把大语言模型的生成能力与外部知识检索能力结合起来从而产出更准确、更有事实依据、更贴合上下文的回答。1.1 为什么用 RAG相比直接使用 vanilla 大模型或微调fine-tuned模型RAG 有五个显著优势事实锚定Factual Grounding回答锚定在检索到的真实文档上显著降低幻觉hallucination概率领域专精Domain Specialization无需重新训练模型即可让通用模型回答特定领域的专业问题知识时效Knowledge Recency可以访问超出模型训练截止时间training cutoff的最新信息可追溯性Transparency生成内容可以引用来源文档方便用户核对可控性Control可以精细控制模型能访问哪些信息、不能访问哪些信息。1.2 传统 RAG 的局限传统 RAG 虽然好用但作为一次检索 一次生成的固定流水线它面临四个典型挑战单次检索Single Retrieval Step如果第一轮检索结果质量差最终生成的答案也会跟着遭殃没有补救机会查询与文档不匹配Query-Document Mismatch用户的查询往往是疑问句而包含答案的文档通常是陈述句词面差异会让字面匹配失效推理能力有限Limited Reasoning简单的 RAG 流水线无法进行多步推理或查询修正上下文窗口约束Context Window Constraints检索到的文档必须能塞进模型的上下文窗口限制了可用的信息量。二、Agentic RAG从固定流水线到可推理的检索 Agent上述局限的根因在于传统 RAG 是一条单向、不可变的流水线。而Agentic RAG的思路是给 Agent 装备检索能力把 RAG 变成交互式、由推理驱动的过程。2.1 Agentic RAG 的关键能力一个带检索工具的 Agent 可以做到✅生成优化查询Formulate optimized queries把用户的原始问题改写为更适合检索的查询形式✅多次检索Perform multiple retrievals按需迭代式地多次检索逐步逼近答案✅对检索内容进行推理Reason over retrieved content对多个来源的信息进行分析、综合与结论提炼✅自我批判与修正Self-critique and refine评估检索结果质量调整检索策略后再试。2.2 天然实现的高级 RAG 技术这种思考-行动-观察的循环天然就实现了两类高级 RAG 技术HyDEHypothetical Document Embedding假设性文档嵌入不再直接用用户查询去检索而是让 Agent 先生成一个检索友好的假设性文档或查询再检索对应论文2212.10496HyDE 由 Gao 等人提出Self-Query Refinement自查询修正Agent 先分析第一轮检索结果发现信息不足或方向不对时用修正后的查询发起第二轮检索。在 smolagents 中这两类能力不需要额外框架支持——它们就是CodeAgent在每一轮写代码调用工具中自然涌现的行为。三、实战构建一个 Transformers 文档问答 Agent下面我们按步骤构建一个完整的 Agentic RAG 系统。目标创建一个能回答Hugging Face Transformers 库相关问题的 Agent其知识来源是 Transformers 官方文档。你可以跟着下面的代码片段逐步实现也可以直接查看仓库中完整可运行的示例 examples/rag.py。Step 1安装依赖首先安装所需依赖包pip install smolagents pandas langchain langchain-community sentence-transformers datasets python-dotenv rank_bm25 --upgrade如果你打算使用 Hugging Face 的 Inference API通过InferenceClientModel调用云端推理需要配置 API Token。推荐用python-dotenv从环境变量加载# 加载环境变量包含 HF_TOKEN from dotenv import load_dotenv load_dotenv()InferenceClientModel在初始化时会依次尝试显式传入的token、环境变量HF_TOKEN最后回退到huggingface-cli login保存的本地凭据详见 src/smolagents/models.py。Step 2准备知识库我们使用一个包含 Hugging Face 文档的数据集过滤出 Transformers 部分切分成适合检索的文档块import datasets from langchain.docstore.document import Document from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.retrievers import BM25Retriever # 加载 Hugging Face 文档数据集 knowledge_base datasets.load_dataset(m-ric/huggingface_doc, splittrain) # 只保留 Transformers 相关文档 knowledge_base knowledge_base.filter(lambda row: row[source].startswith(huggingface/transformers)) # 把数据集条目转换为带元数据的 Document 对象 source_docs [ Document(page_contentdoc[text], metadata{source: doc[source].split(/)[1]}) for doc in knowledge_base ] # 将文档切分为更小的块提升检索精度 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个块的最大字符数 chunk_overlap50, # 相邻块之间的重叠字符数避免切断语义 add_start_indexTrue, strip_whitespaceTrue, separators[\n\n, \n, ., , ], # 切分优先级顺序 ) docs_processed text_splitter.split_documents(source_docs) print(fKnowledge base prepared with {len(docs_processed)} document chunks)这里的关键点在于切分参数chunk_size500保证块足够小以便精确检索chunk_overlap50让上下文在块边界处保持连贯separators指定了从段落级到字符级的切分优先级。Step 3创建检索工具Retriever Tool接下来定义一个自定义Tool让 Agent 能用它从知识库中检索信息。这是整个 Agentic RAG 的关键桥梁from smolagents import Tool class RetrieverTool(Tool): name retriever description Uses semantic search to retrieve the parts of transformers documentation that could be most relevant to answer your query. inputs { query: { type: string, description: The query to perform. This should be semantically close to your target documents. Use the affirmative form rather than a question., } } output_type string def __init__(self, docs, **kwargs): super().__init__(**kwargs) # 用处理后的文档初始化 BM25 检索器返回 Top-10 相关文档 self.retriever BM25Retriever.from_documents( docs, k10 ) def forward(self, query: str) - str: 执行检索并格式化返回结果。 assert isinstance(query, str), Your search query must be a string # 执行检索 docs self.retriever.invoke(query) # 格式化检索结果便于 Agent 阅读 return \nRetrieved documents:\n .join( [ f\n\n Document {str(i)} \n doc.page_content for i, doc in enumerate(docs) ] ) # 用处理好的文档初始化检索工具 retriever_tool RetrieverTool(docs_processed)[!TIP] 这里选用BM25词法检索方法是为了简单和快速。生产环境可以换用基于 embedding 的语义检索以获得更好的检索质量可参考 MTEB 排行榜挑选高质量的 embedding 模型。源码视角Tool基类到底做了什么要理解RetrieverTool需要看看它的基类实现src/smolagents/tools.py必填类属性子类必须声明namestr、descriptionstr、inputsdict每个输入项必须含type和description两个键、output_typestr。Tool.__init_subclass__会触发validate_after_init即在__init__执行完毕后自动调用validate_arguments()做一次全量校验校验规则validate_argumentsname必须是合法 Python 标识符且非保留字inputs中的type必须是受支持类型合法取值来自AUTHORIZED_TYPES [string, boolean, integer, number, image, audio, array, object, any, null]forward方法的参数名集合必须与inputs的键完全一致否则直接抛异常调用入口__call__会先检查is_initialized若未初始化则调用可覆写的setup()适合放置加载模型等昂贵操作随后执行forward(*args, **kwargs)并返回结果提示词注入to_code_prompt()会把工具的签名如retriever(query: string) - string、描述与参数说明拼装成代码形式的函数文档注入到 CodeAgent 的系统提示词中让模型知道可以调用retriever(query)这个函数。这也是为什么示例中inputs里只有query一个键forward就只接收query一个参数——两者必须严格对应代码里对工具的使用方式与给模型的提示词才一致。Step 4创建检索 Agent现在创建能调用retriever_tool的CodeAgentfrom smolagents import InferenceClientModel, CodeAgent # 用我们的检索工具初始化 Agent agent CodeAgent( tools[retriever_tool], # 提供给 Agent 的工具列表 modelInferenceClientModel(), # 默认模型 Qwen/Qwen3-Next-80B-A3B-Thinking max_steps4, # 限制推理步数 verbosity_level2, # 输出详细的 Agent 推理过程 ) # 想指定特定模型时可以这样写 # modelInferenceClientModel(model_idmeta-llama/Llama-3.3-70B-Instruct)[!TIP] Inference Providers 通过 serverless 推理合作伙伴提供数百个模型。不传provider时默认走 auto即按用户在账户设置里的偏好顺序选择可用供应商支持 Cerebras、Cohere、Fal、Fireworks、HF-Inference、Hyperbolic、Nebius、Novita、Replicate、SambaNova、Together 等多家供应商详见 src/smolagents/models.py。源码视角CodeAgent与InferenceClientModel的关键参数CodeAgentsrc/smolagents/agents.py是以代码形式表达工具调用的 AgentLLM 每次行动会生成一段 Python 代码例如调用retriever(query...)解析后交给 Python 执行器运行。常用参数参数默认值说明tools必填Agent 可用的Tool列表model必填负责生成行动的Model实例max_steps20最大推理步数MultiStepAgent._run_stream中循环条件为self.step_number max_steps超限会进入_handle_max_steps_reached分支src/smolagents/agents.pyverbosity_levelLogLevel.INFO日志详细程度示例中2对应更详细的推理输出stream_outputsFalse是否流式输出置True时要求模型实现generate_stream方法否则抛ValueErrorsrc/smolagents/agents.pyexecutor_typelocal代码执行器类型可选local、blaxel、e2b、modal、dockerplanning_intervalNone每隔 N 步插入一次规划步骤适合复杂长任务additional_authorized_imports[]额外允许 Agent 导入的包仓库示例 examples/rag.py 中还额外开启了stream_outputsTrue可以边推理边流式输出。InferenceClientModelsrc/smolagents/models.py是访问 Hugging Face Inference Providers 的模型封装model_id默认Qwen/Qwen3-Next-80B-A3B-Thinking也支持传入已部署的 Inference Endpoint URLprovider用于指定供应商如hyperbolic默认auto按用户偏好自动选择传了base_url时provider不生效token需要被授权调用 serverless Inference Providers若模型是 gated如 Llama-3 系列token 还需有对应仓库的读取权限。不传时依次回退到HF_TOKEN环境变量和 HF CLI 登录凭据timeout默认 120 秒api_key是token的别名与 OpenAI 客户端风格对齐二者不能同时传入若要本地私有部署也可换用仓库中的TransformersModelsrc/smolagents/models.py直接加载本地模型权重。Step 5运行 Agent 回答问题最后向 Agent 提出一个需要检索文档才能回答的问题# 提出一个需要检索信息才能回答的问题 question For a transformers model training, which is slower, the forward or the backward pass? # 运行 Agent 获取答案 agent_output agent.run(question) # 打印最终答案 print(\nFinal answer:) print(agent_output)agent.run()背后的执行流程是生成系统提示词包含retriever工具的代码签名→ 进入思考-写代码-执行-观察循环 → 每步把结果写回 memory → 直到模型输出final_answer或达到max_steps上限src/smolagents/agents.py。针对forward 与 backward 谁更慢这类问题Agent 会先改写为陈述式检索查询如backward pass is slower than forward pass调用retriever拿到相关文档片段再综合多个文档块给出有依据的答案——这正是 HyDE 与多轮检索在实践中的体现。四、Agentic RAG 的典型应用场景掌握上述构建方式后Agentic RAG 可以迁移到多种实际业务中技术文档助手帮用户快速定位复杂技术文档中的关键信息科研论文分析从多篇论文中抽取并综合结论法律文书审查在海量判例与条款中查找相关先例智能客服基于产品文档与知识库回答用户问题教育辅导基于教材与学习资料提供定制化讲解。替换知识库来源如换成自己的内部 Wiki、PDF 语料或数据库、换用语义检索器如基于 embedding 的向量检索即可适配上述场景而 Agent 的检索-推理骨架无需改动。五、结论Agentic RAG 相对传统 RAG 流水线是一次显著升级把 LLM Agent 的推理能力与检索系统的事实锚定能力结合起来可以构建更强大、更灵活、更准确的信息系统。本文演示的方案用RetrieverTool继承Tool基类把 BM25 检索器包装成 Agent 可调用的工具用CodeAgentInferenceClientModel驱动思考-检索-推理循环突破了单次检索的局限让 Agent 与知识库之间形成更自然的交互通过自我批判与查询修正为持续改进提供了框架。当你构建自己的 Agentic RAG 系统时建议在检索方法BM25 vs 语义检索、Agent 架构CodeAgentvsToolCallingAgent后者见 src/smolagents/agents.py以及知识源三个维度上多做实验找到最适合自己业务场景的组合。【免费下载链接】smolagents smolagents: a barebones library for agents that think in code.项目地址: https://gitcode.com/gh_mirrors/smo/smolagents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表