构建使用工具的多轮对话需要处理来自Claude的不同响应类型。当Claude响应时,它可能需要使用工具,也可能直接提供答案。您的代码需要优雅地处理这两种情况。
简单工具集成的问题
如果您只是将工具结果添加到每次对话中,就会遇到问题。当Claude回答像"1+1等于多少?"这样的简单问题时,它不需要任何工具。但如果您的代码总是尝试处理工具结果,最终会在对话历史中添加空消息。
解决方案是检查每次Claude响应返回的stop_reason。这会告诉您Claude为什么停止生成——是自然完成,还是因为它想使用工具。
停止原因

Claude可能因以下几种原因停止:
"tool_use"- 模型想要调用工具"end_turn"- 模型已完成生成其响应"max_tokens"- 达到输出限制"stop_sequence"- 遇到了您提供的停止序列
改进聊天函数
首先,更新您的聊天函数以返回更多信息。不要只是分别返回文本和各个部分,而是返回一个包含您所需一切内容的字典:
python
def chat(messages, tools=None, system=None, **kwargs):
# ……现有代码……
return {
"parts": parts,
"stop_reason": response["stopReason"],
"text": "\n".join([p["text"] for p in parts if "text" in p])
}这种方法从响应部分中提取所有文本内容,这比假设第一部分始终是文本更加稳健。
构建对话循环
创建一个处理完整对话流程的函数:
python
def run_conversation(messages):
while True:
result = chat(messages, tools=[get_current_datetime_schema])
add_assistant_message(messages, result["parts"])
print(result["text"])
if result["stop_reason"] != "tool_use":
break
tool_result_parts = run_tools(result["parts"])
add_user_message(messages, tool_result_parts)
return messages这个循环会持续进行,直到Claude因工具使用以外的原因停止。每次迭代:
- 将当前消息发送给Claude
- 将Claude的响应添加到消息历史中
- 检查Claude是否想要使用工具
- 如果是,运行工具并将结果添加回对话中
- 如果不是,退出循环
测试实现
这种方法可以处理需要工具的问题和简单问题:
python
# 需要工具的问题
messages = []
add_user_message(messages, "What time is it?")
run_conversation(messages)
# 简单问题
messages = []
add_user_message(messages, "What is 1+1?")
run_conversation(messages)对于时间相关的问题,Claude会使用datetime工具。对于数学问题,它会直接响应,不进行任何工具调用。对话循环会根据Claude的停止原因自动调整。
当您添加更多工具时,这种模式可以很好地扩展——同一个循环可以处理工具使用和直接响应的任何组合,使您的对话式AI更加稳健和自然。