Claude 的 API,我本來還以為只是單純呼叫模型而已,沒想到居然一直在進化!

環境

建立一個 Python 專案,並安裝 Anthropic 的官方 SDK。

uv init app --python 3.13 --no-package
cd app
uv add anthropic

因為我想使用不用 API 金鑰的驗證方式,所以安裝 ant 指令。

mise use github:anthropics/anthropic-cli

登入。

ant auth login

基本的呼叫

先從最簡單的呼叫開始。到這裡為止我也還知道。

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-haiku-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "こんにちは"}],
)

print(next(b.text for b in response.content if b.type == "text"))

因為有時候會出現思考區塊,所以 print 稍微複雜了一點

執行結果

こんにちは!今天有什麼我可以幫忙的嗎?

基本的呼叫 with 系統提示詞

加上系統提示詞之後就是這樣。

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-haiku-5-5",
    max_tokens=1024,
    system="あなたは関西弁で話す陽気なアシスタントです。",
    messages=[{"role": "user", "content": "こんにちは"}],
)

print(next(b.text for b in response.content if b.type == "text"))

執行結果

こんにちは!ええ天気やなあ、今日もなんでも聞いてや!

何かお手伝いできることあったら、気軽に言うてな。

系統提示詞を途中で追記する

從這裡開始就是未知領域了!

首先,可以在中途追加系統提示詞。

  • 第 1 次請求
    • 系統:你是一個親切的助理
    • 使用者:早餐要吃什麼?
  • 第 2 次請求
    • 使用者:那午餐呢?
    • 系統:(在第 1 次請求的基礎上)從這裡開始請用英文回答

要追加的系統提示詞,必須放在使用者提示詞之後。

這樣就能在維持提示詞快取的同時修改系統提示詞!

import anthropic

client = anthropic.Anthropic()
MODEL = "claude-haiku-5-5"

messages = [{"role": "user", "content": "おすすめの朝ごはんを教えて"}]

first = client.messages.create(
    model=MODEL,
    max_tokens=1024,
    system="あなたは親切なアシスタントです。",
    messages=messages,
)
print("【第 1 回合】")
print(next(b.text for b in first.content if b.type == "text"))

# 將 assistant 的回覆加入歷史,接著加上下一次使用者發言與「中途追加的 system」
messages.append({"role": "assistant", "content": first.content})
messages.append({"role": "user", "content": "じゃあ昼ごはんは?"})
messages.append(
    {
        "role": "system",
        "content": "ここからは必ず英語で、2文以内で答えてください。",
    }
)

second = client.messages.create(
    model=MODEL,
    max_tokens=1024,
    system="あなたは親切なアシスタントです。",  # 與第 1 回合同樣(不變)
    messages=messages,
)
print("【第 2 回合(中途追加 system)】")
print(next(b.text for b in second.content if b.type == "text"))

執行結果

【第 1 回合】
朝ごはんのおすすめをいくつかご紹介します。

(中略)

今日の気分や時間、好みの味(和食・洋食など)を教えてもらえれば、もっと絞ったレシピもご提案できます。
【第 2 回合(中途追加 system)】
For lunch, try a chicken teriyaki rice bowl with steamed vegetables, which is filling and easy to prepare. If you want something lighter, a salmon and avocado salad with a sesame dressing is a refreshing choice.

工具定義を途中で追記する

不只是系統提示詞,工具也可以在途中追加!

截至發文時這還是 Beta 功能,需要指定 inline-tools-2026-09-15。

會作為中途插入的系統提示詞的一部分來追加。

  • 第 1 次請求
    • 只有 GET_WEATHER 工具
  • 第 2 次請求
    • 新增 GET_TIME 工具

(節錄)

messages.append(
    {
        "role": "system",
        "content": [
            {
                "type": "tool_addition",
                "tool": {"type": "tool_definition", "definition": GET_TIME},
            }
        ],
    }
)

這樣就能在維持提示詞快取的同時新增工具!

