☰
smol-course Agents 模块实战指南:用 smolagents 构建检索、代码与自定义函数 Agent
2026/10/9 2:13:37 网站建设 项目流程
  • 教程
  • 人工智能
  • 大模型
  • NLP
  • 微调

【免费下载链接】smol-course

A course on aligning smol models.

项目地址:https://gitcode.com/gh_mirrors/smo/smol-course
点击查看免费下载

导读

本指南围绕 smol-course v1 的 Agents 模块展开,系统讲解如何基于smolagents轻量级框架构建三类典型 Agent:具备知识检索能力的 Agentic RAG 系统、面向软件开发任务的代码型 Agent,以及通过自定义函数与业务逻辑深度集成的函数型 Agent。读完本文,你将掌握 Agent 的核心组成、CodeAgent/Tool的关键用法,并能通过配套 Notebook 完成从简单 RAG 到完整研究助手的分级实战练习。

Agents 模块概览:Agent 的三大核心能力

在 Agents 模块首页 中,AI Agent 被定义为能够理解用户请求、将其拆解为步骤,并执行动作以完成任务的自主系统。它把语言模型与工具、外部函数结合起来与环境交互,而smolagents正是这门课程用来构建此类 Agent 的轻量级框架。

构建一个有效的 Agent 需要理解三个关键组件:

  1. 检索能力(Retrieval):让 Agent 能够从多种来源访问和利用相关信息;
  2. 函数调用(Function Calling):让 Agent 能够在环境中采取具体行动;
  3. 领域知识与工具(Domain-Specific Knowledge and Tooling):为 Agent 装备执行代码操作等专业任务的能力。

这三者分别对应本模块的三个子主题:检索型 Agent、代码型 Agent 与自定义函数 Agent。此外,模块还附带一份分级练习 Notebook,帮助你从基础到复杂逐步上手。

环境准备与练习入口

安装与认证

Notebook 的安装步骤(见 agents.ipynb)非常轻量:核心依赖只有一个smolagents包,运行在 Google Colab 等环境时可同时安装transformers、datasets、trl、huggingface_hub等常用依赖:

!pip install smolagents # Install the requirements in Google Colab # !pip install transformers datasets trl huggingface_hub # Authenticate to Hugging Face from huggingface_hub import login login()

代码中的HfApiModel()默认调用 Hugging Face 上的推理 API,因此首次使用前需要先完成登录认证(调用login()并填入 access token)。

Notebook 练习结构

配套练习 agents.ipynb 采用三档难度递进的设计:

练习主题目标
🐢 Exercise 1基础代码 Agent用DuckDuckGoSearchTool回答编程问题
🐕 Exercise 2自定义函数 Agent用@tool装饰器实现计算器工具
🦁 Exercise 3高级检索 Agent结合 Web 搜索与记忆维护多轮对话上下文

下文将依次讲解支撑这些练习的三大技术主题。

检索型 Agent:构建 Agentic RAG 系统

传统 RAG 的局限与 Agentic RAG 的优势

retrieval_agents.md 开篇点明了 Agentic RAG(检索增强生成)与传统 RAG 的本质区别:传统 RAG 只是用 LLM 基于检索到的信息回答查询,而 Agentic RAG 允许系统智能地控制自身的检索与回答过程。

传统 RAG 的关键局限在于:

  • 只执行单次检索;
  • 仅依赖用户查询与文档之间的直接语义相似度,容易遗漏相关信息。

Agentic RAG 通过让 Agent 自主拟定搜索查询、批判性评估结果、按需执行多次检索来解决上述问题。

第一步:用 DuckDuckGo 构建最简检索 Agent

最简单的检索型 Agent 只需三步:初始化搜索工具、初始化模型、组合成 Agent:

from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel # Initialize the search tool search_tool = DuckDuckGoSearchTool() # Initialize the model model = HfApiModel() agent = CodeAgent( model = model, tools=[search_tool] ) # Example usage response = agent.run( "What are the latest developments in fusion energy?" ) print(response)

