1
2
3
4
5
6
7
8
9
10
11
12
13
while True: # 每个Agent都有一个自己的死循环
# 1. 阅读收件箱(如果有消息就用 user 身份插进 context 中作为打断提示)
# 2. 调用大模型 API 思考
response = client.messages.create(...)
# 3. 决定是否调用了工具
if response.stop_reason != "tool_use":
break # (或者 return)
# 4. 执行自己手里的工具箱并收集结果
for block in response.content:
output = handler(...)
results.append({"type":"tool_result", ... output})
# 5. 把结果还给 Context,进入下一轮
messages.append({"role": "user", "content": results})

实际样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def agent_loop(messages: list):
    while True:
        response = client.messages.create(
            model=MODEL, system=SYSTEM, messages=messages,
            tools=TOOLS, max_tokens=8000,
        )
        # Append assistant turn
        messages.append({"role": "assistant", "content": response.content})
        # If the model didn't call a tool, we're done
        if response.stop_reason != "tool_use"
            return
        # Execute each tool call, collect results
        results = []
        for block in response.content:
            if block.type == "tool_use":
                print(f"\033[33m$ {block.input['command']}\033[0m")
                output = run_bash(block.input["command"])
                print(output[:200])
                results.append({"type": "tool_result", "tool_use_id": block.id,"content": output})
        messages.append({"role": "user", "content": results})

根据Anthropic SDK 相关文档response是一个 Message 对象

1
2
3
4
5
6
7
8
9
10
Message(
    id='msg_01...',
    type='message',
    role='assistant',
    model='claude-3-sonnet-20240229', # 或其他对应模型
    stop_reason='tool_use',           # 告诉我们模型是为什么停止生成的
    stop_sequence=None,
    usage=Usage(input_tokens=..., output_tokens=...),
    content=[...这里是主要内容...]
)

在一个单独的回复(round)中,模型可以同时(并行)调用多个工具。response.content是一个包含**代码块(Block)对象的列表 (List)**。在 Anthropic 的设定中,模型的回复不只是单一的纯文本字符串,而是由多个不同类型的 Block 组合而成的序列。