如果刚开始接触智能体,最容易卡住的地方通常不是“概念听不懂”,而是“看完原理还是不知道怎么自己跑起来”。这篇文章的目标很直接:结合 Datawhale《Hello Agents》第一章 1.3 小节“动手体验:5 分钟实现第一个智能体”的思路,分析我手上的这个 travel_agent_demo 项目,并给出一条适合本地环境的实践路径。
这份项目的价值在于,它没有上来就引入一堆框架,而是保留了 Agent 最核心的闭环:
- 大模型负责理解任务和做决策
- Python 函数负责充当工具
- 主循环负责执行
Thought -> Action -> Observation
如果你本地已经安装了 ollama,并且已经拉好了 gemma4:31b,那么这个项目基本就是一份很适合入门的最小可运行样例。
先看理论:1.3 小节到底讲了什么
Datawhale 在 1.3 小节里做了一件很重要的事:它没有先讲复杂框架,而是先带你手写一个最小智能体。这个例子的核心任务是:
先查询天气,再根据天气推荐景点。
这个任务看起来简单,但已经完整覆盖了一个 Agent 的基本能力:
- 接收用户目标
- 将目标拆成多个步骤
- 在每一步决定是否调用工具
- 读取工具返回结果
- 基于新观察继续推理
- 在信息足够时输出最终答案
这正是 Thought-Action-Observation 范式最适合演示的地方。Datawhale 1.3 小节把这个过程拆成了三部分:
- 定义系统提示词,约束模型输出
Thought和Action - 定义工具,例如天气查询和景点推荐
- 写一个循环,不断把历史上下文和工具观察结果喂给模型
它的重点不在“代码很多”,而在“闭环完整”。这一点,正好和当前这个项目完全对上。
参考链接: Datawhale 原文
这个项目和 1.3 小节是一一对应的
travel_agent_demo 的结构非常克制,只有 4 个核心文件:
config.pytools.pyllm_client.pyagent.py
如果按 1.3 小节的思路去看,它们的分工非常清晰。
1. config.py:把“提示词”显式写出来
Datawhale 1.3 的第一步是写 AGENT_SYSTEM_PROMPT,告诉模型:
- 你是谁
- 你有哪些工具
- 你必须用什么格式回复
这个项目同样把提示词放在了 config.py 里,并明确要求模型每次只能输出一组:
Thought: ...Action: ...
同时要求 Action 只能是两种形式:
- 工具调用:
function_name(arg="value") - 结束任务:
Finish[最终答案]
这一步很关键。很多初学者以为“有模型就有 Agent”,其实不对。没有明确的动作协议,模型就无法稳定进入“可执行”的状态。
2. tools.py:把外部世界变成可调用能力
在 Agent 体系里,工具就是模型接触环境的“手”和“眼”。这个项目提供了 3 个工具:
get_weather(city: str)web_search(query: str)get_attraction(city: str, weather: str)
它们背后的实现也非常直白:
get_weather调用wttr.inweb_search调用 Tavily 搜索 APIget_attraction本质上是构造一个景点推荐搜索词,再复用web_search
这和 1.3 小节的设计是同一种思想:工具不用复杂,但要让模型真的“能做事”。
3. llm_client.py:对接 OpenAI 兼容接口
1.3 小节专门强调了一个现实问题:很多模型服务都走 OpenAI 兼容接口,所以最好封一个通用客户端。这个项目正是这么做的。
llm_client.py 里的 OpenAICompatibleClient 很轻量,核心只有一件事:把 system_prompt 和 user prompt 发送给兼容 OpenAI Chat Completions 的接口。
这也是它能直接接入本地 Ollama 的原因。只要你的 Ollama 开了 OpenAI 兼容入口,配置好:
LLM_BASE_URLLLM_API_KEYLLM_MODEL
就可以把本地模型当成 Agent 的“大脑”。
4. agent.py:真正的 Agent 循环
整个项目最像 1.3 小节“原样落地”的部分,就是 agent.py。
它做了几件非常典型的事:
- 接收用户输入
- 拼接历史上下文
prompt_history - 调用大模型生成
Thought + Action - 解析
Action - 如果是工具调用,就执行对应 Python 函数
- 把结果写成
Observation - 继续下一轮,直到遇到
Finish[...]
这就是一个标准的最小 Agent 闭环。
如果只用一句话概括这个项目,可以这么说:
它不是“把大模型接到 Python 上”,而是“让大模型在一个受控循环里学会决定何时调用工具”。
为什么这个项目适合写成“第一个智能体”
因为它刚好处在一个很好的平衡点上:
- 比纯 Prompt Demo 更完整,因为已经有工具调用和多轮循环
- 比 LangChain、AutoGen 之类框架更容易理解,因为每一步都能直接看到
- 比只会对话的聊天机器人更接近真正的 Agent,因为它具备行动能力
对于博客读者来说,这种项目有三个优点。
第一,代码量小,读者不会在框架封装里迷路。
第二,概念和实现能一一对应。你在书里看到的:
- 提示词
- 工具
- 动作解析
- 观察回填
- 结束条件
在项目代码里都能找到落点。
第三,容易迁移。你今天做的是旅行助手,明天就能改成:
- 本地知识库问答 Agent
- 网页检索 Agent
- 天气与出行建议 Agent
- 带记忆的个性化推荐 Agent
用本地 Ollama 跑这个项目
你的环境已经具备一个关键前提:本地安装了 ollama,并且已经拉好了 gemma4:31b。这意味着 LLM 侧基本已经准备完成。
这个项目的 README 给出的配置思路如下:
pip install -r requirements.txt
然后准备 .env:
TAVILY_API_KEY=你的key
LLM_API_KEY=ollama
LLM_BASE_URL=http://127.0.0.1:11434/v1
LLM_MODEL=gemma4:31b
注意一件事:项目当前 README 里示例地址写的是局域网 IP http://局域网IP:11434/v1。如果你就是在本机运行 Ollama,更常见也更稳妥的写法是:
LLM_BASE_URL=http://127.0.0.1:11434/v1
启动方式很简单:
python agent.py
然后输入类似:
帮我查询今天贵阳的天气,并推荐一个适合现在去的景点
运行前要知道的两个现实问题
这个项目能跑,不代表它已经“产品化”。如果你要写博客,最好把下面两点讲清楚。
1. 没有 TAVILY_API_KEY,景点推荐链路会失败
项目里 get_attraction() 实际上是复用 web_search() 完成的,而 web_search() 依赖 Tavily。
这意味着:
- 查天气可以走
wttr.in - 查景点推荐依赖 Tavily
- 如果没配置
TAVILY_API_KEY,涉及网页搜索和景点推荐的步骤会返回错误
所以如果你想完整复现 Datawhale 1.3 里的“天气 -> 景点推荐 -> 最终总结”三步链路,最好提前准备 Tavily Key。
2. 大模型越大,多轮循环越容易变慢
项目作者已经意识到了这一点,所以在 agent.py 里做了一个很实用的小优化:对 Observation 做摘要截断,避免上下文越来越长。
这件事在本地模型场景下尤其重要。gemma4:31b 的效果会更稳,但如果机器资源一般,多轮推理的等待感会明显上升。博客里可以直接提醒读者:
- 入门先关注闭环是否跑通
- 再关注响应速度
- 最后再考虑更复杂的记忆、规划和反思机制
从“能跑”到“像一个真正的智能体”,这个项目还差什么
如果把标准放在“第一个智能体”,这个项目已经合格。如果把标准放在“更像真实 Agent 系统”,它还可以继续往前走。
1. 记忆
当前 prompt_history 只保存本次会话中的历史,没有用户长期偏好。
如果要增强,可以增加:
- 用户偏好存储
- 预算约束
- 喜欢的景点类型
- 历史拒绝记录
这正好对应 Datawhale 习题里提到的“记住用户偏好”方向。
2. 反思与容错
目前如果工具失败,模型只能在错误信息上继续推理,但没有明确的重试策略和回退策略。
更稳一点的做法是增加:
- 工具失败重试
- 参数修正
- 备选工具
- 明确的失败收敛条件
3. 更强的动作协议
现在 parse_action() 通过正则解析参数,足够轻量,但对复杂参数不够稳。
如果后续想扩展更多工具,更建议演进成:
- JSON 格式动作
- 函数调用 schema
- 严格参数校验
4. 更真实的旅游场景
当前的“景点推荐”本质上还是网页搜索摘要,离真正旅游助手还有距离。下一步可以扩展的能力包括:
- 酒店查询
- 路线规划
- 门票信息
- 用户预算约束
- 多城市 itinerary 生成
从 Datawhale 1.3 小节到这个 travel_agent_demo,最大的体会是:第一个智能体不需要复杂,关键是先把闭环搭起来。只要模型能按照约定输出动作、程序能解析动作、工具能把外部信息带回来,一个真正意义上的 Agent 就已经出现了。
而当这个闭环跑在本地 Ollama + gemma4:31b 上时,学习体验会非常具体。你不再只是“理解概念”,而是真的看见模型如何决定先查天气、再查景点、最后合成答案。对初学者来说,这一步比额外学习十个框架更重要。
参考资料
- DatawhaleChina, Hello Agents, 第一章《初识智能体》
- 本项目 README:
README.md - 本项目核心实现:
config.py、tools.py、llm_client.py、agent.py
