> For the complete documentation index, see [llms.txt](https://docs.console.zenlayer.com/api-reference/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.console.zenlayer.com/api-reference/cn/ai/aig/chat-completion/anthropic-claude/anthropic-claude-chat-completion.md).

# 兼容API (/chat/completions)

## 1. 概述

Claude是Anthropic开发的大语言模型，具有强大的对话和写作能力。它能理解上下文、生成连贯文本、编写代码，并擅长逻辑推理和分析。注重安全性和道德准则，会明确表明自己是AI助手的身份。它支持多语言交流，能够处理复杂任务和长对话。

{% hint style="success" %}
本 API 与 OpenAI 接口格式兼容。
{% endhint %}

**模型列表：**

* `claude-sonnet-4-5-20250929`
* `claude-haiku-4-5-20251001`
* `claude-opus-4-5-20251101`
* `claude-opus-4-6`
* `claude-sonnet-4-6`
* `claude-opus-4-7`
* `claude-opus-4-8`
* `claude-sonnet-5`
* `claude-fable-5`
* `claude-opus-5`
* `claude-opus-5-5`
* `claude-sonnet-5-5`
* `claude-haiku-5-5`

## 2. 请求说明

* **请求方法**:`POST`
* **请求地址**:

  > `https://gateway.theturbo.ai/v1/chat/completions`

{% hint style="info" %}
平台为保障并发资源量，后端为多账号负载，如需提高缓存命中率，多轮对话模式可携带http请求头`X-Conversation-Id`加随机字符串请求，平台会优先路由到后端同一账号上。[参考文档](/api-reference/cn/ai/aig/gateway-features/cache-optimization.md)
{% endhint %}

***

## 3. 请求参数

### 3.1 Header 参数

| 参数名称            | 类型     | 必填 | 说明                                         | 示例值                    |
| --------------- | ------ | -- | ------------------------------------------ | ---------------------- |
| `Content-Type`  | string | 是  | 设置请求头类型，必须为 `application/json`             | `application/json`     |
| `Authorization` | string | 是  | 身份验证所需的 API\_KEY，格式 `Bearer $YOUR_API_KEY` | `Bearer $YOUR_API_KEY` |

***

### 3.2 Body 参数 (application/json)

| 参数名称                           | 类型              | 必填 | 说明                                                                                                                                                                                                                                    | 示例                                   |
| ------------------------------ | --------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| **model**                      | string          | 是  | 要使用的模型 ID。详见[概述](#id-1.-gai-shu)列出的可用版本，如 `claude-haiku-4-5-20251001`。                                                                                                                                                                | `claude-haiku-4-5-20251001`          |
| **messages**                   | array           | 是  | 聊天消息列表，格式与 OpenAI 兼容。数组中的每个对象包含 `role`(角色) 与 `content`(内容)。                                                                                                                                                                           | `[{"role": "user","content": "你好"}]` |
| message.role                   | string          | 否  | 消息角色，可选值：`system`、`user`、`assistant`。                                                                                                                                                                                                 | `user`                               |
| message.content                | string          | 否  | 消息的具体内容。支持字符串或内容块数组（`text`、`image_url`）。                                                                                                                                                                                              | `你好，请给我讲个笑话。`                        |
| message.content.cache\_control | object          | 否  | 在消息内容块上添加缓存断点，用于开启提示词缓存。仅支持内容块数组形式，详见[提示词缓存（Prompt Caching）](#id-4.5-ti-shi-ci-huan-cun-prompt-caching)。                                                                                                                              | `{"type":"ephemeral"}`               |
| message.reasoning\_content     | string          | 否  | 多轮对话中回传的上一轮模型思考内容，用于保持思考连续性。详见[多轮对话](#id-4.4-duo-lun-dui-hua)。                                                                                                                                                                        | `用户介绍了他们的名字……`                       |
| message.reasoning\_details     | array           | 否  | 与 `reasoning_content` 配对的思考签名信息，元素含 `signature` 字段。                                                                                                                                                                                   | `[{"signature":"Er4CC..."}]`         |
| message.tool\_calls            | array           | 否  | `assistant` 消息中回传的工具调用列表，元素含 `id` 与 `function`(`name`、`arguments`)。                                                                                                                                                                   | 见[函数调用](#id-4.3-han-shu-diao-yong)   |
| message.tool\_call\_id         | string          | 否  | `tool` 消息中对应的工具调用 ID，用于回传工具执行结果。                                                                                                                                                                                                      | `call_abc123`                        |
| temperature                    | number          | 否  | 采样温度，取值 `0～2`。数值越大，输出越随机；数值越小，输出越集中和确定。仅在 4.6 及以下版本模型生效，且开启思考（`thinking`）时不生效。                                                                                                                                                        | `0.7`                                |
| top\_p                         | number          | 否  | 另一种调节采样分布的方式，取值 `0～1`。和 `temperature` 通常二选一设置，同时携带时仅 `temperature` 生效。仅在 4.6 及以下版本模型生效。                                                                                                                                               | `0.9`                                |
| stream                         | boolean         | 否  | 是否开启流式输出。设置为 `true` 时，返回类似 ChatGPT 的流式数据。                                                                                                                                                                                             | `false`                              |
| max\_tokens                    | number          | 否  | 单次回复可生成的最大 token 数量，受模型上下文长度限制。                                                                                                                                                                                                       | `8192`                               |
| max\_completion\_tokens        | number          | 否  | 单次回复可生成的最大 token 数量，作用与 `max_tokens` 相同，同时设置时优先生效。                                                                                                                                                                                    | `8192`                               |
| stop                           | string 或 array  | 否  | 停止序列。模型生成到该内容时停止输出，可传单个字符串或字符串数组。                                                                                                                                                                                                     | `["\n"]`                             |
| reasoning\_effort              | string          | 否  | 用来控制模型在推理任务中投入多少“思考精力”。支持`low` `medium` `high` `xhigh` `max` `none`。平台会将其转换成`thinking`与`output_config.effort`参数回源，如果用户直接携带了`thinking`与`output_config`参数，会优先使用客户携带的参数回源。`claude-sonnet-5`默认开启思考，如需关闭，须显式携带`"reasoning_effort":"none"`。 | `none`                               |
| thinking                       | struct          | 否  | 启用 Claude 扩展思考的配置。优先于`reasoning_effort`参数。                                                                                                                                                                                            | `{"type":"adaptive"}`                |
| thinking.type                  | string          | 是  | thinking类型，支持配置`enabled`、`disabled`、`adaptive`。4.7版本及以上只支持`adaptive`、`disabled`，4.6版本三者均支持，4.5版本及以下只支持`enabled`、`disabled`。`claude-sonnet-5`默认为`adaptive`。                                                                            | `adaptive`                           |
| thinking.budget\_tokens        | number          | 否  | `type`配置为`enabled`时必须设置。用于确定 Claude 在内部推理过程中可以使用多少 token。更大的预算可以让 Claude 在处理复杂问题时进行更深入的分析，从而提升回答质量。该值必须大于等于`1024`，并且小于`max_tokens`。                                                                                                   | `1024`                               |
| thinking.display               | string          | 否  | 当设置为`summarized`时，思考内容会正常返回。当设置为`omitted`时，思考内容会被隐藏，但会返回一个签名（signature），用于支持多轮对话的连续性。4.7版本及以上通常默认会被设置为`omitted`。                                                                                                                      | `omitted`                            |
| output\_config.effort          | string          | 否  | 用来控制模型在推理任务中投入多少“计算精力”。支持配置`low`、`medium`、`high`、`xhigh`、`max`。                                                                                                                                                                       | `medium`                             |
| effort                         | string          | 否  | 顶层快捷写法，等价于 `output_config.effort`，支持 `low`、`medium`、`high`、`xhigh`、`max`。                                                                                                                                                             | `medium`                             |
| response\_format               | object          | 否  | 指定输出格式。支持 `type` 为 `json_schema` 的结构化输出（不支持 `json_object`）。4.7版本及以上不支持该参数。                                                                                                                                                            | `{"type":"json_schema",...}`         |
| tools                          | array           | 否  | 模型可调用的工具列表，目前仅支持 `type` 为 `function` 的工具。详见[函数调用](#id-4.3-han-shu-diao-yong)。                                                                                                                                                         | 见函数调用示例                              |
| tool\_choice                   | string 或 object | 否  | 控制模型如何选择工具，支持 `auto`、`required`、`none`，或通过对象指定具体函数。                                                                                                                                                                                   | `auto`                               |
| parallel\_tool\_calls          | boolean         | 否  | 是否允许一次回复中并行调用多个工具。设为 `false` 时禁用并行工具调用。                                                                                                                                                                                               | `true`                               |

***

## 4. 请求示例

### 4.1 基础对话

{% tabs %}
{% tab title="HTTP" %}

```http
POST /v1/chat/completions
Content-Type: application/json
Authorization: Bearer $YOUR_API_KEY

{
	"model": "claude-haiku-4-5-20251001",
	"messages": [
		{
			"role": "user",
			"content": "你好，给我科普一下量子力学吧"
		}
	]
}
```

{% endtab %}

{% tab title="Shell" %}

```sh
curl https://gateway.theturbo.ai/v1/chat/completions \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer $YOUR_API_KEY" \
	-d "{
	\"model\": \"claude-haiku-4-5-20251001\",
	\"messages\": [{
		\"role\": \"user\",
		\"content\": \"你好，给我科普一下量子力学吧\"
	}]
}"
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
)

func main() {
	apiKey := "sk-123456789012345678901234567890123456789012345678"

	client := openai.NewClient(
		option.WithAPIKey(apiKey),
		option.WithBaseURL("https://gateway.theturbo.ai/v1"),
	)

	resp, err := client.Chat.Completions.New(
		context.Background(),
		openai.ChatCompletionNewParams{
			Model: "claude-haiku-4-5-20251001",
			Messages: []openai.ChatCompletionMessageParamUnion{
				openai.UserMessage("你好，给我科普一下量子力学吧"),
			},
		},
	)

	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(resp.Choices[0].Message.Content)
}

```

{% endtab %}

{% tab title="Python" %}

```python
#!/usr/bin/env python3

from openai import OpenAI

def main():
    api_key = "sk-123456789012345678901234567890123456789012345678"

    client = OpenAI(
        api_key=api_key,
        base_url="https://gateway.theturbo.ai/v1"
    )

    response = client.chat.completions.create(
        model="claude-haiku-4-5-20251001",
        messages=[
            {"role": "user", "content": "你好，给我科普一下量子力学吧"}
        ]
    )

    print(response.choices[0].message.content)

if __name__ == "__main__":
    main()

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-123456789012345678901234567890123456789012345678",
  baseURL: "https://gateway.theturbo.ai/v1",
});

const response = await client.chat.completions.create({
  model: "claude-haiku-4-5-20251001",
  messages: [
    { role: "user", content: "你好，给我科普一下量子力学吧" },
  ],
});

console.log(response.choices[0].message.content);
```

{% endtab %}

{% tab title="Java" %}

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;

public final class Main {
    public static void main(String[] args) {
        String apiKey = "sk-123456789012345678901234567890123456789012345678";

        OpenAIClient client = OpenAIOkHttpClient.builder()
                .apiKey(apiKey)
                .baseUrl("https://gateway.theturbo.ai/v1")
                .build();

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("claude-haiku-4-5-20251001")
                .addUserMessage("你好，给我科普一下量子力学吧")
                .build();

        ChatCompletion chatCompletion = client.chat().completions().create(params);

        System.out.println(chatCompletion.choices().get(0).message().content().orElse(""));
    }
}
```

{% endtab %}
{% endtabs %}

### 4.2 图片理解

多模态图片理解功能，通过上传图片或图片URL提交图片给大模型。

<details>

<summary>支持的图片类型</summary>

`image/png` `image/jpeg` `image/webp` `image/gif`

</details>

{% tabs %}
{% tab title="HTTP" %}

```http
POST /v1/chat/completions
Content-Type: application/json
Authorization: Bearer $YOUR_API_KEY

{
	"model": "claude-haiku-4-5-20251001",
	"messages": [
		{
			"role": "user",
			"content": [
				{
					"type": "text",
					"text": "这张图片里有什么？"
				},
				{
					"type": "image_url",
					"image_url": {
						"url": "data:image/jpeg;base64,${base64_image}"
					}
				}
			]
		}
	]
}
```

{% endtab %}

{% tab title="Shell" %}

```sh
base64_image=$(base64 -i "Path/to/agi/image.jpeg");
curl https://gateway.theturbo.ai/v1/chat/completions \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer $YOUR_API_KEY" \
	-d "{
	\"model\": \"claude-haiku-4-5-20251001\",
	\"messages\": [{
		\"role\": \"user\",
		\"content\": [{
				\"type\": \"text\",
				\"text\": \"这张图片里有什么？\"
			},
			{
				\"type\": \"image_url\",
				\"image_url\": {
					\"url\": \"data:image/jpeg;base64,${base64_image}\"
				}
			}
		]
	}]
}"
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"context"
	"encoding/base64"
	"fmt"
	"os"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
)

