代理循环概览
发出请求、检查 stop_reason、运行工具并重复。
代理循环概览 是 CoddyKit 上的免费 Claude Architect 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Claude Architect 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Claude Architect 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
What Is the Agentic Loop?
An agent is just a loop around the Claude Messages API. You send a request, Claude either finishes or asks to run a tool, you run it, and you send the results back. Repeat until Claude is done.
The whole pattern is four steps:
- Request — call the API with your message history.
- Inspect the
stop_reasonin the response. - Run tools if Claude asked for them, then add the results to the history.
- Repeat until
stop_reasonisend_turn.
Master this one loop and you understand the core of every agent.
The Request: Full History Every Turn
The Claude API is stateless. The model keeps no memory between calls, so you must send the full message history every single turn.
A request carries these fields:
model— which Claude model to use.max_tokens— the output cap.system— the system prompt.messages— the entire conversation so far.tools— the tools Claude may call.
If you forget to append a turn, Claude simply won't know it happened.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system="You are a helpful weather assistant.",
tools=tools,
messages=messages, # the FULL history, every turn
)The Response: Read stop_reason
Every response comes back with a stop_reason. This field — not the text — tells you what to do next. The four values are:
end_turn— Claude finished. The loop is over.tool_use— Claude wants a tool run. Execute it and continue.max_tokens— output was truncated by the limit.stop_sequence— a custom stop sequence was hit.
Your loop is really just a decision based on this one field.
if response.stop_reason == "end_turn":
# Done — return the answer
...
elif response.stop_reason == "tool_use":
# Run the requested tool(s), then loop again
...Defining a Tool
A tool is a function you let Claude call. You describe it with a name, a description, and a JSON Schema for its inputs.
The description is the most important part — Claude reads it to decide when to use the tool. Be clear about its purpose, its inputs, and when it applies.
Claude never runs your tool itself. It only asks for it; your code does the actual work and reports back.
tools = [
{
"name": "get_weather",
"description": "Get the current weather for a city. "
"Call this when the user asks about weather "
"or temperature.",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"],
},
}
]When Claude Asks for a Tool
When stop_reason is tool_use, the response content contains a tool_use block. It carries:
- an
id— used to match the result back to the request, - a
name— which tool to run, - an
input— the arguments, already parsed as an object.
Claude can ask for several tools in one response. Run them all before continuing.
for block in response.content:
if block.type == "tool_use":
print(block.name) # "get_weather"
print(block.input) # {"city": "Paris"}
print(block.id) # "toolu_01A..." -> needed for the resultSending the Result Back
To continue, you append two things to the history:
- The assistant's full
response.content(so thetool_useblock is preserved). - A new
usermessage holding atool_resultblock.
Each tool_result must include the matching tool_use_id. Then you call the API again — that's one turn of the loop.
result = run_tool(block.name, block.input)
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": block.id, # must match the tool_use id
"content": result,
}],
})The Full Loop in Code
Put it together and the agent is a short while loop:
- Call the API with the full history.
- If
stop_reasonisend_turn, break. - Otherwise run the requested tools, append the results, and loop.
The model drives the decisions; your code just runs the tools and carries the history.
while True:
response = client.messages.create(
model="claude-opus-4-8", max_tokens=1024,
tools=tools, messages=messages,
)
if response.stop_reason == "end_turn":
break
messages.append({"role": "assistant", "content": response.content})
results = [
{"type": "tool_result", "tool_use_id": b.id,
"content": run_tool(b.name, b.input)}
for b in response.content if b.type == "tool_use"
]
messages.append({"role": "user", "content": results})Terminate on stop_reason, Not Text
Here is the rule that separates a robust agent from a fragile one: always terminate on stop_reason, never by reading the text.
Scanning Claude's output for words like "done", "finished", or "complete" is a classic anti-pattern. The model might say "I'm not done yet" or mention the word "done" in a sentence, and your loop breaks at the wrong moment.
The stop_reason field is the one reliable signal. Trust it.
# WRONG — fragile text parsing
if "done" in response_text.lower():
break
# RIGHT — structural signal
if response.stop_reason == "end_turn":
breakIteration Caps Are a Safety Net
It's wise to add a maximum-iteration counter so a misbehaving loop can't run forever. But understand its role: a cap is a safety net, not the primary way you stop.
The primary stop mechanism is always stop_reason == end_turn. The cap only catches the rare runaway case.
Treating an arbitrary iteration cap as your main stop condition is an anti-pattern — it cuts off legitimate work that just needed one more turn.
MAX_ITERS = 20 # safety net only
for _ in range(MAX_ITERS):
response = client.messages.create(...)
if response.stop_reason == "end_turn":
break # the REAL stop condition
# ... run tools, append results ...Model-Driven Decisions, Coded Guarantees
In the agentic loop, the model decides what to do: which tool to call, with what inputs, and when to stop. That flexibility is the whole point of an agent.
Reserve hard code for the things you must guarantee — for example, a deterministic check that a refund can't exceed a policy limit, or that an action only runs after identity is verified.
Let the model plan; let your code enforce. Don't hard-code the trajectory, and don't ask a prompt to enforce a critical rule.
Handling the Other Stop Reasons
Two stop reasons are easy to forget but matter in production:
max_tokens— the output hit the limit and is truncated. Raisemax_tokensor stream, then retry; don't treat partial output as final.stop_sequence— a custom stop sequence you configured was matched.
A complete loop branches on all four values. Silently ignoring max_tokens leads to cut-off answers and broken tool calls.
if response.stop_reason == "end_turn":
finish()
elif response.stop_reason == "tool_use":
run_tools_and_continue()
elif response.stop_reason == "max_tokens":
# truncated — raise max_tokens / stream and retry
handle_truncation()
elif response.stop_reason == "stop_sequence":
handle_stop_sequence()Quick Check
Test your understanding of how to terminate the agentic loop.
Recap: The Agentic Loop
You now know the engine behind every agent:
- Request the API with the full history every turn — the model keeps no state.
- Inspect
stop_reason:end_turn(done),tool_use(run tools),max_tokens(truncated),stop_sequence. - On
tool_use, run the tools and append eachtool_resultwith its matchingtool_use_id. - Repeat until
end_turn.
Terminate on stop_reason, never by parsing text. Iteration caps are a safety net only. Let the model make decisions; reserve hard code for guarantees.
用 AI 导师学习 Python — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 26
- 课程
- 104
常见问题解答
「代理循环概览」课时是免费的吗?
是的 — 「代理循环概览」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Claude Architect 课程的其余内容,请升级到 CoddyKit PRO。 Claude Architect 课程共包含 4 节课。
「代理循环概览」这节课中我会学到什么?
发出请求、检查 stop_reason、运行工具并重复。 你通过在浏览器中直接运行的动手代码来练习 Claude Architect,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Claude Architect 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Claude Architect 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「代理循环概览」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Claude Architect 课中编写并运行代码吗?
能。每节 Claude Architect 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。