用實(shí)戰(zhàn):從demo包到流暢對(duì)話的完整指南)
簡(jiǎn)介面向 DeepSeek API 調(diào)用場(chǎng)景的 Python 入門(mén)示例包專(zhuān)門(mén)服務(wù)于正在學(xué)習(xí)“DeepSeek API 如何調(diào)用”的開(kāi)發(fā)者定位清晰、使用門(mén)檻低無(wú)論用于學(xué)習(xí)研究、快速嘗試接口效果還是作為后續(xù)二次開(kāi)發(fā)的起始骨架都很合適。包內(nèi)包含兩個(gè) Python 示例腳本分別演示單次請(qǐng)求與循環(huán)調(diào)用兩種典型形態(tài)讀者可先運(yùn)行腳本觀察請(qǐng)求返回結(jié)果與執(zhí)行日志再遷移到自己的項(xiàng)目中同時(shí)開(kāi)源配置文件與許可協(xié)議一并收錄便于合規(guī)使用并復(fù)用項(xiàng)目結(jié)構(gòu)。壓縮包共 4 個(gè)文件整體僅 14KB體量輕量保留開(kāi)源項(xiàng)目常見(jiàn)目錄結(jié)構(gòu)下載后可快速對(duì)照源碼進(jìn)行動(dòng)手調(diào)試也能作為本地原型驗(yàn)證的極簡(jiǎn)基礎(chǔ)。示例外圍的通用調(diào)用要點(diǎn)進(jìn)一步梳理了完整鏈路先閱讀官方文檔確認(rèn)接口規(guī)范再申請(qǐng)并安全保存密鑰隨后按要求構(gòu)造請(qǐng)求方法與參數(shù)、解析響應(yīng)數(shù)據(jù)并針對(duì)網(wǎng)絡(luò)異常、鑒權(quán)失敗、限流等常見(jiàn)錯(cuò)誤設(shè)計(jì)處理邏輯將這些要點(diǎn)與包內(nèi)腳本對(duì)照學(xué)習(xí)可幫助讀者建立從零到一的清晰調(diào)用思路為后續(xù)在真實(shí)項(xiàng)目中使用 DeepSeek API 打下基礎(chǔ)。目前已有 283 人學(xué)習(xí)下載適合作為 DeepSeek API 入門(mén)階段小而精的參考資料。1. DeepSeek API 如何調(diào)用先搞清楚這個(gè) demo 包里有什么很多剛接觸 DeepSeek API 的人第一件事就是去下載一個(gè)叫deepseek-demo-master.zip的壓縮包。滿懷期待地解壓然后對(duì)著里面的幾十個(gè)文件發(fā)懵哪個(gè)是入口怎么跑起來(lái)API Key 填在哪里如果你也卡在這一步這篇筆記就是給你寫(xiě)的。我要做的是把這個(gè)壓縮包的用途、調(diào)用鏈路和踩坑點(diǎn)拆開(kāi)讓你從「下了一個(gè)包」到「真正調(diào)通一次對(duì)話」全程不超過(guò)半小時(shí)。這里適合三種人想快速驗(yàn)證 DeepSeek 能力的開(kāi)發(fā)者、要把 API 集成進(jìn)自己項(xiàng)目的人以及看了很多文檔但始終沒(méi)跑通的半新手。下面我們直接從鑒權(quán)開(kāi)始因?yàn)樗姓{(diào)用都繞不開(kāi)它。2. 獲取 API Key 與鑒權(quán)方式調(diào)用前必須邁過(guò)的一道門(mén)檻調(diào)用任何大模型 API第一件事不是寫(xiě)代碼而是拿到一把「鑰匙」。DeepSeek 的調(diào)用方式和 OpenAI 兼容這意味著你只需要一個(gè) Key就能用 HTTP 請(qǐng)求完成對(duì)話。但很多人在這個(gè) demo 里卡住是因?yàn)椴磺宄?Key 從哪來(lái)、怎么填、以及填錯(cuò)了會(huì)看到什么報(bào)錯(cuò)。2.1 從開(kāi)放平臺(tái)拿 Key注冊(cè)、創(chuàng)建、充值三步我一般會(huì)先打開(kāi) DeepSeek 開(kāi)放平臺(tái)頁(yè)面用手機(jī)號(hào)注冊(cè)一個(gè)賬號(hào)。這一步?jīng)]什么門(mén)檻但要注意平臺(tái)可能會(huì)要求實(shí)名認(rèn)證否則某些服務(wù)不可用。注冊(cè)完成后進(jìn)入「API Keys」管理頁(yè)面點(diǎn)擊創(chuàng)建新 Key復(fù)制保存。這個(gè) Key 只在創(chuàng)建時(shí)完整顯示一次關(guān)掉頁(yè)面后就只能刪了重建所以我會(huì)立刻粘貼到一個(gè)臨時(shí)文件里。Key 拿到之后還有個(gè)現(xiàn)實(shí)問(wèn)題新賬號(hào)通常有免費(fèi)額度但正式調(diào)用需要賬戶余額。在平臺(tái)左側(cè)找到「充值」入口充個(gè)最低額度就能用。注意DeepSeek 的計(jì)費(fèi)是按 token 算的不是按請(qǐng)求次數(shù)所以哪怕調(diào) 1000 次短對(duì)話可能也就幾分錢(qián)。這里我踩過(guò)一次坑以為 Key 創(chuàng)建成功就能無(wú)限調(diào)用結(jié)果一直返回 402查了才知道是余額不足。提示別把 Key 硬編碼在 demo 的源碼里尤其當(dāng)你打算把項(xiàng)目推到公開(kāi)倉(cāng)庫(kù)時(shí)。后面我們會(huì)用環(huán)境變量來(lái)存。2.2 鑒權(quán)頭與請(qǐng)求體看懂官方 SDK 之外的原始 HTTP 調(diào)用這個(gè) demo 包內(nèi)部可能封裝了 SDK但你要明白底層發(fā)生了什么否則出問(wèn)題只能瞎猜。DeepSeek 的 REST API 端點(diǎn)是固定的請(qǐng)求頭里帶Authorization: Bearer 你的Key請(qǐng)求體是標(biāo)準(zhǔn)的 Chat Completion 格式。下面是一個(gè)最原始的curl調(diào)用我建議你在跑 demo 前先執(zhí)行一遍能幫助快速確認(rèn) Key 是否有效。curl https://api.deepseek.com/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $DEEPSEEK_API_KEY \ -d { model: deepseek-chat, messages: [ {role: system, content: 你是一個(gè)簡(jiǎn)潔的助手}, {role: user, content: 用一句話介紹你自己} ], stream: false }這段命令里$DEEPSEEK_API_KEY是環(huán)境變量如果沒(méi)設(shè)置就直接替換成你的 Key 字符串。model字段指定模型deepseek-chat是通用對(duì)話模型某些新模型可能有單獨(dú)的模型名以文檔為準(zhǔn)。重點(diǎn)看messages數(shù)組的結(jié)構(gòu)每條消息必須有role和contentrole只能是system、user、assistant三種。stream設(shè)為false表示一次性返回完整結(jié)果調(diào)試時(shí)這樣最直觀。執(zhí)行后你會(huì)得到一大段 JSON其中choices[0].message.content就是模型回答。如果返回 401說(shuō)明 Key 錯(cuò)了或過(guò)期返回 402 是欠費(fèi)返回 400 大多是請(qǐng)求格式問(wèn)題比如messages缺字段。走通這一步再回頭看 demo 里的代碼你會(huì)覺(jué)得所有封裝都不過(guò)是在拼這個(gè)請(qǐng)求。3. 把 deepseek-demo-master.zip 跑起來(lái)從解壓到首次對(duì)話下載下來(lái)的壓縮包通常帶著-master后綴說(shuō)明是某個(gè)倉(cāng)庫(kù)的主分支打包。解壓后你可能會(huì)看到 Python 腳本、前端頁(yè)面、配置文件混在一起。別慌先摸清目錄結(jié)構(gòu)再找到入口然后跑通一次對(duì)話。3.1 解壓目錄結(jié)構(gòu)先分清哪個(gè)是服務(wù)端、哪個(gè)是客戶端我習(xí)慣先執(zhí)行tree -L 2看一眼整體布局或者用文件管理器逐層展開(kāi)。常見(jiàn)的 demo 包會(huì)包含這幾類(lèi)東西main.py或app.py作為后端入口requirements.txt是依賴清單.env.example是環(huán)境變量模板templates/或static/是前端資源還有README.md。這里最容易翻車(chē)的是有人直接雙擊index.html以為打開(kāi)頁(yè)面就能調(diào)用 API結(jié)果跨域報(bào)錯(cuò)——因?yàn)闉g覽器里的 JS 調(diào)用 API 會(huì)遇到 CORS 限制必須通過(guò)后端轉(zhuǎn)發(fā)。我的建議是先把 README 完整讀一遍不要跳著看。很多 demo 的啟動(dòng)命令、Python 版本要求都寫(xiě)在里面。如果 README 寫(xiě)得太簡(jiǎn)略就看requirements.txt里的依賴推斷技術(shù)棧。比如里面有flask那大概率是個(gè) Web 服務(wù)如果只有openai說(shuō)明是個(gè)純腳本。下面是我處理這種 demo 的通用流程cd deepseek-demo-master python3 -m venv venv source venv/bin/activate pip install -r requirements.txt cp .env.example .env這段命令創(chuàng)建虛擬環(huán)境并安裝依賴。注意python3 -m venv venv需要 Python 3.8 以上如果報(bào)錯(cuò)說(shuō)明系統(tǒng)缺venv模塊可以用pip install virtualenv替代。cp .env.example .env這一步很關(guān)鍵因?yàn)楹芏嘈率痔^(guò)它直接運(yùn)行程序然后報(bào)錯(cuò)KeyError: DEEPSEEK_API_KEY。3.2 配置環(huán)境變量把 Key 寫(xiě)進(jìn) .env而不是代碼里env.example文件里通常有一行DEEPSEEK_API_KEY你打開(kāi).env把 Key 填在等號(hào)后面。注意不要加引號(hào)也不要留空格。如果你不習(xí)慣用.env也可以直接在終端里導(dǎo)出環(huán)境變量但這只對(duì)當(dāng)前終端會(huì)話有效。# 在 .env 中配置推薦 DEEPSEEK_API_KEYsk-你的完整Key # 或者臨時(shí)導(dǎo)出 export DEEPSEEK_API_KEYsk-你的完整Key有些 demo 會(huì)用python-dotenv自動(dòng)加載.env文件有些不會(huì)。如果你運(yùn)行后發(fā)現(xiàn)KeyError就手動(dòng)在代碼入口加上一行from dotenv import load_dotenv; load_dotenv()。這里也提醒一句.env文件不要提交到 Git否則等于公開(kāi) Key。我會(huì)在.gitignore里加上.env并且刪除從壓縮包帶出來(lái)的任何歷史.env備份。3.3 最小調(diào)用示例用 Python 完成第一次對(duì)話如果這個(gè) demo 本身結(jié)構(gòu)太亂我建議先跳過(guò)它自己寫(xiě)一個(gè) 20 行的腳本驗(yàn)證 API。這樣能最快排除「項(xiàng)目問(wèn)題」和「API 問(wèn)題」。下面是我每次調(diào)試新環(huán)境都會(huì)用的最小示例# test_deepseek.py import os from openai import OpenAI client OpenAI( api_keyos.getenv(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com ) response client.chat.completions.create( modeldeepseek-chat, messages[ {role: system, content: 你是一個(gè)樂(lè)于助人的助手}, {role: user, content: 你好請(qǐng)簡(jiǎn)單介紹 DeepSeek API 的調(diào)用方式} ], streamFalse, temperature0.7 ) print(response.choices[0].message.content)用openaiSDK 是因?yàn)?DeepSeek 兼容這一協(xié)議你不需要引入額外的包。關(guān)鍵參數(shù)有三個(gè)base_url必須指向 DeepSeek 的地址否則 SDK 默認(rèn)會(huì)去別的地方model決定模型版本temperature控制隨機(jī)性0.7 是通用值后面會(huì)細(xì)說(shuō)。運(yùn)行前確認(rèn)環(huán)境變量已加載python test_deepseek.py如果看到輸出文本說(shuō)明 API 調(diào)用成功。如果報(bào)錯(cuò)百分之九十是環(huán)境變量沒(méi)讀進(jìn)來(lái)或在client初始化時(shí)少了base_url。這時(shí)候回到第 2 章用 curl 驗(yàn)證 Key 是否有效能快速縮小問(wèn)題范圍。4. 參數(shù)調(diào)優(yōu)與上下文管理讓回答質(zhì)量從「能用」到「好用」跑通一次對(duì)話只是開(kāi)始。實(shí)際使用中你會(huì)發(fā)現(xiàn)同樣的輸入?yún)?shù)設(shè)置不同輸出的質(zhì)量和風(fēng)格天差地別。這一章講的是 demo 里通常會(huì)忽略但你必須學(xué)會(huì)的三個(gè)東西temperature、top_p、max_tokens以及多輪對(duì)話時(shí)消息數(shù)組該怎么維護(hù)。4.1 temperature、top_p 與 max_tokens三個(gè)參數(shù)決定回答風(fēng)格temperature控制隨機(jī)性取值范圍一般是 0 到 2。調(diào)得越低回答越確定、越保守適合寫(xiě)代碼、提取結(jié)構(gòu)化信息調(diào)得越高回答越發(fā)散、越有創(chuàng)造性適合頭腦風(fēng)暴。我自己的習(xí)慣是日常問(wèn)答用 0.7代碼生成用 0.2文案創(chuàng)作用 1.0 以上。top_p是核采樣作用類(lèi)似但機(jī)制不同。它按概率累計(jì)截?cái)啾热鐃op_p0.9意味著只從累計(jì)概率達(dá)到 90% 的 token 里選擇。官方建議是不要同時(shí)大幅調(diào)整這兩個(gè)參數(shù)保持一個(gè)為默認(rèn)值、只調(diào)另一個(gè)否則會(huì)互相干擾導(dǎo)致輸出難以預(yù)測(cè)。max_tokens限制單次回答的最大 token 數(shù)不是字符數(shù)。一個(gè)中文字大約占 1 到 2 個(gè) token英文一個(gè)詞約 1 個(gè) token。如果回答經(jīng)常被截?cái)嗑驼{(diào)大這個(gè)值但注意它也會(huì)影響費(fèi)用。下面是一段對(duì)比代碼讓你直觀感受參數(shù)變化params [ {temperature: 0.2, top_p: 0.5}, {temperature: 1.2, top_p: 0.9}, ] for p in params: resp client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: 寫(xiě)一句鼓勵(lì)加班的話}], temperaturep[temperature], top_pp[top_p], max_tokens100 ) print(p, resp.choices[0].message.content)你會(huì)發(fā)現(xiàn)低溫時(shí)回答更像是「合理的勸說(shuō)」高溫時(shí)可能變成反諷或冷幽默。這正好說(shuō)明調(diào)試時(shí)不要一上來(lái)就改代碼邏輯先試參數(shù)。很多「回答變笨了」的問(wèn)題其實(shí)是temperature被設(shè)成了 0導(dǎo)致模型每次只選概率最高的答案缺乏靈活性。4.2 多輪對(duì)話與上下文窗口system 消息和 history 怎么傳大模型本身是無(wú)狀態(tài)的每次請(qǐng)求都是獨(dú)立的。所謂「多輪對(duì)話」就是你手動(dòng)把所有歷史消息都放在messages里一起傳過(guò)去。demo 里常見(jiàn)的錯(cuò)誤是用戶在第二輪提問(wèn)時(shí)只傳了當(dāng)前問(wèn)題導(dǎo)致模型完全忘了前面說(shuō)過(guò)什么。正確做法是維護(hù)一個(gè)列表把系統(tǒng)提示、用戶消息、助手消息按順序追加進(jìn)去每次請(qǐng)求都把整個(gè)列表傳給 API。下面是偽代碼結(jié)構(gòu)messages [{role: system, content: 你是一個(gè)智能客服}] messages.append({role: user, content: 我想退貨}) # 第一次響應(yīng)... messages.append({role: assistant, content: 請(qǐng)?zhí)峁┯唵翁?hào)}) messages.append({role: user, content: 訂單號(hào)是12345}) # 第二次請(qǐng)求時(shí)messages 已包含全部?jī)?nèi)容 response client.chat.completions.create( modeldeepseek-chat, messagesmessages )這里有兩個(gè)實(shí)際問(wèn)題。第一上下文窗口有上限D(zhuǎn)eepSeek 的上下文長(zhǎng)度取決于具體模型通常足夠長(zhǎng)但如果對(duì)話超過(guò)限制最早的消息會(huì)被截?cái)嗷蛑苯訄?bào)錯(cuò)。第二system消息會(huì)影響全局風(fēng)格我一般把它放在第一位并且只在開(kāi)頭設(shè)置一次不要每輪都重復(fù)往里塞否則模型可能被搞糊涂。另外要注意assistant消息里的content必須是模型上一次真正返回的內(nèi)容不要自己編。如果你重復(fù)傳相同的assistant消息模型可能陷入重復(fù)循環(huán)。如果想讓模型忘記某些話題直接把前面的消息從列表里刪掉再請(qǐng)求即可這相當(dāng)于「手動(dòng)清空記憶」。5. DeepSeek API 調(diào)用避坑5 個(gè)最容易翻車(chē)的點(diǎn)這一章是我在實(shí)際調(diào)試中多次撞墻后的記錄每條都按現(xiàn)象、原因、解決三步寫(xiě)。希望你看完能少走彎路。5.1 現(xiàn)象返回 401 UnauthorizedKey 明明沒(méi)錯(cuò)原因有兩個(gè)可能一是 Key 復(fù)制時(shí)多了空格或換行二是.env文件里的值包含了引號(hào)比如DEEPSEEK_API_KEYsk-xxx系統(tǒng)會(huì)把引號(hào)也當(dāng)成 Key 的一部分。解決方法是打印 Key 的前幾個(gè)字符做檢查python -c import os; print(repr(os.getenv(DEEPSEEK_API_KEY)))如果輸出是sk-abc123正常如果是sk-abc123說(shuō)明引號(hào)被吃進(jìn)去了。去.env里去掉引號(hào)。還有一個(gè)隱蔽情況某些環(huán)境變量加載庫(kù)會(huì)覆蓋已有變量如果系統(tǒng)里本來(lái)就有一個(gè)舊的DEEPSEEK_API_KEY也會(huì)導(dǎo)致 401。5.2 現(xiàn)象請(qǐng)求成功但響應(yīng)極慢甚至超時(shí)原因大多是stream設(shè)為false而模型要在生成完整回答后才一次性返回。長(zhǎng)回答可能耗時(shí)幾十秒如果你用了默認(rèn)的短超時(shí)時(shí)間就會(huì)報(bào)ReadTimeout。解決方法是開(kāi)啟流式輸出或者調(diào)大 HTTP 超時(shí)時(shí)間。我這個(gè) demo 里建議直接用 streamresponse client.chat.completions.create( modeldeepseek-chat, messagesmessages, streamTrue # 邊生成邊返回 ) for chunk in response: delta chunk.choices[0].delta if delta and delta.content: print(delta.content, end, flushTrue)這種流式方式不僅響應(yīng)快還能給用戶一種「正在思考」的交互感。注意流式模式下response變成一個(gè)生成器不能像之前那樣直接取choices[0].message.content必須遍歷。5.3 現(xiàn)象中文回答內(nèi)容被截?cái)嗟孟駲C(jī)翻原因通常是max_tokens設(shè)得太小比如 50。因?yàn)槟P鸵谟邢?token 內(nèi)完成回答被迫用簡(jiǎn)潔的短句很多上下文丟失。解決方法是先估算回答長(zhǎng)度再設(shè)置max_tokens。一個(gè)粗略的經(jīng)驗(yàn)中文字符數(shù)除以 1.5 約等于 token 數(shù)。如果你期望 300 字回答max_tokens至少設(shè) 500。同時(shí)檢查temperature是否過(guò)低因?yàn)榈蜏貢?huì)讓模型傾向于保守的短回答。5.4 現(xiàn)象把 Key 提交到了 Git被人盜刷這是我最心疼的一次翻車(chē)。原因是 demo 自帶的.gitignore沒(méi)包含.env我順手git add .就把 Key 推上去了。幾個(gè)小時(shí)后余額沒(méi)了。解決方法是立即到平臺(tái)刪掉這個(gè) Key創(chuàng)建一個(gè)新 Key然后檢查倉(cāng)庫(kù)歷史里是否有泄露。最好用git filter-repo清理歷史或者干脆把整個(gè)倉(cāng)庫(kù)設(shè)為私有。以后每次提交前我都用git status確認(rèn)沒(méi)有.env。5.5 現(xiàn)象同一段 prompt兩次調(diào)用結(jié)果完全一樣懷疑是緩存原因是你把temperature設(shè)成了 0模型退化為貪心解碼每次都生成概率最高的序列。某些情況下這很合理比如提取 JSON 也要固定輸出。但如果想要多樣化的回答把temperature調(diào)到 0.7 到 1.0并且不要同時(shí)固定top_p和temperature。另外官方可能對(duì)完全相同的請(qǐng)求做緩存如果你需要測(cè)試不同效果一定要在 prompt 里加一點(diǎn)隨機(jī)變化比如時(shí)間戳或序列號(hào)。6. 進(jìn)階把 demo 改造成你自己的命令行問(wèn)答工具到這里你已經(jīng)能調(diào)通 API、理解參數(shù)、避開(kāi)大多數(shù)坑。最后這一步我們把這套能力固化成一個(gè)可以日常使用的命令行工具而不是每次寫(xiě)測(cè)試腳本。這個(gè)工具會(huì)讀取.env里的 Key在終端里進(jìn)行多輪對(duì)話并支持/reset指令清空上下文。# cli_chat.py import os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client OpenAI(api_keyos.getenv(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com) messages [{role: system, content: 你是一個(gè)簡(jiǎn)潔、準(zhǔn)確的中文助手}] print(DeepSeek CLI 已啟動(dòng)輸入 /reset 清空記憶輸入 /quit 退出。) while True: user_input input(\n你: ) if user_input.strip() /quit: break if user_input.strip() /reset: messages [{role: system, content: 你是一個(gè)簡(jiǎn)潔、準(zhǔn)確的中文助手}] print([上下文已清空]) continue messages.append({role: user, content: user_input}) stream client.chat.completions.create( modeldeepseek-chat, messagesmessages, streamTrue, temperature0.6 ) print(\nDeepSeek: , end, flushTrue) reply_parts [] for chunk in stream: if chunk.choices[0].delta and chunk.choices[0].delta.content: content chunk.choices[0].delta.content print(content, end, flushTrue) reply_parts.append(content) messages.append({role: assistant, content: .join(reply_parts)})這段代碼最關(guān)鍵的兩個(gè)設(shè)計(jì)一是把a(bǔ)ssistant返回的內(nèi)容拼接到messages里保證下一輪對(duì)話有完整上下文二是streamTrue讓回答逐字出現(xiàn)體感流暢很多。/reset只是重置了內(nèi)存里的消息列表不會(huì)影響 Key 或配置這個(gè)邏輯很簡(jiǎn)單但很實(shí)用。我之前遇到一個(gè)奇怪問(wèn)題CLI 有時(shí)會(huì)重復(fù)回答最后一次內(nèi)容。后來(lái)發(fā)現(xiàn)是我在拼reply_parts時(shí)把chunk里的delta.content重復(fù)添加了因?yàn)榱魇椒祷刈詈笠粋€(gè) chunk 可能包含空字符串或結(jié)束標(biāo)記。解決辦法是加了if chunk.choices[0].delta and chunk.choices[0].delta.content:的判斷。同樣的思路如果你在集成這個(gè) demo 到 Web 服務(wù)時(shí)遇到回答中斷優(yōu)先檢查流式解析邏輯而不是懷疑 API。另外一個(gè)實(shí)用技巧把temperature調(diào)成 0.6并且給system消息加上「請(qǐng)分點(diǎn)回答」或「請(qǐng)給出代碼示例」這樣的約束能明顯提升代碼相關(guān)問(wèn)題的回答質(zhì)量。這也是我長(zhǎng)期使用的固定配置。希望這篇筆記能幫你節(jié)省幾個(gè)小時(shí)讓 DeepSeek API 的調(diào)用從「玄學(xué)」變成「手腳架上的熟練活」。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取