> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yelu.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 工具调用示例

> 请求 Tool Call、校验参数、返回工具结果，并生成最终回答。

以下示例演示两次请求的完整协议。天气结果是确定性的应用示例数据，生产环境应替换为经过鉴权和校验的工具实现。

<CodeGroup>
  ```bash Curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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'
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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"])
  ```
</CodeGroup>

<Warning>不要仅因为模型发起 Tool Call 就执行。必须校验函数名和参数、执行最终用户授权，并对重要操作要求二次确认。</Warning>