func main() {
	apiKey := "sk-123456789012345678901234567890123456789012345678"

	client := openai.NewClient(
		option.WithAPIKey(apiKey),
		option.WithBaseURL("https://gateway.theturbo.ai/v1"),
	)

	imagePath := "Path/to/agi/image.jpeg"
	imageBytes, err := os.ReadFile(imagePath)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	base64Image := base64.StdEncoding.EncodeToString(imageBytes)
	imageURL := "data:image/jpeg;base64," + base64Image

	resp, err := client.Chat.Completions.New(
		context.Background(),
		openai.ChatCompletionNewParams{
			Model: "claude-haiku-4-5-20251001",
			Messages: []openai.ChatCompletionMessageParamUnion{
				openai.UserMessage([]openai.ChatCompletionContentPartUnionParam{
					openai.TextContentPart("这张图片里有什么？"),
					openai.ImageContentPart(openai.ChatCompletionContentPartImageImageURLParam{
						URL: imageURL,
					}),
				}),
			},
		},
	)

	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(resp.Choices[0].Message.Content)
}

```

{% endtab %}

{% tab title="Python" %}

```python
#!/usr/bin/env python3

import base64
from openai import OpenAI

def main():
    api_key = "sk-123456789012345678901234567890123456789012345678"

    client = OpenAI(
        api_key=api_key,
        base_url="https://gateway.theturbo.ai/v1"
    )

    image_path = "Path/to/agi/image.jpeg"
    with open(image_path, "rb") as f:
        image_bytes = f.read()

    base64_image = base64.b64encode(image_bytes).decode("utf-8")
    image_url = f"data:image/jpeg;base64,{base64_image}"

    response = client.chat.completions.create(
        model="claude-haiku-4-5-20251001",
        messages=[{
            "role": "user",
            "content": [
                {"type": "text", "text": "这张图片里有什么？"},
                {"type": "image_url", "image_url": {"url": image_url}}
            ]
        }]
    )

    print(response.choices[0].message.content)