该 Agent 的执行链路是:

  1. 分析查询:确定需要哪些信息;
  2. 搜索:用 DuckDuckGo 检索相关内容;
  3. 综合:把检索结果整合为连贯回答;
  4. 记忆:将交互存入记忆供后续引用。

第二步:自定义知识库工具(向量检索)

对于领域特定应用,往往需要把 Web 搜索与自己的知识库结合起来。此时可以继承smolagents的Tool基类编写自定义工具。课程示例用BM25Retriever对 transformers 文档做语义检索:

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) self.retriever = BM25Retriever.from_documents( docs, k=10 ) def forward(self, query: str) -> str: assert isinstance(query, str), "Your search query must be a string" docs = self.retriever.invoke( query, ) 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)

自定义Tool的关键点在于:

  • name与description是 Agent 选择工具的依据,description应写清适用场景与查询写作建议(示例中甚至建议用肯定句而非疑问句);
  • inputs声明参数的 JSON Schema(类型 + 描述),供模型理解参数语义;
  • forward是实际执行逻辑,返回的字符串会作为工具输出注入模型上下文。

把这个工具加入 Agent 后,检索型 Agent 可以:先在文档中查找相关信息 → 必要时回退到 Web 搜索 → 综合两个来源的信息 → 通过记忆维护对话上下文。

第三步:构建知识库(数据处理流水线)

RetrieverTool的输入docs_processed来自一条标准的文档处理流水线:加载数据集 → 过滤源 → 构造Document→ 按块切分。示例以m-ric/huggingface_doc数据集中的 transformers 文档为原料:

import datasets from langchain.docstore.document import Document from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.retrievers import BM25Retriever knowledge_base = datasets.load_dataset("m-ric/huggingface_doc", split="train") knowledge_base = knowledge_base.filter(lambda row: row["source"].startswith("huggingface/transformers")) source_docs = [ Document(page_content=doc["text"], metadata={"source": doc["source"].split("/")[1]}) for doc in knowledge_base ] text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, add_start_index=True, strip_whitespace=True, separators=["\n\n", "\n", ".", " ", ""], ) docs_processed = text_splitter.split_documents(source_docs)

其中RecursiveCharacterTextSplitter的chunk_size=500、chunk_overlap=50、按["\n\n", "\n", ".", " ", ""]的优先级递归切分,是为了在保持语义完整性的同时让每个块足够小,提升 BM25 检索命中质量。

增强检索策略:不止于一次搜索

Agentic RAG 的价值在于 Agent 可以主动采用更复杂的检索策略:

  1. 查询改写(Query Reformulation):不用原始用户查询,而是构造更贴合目标文档的优化搜索词;
  2. 多步检索(Multi-Step Retrieval):执行多次搜索,用初次结果指导后续查询;
  3. 来源整合(Source Integration):综合 Web 搜索与本地文档等多个来源的信息;
  4. 结果校验(Result Validation):在回答前分析检索内容的相关性与准确性。

要做出有效的 Agentic RAG 系统,还需重点考虑:根据查询类型与上下文在可用工具间做选择、用记忆系统维护对话历史并避免重复检索、设计主检索失败时的回退策略,以及加入校验步骤保证信息准确。该模块的后续衔接见 代码型 Agent。

代码型 Agent:面向软件开发的自主系统

为什么需要代码 Agent

code_agents.md 指出,代码型 Agent 是专门处理编码任务的自主系统,覆盖分析、生成、重构与测试等环节。它利用编程语言、构建系统与版本控制方面的领域知识来增强软件开发工作流。其价值在于:通过自动化重复性任务加速开发、生成样板代码、执行系统性重构、借助静态分析发现潜在问题——这些能力的基础是把检索能力(访问外部文档与仓库)和函数调用(创建文件、运行测试等具体动作)结合起来。

代码 Agent 的构成

代码 Agent 建立在针对代码理解做过微调的语言模型之上,再叠加 linter、formatter、编译器之类的开发工具与真实环境交互;通过检索技术访问文档与代码历史以维持上下文感知、对齐组织模式与规范;通过动作导向的函数执行提交更改、发起 merge request 等具体任务。

最小示例:带 Web 搜索的代码 Agent

