入门 📋 6 个步骤 第 555 / 557 篇

用 Datawhale Hello-Agents 从零构建智能体:环境配置、三大范式与自研框架实操

Agent 教程东一块西一块、官方框架又太重?Datawhale 开源的 Hello-Agents 是一套 16 章中文系统教程:从智能体四要素讲起,带你手写 ReAct、Plan-and-Solve、Reflection 三大范式,基于 OpenAI 原生 API 攒出自己的 HelloAgents 框架,最后用 LLM Judge 与 Win Rate 给智能体打分。本教程给出一条当天可跑通的动手路线。

2026.10.22· 12 分钟上手· 约 3949 字· 📘 Hello-Agents / 🐍 Python

学智能体最常见的困境是:教程东一块西一块,这篇讲 ReAct、那篇讲 RAG,串不起来;官方文档又长又深,看完更迷糊;或者学来学去变成了学 Dify 的节点怎么连、n8n 的工作流怎么配——本质上还是在做软件工程,只是把大模型当成后端的一个黑盒。Datawhale 社区开源的 Hello-Agents 冲的就是这个缺口:它是一套 16 章的中文系统教程,从智能体的定义与发展史讲起,带你手写 ReAct、Plan-and-Solve、Reflection 三大经典范式,再到基于 OpenAI 原生 API 自己攒出一个叫 HelloAgents 的框架,最后还教你用 LLM Judge 与 Win Rate 给自己的智能体打分。本教程不是把 16 章复述一遍,而是给你一条能当天跑通的动手路线:装环境、跑通最简智能体、手写范式、注册工具、做评估,每一步都有可直接执行的命令与代码。

📘 本教程适合:有基础 Python 能力、会写简单 API 调用,想从「大模型使用者」转成「智能体构建者」的开发者与学生。硬件没有门槛,普通笔记本即可;你需要自备一个大模型的 API Key(OpenAI、DeepSeek、通义千问、ModelScope 等都行)。项目为开源免费教程,代码以 MIT 协议发布。文中命令以官方仓库当前 README 为准。

Step 1:两条路线起步,先把环境与密钥配好

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:跑通最简智能体,看清四要素怎么拼起来

2 SimpleAgent 是最小可运行单元

框架把智能体拆成四件事:感知(用户消息、工具输出、记忆)、规划(任务分解与步骤编排)、行动(调工具、调接口)、记忆(短期对话与长期存储)。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 换成两种风格(比如「简洁的运维工程师」与「啰嗦的大学老师」),用同一个问题各问一次。你会直观感受到「人设与约束」对输出的影响有多大,而这恰恰是后面所有范式里最容易被忽视、却最影响效果的一层。官方在学习建议里也反复强调:强烈建议亲自运行、调试甚至修改项目里的每一段代码,只看不动手等于没学。

💡 报错先看三类:ModuleNotFoundError 说明装错了虚拟环境;AuthenticationError 说明 .env 里的 KEY 与 BASE_URL 不匹配(这是最常见的一类);本地模型响应极慢,多半是模型服务没起来或 BASE_URL 指向了错误的端口。把这三类排掉,九成的「跑不起来」就解决了。

Step 3:手写三大经典范式,别只会调框架

3 ReAct / Plan-and-Solve / Reflection

第 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:注册自己的工具,让智能体真的能干活

4 ToolRegistry 与 BaseTool

没有工具的智能体只会说话。框架用 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 的返回值要「给模型看」而不是「给程序看」:抛异常会让整轮循环崩掉,而返回一句「读取失败:文件不存在,请检查路径」能让模型自己纠错、换个路径重试,这是工具调用健壮性的分水岭。二是工具要小而专:一个工具只做一件事,比一个工具接受十几个参数更好调用;需要组合能力时,让模型连着调两次,而不是塞进一个巨型工具里。

💡 注册之后先手动跑一遍 registry.run("data_read_tool", ...) 确认输出格式,再交给模型。很多「模型不会用我的工具」的问题,本质是工具本身返回了一坨模型读不懂的东西。

Step 5:记忆与上下文工程,别让对话越长越笨

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 收尾

6 没有评估就没有迭代

第 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 资源,新手可以先跳过,等前面的链路都熟了再回来啃。

💡 三个读法:想系统打基础,从第 1 章顺序读,重点动手做第 4 章与第 7 章;已经有经验的,直接跳到第 4 章;准备面试,看第 1、4、6、7 章加社区贡献的面试题汇总。PDF 版可从发布页免费下载,带社区水印,禁止商用转售。

这是教程不是工具: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 一下服务端点
长对话越聊越笨缺记忆与上下文裁剪;加摘要 + 长期记忆按需回填
← 返回教程中心