另外也有移除工具用的 "type": "tool_removal",


import json
from datetime import datetime

import anthropic

client = anthropic.Anthropic()
MODEL = "claude-haiku-5-5"
BETAS = ["inline-tools-2026-09-15"]

GET_WEATHER = {
    "name": "get_weather",
    "description": "回傳城市目前的天氣",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
    },
}
GET_TIME = {
    "name": "get_time",
    "description": "回傳目前日期與時間",
    "input_schema": {"type": "object", "properties": {}},
}

def run_tool(name: str, args: dict) -> str:
    if name == "get_weather":
        return f"{args['city']}: 晴朗,18 度"
    if name == "get_time":
        return datetime.now().isoformat(timespec="minutes")
    return "unknown tool"

def ask(messages: list) -> None:
    """只要有 tool_use 就持續迴圈,直到顯示最終文字。"""
    while True:
        response = client.beta.messages.create(
            model=MODEL,
            max_tokens=2048,
            betas=BETAS,
            tools=[GET_WEATHER],  # 從頭到尾都只有 get_weather(不改動)
            messages=messages,
        )
        messages.append({"role": "assistant", "content": response.content})

        tool_uses = [b for b in response.content if b.type == "tool_use"]
        if not tool_uses:
            print(next(b.text for b in response.content if b.type == "text"))
            return
        for b in tool_uses:
            print(f"  [tool_use] {b.name}({json.dumps(b.input, ensure_ascii=False)})")
        messages.append(
            {
                "role": "user",
                "content": [
                    {
                        "type": "tool_result",
                        "tool_use_id": b.id,
                        "content": run_tool(b.name, b.input),
                    }
                    for b in tool_uses
                ],
            }
        )

messages = [{"role": "user", "content": "東京の天気は?"}]
print("【第 1 回合:只能使用 get_weather】")
ask(messages)

# 中途新增 get_time。tools[] 不動,改以 system 訊息帶入定義
messages.append({"role": "user", "content": "現在幾點?還有再告訴我一次東京的天氣"})
messages.append(
    {
        "role": "system",
        "content": [
            {
                "type": "tool_addition",
                "tool": {"type": "tool_definition", "definition": GET_TIME},
            }
        ],
    }
)
print("【第 2 回合:中途新增 get_time】")
ask(messages)

執行結果

【第 1 回合:只能使用 get_weather】
  [tool_use] get_weather({"city": "東京"})
東京目前的天氣是晴天,氣溫是18度。
【第 2 回合:中途新增 get_time】
  [tool_use] get_time({})
  [tool_use] get_weather({"city": "東京"})
現在的時間是2026年11月14日 14時11分。

東京的天氣再次確認後依然是晴天,氣溫是18度。

思考層級(effort)在途中變更

模型的思考層級也可以在途中變更。這也是透過插入系統提示詞來做到的。

截至發文時這是 Beta 功能,需要指定 mid-conversation-output-config-2026-07-01。

(節錄)

messages.append(
    {"role": "system", 
     "content": [], 
     "output_config": {"effort": "low"}
    }
)

變更之後會一直生效,因此如果想再次變更,就再插入一次系統提示詞即可。

這樣就能在維持提示詞快取的同時變更 Effort!

import anthropic

client = anthropic.Anthropic()
MODEL = "claude-haiku-5-5"
BETAS = ["mid-conversation-output-config-2026-07-01"]

QUESTIONS = [
    "4桁の数のうち、各桁の数字がすべて異なり、かつ千の位が百の位より大きい数は全部でいくつ?",
    "1から100までの整数のうち、3でも5でも割り切れない数は全部でいくつ?",
    "5人が円卓に座る並び方(回転して同じになるものは同一視)のうち、特定の2人が隣り合う並び方はいくつ?",
]

def effort(level: str) -> dict:
    return {"role": "system", "content": [], "output_config": {"effort": level}}

