简介:这份由北京大学相关机构联合出品的讲座材料为PDF格式,面向程序员、教师、科研人员、管理者等不同行业人士,旨在解决如何借助推理大模型完成公文写作、教学设计、数据分析、编程开发等日常任务的提效问题。文档聚焦深度求索模型的核心优势,如推理过程可视化、低成本与开源生态;不仅分析了其火爆原因,涵盖能力突破、开源共享、低成本与国产化加持,还系统梳理了直接使用的三种方式、提示词工程常用技巧及常见误区,并结合教育、学术、专业工作、医疗保健等领域的真实案例展开说明。整个资源为单份PDF文件,压缩包大小约18.66兆字节,内容完整便于阅读保存。目前已有三百一十一人学习下载。读者通过这套整理,既能理解深度求索模型的推理机制与调用路径,包括官方接口、第三方平台及私有化部署,又能获得多个垂直场景的提示词示例和配套学习指引,快速迁移到实际工作与学习中。
1. DeepSeek 提示词工程到底在解决什么:推理模型不是更聪明的对话模型
把之前给对话模型的提示词原样搬到 DeepSeek 推理模型上,第一天上线就翻车——响应变慢只是小事,更要命的是模型开始把“分析过程”打印进回答,客户看到的是一堆“首先、其次、综上”的内心戏。后来我把提示词从八百字砍到一百二十字,只留任务、边界、输出格式,效果反而变好了。这件事让我意识到,提示词工程在推理模型这里换了一套规则:以 DeepSeek 为代表的推理模型把“思考”内化到了参数里,用户要写的是任务边界,不是思考步骤。
北京大学那份《DeepSeek 提示词工程和产业应用》公开材料,主线就是把推理模型的应用场景和落地实践讲清楚。这篇内容沿着同一条主线展开,适合三类人:正在把 deepseek-reasoner 接进业务后端的开发,带产品需要评估推理模型成本与效果的负责人,以及被 Agent 工具链折磨、想搞清提示词和 skill 到底怎么分工的从业者。后面的内容不聊空概念,全部是能直接抄的写法、参数和排错经验。
2. 推理模型与对话模型的提示词边界:为什么“请一步步思考”会翻车
2.1 推理模型的工作机制:思维链从提示词搬进了模型内部
要搞清楚提示词怎么写,得先清楚这代推理模型(reasoning model)和上一代对话模型(chat model)在生成机制上的差别。对话模型是“看到问题直接给答案”:你给它什么指令,它按指令组织语言。所以过去几年我们养成的习惯是给模型布置详细步骤,先做什么后做什么,条理越清晰越好,因为对话模型本身不具备“规划”能力,步骤是用户替它想的。
推理模型不一样。DeepSeek 的 deepseek-reasoner 在正式回答之前,会在内部生成一段不对外展示的思考链(reasoning chain)。这段思考链占据额外的生成时间和 token,换来的是复杂任务上的准确率提升。从产品角度看,这段思考链是一个“黑匣子”:你只能看到最终答案和一段摘要,看不到完整的脑内活动。这也是推理模型主要测试指标里“首字延迟 TTFT”比对话模型高的根本原因——它在开口之前先想了很久。
这个机制直接带来一个反直觉结论:提示词写得越“完备”,推理模型越难受。当你要求它“请一步一步地思考”,它要么把内部推理过程误认为输出要求,在回答里复述推导;要么把这句话当成额外约束,反而限制了它本来更高效的那条推理路径。真正该做的是把提示词收敛成“任务 + 约束 + 输出格式”三段,其余过程交给模型。
2.2 一套提示词写两种模型:对话模型给步骤,推理模型给边界
用一个真实的业务场景做对照:合同风险审查。给对话模型写提示词,我会把审查步骤拆开;给推理模型写,只交代清楚要什么格式的结果。同一个后端服务里,两者可以共存,但提示词模板要分开维护。
from openai import OpenAI client = OpenAI( base_url="https://api.deepseek.com", api_key="sk-xxxx", # 换成你的 key ) user_prompt = """审查这份合同,输出 JSON: {"risks": [{"clause": "条款编号", "level": "高/中/低", "reason": "一句话理由"}], "suggestions": [{"clause": "条款编号", "new_text": "建议文本"}]}""" # 对话模型版本:给它走查步骤,效果更好 chat_resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "你是资深合同审查法务。先通读合同,再按条款逐一识别风险。"}, {"role": "user", "content": user_prompt}, ], temperature=0.3, # 对话模型建议低温,减少随机性 max_tokens=2048, ) # 推理模型版本:给任务和输出格式,思考步骤交给它自己 reasoner_resp = client.chat.completions.create( model="deepseek-reasoner", messages=[ {"role": "user", "content": user_prompt}, ], max_tokens=4096, # 注意:内部推理 token 也占用这个上限 )注意差异:对话模型版本里我放了一条 system 指令,告诉它“先通读,再按条款走查”,这对 deepseek-chat 是有效的;推理模型版本我直接去掉了 system 消息,只留任务和输出格式。原因是 deepseek-reasoner 对“怎么做”的指令非常敏感,一旦它认为你在规定流程,就会牺牲自己的推理路径去迎合你的流程。另一个差异是 max_tokens:同样的任务,推理模型需要更大的上限,因为它要在同一个生成序列里“先想后答”,我在线上一般直接给对话模型的 1.5 到 2 倍。
2.3 推理模型的三个关键指标:首字延迟、推理耗时、输出一致性
把推理模型接进生产环境,评估指标和对话模型不完全一样。对话模型看吞吐和首字延迟就够了,推理模型还要多关注两件事:推理耗时和输出一致性。下面这是我在项目里实际盯的三个指标。
| 指标 | 含义 | 对提示词的影响 |
|---|---|---|
| 首字延迟 TTFT | 请求发出到收到第一个 token 的时间 | 提示词里的长背景、大段落 few-shot 会显著推迟首字;任务复杂度也直接影响这个值 |
| 推理耗时 | 模型内部思考链消耗的时间与 token 数 | 提示词里的冲突指令会让推理链变长,比如让它“先按 A 再按 B 分析” |
| 输出一致性 | 相同输入多次输出的稳定程度 | 推理模型内部有采样随机性,同一提示词可能给出不同结构的结果 |
TTFT(Time To First Token)是推理模型最直观的体验指标。用户发出一个请求,半天没动静,产品上就会觉得“卡了”。我在线上用 stream=True 把首字时间从 3 秒到 8 秒的波动,优化成了固定等待的“打字机效果”,体感改善明显。但注意,这只是遮羞布——真正治本的是把输入长度压下来,这个放在后面避坑章细说。
3. DeepSeek 提示词工程落地:API 调用与场景化参数设置
3.1 最小调用代码:把 deepseek-reasoner 接进业务线
DeepSeek 的 API 兼容 OpenAI 的协议,这意味着你不需要引入新的 SDK,直接用 openai 库换 base_url 就能工作。最小调用代码比想象中短,但有几个参数必须一次性配对,否则上线后要反复改。
import os from openai import OpenAI client = OpenAI( base_url="https://api.deepseek.com", # 如果报 404,改成 https://api.deepseek.com/v1 api_key=os.getenv("DEEPSEEK_API_KEY"), timeout=60.0, # 推理模型耗时是秒级起步,别用默认 10 秒 max_retries=2, ) resp = client.chat.completions.create( model="deepseek-reasoner", messages=[ {"role": "user", "content": "把下面的需求拆成数据库表结构,输出 DDL,不要解释:……"} ], max_tokens=8192, stream=False, ) print(resp.choices[0].message.content)参数说明:base_url 填 https://api.deepseek.com 或者带 /v1 都有人用,我的经验是优先填不带 /v1 的官方地址,如果客户端版本较老出现 404,再补 /v1。timeout 是第一个要改的参数,默认值通常只有 10 秒,而 deepseek-reasoner 处理中等难度任务时,推理阶段就可能花 20 到 40 秒,提前超时会让业务端误判为失败。max_retries 不要设太大,推理模型的重复请求会成倍消耗账号额度,2 次重试已经是上限。
另外,如果你是把 DeepSeek 接进企业微信这类 IM 机器人,记得在系统提示词里强制要求“输出纯文本,不要 Markdown,不要表格”。推理模型生成的表格在微信里会被渲染成一坨乱码,这算是提示词工程里最容易忽略的落地细节。
3.2 参数取舍:temperature、max_tokens 与推理预算
推理模型的参数和对话模型是同名的,但语义发生了偏移,尤其是 temperature 和 max_tokens。下面是我在实际项目中固定下来的参数基线,可以直接作为起点。
| 参数 | 推荐设置 | 说明 |
|---|---|---|
| temperature | 保持默认,不手动调低 | deepseek-reasoner 内部已经有采样策略,调低不会提高稳定性,反而可能让它思考不充分 |
| max_tokens | 对话模型的 1.5 到 2 倍 | 内部推理 token 和最终回答 token 共用这个上限,设太小会截断在思考链里,导致“答案没说完” |
| stream | 推荐 True | 推理阶段没有 token 输出,开启流式后虽然前端还是会等待,但至少能看到连接是活的 |
| timeout | 60 秒以上 | 不能按对话模型的 10 秒习惯来,任务越难,推理耗时越长 |
关于“推理预算”这个概念:推理模型内部有一个类似思考深度控制的机制,DeepSeek 这边没有直接开放专门的预算参数,但可以通过 max_tokens 和提示词里的复杂度要求来间接控制。比如同一个分类任务,你在提示词里写“只输出类别,不要分析”,它的推理链会明显变短;如果写“先分析再下结论”,推理耗时可能翻倍。预算控制不是调一个旋钮,而是靠提示词约束思考范围,这是很多人忽略的点。
3.3 上下文工程:系统提示词、任务文本与 skill/agent 的分工
提示词工程发展到今天,已经不只是“写一段话塞进 system”了。更准确的说法是上下文工程:把系统提示词、任务文本和外挂的能力(skill、工具调用)分开管理。很多人问“系统提示词工程和 skill agent 有什么区别”,我的理解是:系统提示词定义的是不变的策略和边界,skill/agent 定义的是可复用的动作流程,两者混在一起是常见的翻车点。
system_prompt = """ 你是客服质检分析助手。 策略:只分析用户消息中的情绪与诉求,不评价客服表现。 边界:不输出任何个人信息,不输出原始聊天记录。 格式:JSON,字段 fixed:sentiment(positive/negative/neutral)、request_category。 """ task_prompt = """ 输入客服会话: {"user": "你们物流也太慢了,三天了还没到!", "agent": "先生您好,我帮您查一下……"} """ resp = client.chat.completions.create( model="deepseek-reasoner", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": task_prompt}, ], max_tokens=2048, )这个例子里,system 提示词只放“不可变策略”,任务文本放“本次输入”,而真正的质检规则、敏感词表、工单流转动作则由外部代码和 skill 去执行,不塞进大模型上下文。按照这条线去拆,系统提示词会越来越薄,但效果反而更稳。把可枚举的规则写进提示词是大忌——那些规则本应写在代码里或检索库里,写进提示词只会让推理模型在互相冲突的约束间打转。
4. 从 API 到产业部署:本地部署、vLLM 服务化与开发工具接入
4.1 先算账:API 与本地部署的成本与延迟权衡
产业落地第一步不是选模型,是选部署形态。同一个 DeepSeek 推理模型,走官方 API 和本地部署,成本和体验是两个极端。先算明白这笔账,再决定要不要自建推理服务。
| 维度 | 官方 API | 本地部署(vLLM + 蒸馏模型) |
|---|---|---|
| 启动成本 | 几分钟接入 | 需要至少一张 24GB 以上显存的 GPU |
| 数据合规 | 数据出内网 | 数据不出内网,适合政务、医疗、金融 |
| 首字延迟 TTFT | 波动较大,取决于服务端负载 | 自控,但小显存下会明显偏高 |
| 单位成本 | 按 token 计费,推理 token 也收费 | 一次性硬件投入加电费,量大时更划算 |
需要特别提醒:deepseek-reasoner 的计费不只是按“回答字数”算的,内部推理生成的 token 同样计入账单。我在项目里见过一个只看输出字数的成本预估,上线后实际账单超出预算三倍——原因是用户每次提问,模型都先花几百个 token 思考。要做成本估算,一定要先把“推理 token 占比”加进去,建议先跑一周日志,统计真实 token 消耗再定价。数据合规要求高的场景,本地部署不是选择题而是必答题,下面这份部署流程是按 vLLM 的常见做法整理的。
4.2 用 vLLM 把 DeepSeek 蒸馏模型部署成本地服务
本地部署 DeepSeek,最常见的开源推理服务框架是 vLLM。它把 OpenAI 兼容接口直接暴露出来,业务端只需要改一行 base_url。部署命令如下:
# 安装 vLLM(建议在 Python 3.10+ 环境) pip install vllm # 启动推理服务,模型用 R1 的 Qwen 蒸馏版 vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \ --dtype bfloat16 \ --max-model-len 32768 \ --gpu-memory-utilization 0.9 \ --port 8000 \ --served-model-name deepseek-reasoner参数说明:--max-model-len 是上下文上限,蒸馏模型本身支持长上下文,但如果显存只有 48GB,把上限压到 16384 或 8192,能显著降低首字延迟和显存占用,线上常见的做法是“按业务实际需求裁剪,而不是按模型最大值配置”。--gpu-memory-utilization 设置为 0.9 是给驱动和并发请求留余量,多卡场景建议降到 0.85。--served-model-name 是关键,它让本地服务对外暴露的模型名和官方 API 保持一致,这样业务端切换时只需要改 base_url 和 api_key,不用改任何业务代码。
启动之后,原来的 OpenAI 客户端代码里 base_url 改成 http://localhost:8000/v1 即可。如果你部署的是小参数量蒸馏模型,比如 7B 或 14B 级别,还可以在这台机器上同时跑量化版本(INT4 或 INT8),显存占用直接砍半。像 Jetson Orin 这类边缘设备上跑推理模型,目前可行方案就是“小蒸馏模型 + INT4 量化 + 压低 max-model-len”,不要去试 32B 甚至更大参数的模型,TTFT 会突破用户忍耐极限。本地部署适合对延迟要求高、数据敏感的场景,但换来的是你要自己处理并发排队、显存溢出和日志监控,运维成本不会低。
4.3 开发工具链路接入:Codex、Claude Code 与多智能体编排框架
产业落地的另一条常见路径是把 DeepSeek 接进开发工具和 Agent 框架。Codex CLI 和 Claude Code 这类工具都支持通过环境变量改写模型接入点,配置思路完全一致:指向 DeepSeek 的 OpenAI 兼容接口。
# Codex CLI 接入 DeepSeek export OPENAI_API_KEY="sk-xxxx" codex config set api_base_url https://api.deepseek.com codex config set model deepseek-reasoner # Claude Code 接入 DeepSeek(走 Anthropic 兼容层时) export ANTHROPIC_BASE_URL="https://api.deepseek.com" export ANTHROPIC_MODEL="deepseek-reasoner"配置说明:Codex 和 Claude Code 这类 agent 工具在调用模型时,不会只发一次请求,它们会反复对话、调用工具、读取文件,整个会话里的 token 消耗比单次问答高一个数量级。所以接入前先确认账号余额和限流策略,不然很容易在半小时内把日配额打光。
Agent 场景里,推理模型更适合做“规划大脑”,而不是每个环节都交给它。类似 DeepSeek Harness 这样的多智能体编排框架,常见做法是让 deepseek-reasoner 负责拆解任务和决策,让轻量模型或外部工具负责检索、格式化和执行动作,避免每个节点都触发一次深度推理,否则一次任务的耗时会被累加成分钟级。另一个硬性要求:agent 框架在调用工具后,必须立即把工具结果回传给模型;如果 messages 里夹带一大段历史对话再回传,推理模型会因为上下文过长而长时间无响应,严重的会直接触发超时错误。这个场景下,控制 messages 长度比提示词质量还重要。
5. 推理模型落地避坑:5 个从线上翻车里总结的教训
5.1 现象:提示词里写了“请一步步思考”,结果响应又慢又差
某次客服工单分类需求,我把详细的分析步骤写进了提示词,上线后准确率反而比 baseline 低了 8 个百分点,响应时间翻倍。原因:推理模型把“一步步思考”当成输出要求,在回答里复述推导过程,干扰了它原有的推理链。解决:删掉所有描述思考过程的句子,只保留“任务、约束、输出格式”三段。我现在的规范是提示词里禁止出现“思考”“分析”“逐步”这类动词。
5.2 现象:思维链像黑匣子,解释不了模型为什么翻车
人工审核时发现模型把一个标点异常的合同判为“无风险”,但没人能说清判断依据。原因:推理模型的思考链默认不完整对外暴露,运营侧只能看到结果,无法定位是提示词问题还是模型能力问题。解决:在提示词末尾加一条“输出关键依据”,让每条结论都带一句话理由——比如“依据合同第 7 条第 2 款”,这在可解释性要求高的行业几乎是硬性需求,代价是每个回答多消耗几十个 token,但值得。
5.3 现象:tool call 之后长时间无响应,直到超时报错
Agent 框架里,模型返回了一个工具调用结果,框架去执行完工具后,把一段很长的历史消息连同工具结果一起回传,结果模型迟迟不给最终回复。原因:消息列表里既有 history 又有工具输出,上下文长度暴涨,推理模型的预填充时间被拉长到秒级甚至分钟级,触发 LLM 服务端的超时限制。解决:收到 tool call 后立即把工具结果作为 user 消息传回,不要把整段对话历史再送一遍;对不需要模型关注的历史做截断或摘要。在不少 agent 框架里,这条规则直接决定一个任务能不能跑完。
5.4 现象:首字延迟 TTFT 飙升,长文档把用户等没
金融场景里需要模型分析一份五十页的 PDF,用户点击“分析”之后等了四十秒没看到任何反馈,直接关闭页面。原因:长文档的预填充本身就耗时,推理模型还要在读完文档后再思考一轮,首字延迟被叠加放大。解决:不要直接把整份文档塞给推理模型。先用对话模型或检索模块抽取出关键段落,再交给推理模型做判断。另一种补救是用 stream=True 配合前端流式输出,至少让用户看到“正在生成”,但这只是缓解体感,真正的优化是减少输入长度。
5.5 现象:系统提示词越长越好?两千字约束压坏了推理
为了做合规,往系统提示词里堆了两千字规则和案例,结果模型频繁输出“根据规则 17 无法判断”之类的话。原因:推理模型对相互冲突的约束极度敏感,超长系统提示词里任何两条规则存在语义重叠,都会让它进入无休止的内部权衡,推理 token 消耗暴增。解决:系统提示词压到两百字以内,只保留不可变红线;可枚举的规则、名单、案例全部外置到检索库或代码逻辑里。提示词是给模型划边界用的,不是给它装知识的——装知识用 RAG,这句话写进团队规范后,这类问题少了八成。
6. 验证推理模型的产出质量:不靠感觉的回归检查方案
6.1 固定用例集与三组指标
每次改完提示词,不能只拿一两个例子“肉眼验收”,那和掷骰子没区别。我把线上真实请求抽了四十条,按难易程度分成三层,组成固定用例集,每次变更后跑回归。指标只看三组:首字延迟 TTFT、总耗时、结果格式可用率。格式可用率很重要——我遇到过提示词改动后模型开始偶尔漏字段的情况,肉眼根本看不出来,但下游入库直接失败。
6.2 回归检查的最小实现
import json import time from openai import OpenAI client = OpenAI( base_url="https://api.deepseek.com", api_key="sk-xxxx", timeout=120, ) cases = [ {"name": "simple_10", "prompt": "1+1=?", "expect": "2"}, {"name": "contract_01", "prompt": "审查合同,输出JSON风险列表", "expect": "risks"}, ] def check_case(case): t0 = time.time() resp = client.chat.completions.create( model="deepseek-reasoner", messages=[{"role": "user", "content": case["prompt"]}], max_tokens=4096, stream=True, # 流式拿首字时间 ) first_token_time = None content = "" for chunk in resp: if not first_token_time: first_token_time = time.time() - t0 content += chunk.choices[0].delta.content or "" return { "name": case["name"], "ttft": round(first_token_time, 2), "total": round(time.time() - t0, 2), "ok": case["expect"] in content, } for case in cases: print(json.dumps(check_case(case), ensure_ascii=False))这段脚本把每个用例的 TTFT、总耗时和是否包含期望关键词全部打印出来。我做提示词变更时,要求 TTFT 不超过上一次基准的 1.5 倍,格式字段一个不能漏,否则不进发布。这套回归脚本已经在项目里跑了大半年,最大的价值不是测 bug,而是让我在改提示词时敢下手——改坏了能立刻知道,改好了也能量化出效果。
我自己的习惯是每次只改一个变量,要么删一段 system 提示词,要么动输出格式模板,改完就跑回归,用数据说话。这比任何人拍胸脯保证“这版效果更好”都可靠。希望这套思路帮你也少踩几个坑。
本文还有配套的精品资源,点击获取