import json
import os
from openai import OpenAI
from dotenv import load_dotenv
# 加载 .env 文件
load_dotenv()
client = OpenAI(
# 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
messages = [
# {'role': 'system', 'content': ''},
{'role': 'user', 'content': '我的手上有10个苹果 又买了3个 还剩多少个?'}
]
tools = [
{
"type": "function",
"function": {
"name": "sum",
"description": "使列表中n个数字相加",
"parameters": {
"type": "object",
"properties": {
"query": {
"description": "列表",
"type": "array",
"items": {
"type": "number"
}
}
},
"required": ["query"]
}
}
}
]
def call_model_with_tool_response(messages):
# 继续与模型对话
response = client.chat.completions.create(
model="qwen-plus",
messages=messages,
temperature=0, max_tokens=1024, top_p=1, frequency_penalty=0, presence_penalty=0,
tools=tools
)
return response
message = call_model_with_tool_response(messages).choices[0].message
print(message)
#定义一个方法使调用工具回参
while message.tool_calls and message.tool_calls[0].function is not None:
arguments = json.loads(message.tool_calls[0].function.arguments)["query"]
name = message.tool_calls[0].function.name
sumReturn = sum(arguments)
print(name)
print(arguments)
if name == "sum":
sumReturn = sum(arguments)
messages.append(message)
messages.append({
'tool_call_id': message.tool_calls[0].id,
'role': 'tool',
'name': name,
'content': str(sumReturn)
})
response = call_model_with_tool_response(messages)
message = response.choices[0].message
print(message)
调用tool_calls的步骤实际上是访问了两次大模型
1.大模型根据用户定义的tools识别出本次要用的tool 并在message内部返回本次调用的tool信息
2. 用户把大模型给的tool运行出来
3.用户把tool结果和tool_call_id 附加大模型第一次返回的message信息在第二次发送给大模型
第三条需要特别注意不然不会被大模型识别为二次调用:
抛出异常:openai.BadRequestError: Error code: 400 - {'error': {'code': 'invalid_parameter_error', 'param': None, 'message': '<400> InternalError.Algo.InvalidParameter: messages with role "tool" must be a response to a preceeding message with "tool_calls".', 'type': 'invalid_request_error'}, 'id': 'chatcmpl-c6979e5a-22b5-92ea-80ad-b18e820b279f', 'request_id': 'c6979e5a-22b5-92ea-80ad-b18e820b279f'}
4.如果需要更多的工具调用 例如 func1->func2->func3...->funN 大模型会逐步返回,真实与大模型发生N+1次交互