if __name__ == "__main__":
    main()

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-123456789012345678901234567890123456789012345678",
  baseURL: "https://gateway.theturbo.ai/v1",
});

const imagePath = "Path/to/agi/image.jpeg";
const base64Image = fs.readFileSync(imagePath).toString("base64");
const imageUrl = `data:image/jpeg;base64,${base64Image}`;

const response = await client.chat.completions.create({
  model: "claude-haiku-4-5-20251001",
  messages: [
    {
      role: "user",
      content: [
        { type: "text", text: "这张图片里有什么？" },
        { type: "image_url", image_url: { url: imageUrl } },
      ],
    },
  ],
});

console.log(response.choices[0].message.content);
```

{% endtab %}

{% tab title="Java" %}

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionContentPart;
import com.openai.models.chat.completions.ChatCompletionContentPartImage;
import com.openai.models.chat.completions.ChatCompletionContentPartText;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.List;

public final class Main {
    public static void main(String[] args) throws IOException {
        String apiKey = "sk-123456789012345678901234567890123456789012345678";

        OpenAIClient client = OpenAIOkHttpClient.builder()
                .apiKey(apiKey)
                .baseUrl("https://gateway.theturbo.ai/v1")
                .build();

        byte[] imageBytes = Files.readAllBytes(Path.of("Path/to/agi/image.jpeg"));
        String imageUrl = "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(imageBytes);

        ChatCompletionContentPart textPart = ChatCompletionContentPart.ofText(
                ChatCompletionContentPartText.builder()
                        .text("这张图片里有什么？")
                        .build());
        ChatCompletionContentPart imagePart = ChatCompletionContentPart.ofImageUrl(
                ChatCompletionContentPartImage.builder()
                        .imageUrl(ChatCompletionContentPartImage.ImageUrl.builder()
                                .url(imageUrl)
                                .build())
                        .build());

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("claude-haiku-4-5-20251001")
                .addUserMessageOfArrayOfContentParts(List.of(textPart, imagePart))
                .build();

        ChatCompletion chatCompletion = client.chat().completions().create(params);

        System.out.println(chatCompletion.choices().get(0).message().content().orElse(""));
    }
}
```

{% endtab %}
{% endtabs %}

### 4.3 函数调用

{% tabs %}
{% tab title="HTTP" %}

```http
POST /v1/chat/completions
Content-Type: application/json
Authorization: Bearer $YOUR_API_KEY

{
	"model": "claude-haiku-4-5-20251001",
	"messages": [{
		"role": "user",
		"content": "What's the weather like in Boston today?"
	}],
	"tools": [{
		"type": "function",
		"function": {
			"name": "get_current_weather",
			"description": "Get the current weather in a given location",
			"parameters": {
				"type": "object",
				"properties": {
					"location": {
						"type": "string",
						"description": "The city and state, e.g. San Francisco, CA"
					},
					"unit": {
						"type": "string",
						"enum": ["celsius", "fahrenheit"]
					}
				},
				"required": ["location"]
			}
		}
	}],
	"tool_choice": "auto"
}
```

{% endtab %}

{% tab title="Shell" %}

```sh
curl https://gateway.theturbo.ai/v1/chat/completions \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer $YOUR_API_KEY" \
	-d "{
	\"model\": \"claude-haiku-4-5-20251001\",
	\"messages\": [{
		\"role\": \"user\",
		\"content\": \"What's the weather like in Boston today?\"
	}],
	\"tools\": [{
		\"type\": \"function\",
		\"function\": {
			\"name\": \"get_current_weather\",
			\"description\": \"Get the current weather in a given location\",
			\"parameters\": {
				\"type\": \"object\",
				\"properties\": {
					\"location\": {
						\"type\": \"string\",
						\"description\": \"The city and state, e.g. San Francisco, CA\"
					},
					\"unit\": {
						\"type\": \"string\",
						\"enum\": [\"celsius\", \"fahrenheit\"]
					}
				},
				\"required\": [\"location\"]
			}
		}
	}],
	\"tool_choice\": \"auto\"
}"
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
	"github.com/openai/openai-go/packages/param"
	"github.com/openai/openai-go/shared"
)

func main() {
	apiKey := "sk-123456789012345678901234567890123456789012345678"

	client := openai.NewClient(
		option.WithAPIKey(apiKey),
		option.WithBaseURL("https://gateway.theturbo.ai/v1"),
	)

	tools := []openai.ChatCompletionToolParam{
		{
			Type: "function",
			Function: shared.FunctionDefinitionParam{
				Name:        "get_current_weather",
				Description: param.NewOpt("Get the current weather in a given location"),
				Parameters: shared.FunctionParameters{
					"type": "object",
					"properties": map[string]interface{}{
						"location": map[string]interface{}{
							"type":        "string",
							"description": "The city and state, e.g. San Francisco, CA",
						},
						"unit": map[string]interface{}{
							"type": "string",
							"enum": []string{"celsius", "fahrenheit"},
						},
					},
					"required": []string{"location"},
				},
			},
		},
	}

	resp, err := client.Chat.Completions.New(
		context.Background(),
		openai.ChatCompletionNewParams{
			Model: "claude-haiku-4-5-20251001",
			Messages: []openai.ChatCompletionMessageParamUnion{
				openai.UserMessage("What's the weather like in Boston today?"),
			},
			Tools: tools,
			ToolChoice: openai.ChatCompletionToolChoiceOptionUnionParam{
				OfAuto: param.NewOpt("auto"),
			},
		},
	)

	if err != nil {
		fmt.Println("error:", err)
		return
	}

	msg := resp.Choices[0].Message

	if msg.ToolCalls != nil && len(msg.ToolCalls) > 0 {
		for _, call := range msg.ToolCalls {
			fmt.Println("🔧 Function called:", call.Function.Name)
			fmt.Println("📥 Arguments JSON:", call.Function.Arguments)

			// 如果你想解析参数
			var args map[string]any
			_ = json.Unmarshal([]byte(call.Function.Arguments), &args)
			fmt.Println("📦 Parsed args:", args)
		}
	} else {
		fmt.Println("💬 Assistant reply:", msg.Content)
	}
}

```

