20 min · 这 30 行代码是你毕业设计(L20)的种子
🎒 预备知识:完成上一课「L7」(零基础入口:第 0 课)
Agent = LLM 在循环里自主决定调用哪些工具,直到达成目标。
它和 chatbot 差在工具,和 workflow 差在谁决定下一步——workflow 是代码写死的图,
agent 是模型现场决策的循环。
别背定义,读代码。下面是一个真的能跑的最小 agent(OpenAI 兼容 API + 一个工具), 注意它怎么体现公式四要素,以及 A3 三条铁律的影子:
from openai import OpenAI
import json
client = OpenAI()
TOOLS = [{"type": "function", "function": {
"name": "read_file", "description": "读取本地文本文件内容",
"parameters": {"type": "object",
"properties": {"path": {"type": "string"}},
"required": ["path"]}}}]
def execute(name, args):
try:
return open(args["path"]).read()[:4000]
except Exception as e:
return json.dumps({"error": str(e)}) # 铁律①:失败也是消息,不抛异常
messages = [{"role": "system", "content": "你是文件问答助手。"},
{"role": "user", "content": "tmp/notes.md 里写了什么?"}]
for step in range(10): # 铁律③:步数上限,防失控
msg = client.chat.completions.create(
model="gpt-4o-mini", messages=messages,
tools=TOOLS).choices[0].message
messages.append(msg) # 铁律②:历史只追加
if not msg.tool_calls: # 停止条件:不再要工具 = 给出最终回答
print(msg.content); break
for call in msg.tool_calls: # 有工具调用:执行并回填,进入下一轮
messages.append({"role": "tool", "tool_call_id": call.id,
"content": execute(call.function.name,
json.loads(call.function.arguments))})
对照公式读:LLM(chat.completions.create 那次调用)、工具(TOOLS 与 execute)、
循环(for + 回填)、停止条件(第 19 行 no tool_calls / 第 12 行步数上限)。
这 30 行就是所有 agent 的胚胎——OpenClaw 那 1562 行(正课 L16)是给它加上流式、并发、
compaction、钩子之后的成人版。
| 下一步谁决定 | 例子 | 退化缺什么 | |
|---|---|---|---|
| Chatbot | 没有"下一步",一次回答 | 裸聊 LLM | 缺工具+循环 |
| Workflow | 代码写死的流程图,LLM 只填空 | 固定管道:摘要→翻译→润色 | 有工具但无自主决策 |
| Agent | 模型现场决定,路径不可预知 | Easel、Claude Code | 四要素齐备 |
判定口诀:跟踪一次真实任务的调用序列,如果写代码时就能画出完整流程图,它是 workflow; 如果流程图必须等模型边跑边画,它才是 agent。
Anthropic 的工程建议值得抄在墙上:能 workflow 就别 agent——确定性任务用固定图更便宜 (少轮数、可缓存、可测试);agent 的自由度留给真正需要现场判断的任务。 Easel 是 agent,因为"发一条小红书"的路径(先查热点还是先写文案?图片几张?要不要先过闸门?)无法预写。
坑 1:一切皆 agent。把"翻译这段话"也包成 agent——多花十倍 token 换来零收益。 先问:这个任务需要几次现场决策?答案是 0 次就别用 agent。
坑 2:agent 没有预算。步数上限、超时、费用护栏缺一不可——一次坏决策在循环里会 自我放大(模型决定"再试一次"是它的天性)。
坑 3:把 workflow 伪装成 agent。prompt 里写死"第一步…第二步…第三步…", 模型只是念稿——这不是 agent,是昂贵的 workflow。真 agent 的 prompt 写目标和约束, 不写步骤。
判断三个场景该用 chatbot / workflow / agent 哪个,并各说一句理由: ① 每天把日报翻译成英文;② 帮用户找到并修复仓库里的 bug;③ 陪练英语口语。 然后回答:上面 30 行代码里,哪一行如果删掉,它就从 agent 退化成了 chatbot?发到对话里我批改。