def turn(label: str, messages: list) -> None:
    response = client.beta.messages.create(
        model=MODEL,
        max_tokens=16000,
        betas=BETAS,
        output_config={"effort": "high"},  # 整個請求的設定不變
        messages=messages,
    )
    messages.append({"role": "assistant", "content": response.content})
    thinking_tokens = response.usage.output_tokens_details.thinking_tokens
    print(f"【{label}】thinking_tokens={thinking_tokens}")

messages = [{"role": "user", "content": QUESTIONS[0]}]
turn("第 1 回合:high(原始設定)", messages)

messages += [effort("low"), {"role": "user", "content": QUESTIONS[1]}]
turn("第 2 回合:改成 low", messages)

messages += [effort("high"), {"role": "user", "content": QUESTIONS[2]}]
turn("第 3 回合:改回 high", messages)

執行結果(只輸出思考量)

【第 1 回合:high(原始設定)】thinking_tokens=465
【第 2 回合:改成 low】thinking_tokens=0
【第 3 回合:改回 high】thinking_tokens=169

插入只在 1 回合有效的系統提示詞

最後是一個相當小眾的機制,也就是插入只會暫時生效的系統提示詞的方法。

  • 第 1~4 回合
    • 一般系統提示詞:「每次回覆時,隨機從日語、英語、法語、西班牙語、德語中選一種,並且只能用那種語言,以一句話打招呼。」
  • 第 5 回合
    • 只在這一回合有效的系統提示詞:「一定要用法語打招呼。」
  • 第 6 回合
    • 第 2 回合加上的內容不再生效,回到第 1 回合的狀態

透過指定 clear_at 為 next_user_message 來插入系統提示詞。(若未指定,預設值是 never,會被視為一直適用)

截至發文時這是 Beta 功能,需要指定 mid-conversation-system-clear-at-2026-08-21。(和變更思考層級時指定的 mid-conversation-output-config-2026-07-01 數值略有不同)

節錄

{
    "role": "system",
    "clear_at": "next_user_message",
    "content": "絶対にフランス語であいさつしてください。",
}
import anthropic

client = anthropic.Anthropic()
MODEL = "claude-haiku-5-5"
BETAS = ["mid-conversation-system-clear-at-2026-08-21"]

SYSTEM = (
    "返答ごとに、日本語・英語・フランス語・スペイン語・ドイツ語のどれかをランダムに選び、"
    "その言語だけで、1文であいさつしてください。"
)

# 只在第 5 次插入、僅限 1 回合的 system 訊息
NOTICE = {
    "role": "system",
    "clear_at": "next_user_message",
    "content": "絶対にフランス語であいさつしてください。",
}

messages = []
for turn in range(1, 7):
    messages.append({"role": "user", "content": "こんにちは!"})
    if turn == 5:
        messages.append(NOTICE)
    response = client.beta.messages.create(
        model=MODEL,
        max_tokens=1024,
        betas=BETAS,
        system=SYSTEM,
        messages=messages,
    )
    text = next(b.text for b in response.content if b.type == "text")
    # 思考區塊不放進歷史,只保留文字
    messages.append({"role": "assistant", "content": text})
    print(f"{turn}回目{'(固定為法語)' if turn == 5 else ''}: {text}")

執行結果

1回目: Bonjour, ravi de vous rencontrer aujourd'hui !
2回目: Hola, ¡qué gusto saludarte! ¿En qué puedo ayudarte hoy?
3回目: Guten Tag, schön, dass Sie heute da sind!
4回目: Hello, nice to see you today!
5回目(固定為法語): Bonjour, ravi de vous revoir !
6回目: Good morning, hope your day is off to a wonderful start!

總結

API 的進化,就是和提示詞快取的戰爭


原文出處:https://qiita.com/moritalous/items/9e7c02b749037238b2bc


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
boluoji
📝37   💬3   ❤️6
874
🥈
我愛JS
📝3   💬1   ❤️4
83
🥉
站長阿川
📝1   💬3   ❤️2
42
#4
mike
1
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登