简介:由清华大学新闻与传播学院新媒体研究中心元宇宙文化实验室出品的《DeepSeek从入门到精通》103页完整版PDF,面向希望系统掌握DeepSeek应用的AI学习者、开发者和内容创作者,可作为从零基础到进阶提升的系统教程。资源以单个PDF文件打包,共1个文件,约5.01MB,内容分DeepSeek是什么、能够做什么、如何使用三大部分展开。教程不仅梳理了智能对话、文本生成、语义理解、代码生成等核心能力,还重点拆解了推理模型与通用模型的选择原则、快思慢想与CoT链式思维差异,以及面向数学证明、创意写作、代码生成等任务的提示语策略,并配有指令驱动、需求导向、混合模式等具体示例;后段还通过任务-模型匹配表和提示语示例,帮助读者选对模型、写对提示词。已有362人学习浏览,可作为接触DeepSeek时建立完整认知并避开常见误区的实用速查手册。
1. DeepSeek 从入门到精通:这份 103 页资料到底在教什么
很多人拿到 DeepSeek 之后,用成了升级版搜索框:丢问题、接答案、复制粘贴,三周过去还停在入门层。DeepSeek 真正拉开差距的地方,是它的模型分两条线——通用对话模型负责快,推理模型负责想,两者的提示词写法和参数手感完全不同。那份流传很广的 103 页学习资料,主线就是「认识模型 → 调通接口 → 写提示词 → 落到工作流」这么一条可跟做的路径。下面内容不替代那份资料,而是按一线落地顺序,把跑 API、部署到本地、搭提示词模板、解析结构化输出这些能直接抄的步骤拆开,顺便标出五个高频翻车点。适合三类人:要接 API 的开发者、整天和文本表格打交道的分析师、以及想搞清楚提示词为什么时灵时不灵的学习者。
2. 两条路线跑通 DeepSeek:API 最小调用与本地部署的显存底线
2.1 走 API:一个能直接改的 Python 最小调用
先说明选型理由:如果目标是快速验证提示词、或者做原型,API 是最省事的入口,不用管显卡、量化和 CUDA 版本。DeepSeek 的接口协议兼容标准 OpenAI SDK,这意味着你现有的调用代码改个 base_url 就能切过来,学习成本基本为零。
from openai import OpenAI # DeepSeek 接口兼容 OpenAI 协议,SDK 可以直接复用 client = OpenAI( api_key="sk-在这里填你的密钥", # 在官方控制台的密钥页面创建 base_url="https://api.deepseek.com", # 官方 OpenAI 兼容端点 ) resp = client.chat.completions.create( model="deepseek-reasoner", # 推理模型;通用对话请换成 deepseek-chat messages=[ {"role": "system", "content": "你是资深后端工程师,只输出结论和风险点"}, {"role": "user", "content": "检查下面代码在并发场景下的问题,只列 3 条。"}, ], temperature=0.3, # 推理任务压到 0.3;创作类可以拉到 0.8 max_tokens=2000, # 控制单次输出长度,避免一次调用产生过多 token ) # 推理模型会把内部思考过程单独放在 reasoning_content 字段 print("思考过程:") print(resp.choices[0].message.reasoning_content) print("最终输出:") print(resp.choices[0].message.content)代码逻辑说明:先创建客户端,密钥从控制台拿,别写死在代码里,用环境变量更稳。一次 chat.completions.create 就是完整调用,重点在 model 参数——deepseek-reasoner 会先推理后回答,适合复杂任务;deepseek-chat 是直出模式,响应更快。system 消息负责定角色和边界,user 消息才是真正的任务。temperature 是采样随机度,任务越要求确定性压得越低;max_tokens 只限制输出长度,不限制输入。
这段代码踩过坑的地方有两处:一是很多人在 system 里写一大段人格设定,结果每次请求都把这堆字重新计费,后面 5.5 会细说;二是忽略 reasoning_content,把思考过程当正文存库,下游数据会变得特别脏。
2.2 本地部署:蒸馏版模型选型与启动命令
一旦涉及敏感数据,或者要跑固定格式的大批量任务,API 就不划算了,得把模型拉回本地。这里先说一个现实:DeepSeek 主模型是千亿级参数的 MoE 架构,个人机器直接跑不现实。常见做法是跑它的蒸馏版——把推理能力蒸馏到 7B、8B、32B 这些规模,单机能扛得住。
# 方案 A:个人实验、验证提示词,用 Ollama 这类模型管理器最省事 ollama pull deepseek-r1:7b ollama run deepseek-r1:7b# 方案 B:有并发和吞吐要求,用 vLLM 这类推理框架起服务 vllm serve ./models/deepseek-r1-7b-local \ --tensor-parallel-size 1 \ --max-model-len 32768 \ --gpu-memory-utilization 0.9 \ --served-model-name deepseek-r1-local第一段命令适合跑通流程:ollama pull 拉模型,ollama run 进交互。第二段是给生产环境准备的:vllm serve 起一个兼容接口的服务,客户端把 base_url 指到本地端口就行。模型路径按你实际下载到本地的目录填。参数说明:tensor-parallel-size 单卡上就设 1;max-model-len 是上下文总预算,32768 代表输入加输出最长约 3.2 万 token,这个值每涨一倍,KV cache 显存占用就涨一大截;gpu-memory-utilization 0.9 表示允许框架用掉 90% 显存,留点余量给别的进程。
显存底线按经验给个参考:7B 级别加 4bit 量化,16GB 显卡能跑,但别把上下文拉满;32B 级别建议 24GB 以上,不然会触发 CPU offload,慢到没法用。注意两个折扣要心里有数:量化会损失一点推理质量,蒸馏版本身也不是完整版,效果验收时别拿完整版的预期去卡它。
2.3 怎么选:延迟、隐私和成本的取舍表
| 对比项 | API 调用 | 本地部署 |
|---|---|---|
| 前期成本 | 注册即用,按 token 付费 | 硬件投入一次到位 |
| 隐私风险 | 数据经过第三方服务,敏感字段要脱敏 | 数据不出机器 |
| 延迟与并发 | 高峰期不稳定,但不用自己扛扩容 | 延迟稳定,并发受显存和卡数限制 |
| 运维负担 | 几乎为零 | 要处理 CUDA 版本、量化、上下文调优 |
| 模型更新 | 服务端升级,无需干预 | 自己拉新权重重新验证 |
我的选择逻辑是:提示词调试和原型阶段一律走 API,速度快、反馈直接;涉及合同、用户数据、内部日志这类内容,迁到本地;固定格式的批处理任务如果量大,本地跑更划算,但准确率回归测试要先建起来,这个放到第 6 章。还有一条容易被忽略的边界:API 拿到的思考过程和本地模型不完全一样,同一个提示词在两个环境的结果不能直接互相当基准。
3. 提示词写法:为什么 DeepSeek 推理模型不吃「逐步思考」这一套
3.1 先搞懂 CoT 内化
很多人拿到推理模型后干的第一件事,是在提示词里加一句「请一步步思考」,结果回答反而变长变绕。这里有个机制差异要搞清楚:DeepSeek 的通用对话模型是直出模式,你给它步骤它就照做;而推理模型在内部已经跑了一圈思维链,思考过程单独放在 reasoning_content 字段里。你再去要求「逐步思考」,它容易把内部思考外化成正文,白白浪费输出 token,还会让答案结构散掉。
所以提示词设计的落点变了:对推理模型,要給目标、给约束、给输出格式,别去指挥它怎么想;对通用模型,给示例、给步骤、给明确指令。同一个任务两套写法,拿到的结果质量能差一个档次。如果你看到回答开头出现「嗯,让我想一想」这种话,基本可以判定是提示词在逼模型外化推理。
3.2 一套能直接抄的提示词模板:角色-任务-约束-输出格式
# 角色 你是一名有十年经验的 Python 后端工程师。 # 任务 审查下面这个函数,找出它在多线程场景下的竞态条件。 # 约束 - 只列问题,不重写代码; - 按严重程度从高到低排序; - 如果确实不存在竞态,直接说「未发现」,不要硬凑。 # 输出格式 每条:严重级别 | 问题描述 | 涉及行号 # 待审查内容 <把代码贴在这里>这套结构的逻辑是:角色决定用谁的知识体系回答;任务必须只有一个,任务一多模型会自己分配权重,结果两头都浅;约束的作用是砍废话,「不要硬凑」这种否定式约束在推理模型上效果很明显;输出格式保证你拿到的结果能解析。待审查内容用分隔线隔开,避免和指令混在一起。这个模板顺手能改成数据分析、文档审查、翻译等任务,只换角色和约束就行,不需要重学一套写法。
3.3 四个必调的采样参数:temperature、top_p、max_tokens 与惩罚系数
| 参数 | 作用 | 推荐起始值 | 什么时候调整 |
|---|---|---|---|
| temperature | 采样随机度 | 复杂任务 0.3,创作 0.8 | 结果飘忽不定就往下压 |
| top_p | 候选词截断范围 | 0.9 | 与 temperature 二选一调整,别同时猛调 |
| max_tokens | 单次输出长度上限 | 预期长度 × 2 | 输出总在半句处截断就加大 |
| frequency_penalty | 对重复词的惩罚 | 0 | 长文反复绕同一观点时调到 0.5 左右 |
四个参数里最容易翻车的是 temperature 和 top_p 同时调:两者都在控制随机性,一起大幅度改动会把输出变成玄学。我的习惯是固定 top_p 在 0.9,只动 temperature。还有一个反直觉的点:推理模型内部有思维链,很多人以为 temperature 对它无效,实际上它会作用到最终答案的采样,只是影响方式更隐蔽——同样参数下两次结果依然可能不同。所以任何测试都别只跑一次,至少跑三遍看稳定性。
4. 把 DeepSeek 接进真实工作流:三套可复用模板
4.1 代码生成:先要方案、再要代码的两段式调用
直接让模型写完整功能,结果通常是「看起来能跑,边界条件全是洞」。我一般拆成两段:第一段只要设计方案,第二段把方案作为上下文再去要代码。方案在这里起护栏作用,模型照着既定结构落代码,自由发挥空间被压到最小。
def gen_plan(client, task): resp = client.chat.completions.create( model="deepseek-reasoner", messages=[{"role": "user", "content": f"给下面的任务写实现方案:模块划分、数据结构、边界条件。不写代码。\n{task}"}], temperature=0.3, max_tokens=1500, ) return resp.choices[0].message.content def gen_code(client, task, plan): resp = client.chat.completions.create( model="deepseek-reasoner", messages=[{"role": "user", "content": f"任务:{task}\n\n已确认方案:\n{plan}\n\n请严格按方案写完整可运行代码,带关键注释。"}], temperature=0.2, max_tokens=4000, ) return resp.choices[0].message.content两段都用推理模型,但 temperature 不同:方案阶段 0.3 保证结构稳定,代码阶段压到 0.2,让语法和逻辑更收敛。实际用的时候,第一段输出值得人工花三十秒过一遍——方案明显不对就改提示词重跑,别等代码写完再返工。这套做法对 500 行以内的独立功能效果最好,超过这个规模还得叠加模块拆分,不然第二段 prompt 塞太满,代码质量会明显下滑。
4.2 结构化输出:JSON 反序列化的两道保险
让模型返回 JSON 是高频需求,但模型经常不老实:前面补一句「好的,这是结果」,或者把 JSON 包进代码围栏里,再或者布尔值写成中文。解析前做两道保险:
import json, re content = resp.choices[0].message.content # 第一道保险:剥掉 ```json 代码围栏 cleaned = re.sub(r"^```(?:json)?\s*|\s*```$", "", content.strip()) # 第二道保险:只截取第一个 { 和最后一个 } 之间的内容 start, end = cleaned.find("{"), cleaned.rfind("}") cleaned = cleaned[start:end + 1] try: data = json.loads(cleaned) except json.JSONDecodeError as e: # 定位失败位置,把片段打出来人工看 print("JSON 解析失败,位置:", e.pos) print(cleaned[max(0, e.pos - 40):e.pos + 40])第一道正则处理围栏,第二道截取大括号区段,把模型多说的废话全部排除。解析失败时别只打印错误行,把出错位置前后各截 40 个字符出来,一眼能看出是尾逗号、中文引号还是字段缺失。更治本的做法是在提示词里加一句「直接输出 JSON,不要任何解释」,配合上面的两道保险,成功率能稳定到九成以上。
4.3 长文本处理:分块-加工-合并的操作顺序
长文改写、翻译、摘要,最容易踩的是「一次喂进去,输出被截断」。上下文窗口确实够长,但输出有上限,而且超长输入会拖慢首字延迟。常见做法是分块处理:按段落聚合出块,每块独立加工,最后合并,块与块之间不做二次改写,避免信息漂移。
def process_long_text(client, text, chunk_size=1200): chunks, cur, length = [], [], 0 for para in text.split("\n"): cur.append(para) length += len(para) if length >= chunk_size: chunks.append("\n".join(cur)) cur, length = [], 0 if cur: chunks.append("\n".join(cur)) results = [] for i, chunk in enumerate(chunks): resp = client.chat.completions.create( model="deepseek-chat", # 改写类任务不需要深度推理,用直出模型更快更便宜 messages=[{"role": "user", "content": f"把下面第 {i+1}/{len(chunks)} 段改写为技术博客风格,保留术语和数字:\n{chunk}"}], temperature=0.5, max_tokens=len(chunk) * 2, ) results.append(resp.choices[0].message.content) return "\n\n".join(results)分块按段落边界,不在句子中间硬切。chunk_size 1200 是经验值,中文大约对应 1200 字,模型处理起来既不会丢细节,也不会因为块太小失去上下文。这里特意用 deepseek-chat 而不是推理模型:改写不需要深度推理,直出模式速度快、成本低。合并阶段用空行分隔,不做二次加工——很多长文改写出问题的环节就在合并时让模型「顺一遍」,一顺就把术语和数字改歪了。
5. DeepSeek 落地避坑:五个高频翻车现场与排查路径
5.1 JSON 总是解析失败:代码围栏、尾逗号与中文字符的连锁反应
现象:提示词明确要求输出 JSON,代码一跑 json.loads 就抛异常,报错位置每次还不一样。 原因:三个隐患叠加——模型在 JSON 前输出「好的」之类的废话;把整个对象包在代码围栏里;数组末尾多了一个逗号,或者 true/false 被写成中文写法。 解决:解析前先剥围栏、截取首尾大括号,用 4.2 的两道保险兜底;提示词里加一句「直接输出 JSON,不要任何解释」;如果还是失败,把出错位置前后片段打印出来,人工看一眼是哪种脏数据,再决定修提示词还是修解析器。
5.2 上下文一长就截断:max_tokens 和 max-model-len 是两个变量
现象:输入三千字后,输出停在半句话,像是被硬生生切断。 原因:把 max_tokens 当成了总长度限制,但它只管单次输出;输入和输出的总预算是服务端上下文窗口,本地部署则对应启动参数里的模型上下文长度。 解决:API 端先调大 max_tokens,再确认总和没超过套餐上下文上限;本地部署要重新审视上下文长度和显存的平衡——从 8192 拉到 32768,KV cache 占用的显存可能翻好几倍,速度也会明显下降。
5.3 推理模型答非所问:把「请一步步思考」喂给了 R1
现象:用推理模型处理简单分类或短问答,回答又长又绕,正文里甚至出现「让我想想」这类口水话。 原因:推理模型内部已经有一轮思维链,你再要求它逐步思考,它倾向于把思考过程外化到正文里,既浪费 token,也让输出结构散掉。 解决:简单任务换成通用对话模型;复杂任务只给目标、约束和输出格式,不给思考路径;正文一出现自我对话的口吻,马上检查是不是提示词里混入了「逐步思考」这类指令。
5.4 本地部署慢到没法用:显存、量化与上下文长度的三角关系
现象:模型能启动,但一个短回答要半分钟,并发两个请求直接卡死。 原因:显存不够触发 CPU offload,权重在内存和显存之间来回搬运;没开注意力优化;上下文长度设得过大,KV cache 把显存挤没。 解决:推理优先选择为生产设计的服务框架,而不是逐行推理的库;显存吃紧就开 4bit 量化,同时把上下文长度从 32768 降回 8192;7B 级别至少准备 16GB 显存,32B 级别直接按 24GB 以上规划,别想用内存硬扛。
5.5 API 费用失控:系统提示词越长,每次调用越贵
现象:调用次数没涨多少,账单却翻了几倍。 原因:每次请求都带着完整 system prompt 和全部历史记录;system prompt 写成了八百字小作文,对话轮次一多,输入 token 成倍增长。 解决:system prompt 压到 500 字以内,只留角色和关键约束;对话历史用滑动窗口,只保留最近若干轮;大批量固定格式任务迁到本地跑。还有一条:某个提示词模板长期不变的话,优先确认平台是否提供缓存能力,别让同样的字被反复计费。
6. 从会用变成精通:给 DeepSeek 建一个固定回归集
会用和精通的分界线,不是会写多少种提示词,而是手里有没有一把固定的尺子。我的习惯是维护 20 条样本,覆盖代码审查、JSON 抽取、长文改写、问答四类典型任务,每条配一个「通过/不通过」的判定标准,改任何提示词或参数之前,先跑一遍全集记下通过率。
cases = [ {"name": "代码审查", "prompt": "...", "check": lambda x: "并发" in x}, {"name": "JSON 抽取", "prompt": "...", "check": lambda x: json.loads(x)["id"] == 42}, # 其余样本同一结构扩展,check 写可自动判定的规则 ] report = [] for case in cases: output = call_model(case["prompt"]) # 封装你自己的模型调用 report.append((case["name"], case["check"](output))) passed = sum(ok for _, ok in report) print(f"通过率:{passed}/{len(cases)}")样本里要混入两三条非常简单、稳定的用例,它们是看门狗——复杂用例全过了、简单用例反而挂了,说明提示词改动把基础能力带偏了。有一次我把 system prompt 从 300 字扩到 800 字,直觉上更完备,回归集一跑通过率掉了 15 个点,原因就是角色描述太长,模型开始过度解释,该直接给结论的地方绕圈子。从那以后我养成两个习惯:改完必跑回归集,跑完把提示词版本和通过率记在一起;同一个任务至少跑三次取稳定结果,不拿单次输出当结论。这套标尺一开始维护会嫌麻烦,攒到三五十条之后,你会发现它才是真正让自己从「会用」走到「精通」的东西。希望帮到你。
本文还有配套的精品资源,点击获取