与前面检索型 Agent 一脉相承,最简单的代码 Agent 同样可以挂上 DuckDuckGo 搜索工具:

from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel agent = CodeAgent(tools=[DuckDuckGoSearchTool()], model=HfApiModel()) agent.run("How many seconds would it take for a leopard at full speed to run through Pont des Arts?")

CodeAgent的名字揭示了它的工作机制:它会编写并执行 Python 代码片段来完成推理与调用工具,而不只是逐个调用工具。

用 @tool 装饰器定义自定义函数

第二个示例展示了用@tool装饰器把一个普通函数升级为 Agent 工具,并用来查询两地之间的行程时间:

from smolagents import CodeAgent, HfApiModel, tool @tool def get_travel_duration(start_location: str, destination_location: str, departure_time: Optional[int] = None) -> str: """Gets the travel time in car between two places. Args: start_location: the place from which you start your ride destination_location: the place of arrival departure_time: the departure time, provide only a `datetime.datetime` if you want to specify this """ import googlemaps # All imports are placed within the function, to allow for sharing to Hub. import os gmaps = googlemaps.Client(os.getenv("GMAPS_API_KEY")) if departure_time is None: from datetime import datetime departure_time = datetime(2025, 1, 6, 11, 0) directions_result = gmaps.directions( start_location, destination_location, mode="transit", departure_time=departure_time ) return directions_result[0]["legs"][0]["duration"]["text"] agent = CodeAgent(tools=[get_travel_duration], model=HfApiModel(), additional_authorized_imports=["datetime"]) agent.run("Can you give me a nice one-day trip around Paris with a few locations and the times? Could be in the city or outside, but should fit in one day. I'm travelling only via public transportation.")

值得注意的工程细节:

  • 装饰器函数内的所有import都放在函数体内部,以便函数可分享到 Hub(分享时外部依赖会一并打包);
  • 密钥通过os.getenv("GMAPS_API_KEY")从环境变量读取;
  • CodeAgent增加了additional_authorized_imports=["datetime"]参数,即额外授权 Agent 在生成的代码中导入datetime模块——这是smolagents沙箱化执行安全机制的一部分,只有显式授权的导入才会被执行。

框架特性:轻量与沙箱

课程对smolagents框架特性做了概述:核心实现仅约 1000 行代码,是名副其实的轻量级框架;它专注于让 Agent 编写并执行 Python 代码片段,并提供沙箱化执行以保证安全;同时支持开源与专有语言模型,适配多种开发环境。

自定义函数 Agent:与业务逻辑直接集成

为什么用自定义函数 Agent

custom_functions.md 定义了自定义函数 Agent 的定位:利用专门的函数调用(即“工具”)来执行任务的 Agent。与通用 Agent 不同,它聚焦于通过直接集成应用逻辑来驱动高级工作流——例如把数据库查询、系统命令或任意自定义工具封装成独立函数供 Agent 调用。它的三大优势是:

  • 模块化与可扩展:把单个 Agent 拆成一组代表离散能力的独立函数,架构更易扩展;
  • 细粒度控制:开发者通过指定哪些函数可用、接受哪些参数来精确控制 Agent 行为;
  • 可靠性提升:每个函数配清晰的 schema 与校验,减少错误和意外行为。

基本工作流四步法

  1. 识别函数(Identify Functions):确定哪些任务可以转化为自定义函数(如文件 I/O、数据库查询、流式数据处理);
  2. 定义接口(Define the Interface):用函数签名或 schema 精确描述每个函数的输入、输出与预期行为,在 Agent 与环境之间建立强契约;
  3. 注册到 Agent(Register with the Agent):把描述每个函数接口的元数据传给语言模型或 Agent 框架,让 Agent“学会”可用的函数;
  4. 调用并校验(Invoke and Validate):Agent 选定函数后用给定参数执行,校验结果有效后回传给 Agent 作为上下文,驱动后续决策。

示例:数据库搜索函数

课程给出的简化伪代码演示了这一流程(以agent.register_function风格呈现):

