# 使用开放权重模型的工具调用与 JSON 输出

> 以 OpenAI 格式使用开放权重模型进行函数调用：tools、tool_choice、调用与应答循环，以及用于生成有效 JSON 输出的 response_format。

- URL: https://llmwithcrypto.com/zh/docs/tool-calling/
- 最后更新: 2026-10-23
- 发布者: LLMwithCrypto (https://llmwithcrypto.com)

模型可以要求你的代码运行一个函数，然后在回答中使用该结果；也可以直接返回一个 JSON 对象供你的程序读取。两者都使用 OpenAI 请求格式，也都取决于你选择的模型。

**快速回答 — 工具调用在 LLMwithCrypto 上如何工作？**

以 OpenAI 格式在 `tools` 中发送你的函数。当模型需要调用某个函数时，**LLMwithCrypto** 会返回 `finish_reason: "tool_calls"`，其中包含函数名和 JSON 参数；你的代码运行该函数，并将结果作为 `tool` 消息发回。对于结构化回复，`response_format: {"type": "json_object"}` 要求返回有效 JSON。两者均可在支持它们的模型上使用，如 2026 年 10 月 23 日的文档所述。

## 哪些模型支持工具和 JSON？

所有模型都支持流式输出；工具调用和 JSON 输出取决于各模型本身的支持情况。

在依赖某个模型之前，先在你计划使用的模型上测试你自己的 schema。不支持工具的模型会以纯文本作答，而不是调用函数；不支持 JSON 模式的模型会对 `response_format` 返回 `400` 错误。

## 这个循环是什么？

1. **描述函数** — 每个工具都有一个 name、一个供模型阅读以判断何时使用它的 description，以及作为 JSON Schema 的 parameters。
2. **带上工具发送对话** — 模型要么以文本作答，要么以 finish_reason: "tool_calls" 停止，并在 message.tool_calls 中给出一个或多个调用。
3. **运行每个调用** — 解析 function.arguments（一个 JSON 字符串），运行你的函数，绝不要盲目信任参数：像对待任何用户输入一样校验它们。
4. **发回结果** — 追加助手消息，然后为每个调用追加一条 tool 消息，包含其 tool_call_id 和作为文本的结果。再次调用 API；重复此过程，直到模型以文本作答。

*Python：使用 gpt-oss-120b 的完整工具循环*

```python
import json
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://llmwithcrypto.com/api/v1",
    api_key=os.environ["LLMWITHCRYPTO_API_KEY"],
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order_status",
            "description": "Return the delivery status of an order.",
            "parameters": {
                "type": "object",
                "properties": {"order_id": {"type": "string"}},
                "required": ["order_id"],
            },
        },
    }
]


def get_order_status(order_id):
    return {"order_id": order_id, "status": "shipped", "eta": "2026-10-25"}


messages = [{"role": "user", "content": "Where is my order A-1042?"}]
while True:
    resp = client.chat.completions.create(model="gpt-oss-120b", messages=messages, tools=tools, max_tokens=300)
    msg = resp.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_order_status(**args)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

```

## 响应中的工具调用是什么样的？

助手消息没有文本，含有一个 `tool_calls` 数组，且选择以 `finish_reason: "tool_calls"` 结束。参数以 JSON 字符串形式给出，而非对象。下面的 id 和计数仅为示例。

*请求函数调用的响应（示例）*

```json
{
  "id": "chatcmpl-3c9d27e1",
  "object": "chat.completion",
  "created": 1792742400,
  "model": "gpt-oss-120b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_7f31",
            "type": "function",
            "function": {
              "name": "get_order_status",
              "arguments": "{\"order_id\": \"A-1042\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 118,
    "completion_tokens": 22,
    "total_tokens": 140
  }
}

```

## 如何控制何时使用工具？

- **`"tool_choice": "auto"`**（设置 `tools` 时的默认值）：由模型决定。
- **`"tool_choice": "none"`**：即使列出了工具，模型也以文本作答。
- **`"tool_choice": "required"`**：模型必须至少调用一个工具。
- **`{"type": "function", "function": {"name": "get_order_status"}}`**：模型必须调用指定的那一个。

每个工具定义都会在每次调用时作为输入发送，因此冗长的描述和大量工具会增加输入 token。保持描述简短，只发送当前步骤需要的工具。

## 如何获得有效的 JSON 返回？

将 `response_format` 设为 `{"type": "json_object"}`，并在系统消息中描述预期的键：JSON 模式保证回复能被解析，但不保证包含你想要的键。保持较低的 `temperature` 以获得稳定的输出，并在使用前在代码中检查解析后的对象。

*Node.js：使用 response_format 获得 JSON 回复*

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

const resp = await client.chat.completions.create({
  model: 'gpt-oss-120b',
  messages: [
    { role: 'system', content: 'Reply with a JSON object {"sentiment": "positive" | "negative" | "neutral", "reason": string}.' },
    { role: 'user', content: 'The delivery was late but support fixed it in an hour.' },
  ],
  response_format: { type: 'json_object' },
  temperature: 0.2,
  max_tokens: 150,
});
const result = JSON.parse(resp.choices[0].message.content);
console.log(result.sentiment, '-', result.reason);

```

## 工具与 JSON：常见问题

### 工具调用会额外收费吗？

它们本身不收费。工具定义、调用以及你发回的结果都是 token，与其他内容一样计费。按 token 从余额扣费：输入和输出 token 由模型自己的 tokenizer 计数，按该模型每 1M token 的价格计费。以错误结束的调用不收费。

### 模型可以同时调用多个工具吗？

某些模型会在 `tool_calls` 中返回多个调用。全部运行它们，并在下一次请求前为每个调用发送一条 `tool` 消息。

### API 会运行我的函数吗？

不会。模型只说调用哪个函数以及用什么参数；由你的代码来运行它。我们这边不会执行任何内容，交换的任何内容也不会被存储：我们不保存你的提示词或模型的回答：响应一旦发出，其文本即消失。每次调用只留一行日志，记录时间、账户、模型和 token 数量，30 天后删除。

---

LLMwithCrypto: LLMwithCrypto 是一个兼容 OpenAI 的开放权重模型 LLM API，涵盖 DeepSeek V4 Pro、DeepSeek V4.1 Flash、DeepSeek R1、Qwen3.5 397B A17B、Qwen3 235B A22B Instruct、gpt-oss-120b、gpt-oss-20b、GLM-4.7、Llama 3.3 70B Instruct、Gemma 4 31B、Mistral Large 3、Mistral Small 4，按 token 从预付加密货币余额中扣费，价格比公共托管商的中位价低 5%。无需 KYC：无需身份证件、无需自拍、无需文件。不存储提示词和输出。
