
简介面向 DeepSeek API 调用场景的 Python 入门示例包专门服务于正在学习“DeepSeek API 如何调用”的开发者定位清晰、使用门槛低无论用于学习研究、快速尝试接口效果还是作为后续二次开发的起始骨架都很合适。包内包含两个 Python 示例脚本分别演示单次请求与循环调用两种典型形态读者可先运行脚本观察请求返回结果与执行日志再迁移到自己的项目中同时开源配置文件与许可协议一并收录便于合规使用并复用项目结构。压缩包共 4 个文件整体仅 14KB体量轻量保留开源项目常见目录结构下载后可快速对照源码进行动手调试也能作为本地原型验证的极简基础。示例外围的通用调用要点进一步梳理了完整链路先阅读官方文档确认接口规范再申请并安全保存密钥随后按要求构造请求方法与参数、解析响应数据并针对网络异常、鉴权失败、限流等常见错误设计处理逻辑将这些要点与包内脚本对照学习可帮助读者建立从零到一的清晰调用思路为后续在真实项目中使用 DeepSeek API 打下基础。目前已有 283 人学习下载适合作为 DeepSeek API 入门阶段小而精的参考资料。1. DeepSeek API 如何调用先搞清楚这个 demo 包里有什么很多刚接触 DeepSeek API 的人第一件事就是去下载一个叫deepseek-demo-master.zip的压缩包。满怀期待地解压然后对着里面的几十个文件发懵哪个是入口怎么跑起来API Key 填在哪里如果你也卡在这一步这篇笔记就是给你写的。我要做的是把这个压缩包的用途、调用链路和踩坑点拆开让你从「下了一个包」到「真正调通一次对话」全程不超过半小时。这里适合三种人想快速验证 DeepSeek 能力的开发者、要把 API 集成进自己项目的人以及看了很多文档但始终没跑通的半新手。下面我们直接从鉴权开始因为所有调用都绕不开它。2. 获取 API Key 与鉴权方式调用前必须迈过的一道门槛调用任何大模型 API第一件事不是写代码而是拿到一把「钥匙」。DeepSeek 的调用方式和 OpenAI 兼容这意味着你只需要一个 Key就能用 HTTP 请求完成对话。但很多人在这个 demo 里卡住是因为不清楚 Key 从哪来、怎么填、以及填错了会看到什么报错。2.1 从开放平台拿 Key注册、创建、充值三步我一般会先打开 DeepSeek 开放平台页面用手机号注册一个账号。这一步没什么门槛但要注意平台可能会要求实名认证否则某些服务不可用。注册完成后进入「API Keys」管理页面点击创建新 Key复制保存。这个 Key 只在创建时完整显示一次关掉页面后就只能删了重建所以我会立刻粘贴到一个临时文件里。Key 拿到之后还有个现实问题新账号通常有免费额度但正式调用需要账户余额。在平台左侧找到「充值」入口充个最低额度就能用。注意DeepSeek 的计费是按 token 算的不是按请求次数所以哪怕调 1000 次短对话可能也就几分钱。这里我踩过一次坑以为 Key 创建成功就能无限调用结果一直返回 402查了才知道是余额不足。提示别把 Key 硬编码在 demo 的源码里尤其当你打算把项目推到公开仓库时。后面我们会用环境变量来存。2.2 鉴权头与请求体看懂官方 SDK 之外的原始 HTTP 调用这个 demo 包内部可能封装了 SDK但你要明白底层发生了什么否则出问题只能瞎猜。DeepSeek 的 REST API 端点是固定的请求头里带Authorization: Bearer 你的Key请求体是标准的 Chat Completion 格式。下面是一个最原始的curl调用我建议你在跑 demo 前先执行一遍能帮助快速确认 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: 你是一个简洁的助手}, {role: user, content: 用一句话介绍你自己} ], stream: false }这段命令里$DEEPSEEK_API_KEY是环境变量如果没设置就直接替换成你的 Key 字符串。model字段指定模型deepseek-chat是通用对话模型某些新模型可能有单独的模型名以文档为准。重点看messages数组的结构每条消息必须有role和contentrole只能是system、user、assistant三种。stream设为false表示一次性返回完整结果调试时这样最直观。执行后你会得到一大段 JSON其中choices[0].message.content就是模型回答。如果返回 401说明 Key 错了或过期返回 402 是欠费返回 400 大多是请求格式问题比如messages缺字段。走通这一步再回头看 demo 里的代码你会觉得所有封装都不过是在拼这个请求。3. 把 deepseek-demo-master.zip 跑起来从解压到首次对话下载下来的压缩包通常带着-master后缀说明是某个仓库的主分支打包。解压后你可能会看到 Python 脚本、前端页面、配置文件混在一起。别慌先摸清目录结构再找到入口然后跑通一次对话。3.1 解压目录结构先分清哪个是服务端、哪个是客户端我习惯先执行tree -L 2看一眼整体布局或者用文件管理器逐层展开。常见的 demo 包会包含这几类东西main.py或app.py作为后端入口requirements.txt是依赖清单.env.example是环境变量模板templates/或static/是前端资源还有README.md。这里最容易翻车的是有人直接双击index.html以为打开页面就能调用 API结果跨域报错——因为浏览器里的 JS 调用 API 会遇到 CORS 限制必须通过后端转发。我的建议是先把 README 完整读一遍不要跳着看。很多 demo 的启动命令、Python 版本要求都写在里面。如果 README 写得太简略就看requirements.txt里的依赖推断技术栈。比如里面有flask那大概率是个 Web 服务如果只有openai说明是个纯脚本。下面是我处理这种 demo 的通用流程cd deepseek-demo-master python3 -m venv venv source venv/bin/activate pip install -r requirements.txt cp .env.example .env这段命令创建虚拟环境并安装依赖。注意python3 -m venv venv需要 Python 3.8 以上如果报错说明系统缺venv模块可以用pip install virtualenv替代。cp .env.example .env这一步很关键因为很多新手跳过它直接运行程序然后报错KeyError: DEEPSEEK_API_KEY。3.2 配置环境变量把 Key 写进 .env而不是代码里env.example文件里通常有一行DEEPSEEK_API_KEY你打开.env把 Key 填在等号后面。注意不要加引号也不要留空格。如果你不习惯用.env也可以直接在终端里导出环境变量但这只对当前终端会话有效。# 在 .env 中配置推荐 DEEPSEEK_API_KEYsk-你的完整Key # 或者临时导出 export DEEPSEEK_API_KEYsk-你的完整Key有些 demo 会用python-dotenv自动加载.env文件有些不会。如果你运行后发现KeyError就手动在代码入口加上一行from dotenv import load_dotenv; load_dotenv()。这里也提醒一句.env文件不要提交到 Git否则等于公开 Key。我会在.gitignore里加上.env并且删除从压缩包带出来的任何历史.env备份。3.3 最小调用示例用 Python 完成第一次对话如果这个 demo 本身结构太乱我建议先跳过它自己写一个 20 行的脚本验证 API。这样能最快排除「项目问题」和「API 问题」。下面是我每次调试新环境都会用的最小示例# 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: 你是一个乐于助人的助手}, {role: user, content: 你好请简单介绍 DeepSeek API 的调用方式} ], streamFalse, temperature0.7 ) print(response.choices[0].message.content)用openaiSDK 是因为 DeepSeek 兼容这一协议你不需要引入额外的包。关键参数有三个base_url必须指向 DeepSeek 的地址否则 SDK 默认会去别的地方model决定模型版本temperature控制随机性0.7 是通用值后面会细说。运行前确认环境变量已加载python test_deepseek.py如果看到输出文本说明 API 调用成功。如果报错百分之九十是环境变量没读进来或在client初始化时少了base_url。这时候回到第 2 章用 curl 验证 Key 是否有效能快速缩小问题范围。4. 参数调优与上下文管理让回答质量从「能用」到「好用」跑通一次对话只是开始。实际使用中你会发现同样的输入参数设置不同输出的质量和风格天差地别。这一章讲的是 demo 里通常会忽略但你必须学会的三个东西temperature、top_p、max_tokens以及多轮对话时消息数组该怎么维护。4.1 temperature、top_p 与 max_tokens三个参数决定回答风格temperature控制随机性取值范围一般是 0 到 2。调得越低回答越确定、越保守适合写代码、提取结构化信息调得越高回答越发散、越有创造性适合头脑风暴。我自己的习惯是日常问答用 0.7代码生成用 0.2文案创作用 1.0 以上。top_p是核采样作用类似但机制不同。它按概率累计截断比如top_p0.9意味着只从累计概率达到 90% 的 token 里选择。官方建议是不要同时大幅调整这两个参数保持一个为默认值、只调另一个否则会互相干扰导致输出难以预测。max_tokens限制单次回答的最大 token 数不是字符数。一个中文字大约占 1 到 2 个 token英文一个词约 1 个 token。如果回答经常被截断就调大这个值但注意它也会影响费用。下面是一段对比代码让你直观感受参数变化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: 写一句鼓励加班的话}], temperaturep[temperature], top_pp[top_p], max_tokens100 ) print(p, resp.choices[0].message.content)你会发现低温时回答更像是「合理的劝说」高温时可能变成反讽或冷幽默。这正好说明调试时不要一上来就改代码逻辑先试参数。很多「回答变笨了」的问题其实是temperature被设成了 0导致模型每次只选概率最高的答案缺乏灵活性。4.2 多轮对话与上下文窗口system 消息和 history 怎么传大模型本身是无状态的每次请求都是独立的。所谓「多轮对话」就是你手动把所有历史消息都放在messages里一起传过去。demo 里常见的错误是用户在第二轮提问时只传了当前问题导致模型完全忘了前面说过什么。正确做法是维护一个列表把系统提示、用户消息、助手消息按顺序追加进去每次请求都把整个列表传给 API。下面是伪代码结构messages [{role: system, content: 你是一个智能客服}] messages.append({role: user, content: 我想退货}) # 第一次响应... messages.append({role: assistant, content: 请提供订单号}) messages.append({role: user, content: 订单号是12345}) # 第二次请求时messages 已包含全部内容 response client.chat.completions.create( modeldeepseek-chat, messagesmessages )这里有两个实际问题。第一上下文窗口有上限DeepSeek 的上下文长度取决于具体模型通常足够长但如果对话超过限制最早的消息会被截断或直接报错。第二system消息会影响全局风格我一般把它放在第一位并且只在开头设置一次不要每轮都重复往里塞否则模型可能被搞糊涂。另外要注意assistant消息里的content必须是模型上一次真正返回的内容不要自己编。如果你重复传相同的assistant消息模型可能陷入重复循环。如果想让模型忘记某些话题直接把前面的消息从列表里删掉再请求即可这相当于「手动清空记忆」。5. DeepSeek API 调用避坑5 个最容易翻车的点这一章是我在实际调试中多次撞墙后的记录每条都按现象、原因、解决三步写。希望你看完能少走弯路。5.1 现象返回 401 UnauthorizedKey 明明没错原因有两个可能一是 Key 复制时多了空格或换行二是.env文件里的值包含了引号比如DEEPSEEK_API_KEYsk-xxx系统会把引号也当成 Key 的一部分。解决方法是打印 Key 的前几个字符做检查python -c import os; print(repr(os.getenv(DEEPSEEK_API_KEY)))如果输出是sk-abc123正常如果是sk-abc123说明引号被吃进去了。去.env里去掉引号。还有一个隐蔽情况某些环境变量加载库会覆盖已有变量如果系统里本来就有一个旧的DEEPSEEK_API_KEY也会导致 401。5.2 现象请求成功但响应极慢甚至超时原因大多是stream设为false而模型要在生成完整回答后才一次性返回。长回答可能耗时几十秒如果你用了默认的短超时时间就会报ReadTimeout。解决方法是开启流式输出或者调大 HTTP 超时时间。我这个 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)这种流式方式不仅响应快还能给用户一种「正在思考」的交互感。注意流式模式下response变成一个生成器不能像之前那样直接取choices[0].message.content必须遍历。5.3 现象中文回答内容被截断得像机翻原因通常是max_tokens设得太小比如 50。因为模型要在有限 token 内完成回答被迫用简洁的短句很多上下文丢失。解决方法是先估算回答长度再设置max_tokens。一个粗略的经验中文字符数除以 1.5 约等于 token 数。如果你期望 300 字回答max_tokens至少设 500。同时检查temperature是否过低因为低温会让模型倾向于保守的短回答。5.4 现象把 Key 提交到了 Git被人盗刷这是我最心疼的一次翻车。原因是 demo 自带的.gitignore没包含.env我顺手git add .就把 Key 推上去了。几个小时后余额没了。解决方法是立即到平台删掉这个 Key创建一个新 Key然后检查仓库历史里是否有泄露。最好用git filter-repo清理历史或者干脆把整个仓库设为私有。以后每次提交前我都用git status确认没有.env。5.5 现象同一段 prompt两次调用结果完全一样怀疑是缓存原因是你把temperature设成了 0模型退化为贪心解码每次都生成概率最高的序列。某些情况下这很合理比如提取 JSON 也要固定输出。但如果想要多样化的回答把temperature调到 0.7 到 1.0并且不要同时固定top_p和temperature。另外官方可能对完全相同的请求做缓存如果你需要测试不同效果一定要在 prompt 里加一点随机变化比如时间戳或序列号。6. 进阶把 demo 改造成你自己的命令行问答工具到这里你已经能调通 API、理解参数、避开大多数坑。最后这一步我们把这套能力固化成一个可以日常使用的命令行工具而不是每次写测试脚本。这个工具会读取.env里的 Key在终端里进行多轮对话并支持/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: 你是一个简洁、准确的中文助手}] print(DeepSeek CLI 已启动输入 /reset 清空记忆输入 /quit 退出。) while True: user_input input(\n你: ) if user_input.strip() /quit: break if user_input.strip() /reset: messages [{role: system, content: 你是一个简洁、准确的中文助手}] 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)})这段代码最关键的两个设计一是把assistant返回的内容拼接到messages里保证下一轮对话有完整上下文二是streamTrue让回答逐字出现体感流畅很多。/reset只是重置了内存里的消息列表不会影响 Key 或配置这个逻辑很简单但很实用。我之前遇到一个奇怪问题CLI 有时会重复回答最后一次内容。后来发现是我在拼reply_parts时把chunk里的delta.content重复添加了因为流式返回最后一个 chunk 可能包含空字符串或结束标记。解决办法是加了if chunk.choices[0].delta and chunk.choices[0].delta.content:的判断。同样的思路如果你在集成这个 demo 到 Web 服务时遇到回答中断优先检查流式解析逻辑而不是怀疑 API。另外一个实用技巧把temperature调成 0.6并且给system消息加上「请分点回答」或「请给出代码示例」这样的约束能明显提升代码相关问题的回答质量。这也是我长期使用的固定配置。希望这篇笔记能帮你节省几个小时让 DeepSeek API 的调用从「玄学」变成「手脚架上的熟练活」。希望帮到你。本文还有配套的精品资源点击获取