Kimi K3 API 快速入门:Python、流式输出、视觉与工具调用

从零调用 Kimi K3 API,介绍 Python 与 cURL 示例、推理强度、流式输出、视觉输入、结构化输出、工具调用及 1M 上下文限制。

Kimi K3 是 Kimi 面向编程、知识工作和复杂推理场景推出的旗舰模型。它采用 Kimi Delta Attention(KDA)、Attention Residuals 和 MoE 架构,参数规模为 2.8 万亿,并提供原生视觉理解与 100 万 token 上下文。

本文基于 Kimi K3 官方 Quickstart,从 API Key 和最小调用开始,整理 Python、cURL、流式输出、视觉输入、结构化输出和工具调用的可运行示例,并标出从 K2.x 迁移时最容易踩到的参数差异。

Quick Answer

准备 Python 3.9+ 和 Kimi API Key,安装 OpenAI SDK,把 Key 写入 MOONSHOT_API_KEY,然后将 OpenAI 客户端的 base_url 指向 https://api.moonshot.ai/v1,模型名使用 kimi-k3

1
python3 -m pip install --upgrade 'openai>=1.0'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import os

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MOONSHOT_API_KEY"],
    base_url="https://api.moonshot.ai/v1",
)

completion = client.chat.completions.create(
    model="kimi-k3",
    messages=[{"role": "user", "content": "用一句话介绍 Kimi K3。"}],
)

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

K3 始终开启思考模式。若要显式设置推理强度,应使用顶层字段 reasoning_effort="max",不要沿用 K2.x 的 thinking 参数。

准备 API Key 和环境变量

先在 Kimi API Platform 获取 API Key。不要把 Key 直接写入脚本或提交到 Git,建议通过环境变量传入。

Windows PowerShell

1
2
$env:MOONSHOT_API_KEY = "你的 API Key"
python .\kimi_k3_demo.py

如需为当前 Windows 用户永久保存,可执行:

1
[Environment]::SetEnvironmentVariable("MOONSHOT_API_KEY", "你的 API Key", "User")

保存后请重新打开终端。

macOS 和 Linux

1
2
export MOONSHOT_API_KEY="你的 API Key"
python3 kimi_k3_demo.py

使用 cURL 完成最小调用

不想先创建 Python 项目时,可以直接调用兼容 OpenAI Chat Completions 的接口:

1
2
3
4
5
6
7
curl https://api.moonshot.ai/v1/chat/completions \
  --header "Authorization: Bearer $MOONSHOT_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "kimi-k3",
    "messages": [{"role": "user", "content": "用一句话介绍 Kimi K3。"}]
  }'

PowerShell 中可用 Invoke-RestMethod,避免直接照搬 Bash 的反斜杠换行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$headers = @{
    Authorization = "Bearer $env:MOONSHOT_API_KEY"
    "Content-Type" = "application/json"
}

$body = @{
    model = "kimi-k3"
    messages = @(
        @{ role = "user"; content = "用一句话介绍 Kimi K3。" }
    )
} | ConvertTo-Json -Depth 5

Invoke-RestMethod `
    -Uri "https://api.moonshot.ai/v1/chat/completions" `
    -Method Post `
    -Headers $headers `
    -Body $body

设置 K3 的推理强度

K3 当前只支持 max,它也是默认值。官方后续会增加更多档位,因此现阶段可以省略该字段;如果希望配置意图更明确,可这样写:

1
2
3
4
5
6
7
8
9
completion = client.chat.completions.create(
    model="kimi-k3",
    reasoning_effort="max",
    messages=[
        {"role": "user", "content": "证明根号 2 是无理数。"}
    ],
)

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

多轮对话和工具调用中,要把 API 返回的完整 assistant message 放回下一次请求,不能只保留 content。完整消息还可能包含推理和工具调用所需的信息,裁剪后容易导致上下文不完整。

分别处理流式推理与最终答案

流式响应会把思考过程放在 reasoning_content,最终答案放在 content。应用界面可以分别处理两类增量:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
stream = client.chat.completions.create(
    model="kimi-k3",
    messages=[{"role": "user", "content": "解释天空为什么是蓝色的。"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta
    reasoning = getattr(delta, "reasoning_content", None)
    if reasoning:
        print(reasoning, end="", flush=True)
    if delta.content:
        print(delta.content, end="", flush=True)

生产环境通常应把 reasoning_content 与面向用户的最终答案分开存储或展示,避免前端把两段内容混为一谈。

发送本地图片

视觉消息的 content 必须是对象数组,不能把数组序列化成字符串。K3 不支持直接读取公网图片 URL,本地图片需要转为 Base64 Data URL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import base64
from pathlib import Path

image_data = base64.b64encode(Path("image.png").read_bytes()).decode()

completion = client.chat.completions.create(
    model="kimi-k3",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{image_data}"
                    },
                },
                {"type": "text", "text": "描述这张图片。"},
            ],
        }
    ],
)

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

