最小循环 · 一个 Agent 只需要什么The Minimal Loop · What an Agent Really Needs.
20 行代码就能写出一个能工作的 Agent —— prompt、LLM、工具调用、结果回传,循环直到完成。A working agent fits in 20 lines — prompt, LLM, tool call, result feedback, loop until done.
8 分钟 · 初稿 2026.058 Min · Drafted 2026.05
第一章说 agent 是一个循环。这一章把那个循环写出来 —— 一个真能跑的最小 agent,不到 30 行,没有任何框架。写完你会有两个收获:一个能改的骨架(就是那个研究助手的种子),和一双能看穿框架的眼睛。Chapter 1 said an agent is a loop. This chapter writes that loop out — a real, working minimal agent in under 30 lines, with no framework. You'll walk away with two things: a skeleton you can edit (the seed of that research assistant), and an eye that sees through frameworks.
— I
一个 Agent 只需要四样东西An Agent Needs Only Four Things.
剥到最小,一个 agent 就是:一个目标、一个会调工具的模型、一组工具、一个带停止条件的循环。其余都是便利,不是本质。Stripped to the minimum, an agent is: a goal, a model that can call tools, a set of tools, and a loop with a stop condition. Everything else is convenience, not essence.这四样里,模型那一项有个硬要求 —— 它得支持 tool use:能在该调工具时返回 stop_reason: "tool_use",而不是硬编一段文本让你自己解析。1注 1Note 1Anthropic 文档 · Tool use overview —— client tool 的循环:Claude 返回 stop_reason: tool_use 与 tool_use 块(id / name / input),你执行后回传 tool_result(带 tool_use_id)。示例模型 claude-opus-4-8,anthropic-version 2023-06-01。截至 2026-05。Anthropic docs · Tool use overview — the client-tool loop: Claude returns stop_reason: tool_use with tool_use blocks (id / name / input); you execute and send back a tool_result (with tool_use_id). Example model claude-opus-4-8, anthropic-version 2023-06-01. As of 2026-05.剩下三样都是你写的代码:目标塞进 messages,工具用 JSON Schema 描述,循环就是一个 while。Of the four, the model has one hard requirement — it must support tool use: returning stop_reason: "tool_use" when a tool is needed, instead of emitting text for you to parse by hand.1注 1Note 1Anthropic 文档 · Tool use overview —— client tool 的循环:Claude 返回 stop_reason: tool_use 与 tool_use 块(id / name / input),你执行后回传 tool_result(带 tool_use_id)。示例模型 claude-opus-4-8,anthropic-version 2023-06-01。截至 2026-05。Anthropic docs · Tool use overview — the client-tool loop: Claude returns stop_reason: tool_use with tool_use blocks (id / name / input); you execute and send back a tool_result (with tool_use_id). Example model claude-opus-4-8, anthropic-version 2023-06-01. As of 2026-05. The other three are code you write: the goal goes into messages, tools are described with JSON Schema, and the loop is a while.框架(LangChain 这类)不是错,它只是把这四样藏在抽象后面,让 agent 看起来很复杂。2注 2Note 2Anthropic · 「Building Effective Agents」(2024-12-19)—— augmented LLM 作为基本积木;agent 是在循环里用工具、读环境反馈、自己决定下一步。Anthropic · 'Building Effective Agents' (2024-12-19) — the augmented LLM as the basic block; an agent uses tools in a loop, reads environment feedback, and decides its next step.先手写一遍,你才知道框架在替你做什么 —— 以及它什么时候碍事。Frameworks (the LangChain kind) aren't wrong — they just hide these four behind abstractions, making an agent look complex.2注 2Note 2Anthropic · 「Building Effective Agents」(2024-12-19)—— augmented LLM 作为基本积木;agent 是在循环里用工具、读环境反馈、自己决定下一步。Anthropic · 'Building Effective Agents' (2024-12-19) — the augmented LLM as the basic block; an agent uses tools in a loop, reads environment feedback, and decides its next step. Write it by hand once, and you'll know what the framework does for you — and when it gets in your way.
— II
把循环写出来Write the Loop Out.
下面是研究助手的种子 —— 它现在只会一件事:搜索。看长度,一个能跑的 agent 没你想象的那么复杂。Here is the seed of the research assistant — right now it does one thing: search. Look at the length; a working agent isn't as complex as you imagined.
import anthropicclient = anthropic.Anthropic() # 读环境变量 ANTHROPIC_API_KEYTOOLS = [{ "name": "web_search", "description": "按查询搜索网页,返回标题和摘要的列表。要查资料时调用。", "input_schema": { "type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], },}]def run_tool(name, args): # 工具的真正执行 if name == "web_search": return search_web(args["query"]) # 真实场景接一个搜索 API return f"未知工具: {name}"def agent(question, max_steps=10): messages = [{"role": "user", "content": question}] for _ in range(max_steps): # 停止条件:步数上限 resp = client.messages.create( model="claude-opus-4-8", max_tokens=1024, tools=TOOLS, messages=messages, ) messages.append({"role": "assistant", "content": resp.content}) if resp.stop_reason != "tool_use": # 模型给出最终回答 return "".join(b.text for b in resp.content if b.type == "text") results = [{ "type": "tool_result", "tool_use_id": b.id, "content": run_tool(b.name, b.input), } for b in resp.content if b.type == "tool_use"] messages.append({"role": "user", "content": results}) return "stopped: 达到 max_steps"
研究助手的种子:一个能搜索的最小 agent(Anthropic Messages API)The research assistant's seed: a minimal agent that can search (Anthropic Messages API)
整个循环就三步:调模型 → 看 stop_reason → 执行工具并回传,直到模型不再要工具,或撞上步数上限。1注 1Note 1Anthropic 文档 · Tool use overview —— client tool 的循环:Claude 返回 stop_reason: tool_use 与 tool_use 块(id / name / input),你执行后回传 tool_result(带 tool_use_id)。示例模型 claude-opus-4-8,anthropic-version 2023-06-01。截至 2026-05。Anthropic docs · Tool use overview — the client-tool loop: Claude returns stop_reason: tool_use with tool_use blocks (id / name / input); you execute and send back a tool_result (with tool_use_id). Example model claude-opus-4-8, anthropic-version 2023-06-01. As of 2026-05.这就是 agent 的全部骨架。The whole loop is three steps: call the model → check stop_reason → run the tool and feed it back, until the model stops asking for tools or hits the step cap.1注 1Note 1Anthropic 文档 · Tool use overview —— client tool 的循环:Claude 返回 stop_reason: tool_use 与 tool_use 块(id / name / input),你执行后回传 tool_result(带 tool_use_id)。示例模型 claude-opus-4-8,anthropic-version 2023-06-01。截至 2026-05。Anthropic docs · Tool use overview — the client-tool loop: Claude returns stop_reason: tool_use with tool_use blocks (id / name / input); you execute and send back a tool_result (with tool_use_id). Example model claude-opus-4-8, anthropic-version 2023-06-01. As of 2026-05. That is the entire skeleton of an agent.它能跑,但它很笨:重启就忘光(没记忆)、工具报错它不会处理、你要是不设 max_steps 它能无限烧钱。这些不是缺陷,是后面章节的入口 —— 记忆是第 4 章,错误处理是第 3 章,停止条件与成本是第 11 章。It runs, but it's dumb: it forgets on restart (no memory), it can't handle a tool error, and without max_steps it would burn money forever. These aren't flaws — they're the doorways to later chapters: memory in chapter 4, error handling in chapter 3, stop conditions and cost in chapter 11.
— III
最小循环里已经埋着所有难题The Minimal Loop Already Hides Every Hard Problem.
这 30 行不是玩具,是后面每一章的地图。循环里的每一格,都对应一个还没解决的问题。These 30 lines aren't a toy — they're the map for every chapter ahead. Each slot in the loop maps to a problem not yet solved.
TOOLS 的定义The TOOLS definition
模型靠 description 决定调不调 —— 写不好它就调错。第 3 章。The model decides by the description — write it poorly and it calls wrong. Chapter 3.
messages 越滚越长messages keeps growing
上下文窗口会满,记忆要分层。第 4 章。The context window fills; memory must be layered. Chapter 4.
run_tool 直接执行run_tool runs directly
它在你机器上跑代码 —— 沙箱与权限。第 7、9 章。It runs code on your machine — sandbox and permissions. Chapters 7 and 9.
max_steps 与停止max_steps and stopping
跑偏了怎么发现、怎么度量。第 10、11 章。How to notice and measure drift. Chapters 10 and 11.
所以别急着加。先让这个最小循环在你自己的一个真任务上跑通 —— 它在哪卡住,哪一章就是你最该先读的。So don't rush to add. Get this minimal loop working on one real task of your own — wherever it breaks is the chapter you should read first.动手 · 让最小循环跑你自己的一个真活:Hands-on · run the minimal loop on one real task of your own:
01
接一个你已有的只读工具Wire one read-only tool you already have
把 run_tool 里的 web_search 接到一个真实搜索 API(先返回假结果也行)—— 研究助手就从这一步开始。Wire run_tool's web_search to a real search API (faking the result is fine to start) — the research assistant begins here.
02
给它一个真目标,跑起来Give it a real goal and run it
用一个你平时要上网查的小问题当 question,看它搜几轮、搜对了没有。Use a small question you'd normally look up as the question; watch how many rounds it searches and whether it searches right.
03
记下它第一个卡住的地方Record the first place it breaks
忘了上文?工具报错崩了?绕圈停不下来?把这个卡点对照上面的地图 —— 那就是你下一章。Lost context? Crashed on a tool error? Looped without stopping? Match the break to the map above — that's your next chapter.
框架把循环藏起来,
手写一遍才看清它有多小。.
Frameworks hide the loop;
writing it once shows how small it is..
Aklman Library
— 讨论Discussion
讨论Discussion.
评论区初始化中…Initializing comments…
01 / 01
没有匹配结果No matches.
换个关键词,或按 Esc 回到页面Try another keyword, or press Esc to return