第一章 The Agent Loop (智能体循环)
[ s01 ] s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12
"本专栏基于开源项目
learn-claude-code的官方文档。原文档非常硬核,为了方便像我一样的新手小白理解,我对文档进行了逐行精读 ,并加入了很多中文注释、大白话解释和踩坑记录。希望这套'咀嚼版'教程能帮你推开 AI Agent 开发的大门。"
"One loop & Bash is all you need" -- 一个工具 + 一个循环 = 一个智能体。
一、问题
语言模型能推理代码, 但碰不到真实世界 -- 不能读文件、跑测试、看报错。没有循环, 每次工具调用你都得手动把结果粘回去。你自己就是那个循环。
二、解决方案
lua
+--------+ +-------+ +---------+
| User | ---> | LLM | ---> | Tool |
| prompt | | | | execute |
+--------+ +---+---+ +----+----+
^ |
| tool_result |
+----------------+
(loop until stop_reason != "tool_use")
一个退出条件控制整个流程。循环持续运行, 直到模型不再调用工具。s01_agent_loop.py 所做的事情,就是用不到 50 行代码,把你自己这一部分给自动化了。
这就是经典的 ReAct (Reasoning and Acting) 范式:让 AI 边思考边行动的交互模式,让大语言模型能够像人类一样推理→行动→观察→再推理,逐步解决复杂问题。
scss
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Thought │ ──→ │ Action │ ──→ │ Observation │ ──→ │ Thought │
│ (思考) │ │ (行动) │ │ (观察) │ │ (再思考) │
└─────────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘
│
任务完成 ←────────────────────────────┘
给出答案
三、工作原理
- 用户 prompt 作为第一条消息。
go
messages.append({"role": "user", "content": query})
- 将消息和工具定义一起发给 LLM。我们定义的TOOLS的列表,这就像是一本"工具使用手册",你把它作为输入的一部分喂给了大模型。
ini
response = client.messages.create(
model=MODEL, system=SYSTEM, messages=messages,
tools=TOOLS, max_tokens=8000,
)
- 追加助手响应。检查
stop_reason-- 如果模型没有调用工具, 结束。
go
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return
- 执行每个工具调用, 收集结果, 作为 user 消息追加。回到第 2 步。
css
results = []
for block in response.content:
if block.type == "tool_use":
output = run_bash(block.input["command"])
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output,
})
messages.append({"role": "user", "content": results})
- 组装为一个完整函数:
python
def agent_loop(query):
messages = [{"role": "user", "content": query}]
while True: # 循环开始,理论上可以无限跑
# ... 这里是 LLM 思考的过程 ...
response = client.messages.create(
model=MODEL, system=SYSTEM, messages=messages,
tools=TOOLS, max_tokens=8000,
)
messages.append({"role": "assistant", "content": response.content})
# ... 这里就是那个"唯一的退出条件" ...
if response.stop_reason != "tool_use":
return
results = []
for block in response.content:
if block.type == "tool_use":
output = run_bash(block.input["command"])
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output,
})
messages.append({"role": "user", "content": results})
不到 30 行, 这就是整个智能体。后面 11 个章节都在这个循环上叠加机制 -- 循环本身始终不变。
四、变更内容
| 组件 | 之前 | 之后 |
|---|---|---|
| Agent loop | (无) | while True + stop_reason |
| Tools | (无) | bash (单一工具) |
| Messages | (无) | 累积式消息列表 |
| Control flow | (无) | stop_reason != "tool_use" |
五、试一试
想要跑通之前记得不要忘记了添加.env文件哦。
bash
cd learn-claude-code
python agents/s01_agent_loop.py
试试这些 prompt (英文 prompt 对 LLM 效果更好, 也可以用中文):
Create a file called hello.py that prints "Hello, World!"List all Python files in this directoryWhat is the current git branch?Create a directory called test_output and write 3 files in it
六、其他
block长什么样?
将block打印出来,也就是response.content,它是ToolUseBlock 对象。
ini
ToolUseBlock(
id='bash_0', # 工具调用唯一标识符
caller=None, # 调用者信息(教学版中为None)
input={'command': 'echo 'print("Hello, World!")' > hello2.py'}, # ← 核心参数
name='bash', # 工具名称
type='tool_use' # 块类型
)