{% endtab %}

{% tab title="Python" %}

```python
#!/usr/bin/env python3

import json
from openai import OpenAI

def main():
    api_key = "sk-123456789012345678901234567890123456789012345678"

    client = OpenAI(
        api_key=api_key,
        base_url="https://gateway.theturbo.ai/v1"
    )

    tools = [{
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["location"]
            }
        }
    }]

    response = client.chat.completions.create(
        model="claude-haiku-4-5-20251001",
        messages=[
            {"role": "user", "content": "What's the weather like in Boston today?"}
        ],
        tools=tools,
        tool_choice="auto"
    )

    msg = response.choices[0].message

    if msg.tool_calls:
        for call in msg.tool_calls:
            print(f"🔧 Function called: {call.function.name}")
            print(f"📥 Arguments JSON: {call.function.arguments}")

            args = json.loads(call.function.arguments)
            print(f"📦 Parsed args: {args}")
    else:
        print(f"💬 Assistant reply: {msg.content}")

if __name__ == "__main__":
    main()

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-123456789012345678901234567890123456789012345678",
  baseURL: "https://gateway.theturbo.ai/v1",
});

const tools = [
  {
    type: "function",
    function: {
      name: "get_current_weather",
      description: "Get the current weather in a given location",
      parameters: {
        type: "object",
        properties: {
          location: {
            type: "string",
            description: "The city and state, e.g. San Francisco, CA",
          },
          unit: { type: "string", enum: ["celsius", "fahrenheit"] },
        },
        required: ["location"],
      },
    },
  },
];

const response = await client.chat.completions.create({
  model: "claude-haiku-4-5-20251001",
  messages: [
    { role: "user", content: "What's the weather like in Boston today?" },
  ],
  tools,
  tool_choice: "auto",
});

const message = response.choices[0].message;

if (message.tool_calls) {
  for (const call of message.tool_calls) {
    console.log("🔧 Function called:", call.function.name);
    console.log("📥 Arguments JSON:", call.function.arguments);

    const args = JSON.parse(call.function.arguments);
    console.log("📦 Parsed args:", args);
  }
} else {
  console.log("💬 Assistant reply:", message.content);
}
```

{% endtab %}

{% tab title="Java" %}

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.FunctionDefinition;
import com.openai.models.FunctionParameters;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionFunctionTool;
import com.openai.models.chat.completions.ChatCompletionMessage;
import java.util.List;
import java.util.Map;

public final class Main {
    public static void main(String[] args) {
        String apiKey = "sk-123456789012345678901234567890123456789012345678";

        OpenAIClient client = OpenAIOkHttpClient.builder()
                .apiKey(apiKey)
                .baseUrl("https://gateway.theturbo.ai/v1")
                .build();

        FunctionParameters parameters = FunctionParameters.builder()
                .putAdditionalProperty("type", JsonValue.from("object"))
                .putAdditionalProperty("properties", JsonValue.from(Map.of(
                        "location", Map.of(
                                "type", "string",
                                "description", "The city and state, e.g. San Francisco, CA"),
                        "unit", Map.of(
                                "type", "string",
                                "enum", List.of("celsius", "fahrenheit")))))
                .putAdditionalProperty("required", JsonValue.from(List.of("location")))
                .build();

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("claude-haiku-4-5-20251001")
                .addUserMessage("What's the weather like in Boston today?")
                .addTool(ChatCompletionFunctionTool.builder()
                        .function(FunctionDefinition.builder()
                                .name("get_current_weather")
                                .description("Get the current weather in a given location")
                                .parameters(parameters)
                                .build())
                        .build())
                .build();

        ChatCompletion chatCompletion = client.chat().completions().create(params);
        ChatCompletionMessage message = chatCompletion.choices().get(0).message();

        if (message.toolCalls().isPresent() && !message.toolCalls().get().isEmpty()) {
            message.toolCalls().get().forEach(toolCall -> {
                System.out.println("🔧 Function called: " + toolCall.asFunction().function().name());
                System.out.println("📥 Arguments JSON: " + toolCall.asFunction().function().arguments());
            });
        } else {
            message.content().ifPresent(content -> System.out.println("💬 Assistant reply: " + content));
        }
    }
}
```

{% endtab %}
{% endtabs %}

### 4.4 多轮对话

{% tabs %}
{% tab title="HTTP" %}

```http
POST /v1/chat/completions
Content-Type: application/json
Authorization: Bearer $YOUR_API_KEY

{
    "model": "claude-haiku-4-5-20251001",
    "reasoning_effort": "high",
    "messages": [
        {
            "role": "user",
            "content": "你好，我的名字是z"
        },
        {
            "role": "assistant",
            "content": "你好，z！很高兴认识你。👋\n\n有什么我可以帮助你的吗？",
            "reasoning_content": "用户介绍了他们的名字是\"z\"。这是一个简单的自我介绍。我应该以友好和礼貌的方式回应，并准备好帮助他们。",
            "reasoning_details": [
                {
                    "signature": "Er4CC...CaVGAE="
                }
            ]
        },
        {
            "role": "user",
            "content": "我叫什么名字"
        }
    ]
}
```

{% endtab %}

{% tab title="Shell" %}

```sh
curl https://gateway.theturbo.ai/v1/chat/completions \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer $YOUR_API_KEY" \
	-d "{
    \"model\": \"claude-haiku-4-5-20251001\",
    \"reasoning_effort\": \"high\",
    \"messages\": [
        {
            \"role\": \"user\",
            \"content\": \"你好，我的名字是z\"
        },
        {
            \"role\": \"assistant\",
            \"content\": \"你好，z！很高兴认识你。👋\\n\\n有什么我可以帮助你的吗？\",
            \"reasoning_content\": \"用户介绍了他们的名字是\\\"z\\\"。这是一个简单的自我介绍。我应该以友好和礼貌的方式回应，并准备好帮助他们。\",
            \"reasoning_details\": [
                {
                    \"signature\": \"Er4CC...CaVGAE=\"
                }
            ]
        },
        {
            \"role\": \"user\",
            \"content\": \"我叫什么名字\"
        }
    ]
}"
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
	"github.com/openai/openai-go/packages/param"
	"github.com/openai/openai-go/shared"
)

