导读:用 Claude Code 和 Python 造自主 AI agent

六个目标,从四层栈到 ReAct,从验证和停止条件到防注入、沙箱与预算。每条说清楚它真正难在哪,以及对应哪一篇。附一个三十几行的 Python 循环骨架。

位置
第 00 篇 / 共 6 篇
预计
5 分钟

这个系列讲的是怎么造一个能自己转起来的 AI agent —— 不是写一句更好的提示词,是造那个替你写提示词的东西。

先把目标摆出来,六条。每条后面我加一句它真正难在哪,因为难点往往不在它字面上那个词。

目标 真正难的地方 在哪篇
用 Claude Code 和 Python 从零造自主 agent 循环骨架只有几十行,难的是往里放什么 本篇 + 第四篇
掌握四层栈(提示词 / 上下文 / harness / 循环) 不是学四个词,是知道错误在哪层炸、炸多大 第一篇
用 ReAct 设计可靠的工作流 「观察」那一步最容易被省掉,而它是全部意义所在 第二篇
做出带验证、停止条件的决策循环 停下来比转起来难,而判官不能是干活的那个 第二篇 + 第三篇
防住上下文腐烂、跑飞的循环、提示词注入 这三样的共同点是它们都不报警 第三篇 + 第五篇
上生产:护栏、沙箱、预算控制 上限不是省钱手段,是断路器 第五篇

一个能跑的循环骨架,三十几行

先看骨架,因为看过之后你会发现这东西简单得令人失望 —— 而这正是重点:难的从来不是循环本身。

loop.py · 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() 里那个 推理 → 行动 → 观察 就是 ReAct
  • budget["calls"] += 1 写在请求之前 —— 写在之后的话,超时和被限流的请求不进账,上限就拦不住真实请求数
  • verify() 是那个铰链,而且它是外部函数,不是问模型「你觉得干完了吗」
  • max_turns 那个 for有界迭代 —— 没有它,一个修不好的 bug 能转一整夜

三十几行里,只有三行是「循环」本身,剩下的全是护栏。 这个比例不是巧合,它就是这个系列想说的事。

这个骨架还差什么

上面那段能跑,但它离一个真正的「循环」还差三样,正好是第四篇那张清单里的:

一、它不会自己醒。 得有人调用 loop()。加上定时器,它才从「一次运行」变成「循环」。

二、它没有记忆。 进程一退,messages 就没了。要跨天接着干,状态得落到磁盘上 —— agent 会忘,仓库不会。

三、verify() 里放什么,决定了它的上限。pytest 就是确定性检查,最可信;放「让另一个模型看看」就要小心 —— 那个模型必须没参与干活,否则它是在给自己判卷。

需要什么前置知识

课程说的是不需要 agent 或循环工程的经验。我加两句实际的:

要有的: 会读会写 Python 或者 TypeScript,用过命令行,知道 git 是干什么的。

不需要有的: 机器学习背景。这个系列从头到尾没有一个梯度,它是软件工程,不是模型训练。

真正会卡住人的,是另一样东西: 你得有一个能便宜地判断对错的场景。没有这个,循环转得越勤,坏东西堆得越多 —— 这也是选题那一节最先讲的。

读的顺序

按 1→5 顺着读最省事。但如果你只有一个小时:

  • 想知道这是什么第一篇的「每一层的错误炸开的范围不一样」那一节
  • 想动手 → 直接跳第四篇的五步,回头再补原理
  • 已经有循环在跑 → 从第五篇开始,那四种代价现在可能已经在你的系统里堆着了

如果你想先要一个不带术语的版本,我还写过一份给小孩看的

一句先打的预防针

这个系列里我引用的数字,绝大多数是别人的实验和别人的生产环境 —— 我自己那套东西还停在 harness 那一层,有状态文件、有错误分类、有预算三卡,但没有定时器,每次还得我按启动。

按第四篇那张六要素表自查,我缺的恰好是最关键的两格:调度(让它成为循环)和独立评估器(让它不闯祸)。

转述的实验和自己跑过的实验,可信度不是一回事。 这句话在后面几篇里还会重复。