学智能体最常见的困境是:教程东一块西一块,这篇讲 ReAct、那篇讲 RAG,串不起来;官方文档又长又深,看完更迷糊;或者学来学去变成了学 Dify 的节点怎么连、n8n 的工作流怎么配——本质上还是在做软件工程,只是把大模型当成后端的一个黑盒。Datawhale 社区开源的 Hello-Agents 冲的就是这个缺口:它是一套 16 章的中文系统教程,从智能体的定义与发展史讲起,带你手写 ReAct、Plan-and-Solve、Reflection 三大经典范式,再到基于 OpenAI 原生 API 自己攒出一个叫 HelloAgents 的框架,最后还教你用 LLM Judge 与 Win Rate 给自己的智能体打分。本教程不是把 16 章复述一遍,而是给你一条能当天跑通的动手路线:装环境、跑通最简智能体、手写范式、注册工具、做评估,每一步都有可直接执行的命令与代码。
Step 1:两条路线起步,先把环境与密钥配好
Hello-Agents 有两种打开方式。只想系统地读,直接开在线文档站即可,无需安装任何东西,全部 16 章在浏览器里就能看,国内还有加速镜像。想动手写代码(强烈建议,这个项目的价值有一半在代码里),就克隆仓库到本地:仓库里的 docs 目录是教程原文,code 目录是每一章配套的示例代码,Extra-Chapter 与 Co-creation-projects 是社区贡献的扩展章节与共创案例。别急着通读,正确姿势是「读一章、跑一章」,遇到报错去 Issue 区翻,社区很活跃。
# 路线一:在线阅读(零安装)
# https://datawhalechina.github.io/hello-agents/
# 路线二:本地跑代码
git clone https://github.com/datawhalechina/hello-agents.git
cd hello-agents
# 建独立虚拟环境,避免污染全局依赖
python -m venv .venv
source .venv/bin/activate # Windows 用 .venv\Scripts\activate
pip install -r requirements.txt # 或用官方包:pip install hello-agents
密钥这一步值得多说两句。框架用项目根目录的 .env 文件管理凭证,HelloAgentsLLM 会依据你填了哪些环境变量自动判断该走哪家供应商,所以你不必在代码里硬编码模型地址。常见的三个变量是 LLM_API_KEY、LLM_BASE_URL 与 LLM_MODEL_ID:只填 KEY 时走 OpenAI 官方;把 BASE_URL 指向 DeepSeek、通义千问或本地 Ollama,再配 MODEL_ID,就完成了换模型。.env 一定要进 .gitignore,千万不要提交到公开仓库。
# 复制模板再改,别直接改 .env.example
cp .env.example .env
# .env 示例(三选一思路)
# A. OpenAI 官方
LLM_API_KEY=sk-你的密钥
LLM_MODEL_ID=gpt-4o-mini
# B. 国内供应商(改 BASE_URL 即可换)
LLM_API_KEY=你的密钥
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_MODEL_ID=deepseek-chat
# C. 本地模型(先把 Ollama 跑起来)
LLM_BASE_URL=http://localhost:11434/v1
LLM_MODEL_ID=qwen2.5:7b
密钥就是钱:把 API Key 直接写进 .py 或 Notebook 再推到 GitHub,是被扫号脚本最快光顾的一类失误——公开仓库里泄露的密钥往往在几分钟内就被刷出账单。务必走 .env 且加进 .gitignore;团队共享时用各自的密钥或网关子账号,并给供应商后台设置用量上限。另外,运行示例会产生真实调用费用,先用便宜的小模型把流程跑通再换大模型。
Step 2:跑通最简智能体,看清四要素怎么拼起来
框架把智能体拆成四件事:感知(用户消息、工具输出、记忆)、规划(任务分解与步骤编排)、行动(调工具、调接口)、记忆(短期对话与长期存储)。SimpleAgent 就是这四件事的最小实现——它不带工具、不带复杂循环,只负责「把系统提示词和你这句话交给模型,拿回回答」。先让它跑起来,是为了确认密钥、网络与依赖链路都通了;跑通之后再加工具与循环,出问题时就能快速定位是新加的部分出错,还是底座就没配好。
# 官方 README 的导入路径(不同版本可能略有差异,以本地安装为准)
from hello_agents.agent import SimpleAgent
from hello_agents.llm import HelloAgentsLLM
llm = HelloAgentsLLM() # 自动读取 .env 里的配置
agent = SimpleAgent(
llm=llm,
system_prompt="你是一名严谨的技术文档助手,回答要给出依据,不确定就明说。",
)
print(agent.run("用三句话解释什么是智能体。"))
这一段跑通之后,建议立刻做一件小事:把 system_prompt 换成两种风格(比如「简洁的运维工程师」与「啰嗦的大学老师」),用同一个问题各问一次。你会直观感受到「人设与约束」对输出的影响有多大,而这恰恰是后面所有范式里最容易被忽视、却最影响效果的一层。官方在学习建议里也反复强调:强烈建议亲自运行、调试甚至修改项目里的每一段代码,只看不动手等于没学。
Step 3:手写三大经典范式,别只会调框架
第 4 章是整套教程的分水岭:它不让你调任何现成框架,而是要求你自己把三个范式写出来。ReAct 的核心是一个 Thought(想)→ Action(做)→ Observation(看)的循环,模型每一步先说想法,再决定调哪个工具,拿到结果后拼回上下文继续下一轮,直到给出最终答案;它适合步骤不多、边查边定的任务。Plan-and-Solve 反过来,先一次性把任务拆成计划,再逐步执行、最后整合,适合路径较长、需要先看清全局的任务。Reflection 则多一道自我检查:先生成,再让模型自己按标准挑毛病,然后改一版。
# 一个极简 ReAct 循环的骨架(对照第 4 章补齐细节)
for step in range(MAX_STEPS):
thought = llm.invoke(prompt_of(messages)) # 1) 想:本步要做什么
action = parse_action(thought) # 2) 解析出工具名与参数
if action is None:
return thought # 没动作 = 已得出结论
observation = tool_registry.run(action) # 3) 做:真正执行
messages.append({"role": "system", # 4) 看:结果回写上下文
"content": f"Observation: {observation}"})
return "达到步数上限仍未完成,请缩小任务范围"
写这一遍的价值在于,你会亲手撞上三件事:上下文怎么越滚越长、工具解析失败时怎么兜底、以及「步数上限」到底该设多少。这三件事在任何框架里都存在,只是被封装起来了;先在被封装的地方吃过亏,后面用 LangGraph、AutoGen 之类的框架时,你才知道每个参数在保护你免受什么伤害。第 6 章会带你用这些框架重做一遍同样的任务,那时对比会非常强烈。
循环必须设上限:任何 ReAct 式循环都要有 MAX_STEPS 与超时,否则一次错位解析就可能让模型在「调工具→报错→再调」里空转,几万 token 烧在一个永远结束不了的任务上。教程里的示例同样如此,请务必保留这个闸门,并把它作为评估指标之一(平均步数)记录下来。
Step 4:注册自己的工具,让智能体真的能干活
没有工具的智能体只会说话。框架用 ToolRegistry 统一管理工具,你只要继承 BaseTool,写清楚 name、description 与 run 方法,再 register 进去,模型就能按描述自行决定是否调用。这里最关键也最容易被低估的是 description:模型是照着这段自然语言来决定要不要用、传什么参数的,写得含糊(比如「处理数据」)会导致它要么不用、要么乱传参数;写得具体(比如「读取 CSV 文件,返回行列数与前 5 行预览」)命中率会明显上升。
from hello_agents.tool import ToolRegistry, BaseTool
class DataReadTool(BaseTool):
name = "data_read_tool"
description = "读取 CSV 数据文件,返回数据形状与前 5 行预览"
def run(self, file_path: str) -> str:
import pandas as pd
try:
df = pd.read_csv(file_path)
except Exception as exc:
return f"读取失败:{exc}" # 失败要返回可读文本,别抛异常
return f"形状 {df.shape}\n{df.head().to_string()}"
registry = ToolRegistry()
registry.register_tool(DataReadTool())
print(registry.list_tools()) # 确认注册成功再往下走
工具写法的两条经验值得照抄。一是 run 的返回值要「给模型看」而不是「给程序看」:抛异常会让整轮循环崩掉,而返回一句「读取失败:文件不存在,请检查路径」能让模型自己纠错、换个路径重试,这是工具调用健壮性的分水岭。二是工具要小而专:一个工具只做一件事,比一个工具接受十几个参数更好调用;需要组合能力时,让模型连着调两次,而不是塞进一个巨型工具里。
Step 5:记忆与上下文工程,别让对话越长越笨
第 8、9 两章处理的是长任务里最现实的问题:上下文是有限的,而工具输出与历史对话会把它迅速塞满。做法是把记忆分成两层——短期记忆就是当前这轮对话的消息列表,靠裁剪与摘要控制在窗口内;长期记忆则放进外部存储(向量库或键值库),需要时按相关性检索回来。第 8 章会带你搭一个可用的记忆与检索系统,并演示 RAG 的接入方式;第 9 章的上下文工程则更进一步,讲怎么在持续交互中保持「上下文理解」,包括该保留什么、该压缩什么、该在什么时候重新注入系统约束。
# 思路示意:短期记忆裁剪 + 长期记忆按需回填
short_term = keep_last_n(messages, n=8) # 只留最近若干轮
summary = llm.invoke(SUMMARY_PROMPT + older) # 更早的压成一段摘要
long_term = memory.search(current_query, k=3) # 长期记忆按相关度取回
messages = [system_msg, summary_msg] + long_term + short_term
把这一层做对,收益非常直接:同一批任务在长会话下的表现会稳定得多,而且 token 开销可控。反过来,跳过这一步直接往 messages 里无限追加,你会看到典型的「越聊越笨」——模型开始遗忘开头定下的约束、重复已经做过的步骤。这也是为什么教程把记忆与上下文工程放在框架之后、协议之前:它是从「能跑」到「能稳定跑」之间那道坎。
向量库不是必需品:第 8 章的 RAG 部分会用到 Chroma 或 Weaviate 之类的向量库,但它们属于可选项。数据量小、结构清晰时,用关键词检索甚至一个 JSON 文件都能跑通全流程;等检索质量真的成为瓶颈,再上向量库。别在最开始就把环境复杂度拉满,那是初学者弃坑的高发区。
Step 6:给智能体打分,用 LLM Judge 与 Win Rate 收尾
第 12 章是很多人会跳过、但真正拉开差距的一章。它给出两套互补的评估手段:LLM Judge 让一个模型当评委,按正确性、清晰度、完整性等维度对输出打分,适合衡量主观质量;Win Rate 则把智能体的输出与参考答案成对比较,统计「优于参考答案」的比例,适合量化对比两个版本的好坏。两者都要先准备一个小而稳的测试集——几十条你真正在意的任务就够,比临时想三条强得多。跑评估的正确节奏是:改一处,跑一轮,看分数变了没有;一次改三处,你永远不知道是哪处在起作用。
# 评估循环的最小骨架(评分维度与提示词见第 12 章)
cases = load_cases("eval/cases.jsonl") # 每条:{"input": ..., "reference": ...}
scores = []
for case in cases:
output = agent.run(case["input"])
scores.append({
"judge": judge_llm.score(case["input"], output), # 主观质量分
"win": judge_llm.compare(output, case["reference"]), # 对比胜/平/负
"steps": output.step_count, # 平均步数
"tokens": output.token_usage, # 成本
})
report(scores) # 看均值、看分布,重点看低分样本长什么样
把评估跑起来之后,你的智能体开发才算闭环:改提示词、换模型、调工具,都有了可比较的依据。教程后半部分的综合案例(智能旅行助手、自动化深度研究智能体、赛博小镇)也都建议照着这条路线做——先定任务集,再实现,最后评估。至于第 11 章的 Agentic RL(从 SFT 到 GRPO 训练自己的模型),则需要 GPU 资源,新手可以先跳过,等前面的链路都熟了再回来啃。
这是教程不是工具:Hello-Agents 不会「装一下就能用」,它的产出是你脑子里的东西加你自己敲出来的代码。另外它是面向学习的轻量框架,SimpleAgent 一类组件刻意做得精简,缺少高并发、多租户、可观测这些企业级能力;要上生产,请把它当作理解原理的跳板,再换到成熟框架上重写。各章的 Python 版本要求在 3.9 到 3.11 之间有过口径变化,以仓库 Preface 的当前说明为准。
常见问题速查
| 现象 | 原因与处理 |
|---|---|
| ModuleNotFoundError: hello_agents | 装到了别的虚拟环境;确认 activate 之后再 pip install,用 which python 核对 |
| AuthenticationError / 401 | .env 里 KEY 与 BASE_URL 不匹配,或 MODEL_ID 在该供应商不存在 |
| 导入路径报红 | 不同发布版的包结构有差异;用 pip show hello-agents 定位后再对照本地 README |
| 模型从来不调我的工具 | description 写得太含糊;改成「做什么 + 入参 + 返回什么」的具体句式 |
| 工具一报错整轮就崩 | run 里抛了异常;改成返回可读的错误文本,让模型自己纠错重试 |
| 循环停不下来、token 飞涨 | 没设 MAX_STEPS 与超时;补上闸门并把平均步数纳入评估 |
| 本地模型极慢 | 模型服务没起或 BASE_URL 端口写错;先 curl 一下服务端点 |
| 长对话越聊越笨 | 缺记忆与上下文裁剪;加摘要 + 长期记忆按需回填 |