简介:《DeepSeek从入门到精通》出自清华大学新闻学院与人工智能学院团队,是一份面向AI研究人员、大模型开发者及希望借助提示语设计提升模型效能的从业者的技术指南。全书以“DeepSeek是什么、能做什么、如何使用”为主线,先厘清DeepSeek-R1作为开源推理模型的特点,再对比推理模型与通用模型在数学推导、代码生成、创意写作等任务上的优劣,同时比较快速反应模型与慢速思考模型的适用场景;随后围绕智能对话、文本生成、语义理解、知识推理和编程场景,讲解由“下达指令”到“表达需求”的提示语策略,并给出指令驱动、需求导向、混合模式、启发式提问等具体方法。资源共1个PDF,压缩包大小5.4MB,便于按章查阅。已有3002人学习下载,适合作为从基础认知到自主进阶的参考手册,也可用于日常AI协作的效能优化。
1. 《DeepSeek从入门到精通》免费下载开放了:这本书能解决什么问题,值不值得读
出版方把《DeepSeek从入门到精通》做成免费电子版放出来之后,收藏的人多,真正读完的人少。我见过不少从业者的情况是:PDF 存进网盘,等真要写提示词、调 API 的时候,还是回到聊天框里凭着感觉来。这本书的价值恰恰在于把「提示词怎么设计、上下文怎么喂、结构化输出怎么要」这些散在各处的东西串成一条线,省掉你自己摸索的机会成本。
它解决的是「从会用网页版,到能把模型接进自己工作流」这一步。适合的读者是:想用 DeepSeek 处理报表、写周报、做知识库问答的从业者,以及刚接触大模型开发、需要一条可靠入门路径的新手。纯做研究的人可以跳过里面偏操作的部分,直接看 API 参数和 JSON 输出这两块就行。
下面按入门最常见的学习路径展开:先提示词,再 API 命令,然后是结构化输出和一段避坑清单。每个部分都给了可以直接抄的写法,照着跑通一遍,比存十份 PDF 有用。
2. 先把提示词这块地基打好:角色、任务、约束、输出格式怎么组合才不翻车
DeepSeek 这类大模型,输入输出的唯一交互界面就是文字。提示词不是「问得礼貌一点」,而是你控制模型行为的完整协议。这类入门书最前面几章基本都在讲同一个道理:提示词的结构化程度,直接决定回答能不能直接用,省掉后续大量人工修改。
我一般把提示词拆成四个要素:角色、任务、约束、输出格式。角色决定语气和信息筛选的偏好,任务说明要做什么,约束划出边界,输出格式决定要不要二次加工。四者缺一个,回答就很容易变成「正确的废话」——语法通顺、内容无害,但落到具体场景里用不上。
2.1 上下文窗口:为什么教程把「喂上下文」放在提示词前面
上下文窗口是模型单次能接收的文字总量。窗口大,不代表要把所有资料一次塞进去。很多人刚上手时长上下文很兴奋,把几千行日志、几十页文档全贴进去,结果回答反而变差:模型注意力被无关信息稀释,关键约束被淹没在大量冗余文本里。
常见的做法是「按需喂」:先把业务规则写成 system prompt,再把最近、最相关的数据片段放进 user 消息。比如做客服知识库,只放当前用户问的那一类 FAQ,而不是把整份知识库都丢进去。做周报,只放这一周的工作日志,不用把上个月的一起贴。
这类书里反复强调的另一个点是:示例比描述更有效。你想让模型按某种格式输出,与其描述半天,不如给它一条真实样例,再用「仿照上面的格式」收尾。这一步看着简单,实际对输出质量的提升非常明显,我几乎每个正式任务里都会放一个输出示例。
上下文窗口还有一个实际影响:token 就是成本。窗口越大,单次请求的输入费用越高。别把上下文当免费内存用,能裁剪的先在代码里裁剪好,再发请求。
2.2 一个可以直接抄的提示词模板与参数影响
下面这个模板我配合 DeepSeek 用了很久,覆盖大部分办公场景,直接复制改内容就能用:
角色:你是一名熟悉[业务领域]的资深分析助手。 任务:根据我提供的[素材类型],整理成[交付物名称]。 约束: 1. 只能使用素材中出现的信息,不许编造或补充; 2. 处理结果不超过[条数/字数]; 3. 遇到素材缺失的信息,在末尾单独列出「待补充项」。 素材: [粘贴原始内容] 输出格式: [示例或格式描述]参数方面,最常调的是 temperature。它控制随机性:数值越低,回答越稳定保守;越高越有发散性。事实提取、格式转换这类任务,我习惯固定在 0~0.3;文案创意、头脑风暴可以放到 0.7~1.2。top_p 一般保持默认 1.0,多数情况下不需要和 temperature 同时调。
| 任务类型 | temperature 建议 | 说明 |
|---|---|---|
| 事实抽取、格式转换 | 0~0.3 | 稳定优先,禁止发散 |
| 改写、摘要 | 0.3~0.7 | 保留一定润色空间 |
| 创意写作、头脑风暴 | 0.7~1.2 | 需要多样性和发散 |
调参这件事很容易陷入玄学:同一个提示词,同一批参数,不同时间跑出来的结果也会有细微差异。应对办法是给任务加「可验证的约束」,比如要求输出 JSON、要求不出现某个词、要求必须引用素材原文,而不是靠反复调温度赌运气。
跑题是提示词阶段最常见的翻车点。模型回答得很好,但不是你要的东西,大概率是任务描述里少了「给谁看」和「用来干什么」。写周报就写明「给直属上级看,控制在半页 A4」,模型自然会把细节收敛掉。
2.3 用示例对替代命令式描述:比指令更稳的写法
命令式写法:把下面的数据按重要程度排序。模型能执行,但排序依据、呈现形式全靠它自己猜,十次可能给出十种不同格式。
示例式写法:
输入:项目A 延期3天,项目B 增加2人,项目C 正常推进,项目D 预算超支5%。 输出: 1. 项目D(预算超支,风险最高) 2. 项目A(延期,影响后续排期) 3. 项目B(人力增加,可控) 4. 项目C(状态正常)模型对模仿样例的偏好远高于理解抽象指令。给它一个输入输出对,再补一句「严格按照上面的格式输出」,基本不需要第二次返工。如果效果还不够,就在示例里加一个反例,标注「不要这样做」,比单纯强调约束更直观。
3. 把书里的例子变成能跑的命令:API Key、curl 与 Python 客户端的最小路径
网页版玩得再熟,也替代不了写进脚本。要让 DeepSeek 进入工作流,第一步是把「在聊天框打字」换成「向接口发请求」。这一步打通之后,后面接定时任务、接内部系统、做自动化都是同一套逻辑。
3.1 先确认两件事:模型名和 base_url
调用之前,把两个信息写进配置:模型名和 base_url。模型名决定行为:deepseek-chat 是通用对话模型,适合日常总结、抽取、问答;deepseek-reasoner 是推理模型,适合数学、逻辑、复杂拆解,响应更慢,价格也不同。
base_url 是这个接口的根地址,客户端会在此基础上拼出 /chat/completions 路径。第一次写代码时最容易错的就是这两个值:模型名写成网页版的展示名,或者 base_url 多了个 /v1。我的建议是把它们放到环境变量或配置文件里,不要在代码块里写死。
选型思路很简单:任务需要推理、计算、一步步拆解,就选 reasoner;只是总结、提取、改写,选 chat 就行,便宜且快。没有必须「更贵的模型更好」这回事,匹配任务才是关键。
3.2 用 curl 打通第一个请求,把「连接不上」和「代码问题」分开
export DEEPSEEK_API_KEY="你的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": "用一句话解释什么是上下文窗口"} ], "temperature": 0.3, "max_tokens": 100 }'这条命令做的事情:向 /chat/completions 接口发一个 POST 请求,HTTP 头里带认证信息,请求体里指定模型、消息列表和生成参数。返回内容里 choices[0].message.content 就是模型回复。
参数说明:messages 数组里的 role 有三种常用取值——system 放系统指令,user 放用户输入,assistant 用于多轮对话时把历史回复带上。temperature 这里设 0.3,因为解释类任务需要稳定;max_tokens 限制单次最长输出,超过就截断,别设太小的值。
如果这条命令返回 JSON 结构,说明 Key、地址和模型名都没问题;如果返回 401,检查 Key 是否正确;返回 404,检查路径或模型名。curl 通了再写 Python,排错范围会小很多,这是最快的验证路径。
3.3 用 Python 封装成本地函数,把重复请求收进一个入口
日常脚本里我习惯用官方兼容 OpenAI 的 Python SDK 来做,一个函数封装掉鉴权、请求、超时和返回提取。这样上层业务代码不需要关心接口细节。
from openai import OpenAI client = OpenAI( api_key="你的key", base_url="https://api.deepseek.com", timeout=60, ) def ask_deepseek(system_prompt: str, user_content: str, temperature: float = 0.3) -> str: resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_content}, ], temperature=temperature, max_tokens=1024, ) return resp.choices[0].message.content if __name__ == "__main__": print(ask_deepseek("你是一个行政助手。", "把下面这段话改成一封通知:..."))这里把 base_url 和 api_key 放进 OpenAI 客户端,是和 DeepSeek 接口兼容的关键写法。timeout=60 是给整次请求设置的等待时间,网络不稳定时可以调到 120,但不宜过长,避免脚本卡死在那里等不到返回。
temperature 要按任务传:改写通知这类轻度创作可以 0.7,数据抽取或整理必须 0.2 以下。max_tokens 设 1024 是为了防止个别任务输出过长,把单次响应控制在成本范围内;如果发现回答经常被截断,说明输出确实长,该调大而不是硬撑。
提示:第一次写 Python 客户端时,Key 不要硬编码在脚本里,用环境变量加载。这样后面接定时任务或 CI 时,不会把密钥带到代码仓库里。
封装成函数后,其他脚本只需要 import 这个 ask_deepseek,不用每次关心 Key 怎么传、地址填什么。团队协作时,别人也只需要改参数,不用重写请求逻辑。
4. 让 DeepSeek 输出程序能直接吃的 JSON:结构化输出的两种姿势
网页版聊天无所谓格式,但接进程序就需要 JSON。这一步是「能跑」到「能用」的分水岭。很多人卡在这里,不是因为请求写错,而是因为模型默认输出根本不适合直接解析。
4.1 为什么默认输出不适合直接落库
默认情况下,模型会在目标内容前后加解释、Markdown 标记甚至客套话。直接 json.loads() 几乎必然报错,很多人第一次在这里翻车,还以为是自己代码的问题。
解决方向有两个:一是开 JSON 模式让模型只输出合法 JSON;二是在输出里做兜底提取。两个都要会,因为 JSON 模式不是万能的,遇到旧接口、参数不生效或者特殊字符时,兜底解析能救你一次。
4.2 用 response_format 开 JSON 模式,让模型只吐 JSON
from openai import OpenAI client = OpenAI(api_key="你的key", base_url="https://api.deepseek.com") resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "你是信息抽取助手。只输出JSON,不要输出其他文字。"}, {"role": "user", "content": "从下面简历中抽取:姓名、工作年限、技能列表。\n原始文本:..."}, ], response_format={"type": "json_object"}, temperature=0, ) content = resp.choices[0].message.content print(content)response_format 的关键点是:它保证输出是合法 JSON,但不会保证字段名和结构符合你的预期。字段名需要你在提示词里显式写出来,比如「姓名」「工作年限」「技能列表」作为 key。想更稳,就把期望的 JSON 示例一并放进提示词里,让模型照着填。
temperature 在这里必须设 0。稍微拉高一点,JSON 可能合法但字段乱序、空值变多。抽取类任务和 JSON 模式是固定搭配,我基本上不会再单独调高。
4.3 JSON 字符串常见的坑与兜底解析
就算开了 JSON 模式,也可能遇到三种情况:返回内容带了反引号代码块,JSON 被截断,或者内容里混入多余解释。所以落库前我会再包一层兜底解析,避免偶发情况直接搞崩线上任务。
import json import re def safe_json_loads(content: str): if not content: raise ValueError("empty content") # 去掉常见的 markdown 代码块包裹 content = re.sub(r"^```(?:json)?\s*|\s*```$", "", content.strip()) try: return json.loads(content) except json.JSONDecodeError: # 多数情况是前后有多余文本,把第一个 { 到最后一个 } 之间的部分截出来 match = re.search(r"\{.*\}", content, re.S) if match: return json.loads(match.group(0)) raisesafe_json_loads 先剥离 markdown 代码块,再直接解析;失败时用正则抓出最外层花括号之间的内容,二次解析。这个兜底能解决九成以上的「合法 JSON 被包在多余文字里」的场景。
剩下的少数情况,比如 JSON 被 max_tokens 截断、字符串里出现了未被转义的引号,正则也救不回来。这种没有后悔药,只能回溯:调大 max_tokens,或者让模型输出的字段更短、更少。不要在解析层死磕,尽早回到请求层改提示词。
4.4 字段太自由怎么办:用工具调用收紧结构
如果抽取字段多、层级深,JSON 模式加提示词描述依然不够稳,可以改用工具调用(function calling)来定义结构。工具调用的返回体由接口按你声明的 JSON Schema 约束,字段名和类型更可靠。
tools = [ { "type": "function", "function": { "name": "extract_person", "description": "抽取简历中的个人信息", "parameters": { "type": "object", "properties": { "name": {"type": "string", "description": "姓名"}, "years": {"type": "integer", "description": "工作年限"}, "skills": {"type": "array", "items": {"type": "string"}} }, "required": ["name", "years", "skills"] } } } ] resp = client.chat.completions.create( model="deepseek-chat", messages=[{"role": "user", "content": "从这里抽取:..."}], tools=tools, tool_choice="auto", ) # 结果在 resp.choices[0].message.tool_calls 里注意:工具调用的自动模式不保证每次都调用工具,偶尔模型会直接回普通文本。要严格要求时,把 tool_choice 显式设成需要的函数名,而不是 auto。这算是最接近「黑匣子外面装了个模具」的做法——结构由你定,模型只负责往里填内容。
5. 避坑清单:免费 PDF、模型版本、JSON 解析和本地部署的常见问题
这一章按「现象 → 原因 → 解决」整理我踩过的坑,按出现频率排序。新手照着这几条排查,能省下不少瞎折腾的时间。
5.1 下载的 PDF 是扫描版,复制代码发现全是乱码
现象:从 PDF 里复制代码,缩进丢失,引号变成弯引号,代码没法直接执行。
原因:电子版是扫描件或双栏排版,没有可复制的文本层,或者文本层是 OCR 识别出来的错误字符。这类文件适合阅读,不适合当代码参考。
解决:优先找出版方官网发布的文本版 PDF;如果只有扫描件,把代码区块截图用 OCR 工具识别,识别完逐行校对。文件名带「最新版」「完整版」的来路不明文件,谨慎下载,安全性比版本号重要。
5.2 API 请求返回 404 或提示模型不存在
现象:curl 命令完全照书抄,返回 404,错误信息是模型名找不到。
原因:模型名写错,或者 base_url 路径不对,比如多写了 /v1、少写了 /chat/completions。
解决:以官方开放平台当前文档为准核对模型名和 base_url。先跑第 3 章的 curl 最小命令,确认通了你再写 Python,不要把两个环节的排错混在一起。
5.3 本地部署:量化等级选错,同一个提示词回答质量明显缩水
现象:同样的提示词,网页版回答有逻辑,本地模型开始编数据、说废话。
原因:显存不够,选了很低的量化等级,模型能力压缩太狠。量化是拿精度换体积,等级越低,体积越小,能力损失也越明显。
解决:在显存允许的前提下选更高的量化档位;能用 API 的场景优先走 API,本地部署只留给有数据隐私要求、不能出网的场景。不要指望小显存机器跑出和官方服务一样的效果,那是两套东西。
5.4 temperature 拉太高,JSON 输出不稳定
现象:同样的请求,有时返回合法 JSON,有时字段乱序,有时直接解析失败。
原因:温度设太高,模型在采样时飘了。JSON 是强结构任务,容不下这种随机性。
解决:JSON 任务把 temperature 固定为 0,并且把输出字段的示例放进提示词。先保证稳定,再谈「稍微有点变化」。结构任务里,变化不是优点,是事故。
5.5 书上截图和当前 API 行为不一致
现象:按书上的参数名或返回字段写代码,某些字段取不到值,或者某个参数传进去被忽略。
原因:产品迭代比书快,接口或字段有变化。书出版时记录的是当时的行为,不能当永久接口手册用。
解决:把书当作思路参考,具体请求以官方在线文档为准。遇到取不到值的字段,先打印整个返回 JSON,用肉眼确认字段名,再写解析逻辑。不要假设字段永远存在。
6. 进阶用法:把 DeepSeek 从「聊天框」变成工作流里的一个函数
6.1 把常用诉求固化成一段 system prompt
工作里重复率最高的任务,我会把提示词固化成一个常量,而不是每次现编。这段是我处理「信息整理」类任务常用的开头:
你是一个严谨的信息处理助手。 对输入内容执行以下处理:先提炼核心结论,再按时间线整理关键事实,最后列出需要人工确认的不确定信息。 要求:不添加输入中不存在的信息;不确定处标注「待确认」;输出格式为 Markdown 的分节列表。固定 system prompt 有个附带好处:可以 A/B 测试。同一批输入,换一个词、加一条约束,对比输出质量,慢慢沉淀出自己业务里最稳的一套配置。这比每次凭感觉写要可复用得多,时间越长积累价值越大。
6.2 给脚本加流式输出,长任务不再黑屏等待
同步调用在长输出时会一直等到全部生成完。给脚本加 stream=True,可以边生成边处理,体验和响应速度都会好一截,排查问题时也能及时看到内容方向对不对。
messages = [ {"role": "system", "content": "你是一个简洁的助手。"}, {"role": "user", "content": "用300字介绍你擅长做的事。"}, ] resp = client.chat.completions.create( model="deepseek-chat", messages=messages, stream=True, ) for chunk in resp: delta = chunk.choices[0].delta.content if delta: print(delta, end="", flush=True)stream 模式下,每一条 chunk 都带一个 delta.content 片段,拼起来就是完整回答。注意此时响应对象不是一次性返回,不能在循环外直接读 choices[0].message.content。
我自己的习惯是:先固化 system prompt,再决定要不要开流式,最后才调参数。某开发者当初把一份几十页的文档一次性塞给模型,以为上下文窗口大就万事大吉,结果输出质量反而下降,后来才明白:喂上下文像给新人培训,分批发、给重点,比全量倾倒有效。这个教训我一直带着。希望帮到你。
本文还有配套的精品资源,点击获取