func main() {
	apiKey := "sk-123456789012345678901234567890123456789012345678"

	client := openai.NewClient(
		option.WithAPIKey(apiKey),
		option.WithBaseURL("https://gateway.theturbo.ai/v1"),
	)

	// 组装上一轮 assistant 消息，并回传模型思考内容（reasoning_content / reasoning_details）
	assistant := openai.ChatCompletionAssistantMessageParam{
		Content: openai.ChatCompletionAssistantMessageParamContentUnion{
			OfString: param.NewOpt("你好，z！很高兴认识你。👋\n\n有什么我可以帮助你的吗？"),
		},
	}
	assistant.SetExtraFields(map[string]any{
		"reasoning_content": "用户介绍了他们的名字是\"z\"。这是一个简单的自我介绍。我应该以友好和礼貌的方式回应，并准备好帮助他们。",
		"reasoning_details": []map[string]any{
			{"signature": "Er4CC...CaVGAE="},
		},
	})

	resp, err := client.Chat.Completions.New(
		context.Background(),
		openai.ChatCompletionNewParams{
			Model:           "claude-haiku-4-5-20251001",
			ReasoningEffort: shared.ReasoningEffortHigh,
			Messages: []openai.ChatCompletionMessageParamUnion{
				openai.UserMessage("你好，我的名字是z"),
				{OfAssistant: &assistant},
				openai.UserMessage("我叫什么名字"),
			},
		},
	)

	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(resp.Choices[0].Message.Content)
}

```

{% endtab %}

{% tab title="Python" %}

```python
#!/usr/bin/env python3

from openai import OpenAI

def main():
    api_key = "sk-123456789012345678901234567890123456789012345678"

    client = OpenAI(
        api_key=api_key,
        base_url="https://gateway.theturbo.ai/v1"
    )

    response = client.chat.completions.create(
        model="claude-haiku-4-5-20251001",
        reasoning_effort="high",
        messages=[
            {"role": "user", "content": "你好，我的名字是z"},
            {
                "role": "assistant",
                "content": "你好，z！很高兴认识你。👋\n\n有什么我可以帮助你的吗？",
                # 回传上一轮模型思考内容，保持思考连续性
                "reasoning_content": "用户介绍了他们的名字是\"z\"。这是一个简单的自我介绍。我应该以友好和礼貌的方式回应，并准备好帮助他们。",
                "reasoning_details": [
                    {"signature": "Er4CC...CaVGAE="}
                ]
            },
            {"role": "user", "content": "我叫什么名字"}
        ]
    )

    print(response.choices[0].message.content)

if __name__ == "__main__":
    main()

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-123456789012345678901234567890123456789012345678",
  baseURL: "https://gateway.theturbo.ai/v1",
});

const response = await client.chat.completions.create({
  model: "claude-haiku-4-5-20251001",
  reasoning_effort: "high",
  messages: [
    { role: "user", content: "你好，我的名字是z" },
    {
      role: "assistant",
      content: "你好，z！很高兴认识你。👋\n\n有什么我可以帮助你的吗？",
      // 回传上一轮模型思考内容，保持思考连续性
      reasoning_content:
        '用户介绍了他们的名字是"z"。这是一个简单的自我介绍。我应该以友好和礼貌的方式回应，并准备好帮助他们。',
      reasoning_details: [{ signature: "Er4CC...CaVGAE=" }],
    },
    { role: "user", content: "我叫什么名字" },
  ],
});

console.log(response.choices[0].message.content);
```

{% endtab %}

{% tab title="Java" %}

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.ReasoningEffort;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionAssistantMessageParam;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import java.util.List;
import java.util.Map;

public final class Main {
    public static void main(String[] args) {
        String apiKey = "sk-123456789012345678901234567890123456789012345678";

        OpenAIClient client = OpenAIOkHttpClient.builder()
                .apiKey(apiKey)
                .baseUrl("https://gateway.theturbo.ai/v1")
                .build();

        // 组装上一轮 assistant 消息，并回传模型思考内容（reasoning_content / reasoning_details）
        ChatCompletionAssistantMessageParam assistant = ChatCompletionAssistantMessageParam.builder()
                .content("你好，z！很高兴认识你。👋\n\n有什么我可以帮助你的吗？")
                .putAdditionalProperty("reasoning_content", JsonValue.from(
                        "用户介绍了他们的名字是\"z\"。这是一个简单的自我介绍。我应该以友好和礼貌的方式回应，并准备好帮助他们。"))
                .putAdditionalProperty("reasoning_details", JsonValue.from(
                        List.of(Map.of("signature", "Er4CC...CaVGAE="))))
                .build();

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("claude-haiku-4-5-20251001")
                .reasoningEffort(ReasoningEffort.HIGH)
                .addUserMessage("你好，我的名字是z")
                .addMessage(assistant)
                .addUserMessage("我叫什么名字")
                .build();

        ChatCompletion chatCompletion = client.chat().completions().create(params);

        System.out.println(chatCompletion.choices().get(0).message().content().orElse(""));
    }
}
```

{% endtab %}
{% endtabs %}

### 4.5 提示词缓存（Prompt Caching）

