Python調(diào)用Claude?API全流程指南與踩坑記錄
最近在做一個文檔自動化的副業(yè)項目,選型的時候試了一圈,最后還是選了 Claude——代碼生成質(zhì)量和長文本理解都比較穩(wěn)。
但中文教程 真的少,官方文檔是全英文的,搜到的大部分教程要么是舊版 SDK,要么只有 Hello World 就結(jié)束了。
所以自己踩完坑,寫了這篇。本文覆蓋:
- 環(huán)境配置 & SDK 安裝
- 基礎(chǔ)調(diào)用(同步)
- 流式輸出(stream)
- System Prompt 設(shè)置
- 多輪對話管理
- 錯誤處理 & 自動重試
- 一個可直接用的封裝類
代碼全部驗證可運行,Python 3.10+ 均適用。
一、環(huán)境準(zhǔn)備
# 建議用虛擬環(huán)境,避免依賴沖突 python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install anthropic

最低版本要求:anthropic >= 0.39.0,舊版接口有 breaking change,建議直接裝最新。
二、最簡基礎(chǔ)調(diào)用
先跑通一個最簡單的例子,確認(rèn)環(huán)境沒問題:
import anthropic
client = anthropic.Anthropic(
api_key="your-api-key", # 替換成你的 Key
base_url="https://api.yutaikeji.cn" # 國內(nèi)中轉(zhuǎn)節(jié)點,省去連接問題
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024, # 必填,不傳會報錯
messages=[
{"role": "user", "content": "用一句話解釋什么是閉包"}
]
)
print(message.content[0].text)

