加载中
智能体循环详解
您已经调用过 API,但一次调用只会返回一个响应。如果您想让某个工作流自动化,Claude 需要采取行动、查看结果、决定下一步该做什么,然后继续执行下去。这种模式正是人们在谈论智能体工作流(agentic workflows)时所指的内容。
智能体究竟是什么
智能体(agent)是 Claude 的一种自主版本,它在消息循环的两端都独立运行,中间无需人工干预。智能体接收一项任务,选择一个工具,并在循环中执行代码,直到 Claude 判断任务已经完成。
实现智能体循环最简单的方式如下:
- 向 Claude 发送一条带有可用工具的消息。
- Claude 会回复最终答案,或者请求使用您所定义的某个工具。
- 您的代码执行该工具。
- 您将结果发送回 Claude。
- 只要停止原因(stop reason)是
tool_use,就重复上述过程。end_turn表示 Claude 已完成,而任何其他停止原因也都会结束循环。
可以把它想象成一场轮流进行的对话:用户发起对话,智能体调用工具,工具返回结果,智能体持续推进,直到得出答案为止。
一个最小可运行示例
为了在不引入数据库或 UI 的情况下端到端地运行这个循环,我们将搭建一个名为 get_weather 的虚拟工具,并询问 Claude 今天在奥斯汀应该穿什么。Claude 自身无法知道天气情况,因此它必须调用该工具、读取结果,然后才能给出答案。
下面是完整的脚本:
python
import anthropic
client = anthropic.Anthropic()
# tools 数组告诉 Claude 有哪些工具可用:
# 包括名称、描述以及输入的 JSON 模式。
tools = [
{
"name": "get_weather",
"description": "Get the current weather for a city.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city to get weather for",
}
},
"required": ["city"],
},
}
]
# run_tool 只是一个硬编码的查找。
# 在真实的应用中,这里会访问您的数据库、某个 API,或其他任何东西。
def run_tool(name, tool_input):
if name == "get_weather":
return f"Weather in {tool_input['city']}: 95F, sunny"
raise ValueError(f"Unknown tool: {name}")
messages = [
{"role": "user", "content": "What should I wear in Austin today?"}
]
# 代理循环。每次迭代都会向 Claude 发送消息,
# 并根据响应的停止原因进行分支处理。
while True:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=tools,
messages=messages,
)
if response.stop_reason == "end_turn":
# Claude 已完成。打印最终文本并退出循环。
for block in response.content:
if block.type == "text":
print(block.text)
break
elif response.stop_reason == "tool_use":
# 在响应中找到工具使用块,并逐一运行。
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = run_tool(block.name, block.input)
tool_results.append(
{
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
}
)
# 将助手的响应和我们的工具结果
# 推回 messages 中,然后再次循环,以便 Claude 给出回答。
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
else:
# 其他任何停止原因,例如 max_tokens 或拒绝回答。
# messages 中没有任何变化,所以在此停止。再次循环
# 只会为同一个请求重复付费。
print(f"Stopped early: {response.stop_reason}")
break需要注意三个部分:
- tools 数组告诉 Claude 有哪些可用工具:名称、描述,以及输入的 JSON schema。
run_tool只是一个硬编码的查找函数。在真实应用中,这里会去访问您的数据库、某个 API,或其他任何数据来源。- 循环(loop)就是智能体循环本身。每次迭代都会将消息发送给 Claude,并根据响应的停止原因进行分支处理。当停止原因为
end_turn时,说明 Claude 已完成,因此打印最终文本并退出循环。当停止原因为tool_use时,找到工具使用块,逐一运行,再把助手的响应和您的工具结果推回messages中,然后再次循环,以便 Claude 能够给出答案。对于其他任何情况,打印停止原因并退出循环。
不要省略最后这个分支。如果没有它,一条因 max_tokens 而被截断的回复将不会被添加到 messages 中,于是循环会一遍又一遍地发送同样的请求,而您每次都要为此付费。文档中列出了所有停止原因及相应的处理方法(在新标签页中打开)。
运行它
当您运行该脚本时,会看到两轮交互:
- 第一轮:停止原因是
tool_use。Claude 请求为奥斯汀调用get_weather,您的代码返回温度和天气状况。 - 第二轮:停止原因是
end_turn,Claude 告诉您应该穿轻便透气的衣服。

两次 API 调用,一次工具执行,一个最终答案。这就是整个循环。您用 Claude API 构建的任何内容都会与此类似。
生产环境中的同一循环
在真实环境中,同样的这个循环驱动着诸如自动审查端点之类的应用:一个合规性智能体读取结构报告,通过某个工具查找相关建筑规范,并在工作过程中逐条将风险发现结果写回数据库。

该循环的形态与您刚刚运行的示例完全相同。不同之处在于:
- 使用真实工具而非模拟的天气查询。
- 结果以服务器发送事件(server-sent events)的形式流式传回 UI。
- 发现结果会被持久化存储到一张风险发现数据表中。

小结
- 智能体就是处于循环中的 Claude:观察、决策、行动、重复。
- 这个循环很简单:发送带有工具的消息,运行 Claude 所请求的任何工具,将结果反馈回去,并在停止原因不是
tool_use时停止。 - 循环和工具由您掌控,推理由 Claude 负责。
- 同样的循环形态,从一个模拟的天气演示到一个生产级的合规性智能体都可以扩展使用——变化的只是工具和底层接入方式。
- 当您不想自己管理这个循环时,托管智能体(managed agents)会在 Anthropic 的基础设施上为您运行这套完全相同的循环。