导读:用 Claude Code 和 Python 造自主 AI agent
六个目标,从四层栈到 ReAct,从验证和停止条件到防注入、沙箱与预算。每条说清楚它真正难在哪,以及对应哪一篇。附一个三十几行的 Python 循环骨架。
这个系列讲的是怎么造一个能自己转起来的 AI agent —— 不是写一句更好的提示词,是造那个替你写提示词的东西。
先把目标摆出来,六条。每条后面我加一句它真正难在哪,因为难点往往不在它字面上那个词。
| 目标 | 真正难的地方 | 在哪篇 |
|---|---|---|
| 用 Claude Code 和 Python 从零造自主 agent | 循环骨架只有几十行,难的是往里放什么 | 本篇 + 第四篇 |
| 掌握四层栈(提示词 / 上下文 / harness / 循环) | 不是学四个词,是知道错误在哪层炸、炸多大 | 第一篇 |
| 用 ReAct 设计可靠的工作流 | 「观察」那一步最容易被省掉,而它是全部意义所在 | 第二篇 |
| 做出带验证、停止条件的决策循环 | 停下来比转起来难,而判官不能是干活的那个 | 第二篇 + 第三篇 |
| 防住上下文腐烂、跑飞的循环、提示词注入 | 这三样的共同点是它们都不报警 | 第三篇 + 第五篇 |
| 上生产:护栏、沙箱、预算控制 | 上限不是省钱手段,是断路器 | 第五篇 |
一个能跑的循环骨架,三十几行
先看骨架,因为看过之后你会发现这东西简单得令人失望 —— 而这正是重点:难的从来不是循环本身。
# 省略:import、client 初始化、TOOLS 里那两个工具(read_file / run_tests)
def step(messages, budget): """一次 step = 一次模型请求 + 它调起的工具。预算记在发出之前。""" budget["calls"] += 1 # ← 记在动作之前,不是之后 if budget["calls"] > budget["max_calls"]: raise RuntimeError("预算用完")
res = client.chat.completions.create( model="...", messages=messages, tools=tool_schemas() ) msg = res.choices[0].message messages.append(msg)
# 没有工具调用 = 这一步只是推理,交给上层判断要不要继续 if not msg.tool_calls: return None
for call in msg.tool_calls: # ← 「行动」 fn = TOOLS[call.function.name] out = fn(**json.loads(call.function.arguments)) messages.append({ # ← 「观察」,回填给模型 "role": "tool", "tool_call_id": call.id, "content": str(out)[:4000], }) return msg
def loop(task, verify, budget, max_turns=20): messages = [{"role": "system", "content": SYSTEM}, {"role": "user", "content": task}] for turn in range(max_turns): step(messages, budget) # 推理 → 行动 → 观察 ok, why = verify() # ← 铰链:由外部判定,不问模型 if ok: return "done", turn messages.append({"role": "user", "content": f"验证没过:{why}\n继续。"}) return "gave_up", max_turns # ← 有界,不许无限转这里面每一行都对应系列里的一个概念:
step()里那个 推理 → 行动 → 观察 就是 ReActbudget["calls"] += 1写在请求之前 —— 写在之后的话,超时和被限流的请求不进账,上限就拦不住真实请求数verify()是那个铰链,而且它是外部函数,不是问模型「你觉得干完了吗」max_turns那个for是有界迭代 —— 没有它,一个修不好的 bug 能转一整夜
三十几行里,只有三行是「循环」本身,剩下的全是护栏。 这个比例不是巧合,它就是这个系列想说的事。
这个骨架还差什么
上面那段能跑,但它离一个真正的「循环」还差三样,正好是第四篇那张清单里的:
一、它不会自己醒。 得有人调用 loop()。加上定时器,它才从「一次运行」变成「循环」。
二、它没有记忆。 进程一退,messages 就没了。要跨天接着干,状态得落到磁盘上 —— agent 会忘,仓库不会。
三、verify() 里放什么,决定了它的上限。 放 pytest 就是确定性检查,最可信;放「让另一个模型看看」就要小心 —— 那个模型必须没参与干活,否则它是在给自己判卷。
需要什么前置知识
课程说的是不需要 agent 或循环工程的经验。我加两句实际的:
要有的: 会读会写 Python 或者 TypeScript,用过命令行,知道 git 是干什么的。
不需要有的: 机器学习背景。这个系列从头到尾没有一个梯度,它是软件工程,不是模型训练。
真正会卡住人的,是另一样东西: 你得有一个能便宜地判断对错的场景。没有这个,循环转得越勤,坏东西堆得越多 —— 这也是选题那一节最先讲的。
读的顺序
按 1→5 顺着读最省事。但如果你只有一个小时:
如果你想先要一个不带术语的版本,我还写过一份给小孩看的。
一句先打的预防针
这个系列里我引用的数字,绝大多数是别人的实验和别人的生产环境 —— 我自己那套东西还停在 harness 那一层,有状态文件、有错误分类、有预算三卡,但没有定时器,每次还得我按启动。
按第四篇那张六要素表自查,我缺的恰好是最关键的两格:调度(让它成为循环)和独立评估器(让它不闯祸)。
转述的实验和自己跑过的实验,可信度不是一回事。 这句话在后面几篇里还会重复。