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 設計