提示词缓存可以缓存请求中稳定不变的前缀内容（如工具定义、system 提示词、长文档等），从而降低重复请求的费用并加快响应速度。详细说明可参考[官方文档](https://platform.claude.com/docs/en/build-with-claude/prompt-caching)。

{% hint style="info" %}
本平台仅支持\*\*显式缓存断点（Explicit cache breakpoints）\*\*的方式，即通过在工具（`tools`）、系统消息（`role: system`）以及对话消息（`messages`）的具体内容块上添加 `cache_control` 字段来手动指定缓存位置。请勿在请求顶层设置 `cache_control`（自动缓存方式不受支持）。
{% endhint %}

{% hint style="info" %}
平台为保障并发资源量，后端为多账号负载，如需提高缓存命中率，多轮对话模式可携带http请求头`X-Conversation-Id`加随机字符串请求，平台会优先路由到后端同一账号上。[参考文档](/api-reference/cn/ai/aig/gateway-features/cache-optimization.md)
{% endhint %}

{% hint style="warning" %}
由于平台后端为多账号资源，缓存有效期越长越难保证命中同一后端账号。建议优先使用 5 分钟缓存（`ttl` 默认值），减少使用 1 小时缓存（`ttl: "1h"`）。
{% endhint %}

**`cache_control` 对象说明：**

| 参数名称   | 类型     | 必填 | 说明                      | 示例值         |
| ------ | ------ | -- | ----------------------- | ----------- |
| `type` | string | 是  | 缓存类型，目前仅支持 `ephemeral`  | `ephemeral` |
| `ttl`  | string | 否  | 缓存有效期，支持 `5m`（默认）与 `1h` | `1h`        |

```json
{ "type": "ephemeral" }              // 默认有效期 5 分钟
{ "type": "ephemeral", "ttl": "1h" } // 有效期 1 小时
```

{% hint style="info" %}
使用要点：

* 缓存前缀按 `tools` → `system` → `messages` 的顺序生成，缓存断点会缓存从开头到该断点（含）的全部内容。
* 每次请求最多设置 **4** 个缓存断点。
* `cache_control` 可添加在：`tools` 数组中的某个工具对象上（通常放在最后一个工具上）、系统消息（`role: system`）的内容块上、对话消息的内容块上（`text`、`image_url` 等）。
* 需将消息的 `content` 写成内容块数组形式（而非纯字符串）才能附加 `cache_control`。
* 存在最小可缓存 token 数限制（随模型不同而变化），低于阈值时不会写入缓存，且不会报错。
* 可通过响应 `usage` 中的 `cache_creation_input_tokens`（写入缓存的 token 数）与 `prompt_tokens_details.cached_tokens`（命中缓存的 token 数）验证缓存是否生效。
  {% endhint %}

下面的示例在同一个请求中演示了三种位置的 `cache_control` 用法：工具（`tools`）、系统消息（`role: system`）以及对话消息（`messages`）。

{% tabs %}
{% tab title="HTTP" %}

```http
POST /v1/chat/completions
Content-Type: application/json
Authorization: Bearer $YOUR_API_KEY

{
	"model": "claude-haiku-4-5-20251001",
	"tools": [{
		"type": "function",
		"function": {
			"name": "get_weather",
			"description": "获取指定城市的天气",
			"parameters": {
				"type": "object",
				"properties": {
					"location": {
						"type": "string",
						"description": "城市名称，例如：北京"
					}
				},
				"required": ["location"]
			}
		},
		"cache_control": {
			"type": "ephemeral"
		}
	}],
	"messages": [{
		"role": "system",
		"content": [{
			"type": "text",
			"text": "你是一个友善的人工智能助手，请参考以下知识库回答用户问题：……（此处为需要被缓存的大段稳定上下文，长度需超过模型的最小可缓存 token 数）"
		}, {
			"type": "text",
			"text": "以上为知识库内容。",
			"cache_control": {
				"type": "ephemeral"
			}
		}]
	}, {
		"role": "user",
		"content": [{
			"type": "text",
			"text": "你好，给我科普一下量子力学吧",
			"cache_control": {
				"type": "ephemeral"
			}
		}]
	}]
}
```

{% endtab %}

{% tab title="Shell" %}

```sh
curl https://gateway.theturbo.ai/v1/chat/completions \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer $YOUR_API_KEY" \
	-d "{
	\"model\": \"claude-haiku-4-5-20251001\",
	\"tools\": [{
		\"type\": \"function\",
		\"function\": {
			\"name\": \"get_weather\",
			\"description\": \"获取指定城市的天气\",
			\"parameters\": {
				\"type\": \"object\",
				\"properties\": {
					\"location\": {
						\"type\": \"string\",
						\"description\": \"城市名称，例如：北京\"
					}
				},
				\"required\": [\"location\"]
			}
		},
		\"cache_control\": { \"type\": \"ephemeral\" }
	}],
	\"messages\": [{
		\"role\": \"system\",
		\"content\": [{
			\"type\": \"text\",
			\"text\": \"你是一个友善的人工智能助手，请参考以下知识库回答用户问题：……（此处为需要被缓存的大段稳定上下文，长度需超过模型的最小可缓存 token 数）\"
		}, {
			\"type\": \"text\",
			\"text\": \"以上为知识库内容。\",
			\"cache_control\": { \"type\": \"ephemeral\" }
		}]
	}, {
		\"role\": \"user\",
		\"content\": [{
			\"type\": \"text\",
			\"text\": \"你好，给我科普一下量子力学吧\",
			\"cache_control\": { \"type\": \"ephemeral\" }
		}]
	}]
}"
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
	"github.com/openai/openai-go/packages/param"
	"github.com/openai/openai-go/shared"
)

func main() {
	apiKey := "sk-123456789012345678901234567890123456789012345678"

	client := openai.NewClient(
		option.WithAPIKey(apiKey),
		option.WithBaseURL("https://gateway.theturbo.ai/v1"),
	)

	// cache_control 为平台扩展字段，通过 SetExtraFields 注入到对应对象
	cacheControl := map[string]any{
		"cache_control": map[string]any{"type": "ephemeral"},
	}

	// 1) 在 tool 上添加 cache_control（缓存 tools 前缀）
	weatherTool := openai.ChatCompletionToolParam{
		Function: shared.FunctionDefinitionParam{
			Name:        "get_weather",
			Description: param.NewOpt("获取指定城市的天气"),
			Parameters: shared.FunctionParameters{
				"type": "object",
				"properties": map[string]any{
					"location": map[string]any{
						"type":        "string",
						"description": "城市名称，例如：北京",
					},
				},
				"required": []string{"location"},
			},
		},
	}
	weatherTool.SetExtraFields(cacheControl)

	// 2) 在系统消息内容块上添加 cache_control
	sysStable := openai.ChatCompletionContentPartTextParam{
		Text: "你是一个友善的人工智能助手，请参考以下知识库回答用户问题：……（此处为需要被缓存的大段稳定上下文，长度需超过模型的最小可缓存 token 数）",
	}
	sysBreak := openai.ChatCompletionContentPartTextParam{
		Text: "以上为知识库内容。",
	}
	sysBreak.SetExtraFields(cacheControl)

	// 3) 在对话消息内容块上添加 cache_control
	userPart := openai.ChatCompletionContentPartTextParam{
		Text: "你好，给我科普一下量子力学吧",
	}
	userPart.SetExtraFields(cacheControl)

	resp, err := client.Chat.Completions.New(
		context.Background(),
		openai.ChatCompletionNewParams{
			Model: "claude-haiku-4-5-20251001",
			Tools: []openai.ChatCompletionToolParam{weatherTool},
			Messages: []openai.ChatCompletionMessageParamUnion{
				openai.SystemMessage([]openai.ChatCompletionContentPartTextParam{sysStable, sysBreak}),
				openai.UserMessage([]openai.ChatCompletionContentPartUnionParam{
					{OfText: &userPart},
				}),
			},
		},
	)

	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("💬 Assistant reply:")
	fmt.Println(resp.Choices[0].Message.Content)

	// cache_creation_input_tokens、cache_read_input_tokens 及 prompt_tokens_details.cache_creation
	// 为平台扩展字段，openai-go 未做强类型映射，这里解析 usage 原始 JSON（缺失或 null 均按 0 处理）
	var usage struct {
		PromptTokens        int64 `json:"prompt_tokens"`
		CompletionTokens    int64 `json:"completion_tokens"`
		TotalTokens         int64 `json:"total_tokens"`
		PromptTokensDetails struct {
			CachedTokens  int64 `json:"cached_tokens"`
			CacheCreation struct {
				Ephemeral5mInputTokens int64 `json:"ephemeral_5m_input_tokens"`
				Ephemeral1hInputTokens int64 `json:"ephemeral_1h_input_tokens"`
			} `json:"cache_creation"`
		} `json:"prompt_tokens_details"`
		CacheReadInputTokens     int64 `json:"cache_read_input_tokens"`
		CacheCreationInputTokens int64 `json:"cache_creation_input_tokens"`
	}
	_ = json.Unmarshal([]byte(resp.Usage.RawJSON()), &usage)

	fmt.Println("\n📊 Token usage:")
	fmt.Printf("  - Prompt tokens: %d\n", usage.PromptTokens)
	fmt.Printf("  - Completion tokens: %d\n", usage.CompletionTokens)
	fmt.Printf("  - Total tokens: %d\n", usage.TotalTokens)
	fmt.Printf("  - Cached tokens: %d\n", usage.PromptTokensDetails.CachedTokens)
	fmt.Printf("  - Ephemeral 5m input tokens: %d\n", usage.PromptTokensDetails.CacheCreation.Ephemeral5mInputTokens)
	fmt.Printf("  - Ephemeral 1h input tokens: %d\n", usage.PromptTokensDetails.CacheCreation.Ephemeral1hInputTokens)
	fmt.Printf("  - Cache read input tokens: %d\n", usage.CacheReadInputTokens)
	fmt.Printf("  - Cache creation input tokens: %d\n", usage.CacheCreationInputTokens)
}

```

{% endtab %}

{% tab title="Python" %}

```python
#!/usr/bin/env python3

from openai import OpenAI

def main():
    api_key = "sk-123456789012345678901234567890123456789012345678"

    client = OpenAI(
        api_key=api_key,
        base_url="https://gateway.theturbo.ai/v1"
    )

    response = client.chat.completions.create(
        model="claude-haiku-4-5-20251001",
        # 1) 在 tool 上添加 cache_control（缓存 tools 前缀）
        tools=[{
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "获取指定城市的天气",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "城市名称，例如：北京"
                        }
                    },
                    "required": ["location"]
                }
            },
            "cache_control": {"type": "ephemeral"}
        }],
        messages=[
            # 2) 在系统消息内容块上添加 cache_control
            {
                "role": "system",
                "content": [
                    {
                        "type": "text",
                        "text": "你是一个友善的人工智能助手，请参考以下知识库回答用户问题：……（此处为需要被缓存的大段稳定上下文，长度需超过模型的最小可缓存 token 数）"
                    },
                    {
                        "type": "text",
                        "text": "以上为知识库内容。",
                        "cache_control": {"type": "ephemeral"}
                    }
                ]
            },
            # 3) 在对话消息内容块上添加 cache_control
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "你好，给我科普一下量子力学吧",
                        "cache_control": {"type": "ephemeral"}
                    }
                ]
            }
        ]
    )

    print("💬 Assistant reply:")
    print(response.choices[0].message.content)

    # cache_creation_input_tokens、cache_read_input_tokens 及 prompt_tokens_details.cache_creation
    # 为平台扩展字段，转成 dict 读取，缺失或为空统一按 0 处理
    usage = response.usage.model_dump()
    prompt_tokens_details = usage.get("prompt_tokens_details") or {}
    cache_creation = prompt_tokens_details.get("cache_creation") or {}

    print("\n📊 Token usage:")
    print(f"  - Prompt tokens: {usage.get('prompt_tokens') or 0}")
    print(f"  - Completion tokens: {usage.get('completion_tokens') or 0}")
    print(f"  - Total tokens: {usage.get('total_tokens') or 0}")
    print(f"  - Cached tokens: {prompt_tokens_details.get('cached_tokens') or 0}")
    print(f"  - Ephemeral 5m input tokens: {cache_creation.get('ephemeral_5m_input_tokens') or 0}")
    print(f"  - Ephemeral 1h input tokens: {cache_creation.get('ephemeral_1h_input_tokens') or 0}")
    print(f"  - Cache read input tokens: {usage.get('cache_read_input_tokens') or 0}")
    print(f"  - Cache creation input tokens: {usage.get('cache_creation_input_tokens') or 0}")

if __name__ == "__main__":
    main()

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-123456789012345678901234567890123456789012345678",
  baseURL: "https://gateway.theturbo.ai/v1",
});

const response = await client.chat.completions.create({
  model: "claude-haiku-4-5-20251001",
  // 1) 在 tool 上添加 cache_control（缓存 tools 前缀）
  tools: [
    {
      type: "function",
      function: {
        name: "get_weather",
        description: "获取指定城市的天气",
        parameters: {
          type: "object",
          properties: {
            location: { type: "string", description: "城市名称，例如：北京" },
          },
          required: ["location"],
        },
      },
      cache_control: { type: "ephemeral" },
    },
  ],
  messages: [
    // 2) 在系统消息内容块上添加 cache_control
    {
      role: "system",
      content: [
        {
          type: "text",
          text: "你是一个友善的人工智能助手，请参考以下知识库回答用户问题：……（此处为需要被缓存的大段稳定上下文，长度需超过模型的最小可缓存 token 数）",
        },
        {
          type: "text",
          text: "以上为知识库内容。",
          cache_control: { type: "ephemeral" },
        },
      ],
    },
    // 3) 在对话消息内容块上添加 cache_control
    {
      role: "user",
      content: [
        {
          type: "text",
          text: "你好，给我科普一下量子力学吧",
          cache_control: { type: "ephemeral" },
        },
      ],
    },
  ],
});

console.log("💬 Assistant reply:");
console.log(response.choices[0].message.content);

// cache_creation_input_tokens、cache_read_input_tokens 及 prompt_tokens_details.cache_creation
// 为平台扩展字段，从 usage 原始结构读取，缺失或为空统一按 0 处理
const usage = response.usage ?? {};
const promptTokensDetails = usage.prompt_tokens_details ?? {};
const cacheCreation = promptTokensDetails.cache_creation ?? {};

console.log("\n📊 Token usage:");
console.log(`  - Prompt tokens: ${usage.prompt_tokens ?? 0}`);
console.log(`  - Completion tokens: ${usage.completion_tokens ?? 0}`);
console.log(`  - Total tokens: ${usage.total_tokens ?? 0}`);
console.log(`  - Cached tokens: ${promptTokensDetails.cached_tokens ?? 0}`);
console.log(`  - Ephemeral 5m input tokens: ${cacheCreation.ephemeral_5m_input_tokens ?? 0}`);
console.log(`  - Ephemeral 1h input tokens: ${cacheCreation.ephemeral_1h_input_tokens ?? 0}`);
console.log(`  - Cache read input tokens: ${usage.cache_read_input_tokens ?? 0}`);
console.log(`  - Cache creation input tokens: ${usage.cache_creation_input_tokens ?? 0}`);
```

{% endtab %}

{% tab title="Java" %}

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.FunctionDefinition;
import com.openai.models.FunctionParameters;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionContentPart;
import com.openai.models.chat.completions.ChatCompletionContentPartText;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionFunctionTool;
import com.openai.models.completions.CompletionUsage;
import java.util.List;
import java.util.Map;

public final class Main {
    public static void main(String[] args) {
        String apiKey = "sk-123456789012345678901234567890123456789012345678";

        OpenAIClient client = OpenAIOkHttpClient.builder()
                .apiKey(apiKey)
                .baseUrl("https://gateway.theturbo.ai/v1")
                .build();

        // cache_control 为平台扩展字段，通过 putAdditionalProperty 注入到对应对象
        JsonValue cacheControl = JsonValue.from(Map.of("type", "ephemeral"));

        // 1) 在 tool 上添加 cache_control（缓存 tools 前缀）
        FunctionParameters parameters = FunctionParameters.builder()
                .putAdditionalProperty("type", JsonValue.from("object"))
                .putAdditionalProperty("properties", JsonValue.from(Map.of(
                        "location", Map.of(
                                "type", "string",
                                "description", "城市名称，例如：北京"))))
                .putAdditionalProperty("required", JsonValue.from(List.of("location")))
                .build();

        ChatCompletionFunctionTool weatherTool = ChatCompletionFunctionTool.builder()
                .function(FunctionDefinition.builder()
                        .name("get_weather")
                        .description("获取指定城市的天气")
                        .parameters(parameters)
                        .build())
                .putAdditionalProperty("cache_control", cacheControl)
                .build();

        // 2) 在系统消息内容块上添加 cache_control
        ChatCompletionContentPartText sysStable = ChatCompletionContentPartText.builder()
                .text("你是一个友善的人工智能助手，请参考以下知识库回答用户问题：……（此处为需要被缓存的大段稳定上下文，长度需超过模型的最小可缓存 token 数）")
                .build();
        ChatCompletionContentPartText sysBreak = ChatCompletionContentPartText.builder()
                .text("以上为知识库内容。")
                .putAdditionalProperty("cache_control", cacheControl)
                .build();

        // 3) 在对话消息内容块上添加 cache_control
        ChatCompletionContentPartText userPart = ChatCompletionContentPartText.builder()
                .text("你好，给我科普一下量子力学吧")
                .putAdditionalProperty("cache_control", cacheControl)
                .build();

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("claude-haiku-4-5-20251001")
                .addTool(weatherTool)
                .addSystemMessageOfArrayOfContentParts(List.of(sysStable, sysBreak))
                .addUserMessageOfArrayOfContentParts(List.of(ChatCompletionContentPart.ofText(userPart)))
                .build();

        ChatCompletion chatCompletion = client.chat().completions().create(params);

        System.out.println("💬 Assistant reply:");
        System.out.println(chatCompletion.choices().get(0).message().content().orElse(""));

        // cache_creation_input_tokens、cache_read_input_tokens 及 prompt_tokens_details.cache_creation
        // 为平台扩展字段，openai-java 未做强类型映射，这里通过 _additionalProperties() 读取
        chatCompletion.usage().ifPresent(usage -> {
            System.out.println("\n📊 Token usage:");
            System.out.println("  - Prompt tokens: " + usage.promptTokens());
            System.out.println("  - Completion tokens: " + usage.completionTokens());
            System.out.println("  - Total tokens: " + usage.totalTokens());
            System.out.println("  - Cached tokens: " + usage.promptTokensDetails()
                    .flatMap(CompletionUsage.PromptTokensDetails::cachedTokens).orElse(0L));
            System.out.println("  - Cache read input tokens: "
                    + extLong(usage._additionalProperties().get("cache_read_input_tokens")));
            System.out.println("  - Cache creation input tokens: "
                    + extLong(usage._additionalProperties().get("cache_creation_input_tokens")));
            usage.promptTokensDetails().ifPresent(details -> {
                JsonValue cacheCreation = details._additionalProperties().get("cache_creation");
                if (cacheCreation != null) {
                    System.out.println("  - Cache creation detail: " + cacheCreation);
                }
            });
        });
    }

    // 将平台扩展字段（JsonValue）安全地转换为 long，缺失或非数字时返回 0
    private static long extLong(JsonValue value) {
        if (value == null) {
            return 0L;
        }

        Object number = value.asNumber().orElse(null);
        if (number instanceof Number) {
            return ((Number) number).longValue();
        }

        return 0L;
    }
}
```

{% endtab %}
{% endtabs %}

## 5. 响应示例

```json
{
	"id": "chatcmpl-1234567890",
	"object": "chat.completion",
	"created": 1699999999,
	"model": "claude-haiku-4-5-20251001",
	"choices": [
		{
			"message": {
				"role": "assistant",
				"content": "量子力学是研究微观世界的物理学分支……"
			},
			"finish_reason": "stop"
		}
	],
	"usage": {
		"prompt_tokens": 9608,
		"completion_tokens": 179,
		"total_tokens": 9787,
		"prompt_tokens_details": {
			"cached_tokens": 0,
			"cache_creation": {
				"ephemeral_5m_input_tokens": 4800,
				"ephemeral_1h_input_tokens": 4805
			}
		},
		"cache_read_input_tokens": 0,
		"cache_creation_input_tokens": 9605
	}
}
```
