> ## 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.

# 函数调用

> 使用 JSON Schema、参数校验和 Tool Result 安全地让模型请求应用函数。

Function Calling 允许模型使用结构化参数请求一个具名应用操作。是否执行由你的代码决定，模型本身不会执行函数。

## 定义工具

<CodeGroup>
  ```bash Curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl https://api.yelu.ai/v1/chat/completions \
    -H "Authorization: Bearer $YELU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model":"gpt-4o-mini",
      "messages":[{"role":"user","content":"上海天气怎么样？"}],
      "tools":[{"type":"function","function":{"name":"get_weather","description":"查询城市当前天气","parameters":{"type":"object","properties":{"city":{"type":"string"},"unit":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["city","unit"],"additionalProperties":false}}}],
      "tool_choice":"auto"
    }'
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const payload = {
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: '上海天气怎么样？' }],
    tools: [{ type: 'function', function: {
      name: 'get_weather',
      description: '查询城市当前天气',
      parameters: {
        type: 'object',
        properties: { city: { type: 'string' }, unit: { type: 'string', enum: ['celsius', 'fahrenheit'] } },
        required: ['city', 'unit'],
        additionalProperties: false,
      },
    } }],
    tool_choice: 'auto',
  };
  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(payload),
  });
  if (!response.ok) throw new Error(await response.text());
  console.log((await response.json()).choices[0].message.tool_calls);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os
  import requests

  payload = {
      "model": "gpt-4o-mini",
      "messages": [{"role": "user", "content": "上海天气怎么样？"}],
      "tools": [{"type": "function", "function": {
          "name": "get_weather",
          "description": "查询城市当前天气",
          "parameters": {
              "type": "object",
              "properties": {"city": {"type": "string"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}},
              "required": ["city", "unit"],
              "additionalProperties": False,
          },
      }}],
      "tool_choice": "auto",
  }
  response = requests.post(
      "https://api.yelu.ai/v1/chat/completions",
      headers={"Authorization": f"Bearer {os.environ['YELU_API_KEY']}"},
      json=payload,
      timeout=60,
  )
  response.raise_for_status()
  print(response.json()["choices"][0]["message"].get("tool_calls"))
  ```
</CodeGroup>

## 完成工具循环

<Steps>
  <Step title="读取 Tool Call">当 `finish_reason` 为 `tool_calls` 时，读取所有 `message.tool_calls`；模型可能一次请求多个调用。</Step>
  <Step title="校验参数">解析 `function.arguments`，使用应用自己的 Schema、权限、范围和业务规则校验。它是不可信输入。</Step>
  <Step title="受控执行">只允许精确匹配 Allowlist 的函数名，并应用鉴权、授权、超时、幂等与速率限制。</Step>
  <Step title="返回结果">追加原始 Assistant Tool Call Message，再为每个调用追加匹配 `tool_call_id` 的 `role: tool` 消息，然后请求最终回答。</Step>
</Steps>

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{"role":"tool","tool_call_id":"call_01JYELU","content":"{\"city\":\"上海\",\"temperature\":31,\"unit\":\"celsius\",\"condition\":\"多云\"}"}
```

## 安全规则

* 不要对函数名使用 `eval`、反射或任意 Shell 执行。
* 购买、发消息、删除、权限变更等重要操作必须二次确认。
* 执行时重新校验最终用户权限。
* 限制参数长度、JSON 深度和循环次数。
* 对状态变更工具记录审计事件。

<Warning>JSON Schema 只能改善参数结构，不能证明操作安全或正确。应用层校验和授权仍是强制要求。</Warning>