坑1:max_tokens 是必傳參數(shù),忘了會直接拋 ValidationError,官方文檔沒有特別標(biāo)注,很容易漏。
三、流式輸出(Stream)
做聊天界面的話,流式輸出是剛需,不然用戶盯著空白頁等 2 秒體驗很差。
import anthropic
client = anthropic.Anthropic(
api_key="your-api-key",
base_url="https://api.yutaikeji.cn"
)
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "寫一首關(guān)于深夜寫代碼的詩"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True) # flush=True 很關(guān)鍵,否則輸出會卡住
流式結(jié)束后,還能拿到完整的 usage 信息:
with client.messages.stream(...) as stream:
full_text = ""
for text in stream.text_stream:
print(text, end="", flush=True)
full_text += text
# 流結(jié)束后獲取完整 response
final_message = stream.get_final_message()
print(f"\n\n--- Token 用量 ---")
print(f"輸入: {final_message.usage.input_tokens}")
print(f"輸出: {final_message.usage.output_tokens}")
坑2:用 stream.text_stream 是最簡單的方式,直接拿文本片段。如果你需要更底層的事件(比如 tool_use),用 stream 迭代原始事件。
四、System Prompt 配置
Claude 的 system 參數(shù)是獨立的,不放在 messages 里,這點和 OpenAI 不一樣。
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system="""你是一個資深 Python 工程師助手。
回答規(guī)則:
1. 優(yōu)先給可運行代碼,再給解釋
2. 代碼中加必要注釋
3. 指出潛在 bug 或性能問題""",
messages=[
{"role": "user", "content": "寫一個帶 LRU 緩存的斐波那契函數(shù)"}
]
)
print(response.content[0].text)
坑3:如果你從 OpenAI 遷移過來,習(xí)慣把 system 放在 messages 第一條——Claude 也支持這種寫法,但官方推薦用獨立的 system 參數(shù),兩種都能用,保持一致即可。
五、多輪對話
多輪對話需要自己維護 messages 列表,每輪都要把歷史帶上:
import anthropic
client = anthropic.Anthropic(
api_key="your-api-key",
base_url="https://api.yutaikeji.cn"
)
def chat():
messages = []
print("Claude 助手(輸入 exit 退出)\n")
while True:
user_input = input("你: ").strip()
if user_input.lower() == "exit":
break
if not user_input:
continue
# 把用戶消息加入歷史
messages.append({"role": "user", "content": user_input})
# 流式輸出回復(fù)
print("Claude: ", end="", flush=True)
reply = ""
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
reply += text
print("\n")
# 把 Claude 的回復(fù)也加入歷史,下輪對話才有上下文
messages.append({"role": "assistant", "content": reply})
if __name__ == "__main__":
chat()
坑4:很多人會忘記把 assistant 的回復(fù)也加入 messages,然后發(fā)現(xiàn) Claude 每輪都失憶了。要兩側(cè)都 append。
關(guān)于上下文長度:Claude 3.5 Sonnet 支持 200K token 的上下文窗口,但長對話還是要做截斷處理,否則 Token 費用會快速膨脹。一個簡單策略是保留最近 N 輪:
MAX_HISTORY = 20 # 保留最近 10 輪對話(20條消息)
if len(messages) > MAX_HISTORY:
messages = messages[-MAX_HISTORY:] # 只保留最近的
六、錯誤處理與自動重試
生產(chǎn)環(huán)境里不能讓程序一遇到 API 錯誤就崩。常見錯誤碼:
| 錯誤碼 | 含義 | 處理策略 |
|---|---|---|
| 429 | Rate Limit,請求過快 | 指數(shù)退避重試 |
| 529 | API 過載 | 等待后重試 |
| 500/503 | 服務(wù)端問題 | 重試最多 3 次 |
| 400 | 請求參數(shù)錯誤 | 不重試,修復(fù)參數(shù) |
import time
import anthropic
from anthropic import RateLimitError, APIStatusError, APITimeoutError
client = anthropic.Anthropic(
api_key="your-api-key",
base_url="https://api.yutaikeji.cn"
)
def call_with_retry(messages: list, max_retries: int = 3) -> str:
for attempt in range(max_retries):
try:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages
)
return response.content[0].text
except RateLimitError:
wait = 2 ** attempt # 1s, 2s, 4s 指數(shù)退避
print(f"觸發(fā)限流,{wait}s 后重試(第 {attempt + 1} 次)...")
time.sleep(wait)
except APITimeoutError:
print(f"請求超時,重試中(第 {attempt + 1} 次)...")
time.sleep(1)
except APIStatusError as e:
if e.status_code in (500, 503, 529):
wait = 2 ** attempt
print(f"服務(wù)端錯誤 {e.status_code},{wait}s 后重試...")
time.sleep(wait)
else:
raise # 400 之類的參數(shù)錯誤,直接拋出不重試
raise RuntimeError(f"重試 {max_retries} 次后仍失敗")
七、一個可直接用的封裝類
把上面的邏輯整合成一個干凈的 ClaudeClient:
import time
import anthropic
from anthropic import RateLimitError, APIStatusError, APITimeoutError
from typing import Generator
class ClaudeClient:
def __init__(
self,
api_key: str,
base_url: str = "https://api.yutaikeji.cn",
model: str = "claude-sonnet-4-6",
system: str = "",
max_history: int = 20
):
self.client = anthropic.Anthropic(api_key=api_key, base_url=base_url)
self.model = model
self.system = system
self.max_history = max_history
self.messages: list = []
def _trim_history(self):
"""保留最近 N 條對話"""
if len(self.messages) > self.max_history:
self.messages = self.messages[-self.max_history:]
def chat(self, user_input: str, stream: bool = False):
"""
發(fā)送消息,返回回復(fù)文本。
stream=True 時返回生成器,逐字輸出。
"""
self.messages.append({"role": "user", "content": user_input})
self._trim_history()
kwargs = dict(
model=self.model,
max_tokens=2048,
messages=self.messages,
)
if self.system:
kwargs["system"] = self.system
if stream:
return self._stream_chat(kwargs)
else:
return self._sync_chat(kwargs)
def _sync_chat(self, kwargs: dict) -> str:
for attempt in range(3):
try:
resp = self.client.messages.create(**kwargs)
reply = resp.content[0].text
self.messages.append({"role": "assistant", "content": reply})
return reply
except (RateLimitError, APITimeoutError):
time.sleep(2 ** attempt)
except APIStatusError as e:
if e.status_code in (500, 503, 529):
time.sleep(2 ** attempt)
else:
raise
raise RuntimeError("請求失敗,已重試 3 次")
def _stream_chat(self, kwargs: dict) -> Generator[str, None, None]:
reply = ""
with self.client.messages.stream(**kwargs) as s:
for text in s.text_stream:
reply += text
yield text
self.messages.append({"role": "assistant", "content": reply})
def reset(self):
"""清空對話歷史"""
self.messages = []
# 使用示例
if __name__ == "__main__":
claude = ClaudeClient(
api_key="your-api-key",
system="你是一個 Python 專家,回答簡潔,優(yōu)先給代碼"
)
# 同步調(diào)用
print(claude.chat("用 Python 寫一個單例模式"))
# 流式調(diào)用
for chunk in claude.chat("給上面的代碼加線程安全", stream=True):
print(chunk, end="", flush=True)
print()
八、常見報錯速查
| 報錯信息 | 原因 | 解決方法 |
|---|---|---|
| Missing required parameter: max_tokens | 漏傳 max_tokens | 加上 max_tokens=1024 |
| Invalid API Key | Key 填錯或已過期 | 檢查 Key,注意別帶多余空格 |
| Connection timeout | 網(wǎng)絡(luò)問題 | 檢查 base_url,國內(nèi)建議走中轉(zhuǎn) |
| Rate limit exceeded | 請求太快 | 加指數(shù)退避重試 |
| 'ContentBlock' object has no attribute 'text' | 舊版寫法 | 改成 response.content[0].text |
小結(jié)
| 場景 | 寫法 |
|---|---|
| 單次問答 | client.messages.create() |
| 流式輸出 | client.messages.stream() |
| 多輪對話 | 手動維護 messages 列表,兩端都要 append |
| 錯誤處理 | try/except + 指數(shù)退避,區(qū)分可重試/不可重試錯誤 |
| 生產(chǎn)封裝 | 用上面的 ClaudeClient 類,開箱即用 |
如果還有問題評論區(qū)說,我基本每天都在,看到會及時回復(fù)。
工具推薦
本文所有代碼在以下環(huán)境測試通過:
- Python 3.10 / anthropic 0.40+
- API:玉兔AI(可以直連 Claude API)
到此這篇關(guān)于Python調(diào)用Claude API全流程指南與踩坑記錄的文章就介紹到這了,更多相關(guān)Python調(diào)用Claude API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
網(wǎng)易有道2017內(nèi)推編程題 洗牌(python)
這篇文章主要為大家詳細(xì)介紹了網(wǎng)易有道2017內(nèi)推編程題:洗牌,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06
python3.6.8 + pycharm + PyQt5 環(huán)境搭建的圖文教程
這篇文章主要介紹了python3.6.8 + pycharm + PyQt5 環(huán)境搭建,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
python+jinja2實現(xiàn)接口數(shù)據(jù)批量生成工具
這篇文章主要介紹了python+jinja2實現(xiàn)接口數(shù)據(jù)批量生成工具的操作方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08
Python批量寫入ES索引數(shù)據(jù)的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何使用python腳本批量寫ES數(shù)據(jù)(需要使用pip提前下載安裝es依賴庫),感興趣的小伙伴可以學(xué)習(xí)一下2024-02-02
python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細(xì)流程
這篇文章主要給大家介紹了關(guān)于python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細(xì)流程,requirements.txt 文件是一個文本文件,用于列出你的Python項目所依賴的軟件包及其版本,需要的朋友可以參考下2023-11-11
使用Python來開發(fā)Markdown腳本擴展的實例分享
這篇文章主要介紹了使用Python來開發(fā)Markdown腳本擴展的實例分享,文中的示例是用來簡單地轉(zhuǎn)換文檔結(jié)構(gòu),主要為了體現(xiàn)一個思路,需要的朋友可以參考下2016-03-03