视频应先通过 Files API 上传,再以 ms://<file-id> 引用;任务结束后记得删除临时文件,避免长期保留无用数据。

使用严格 JSON Schema 输出

需要稳定地把结果交给程序处理时,可通过 json_schemastrict: true 限制最终输出。解析时只读取 message.content,不要解析 reasoning_content

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import json

completion = client.chat.completions.create(
    model="kimi-k3",
    messages=[
        {"role": "user", "content": "小林今年 28 岁,提取姓名和年龄。"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                },
                "required": ["name", "age"],
                "additionalProperties": False,
            },
        },
    },
)

person = json.loads(completion.choices[0].message.content or "{}")
print(person)

additionalProperties: false 可以阻止模型增加 schema 以外的字段,适合数据抽取、表单填写和下游自动化。

实现最小工具调用循环

在第一轮设置 tool_choice="required",可以要求模型至少调用一次工具。执行工具后,需要保留完整 assistant message,并为每个调用追加一个具有匹配 tool_call_id 的 tool message。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import json
from typing import Any

tools: list[dict[str, Any]] = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询城市天气",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        },
    }
]

messages: list[Any] = [
    {"role": "user", "content": "今天上海天气如何?"}
]

first = client.chat.completions.create(
    model="kimi-k3",
    messages=messages,
    tools=tools,
    tool_choice="required",
)

assistant_message = first.choices[0].message
messages.append(assistant_message)

for tool_call in assistant_message.tool_calls or []:
    arguments = json.loads(tool_call.function.arguments)
    result = json.dumps(
        {"city": arguments["city"], "weather": "sunny", "temperature_c": 32},
        ensure_ascii=False,
    )
    messages.append(
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": result,
        }
    )

final = client.chat.completions.create(
    model="kimi-k3",
    messages=messages,
    tools=tools,
)

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

真实项目还要校验工具参数、限制可访问资源、设置超时,并在执行写入、删除、发送等高风险操作前加入人工确认。

动态加载工具

如果工具数量很多,可以在对话进行到需要的位置时,通过不含 contentsystem message 注入完整工具定义。定义必须包含 namedescriptionparameters,并在后续请求历史中持续保留;服务端不会替应用保存这段定义。

这个能力适合大型 Agent:先提供少量基础工具,确认任务方向后再加载数据库、浏览器或业务系统工具,减少一开始提交的工具描述。

1M 上下文与自动缓存

普通模型请求会自动尝试上下文缓存,不需要提供缓存 ID、TTL 或额外参数。要提高命中机会,应让较长且稳定的内容位于请求前部,并在后续请求中保持这段前缀不变。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from pathlib import Path

knowledge = Path("knowledge-base.md").read_text(encoding="utf-8")

for question in ["总结主要结论。", "列出三个实施风险。"]:
    completion = client.chat.completions.create(
        model="kimi-k3",
        messages=[
            {"role": "system", "content": knowledge},
            {"role": "user", "content": question},
        ],
    )
    print(completion.choices[0].message.content)

100 万 token 是容量上限,不代表每次请求都应塞满上下文。先做文件筛选、分段检索和结果去重,通常能降低延迟与费用,也能减少无关内容干扰。

当前限制与迁移注意事项

接入前建议逐项检查以下限制:

  • K3 始终启用思考模式,reasoning_effort 目前只支持 max
  • max_completion_tokens 默认为 131072,最高可设为 1048576;
  • temperature=1.0top_p=0.95n=1presence_penalty=0frequency_penalty=0 是固定值,请从请求中省略;
  • 多轮对话与工具调用必须原样返回完整 assistant message;
  • 视觉输入不支持公网图片 URL,应使用 Base64 或 ms://<file-id>
  • Kimi 官方网页搜索工具正在更新,当前不建议用于近期的生产工作流。

如果旧项目使用 K2.x,迁移时先全局搜索 thinking、采样参数和只保存 content 的消息处理代码,再增加流式 reasoning_content、视觉数组格式及工具调用回填测试。

常见问题

Kimi K3 能直接使用 OpenAI SDK 吗?

可以。安装 openai>=1.0,将 base_url 设置为 https://api.moonshot.ai/v1,并通过 MOONSHOT_API_KEY 传入密钥即可。

为什么设置 temperature 后请求失败?

K3 的 temperaturetop_p 等采样参数采用固定值。官方建议省略这些字段,不要照搬其他 OpenAI 兼容模型的通用配置。

图片可以直接传 HTTP 地址吗?

不可以。应把本地图片编码为 Base64 Data URL,或先上传文件后使用 ms://<file-id>

1M 上下文需要手动开启缓存吗?

不需要。常规模型请求会自动尝试缓存。保持长前缀完全一致,有助于后续请求命中缓存。

Kimi K3 如何计费?

官方采用按量计费,100 万 token 上下文不分长度阶梯;输入会区分缓存命中与未命中的单价,输出按 token 计费。具体价格可能调整,使用前应查看 Kimi K3 Pricing 页面。

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计