# Define a custom function with clear input/output types def search_database(query: str) -> list: """ Search the database for articles matching the query. Args: query (str): The query search string Returns: list: List of matching article results """ try: results = database.search(query) return results except DatabaseError as e: logging.error(f"Database search failed: {e}") return [] # Register the function with the agent agent.register_function( name="search_database", function=search_database, description="Searches database for articles matching a query" ) # Example usage def process_search(): query = "Find recent articles on AI" results = agent.invoke("search_database", query) if results: agent.process_results(results) else: logging.info("No results found for query")

这段示例体现了函数接口设计的要点:用类型注解声明输入输出、用 docstring 描述行为、对失败路径做显式处理(捕获DatabaseError并返回空列表而非抛异常)。注意,真实smolagents项目中的写法通常是上面检索模块演示的Tool子类或@tool装饰器,本示例是用于说明流程的伪代码风格。

综合练习:从简单 RAG 到完整研究助手

agents.ipynb 把上述三大主题串成一份可运行的练习:

🐢 Exercise 1 —— 基础代码 Agent:用CodeAgent(tools=[DuckDuckGoSearchTool()], model=HfApiModel())回答 Python 概念问题,并挑战它处理基础语法、语言特性、代码示例三类问题。

🐕 Exercise 2 —— 自定义函数 Agent:用@tool装饰器实现一个calculate工具(支持sum/average/multiply/min/max),并让 Agent 回答“10、15、20、25、30 的平均值”这类问题:

from smolagents import CodeAgent, tool from typing import Union @tool def calculate(operation: str, numbers: object) -> float: """Performs basic mathematical operations on a list of numbers. Args: operation: One of 'sum', 'average', 'multiply', 'min', 'max' numbers: List of numbers to operate on Returns: float: Result of the operation """ if operation == "sum": return sum(numbers) elif operation == "average": return sum(numbers) / len(numbers) elif operation == "multiply": result = 1 for n in numbers: result *= n return result elif operation == "min": return min(numbers) elif operation == "max": return max(numbers) else: raise ValueError(f"Unknown operation: {operation}") # Create agent with custom tool math_agent = CodeAgent(tools=[calculate], model=HfApiModel()) # Test the agent response = math_agent.run("What is the average of 10, 15, 20, 25, and 30?") print(response)

进阶挑战:为计算器增加更多运算;新建自定义工具(如字符串处理、日期计算);在同一个 Agent 里组合多个工具。

🦁 Exercise 3 —— 高级检索 Agent:把 Web 搜索与记忆结合,构建多轮对话中保持上下文的研究 Agent,其 TODO 骨架要求你自行补全research_agent = CodeAgent(...)并用一组连续问题测试上下文保持能力。进阶挑战包括:测试跨主题上下文保持、实现自定义知识库工具(参照 retrieval_agents.md 的RetrieverTool示例)、构建“代码理解 + 研究能力”的混合 Agent。

小结

Agents 模块围绕“语言模型 + 工具 + 外部函数”这一核心范式,给出了三条清晰的技术路径:检索型 Agent 通过 Agentic RAG 实现自主、多步的信息检索;代码型 Agent 以CodeAgent编写并沙箱执行 Python 片段,配合@tool装饰器与additional_authorized_imports机制实现安全可控的工具调用;自定义函数 Agent 则强调接口契约、注册流程与校验逻辑,让 Agent 可靠地接入业务系统。你可以从模块首页 v1/8_agents/README.md 开始,依次阅读 检索型 Agent、代码型 Agent、自定义函数 Agent,最后用 agents.ipynb 完成从 🐢 到 🦁 的分级实战,即可完整掌握 smolagents 构建生产级 Agent 的核心能力。

  • 教程
  • 人工智能
  • 大模型
  • NLP
  • 微调

【免费下载链接】smol-course

A course on aligning smol models.

项目地址:https://gitcode.com/gh_mirrors/smo/smol-course
点击查看免费下载

相关推荐

上一篇:拯救老Mac:用OpenCore Legacy Patcher让2008-2017年设备重获新生
下一篇:searx Docker 部署实战指南:镜像运行、配置注入与自建镜像

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

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

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

立即咨询