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 稍微複雜了一點
執行結果
こんにちは!今天有什麼我可以幫忙的嗎?
加上系統提示詞之後就是這樣。
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"))
執行結果
こんにちは!ええ天気やなあ、今日もなんでも聞いてや!
何かお手伝いできることあったら、気軽に言うてな。
從這裡開始就是未知領域了!
首先,可以在中途追加系統提示詞。
要追加的系統提示詞,必須放在使用者提示詞之後。
這樣就能在維持提示詞快取的同時修改系統提示詞!
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。
會作為中途插入的系統提示詞的一部分來追加。
(節錄)
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度。
模型的思考層級也可以在途中變更。這也是透過插入系統提示詞來做到的。
截至發文時這是 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
最後是一個相當小眾的機制,也就是插入只會暫時生效的系統提示詞的方法。
透過指定 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