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

发布时间:2026/9/19 7:23:55

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),仅供参考
延伸阅读

更多相关文章

2026/9/19 7:18:54

微信小程序+SpringBoot校史馆开发实践与架构解析

1. 项目背景与核心价值重人科校史馆微信小程序作为高校文化数字化建设的典型应用,本质上是通过移动互联网技术解决校史传播中的三个核心痛点:传统线下展览的时空限制、校史资料的检索效率低下、以及年轻群体对校史文化的参与度不足。这个选题在技术实现上…

2026/9/19 7:18:54

通达信高春牛组合公式拆解:选股信号、参数调整与无未来函数验证

简介:这是一份以“高春牛组合”为核心的通达信指标公式源码教程文档,适合有股票技术分析基础、希望自建选股与副图公式的投资者使用。文档将副图公式与选股公式整合在一起,核心逻辑融合金牛、春笋、高精三类买入信号,并结合成交量…

2026/9/19 8:28:59

AIAgent全流程技术图谱与2026趋势预测

1. 项目概述:AIAgent技术全景图的价值去年我在给一家金融机构做技术咨询时,他们的CTO问了这样一个问题:"现在AI技术层出不穷,但到底哪些技能值得团队重点投入?"这个问题直接促使我整理出了这份AIAgent全流程…

2026/9/19 8:28:59

ADK for Kotlin 实战:Android 开发者如何用 KSP 构建 AI Agent

1. 为什么 ADK for Kotlin 值得每一个 Android 开发者关注Google 把 AI Agent 的开发工具链正式带到了 Kotlin 生态里,这件事对 Android 开发者来说意义比表面看起来大得多。过去一年里,AI Agent 的框架基本被 Python 统治,LangChain、AutoGe…

2026/9/19 8:28:59

机器视觉选型八大深坑:从分辨率到光源的完整避坑指南

1. 先把丑话说在前面:选型阶段犯的错,90%会在现场加倍奉还1.1 视觉选型不是攒电脑,是给产线装"眼睛"机器视觉项目做到一半发现检不出来,十有八九不是算法不行,而是选型阶段就埋了雷。我见过太多项目&#xf…

2026/9/19 8:28:59

Cursor高效编码:上下文、提示词、规则文件与老代码重构

上周三下午,同事老张在群里发了一张截图,Cursor 把一个项目里根本不存在的getUserInfoById函数写进了代码,还煞有介事地补上了注释和异常处理。他甩了一句"这玩意儿就是人工智障"。我让他把当时的对话记录发过来,问题一…

2026/9/19 8:28:59

PyCharm集成QGIS Processing实战:打通内核级空间分析开发流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 8:23:59

汽车出口数字化转型:ERP解决方案与供应链优化

1. 汽车出口行业的数字化转型机遇与挑战2024年上海市政府工作报告释放了一个明确信号:跨境电商和二手车出口等新业态将获得前所未有的政策支持。作为一名深耕外贸ERP领域多年的从业者,我亲眼见证了汽车出口企业在这波政策红利下的转型阵痛与突破。在这个…

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码