tools='[{"type":"function","function":{"name":"get_weather","description":"查询城市天气","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"],"additionalProperties":false}}}]'
first=$(jq -nc --argjson tools "$tools" '{model:"gpt-4o-mini",messages:[{role:"user",content:"上海需要带伞吗?"}],tools:$tools}')
response=$(curl -sS https://api.yelu.ai/v1/chat/completions -H "Authorization: Bearer $YELU_API_KEY" -H "Content-Type: application/json" -d "$first")
assistant=$(jq -c '.choices[0].message' <<<"$response")
call_id=$(jq -r '.tool_calls[0].id' <<<"$assistant")
city=$(jq -r '.tool_calls[0].function.arguments | fromjson | .city' <<<"$assistant")
result=$(jq -nc --arg city "$city" '{city:$city,condition:"rain",temperature_c:24}')
second=$(jq -nc --argjson tools "$tools" --argjson assistant "$assistant" --arg id "$call_id" --arg result "$result" '{model:"gpt-4o-mini",messages:[{role:"user",content:"上海需要带伞吗?"},$assistant,{role:"tool",tool_call_id:$id,content:$result}],tools:$tools}')
curl -sS https://api.yelu.ai/v1/chat/completions -H "Authorization: Bearer $YELU_API_KEY" -H "Content-Type: application/json" -d "$second" | jq -r '.choices[0].message.content'
const messages = [{ role: 'user', content: '上海需要带伞吗?' }];
const tools = [{ type: 'function', function: { name: 'get_weather', description: '查询城市天气', parameters: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'], additionalProperties: false } } }];
async function complete() {
const response = await fetch('https://api.yelu.ai/v1/chat/completions', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.YELU_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'gpt-4o-mini', messages, tools }),
});
if (!response.ok) throw new Error(await response.text());
return response.json();
}
const assistant = (await complete()).choices[0].message;
const call = assistant.tool_calls[0];
const args = JSON.parse(call.function.arguments);
if (call.function.name !== 'get_weather' || typeof args.city !== 'string') throw new Error('无效 Tool Call');
messages.push(assistant, { role: 'tool', tool_call_id: call.id, content: JSON.stringify({ city: args.city, condition: 'rain', temperature_c: 24 }) });
console.log((await complete()).choices[0].message.content);
import json
import os
import requests
messages = [{"role": "user", "content": "上海需要带伞吗?"}]
tools = [{"type": "function", "function": {"name": "get_weather", "description": "查询城市天气", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], "additionalProperties": False}}}]
def complete():
response = requests.post(
"https://api.yelu.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['YELU_API_KEY']}"},
json={"model": "gpt-4o-mini", "messages": messages, "tools": tools},
timeout=60,
)
response.raise_for_status()
return response.json()
assistant = complete()["choices"][0]["message"]
call = assistant["tool_calls"][0]
arguments = json.loads(call["function"]["arguments"])
if call["function"]["name"] != "get_weather" or not isinstance(arguments.get("city"), str):
raise ValueError("无效 Tool Call")
messages.extend([assistant, {"role": "tool", "tool_call_id": call["id"], "content": json.dumps({"city": arguments["city"], "condition": "rain", "temperature_c": 24})}])
print(complete()["choices"][0]["message"]["content"])
不要仅因为模型发起 Tool Call 就执行。必须校验函数名和参数、执行最终用户授权,并对重要操作要求二次确认。