在构建使用多个工具的应用程序时,您需要处理这样的场景:Claude 可能需要按顺序调用多个工具来回答单个用户问题。例如,如果用户问"从今天起103天后是哪一天?",Claude 需要先获取当前日期,然后再加上103天。

这就产生了一种多轮对话模式,Claude 在提供最终答案之前会发出多个工具请求。您的应用程序需要自动处理这种情况。
多轮工具模式
以下是当 Claude 需要多个工具时幕后发生的事情:
- 用户问:"从今天起103天后是哪一天?"
- Claude 用一个请求
get_current_datetime的工具使用块进行响应 - 您的服务器调用该函数并返回结果
- Claude 意识到它需要更多信息,于是请求
add_duration_to_datetime - 您的服务器调用该函数并返回结果
- Claude 现在有足够的信息来提供最终答案

构建对话循环
要处理这种模式,您需要一个对话循环,该循环会持续运行,直到 Claude 不再请求工具为止:
python
def run_conversation(messages):
while True:
response = chat(messages)
add_assistant_message(messages, response)
# 伪代码
if response isn't asking for a tool:
break
tool_result_blocks = run_tools(response)
add_user_message(messages, tool_result_blocks)
return messages
重构辅助函数
在实现对话循环之前,您需要更新辅助函数,以正确处理多个消息块。
更新消息处理函数
您的 add_user_message 和 add_assistant_message 函数目前假定它们始终处理纯文本。请更新它们以处理完整的消息对象:
python
from anthropic.types import Message
def add_user_message(messages, message):
user_message = {
"role": "user",
"content": message.content if isinstance(message, Message) else message
}
messages.append(user_message)这样您就可以传入字符串、块列表或完整的消息对象。
更新聊天函数
修改您的聊天函数,使其接受工具列表并返回完整消息,而不仅仅是文本:
python
def chat(messages, system=None, temperature=1.0, stop_sequences=[], tools=None):
params = {
"model": model,
"max_tokens": 1000,
"messages": messages,
"temperature": temperature,
"stop_sequences": stop_sequences,
}
if tools:
params["tools"] = tools
if system:
params["system"] = system
message = client.messages.create(**params)
return message从消息中提取文本
由于聊天函数现在返回完整消息而不仅仅是文本,因此需要添加一个辅助函数,在需要时提取文本:
python
def text_from_message(message):
return "\n".join(
[block.text for block in message.content if block.type == "text"]
)该函数会查找消息中的所有文本块并将它们连接在一起,这在您需要向用户展示最终响应时非常有用。
为什么这些更改很重要
这些重构步骤让您的代码为支持工具的对话这一现实情况做好了准备:
- 每条消息包含多个块 - Claude 的响应可以同时包含文本块和工具使用块
- 灵活的消息处理 - 您的函数现在可以处理各种消息格式
- 完整消息保留 - 您保留了 Claude 提供的所有信息,而不仅仅是文本部分
- 工具列表支持 - 您的聊天函数现在可以接收并使用多个工具
有了这些基础,您就可以实现完整的对话循环,自动处理多次工具调用,从而创造一种无缝的体验,让 Claude 能够使用它所需的任何工具来完整地回答用户问题。