拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DeepSeek提示词工程实战:从生成机制到API落地与避坑

DeepSeek提示词工程实战:从生成机制到API落地与避坑

简介:北京大学DeepSeek系列讲座之《提示词工程和落地场景》PPT,梳理了DeepSeek-R1的核心能力、技术优势与实用方法。内容涵盖模型思考过程可视化、开源低成本国产化三大特点、火爆原因分析,以及官方APP、网页端、API三种直接使用方式。配套讲解提示词技巧如何突破工具表层应用,将专家思维迁移到学习、工作和垂直行业场景中,适合希望零基础上手大模型、提升人机协作效率的普通用户与AI应用开发者。资源为1个pptx演示文稿,压缩包大小808KB,页面结构完整,包含DeepSeek原理拆解、应用渠道对比、私有化部署方式及参考文献指引,可直接用于讲座复盘、内部培训或自学梳理。已有376人学习,对快速理解DeepSeek提示词工程和落地场景具有较高参考价值。

1. 提示词工程不是“把话说清楚”,而是把模型的推理边界画出来

做提示词工程和落地场景,最容易被误解的一点是:以为提示词写不好,是因为话没说明白。我接手过不少 DeepSeek 相关项目,真正的问题从来不是“模型听不懂”,而是“模型太会猜”。你给它一句含糊的指令,它会用最自信的语气编一个最合理的答案。提示词工程要解决的,不是让模型更聪明,而是让它在你的业务边界内输出,少发挥、少脑补、多按规矩办事。这篇笔记我按自己实际跑过的方案来讲,从 DeepSeek 的生成机制、提示词结构、API 落地到排查翻车,把能直接复用的写法和参数都摊开。

2. 提示词工程的第一性:先搞懂 DeepSeek 怎么“读”你的话

2.1 从补全到对话:DeepSeek 的生成机制决定了提示词要怎么写

DeepSeek 这类大模型,本质是一个超长的文本补全器。你在对话框里发的内容,会连同历史消息一起拼成一段上下文,模型从这个上下文往后续写。它没有“理解”你的意图,它只是在计算下一个最可能的 token。这一点决定了提示词工程的核心思路:不要指望模型主动体察你的言外之意,要把言外之意写进上下文里。

我一般会把提示词分成三层来看。第一层是系统提示词,通常放在对话最前面,用来设定角色、目标和全局约束;第二层是用户消息,承载具体任务和材料;第三层是历史对话或工具返回结果,决定模型的短期记忆。绝大多数翻车,问题不在第二层,而在第一层和第三层。系统提示词写得像散文,模型越到后面越容易“忘”;历史消息塞了太多无关内容,模型会把噪声当成线索。

所以写提示词之前,先回答三个问题:模型需要扮演谁、需要做什么、不能做什么。把这三个答案写清楚,比堆砌“你是一个优秀的人工智能助手”有用得多。角色设定要给行为约束,例如“你是售后客服,只根据知识库内容回答,知识库里没有的内容直接说明不知道”,不要只给身份不给规则。

2.2 系统提示词、上下文工程和 Skill Agent 的分工边界

很多人分不清系统提示词、上下文工程和 Skill Agent 的区别,我在团队里也经常被问。简单说,系统提示词是静态约束,每次请求都会原样带上,描述模型在整场对话里的行为准则;上下文工程是动态管理,解决“哪些内容该进上下文、哪些不该进、按什么顺序进”;Skill Agent 则是把提示词、工具调用和决策逻辑打包成一个可复用的智能体单元,类似 DeepSeek harness 里那种多智能体编排的方式。

三者的分工可以用一句话概括:系统提示词定边界,上下文工程管记忆,Agent 编排控流程。如果你的任务是一次性的文本处理,写好系统提示词和用户消息就够了,不需要引入 Agent。如果任务是多步骤的,比如先查资料再写报告,就要考虑用 Agent 或工具调用来拆分,而不是把所有步骤压进一条提示词里。

我见过一个典型误用:有人为了让模型“更聪明”,把几十条规则全部塞进系统提示词,结果模型在长对话后半段开始无视规则。问题的根源不是规则写得不好,而是上下文太长,模型注意力被稀释。这类问题的解法不是继续加规则,而是把规则精简到十条以内,把决策点拆出去,用代码判断或工具调用来替代。

2.3 一个能直接套用的最小提示词模板和参数配置

下面这个模板是我在多个场景里反复用过的,适用于大多数文本生成、信息抽取和问答类任务。它的结构很简单:角色、背景、任务、约束、输出格式。

你是{角色}。 背景:{业务场景一句话} 任务:{要模型完成的动作} 约束: 1. 只基于给定材料回答,不得自行补充外部知识 2. 不确定时输出“信息不足”,不要编造 3. 不要输出与任务无关的内容 输出格式:{JSON 结构或条目列表} 材料: {用户输入}

这套模板看起来平淡,但每个部分都有明确的工程意图。角色设定了回答的立场,背景给模型提供了判断语境的锚点,任务必须是动词开头的具体指令,约束用来压制幻觉和多话,输出格式决定了后续程序能不能直接解析。模板的顺序不要随意打乱,因为模型对靠前内容的注意力更强,角色和约束放前面比放后面更有效。

参数配置上,我通常用这样的起步值:temperature 0.3 以下用于抽取、分类、格式化输出,0.7 左右用于文案生成和头脑风暴,top_p 保持默认或随 temperature 联动。max_tokens 要根据输出格式估算,不要让模型在长输出中途被截断。如果你在用 API,建议把 response_format 设为 JSON,能显著提高结构化输出的稳定性,后面第四章会专门讲调用方式。

3. 动手写提示词:把思路落成可复现的指令

3.1 用“角色-任务-约束-输出格式”四段式搭骨架

上一章给了一个最小模板,这一章讲怎么把业务需求翻译成提示词。我习惯用“角色-任务-约束-输出格式”四段式搭骨架,原因很简单:它强迫你把模糊的需求拆成模型可以执行的操作。

先写角色。角色不是装饰,它决定了模型调用哪部分知识。同一个问题,“请解释什么是幂等性”和“你是一名系统架构师,请向初级开发解释什么是幂等性”,后者的输出在术语深度和表达方式上都会不同。角色描述要具体,最好带上行业和职级。

再写任务。任务要避免“请帮我分析一下”这种空泛写法,换成“请从这段日志中提取错误码、发生时间和影响范围”。任务的每个动词都对应一种输出,提取对应结构化结果,改写对应文本重写,判断对应结论加理由。

然后是约束。约束是防幻觉和防跑题的关键。常见的约束包括:只基于给定材料、不要输出思考过程、不确定时直接说不知道、禁止重复材料中的无关内容。约束不要超过五条,太多约束会互相打架,模型会为了满足某一条而牺牲另一条。

最后是输出格式。如果你要接程序,直接给 JSON 结构示例;如果要给人看,给分条列表的示例。模型对格式的遵循能力比你想象的要强,只要你在提示词里给了明确的格式范例,它就很少跑偏。反过来,如果你只写“结构化输出”,模型会按照它对“结构化”的理解自由发挥。

3.2 给模型“思考空间”:复杂任务用步骤化指令而不是催它给答案

场景一复杂,直接把结果丢给模型,它常常会跳步骤、合并问题、省略中间推导。这是我做提示词工程时踩得最深的坑之一。后来我发现,对复杂任务,与其催它直接给答案,不如把步骤写进提示词,让模型一步步来。

做法是在任务描述里加上步骤编号:

任务:判断用户的退款申请是否符合规则。 步骤: 1. 从用户描述中提取订单号、申请原因、商品类目 2. 对照规则表中对应的退款条件 3. 列出符合和不符合的条款 4. 给出结论:同意退款 / 拒绝退款 / 需要人工复核

这个写法利用的是模型在逐token生成时的自注意力机制:分步指令让模型在每一步生成的文本,都会成为下一步的上下文,相当于强迫它先思考再落结论。你还可以在提示词里加一句“请先列出你的判断依据,再输出结论”,效果类似。

但这里有个边界:步骤化指令只对逻辑可拆解的任务有效。对创意写作、情感分析这类任务,强行分步骤反而会限制输出质量。我的原则是,任务越接近“判断题”或“计算题”,越适合分步;任务越接近“开放题”,越应该少给步骤,多给风格和样例。

另外注意,分步思考不等于把模型内心想法全量输出。如果输出要给人看,你可以在提示词里注明“只输出最终结论,不要输出分析过程”,这不会影响模型的内部推理,但会让最终文本干净很多。

3.3 用示例和边界条件约束输出:从“能跑”到“稳定跑”

提示词工程里,最容易被低估的技术是示例(few-shot)。一段干巴巴的规则,模型可能理解,但执行起来会有偏差;给它一个正面例子和一个反面例子,它立刻能对齐你的预期。

我举个例子。做评论审核分类,直接写“判断评论是否涉及人身攻击”,模型会把“你就是个笨蛋”和“这个功能太蠢了”都判成攻击。加上示例就好很多:

请判断以下评论是否属于人身攻击,只输出“是”或“否”。 示例1: 评论:这个作者水平太差,完全是外行在误导人。 输出:是 示例2: 评论:这篇文章的逻辑我没看懂,但数据看起来不太对。 输出:否 待判断: 评论:连基本语法都写不对,还好意思发教程。

示例的关键是边界贴近你的真实业务。你要覆盖最容易误判的那类输入,而不是给几个无关痛痒的样例。通常两个正面加两个反面就够,多了会占用上下文,还可能出现示例彼此矛盾的问题。

边界条件也要写清楚。比如“当输入长度超过模型窗口时截断策略是什么”“当材料内容为空时怎么回复”“当用户问题与角色无关时怎么处理”。这些边界条件看起来是小事,但生产环境里模型被问住的情况,绝大多数落在你没有定义过的边界上。把边界提前写进提示词,比事后写代码兜底要省事得多。

4. 调用 API 落地场景:从提示词到可交付功能

4.1 DeepSeek API 调用:最小可运行代码与参数说明

提示词写得再好,如果调用方式不对,落地一样失败。DeepSeek 的 API 走的是 OpenAI 兼容格式,这意味着你之前写的认知可以无缝迁移。下面是最小可运行代码,我一般用 Python 和 requests 直接调,不引额外包,方便在任何环境里跑通。

import requests payload = { "model": "deepseek-chat", "messages": [ {"role": "system", "content": "你是售后客服,只根据知识库回答。"}, {"role": "user", "content": "订单号 123456 什么时候发货?"} ], "temperature": 0.2, "max_tokens": 500, "stream": False } resp = requests.post( "https://api.deepseek.com/chat/completions", headers={ "Authorization": "Bearer 你的API密钥" }, json=payload, timeout=60 ) data = resp.json() print(data["choices"][0]["message"]["content"])

这段代码的逻辑很直接:构造 messages 列表,系统消息决定模型角色,用户消息承载实际请求,然后 POST 给 chat/completions 接口。返回的数据结构中,choices 数组里取第一个元素的 message.content,就是模型生成的文本。

参数说明上,temperature 控制随机性,0.2 适合客服、抽取这类低容错任务;max_tokens 限制生成长度,注意它算的是输出 token,不是字数,中文通常一个汉字约一个 token。timeout 我习惯设 60 秒以上,因为 DeepSeek 在长上下文或复杂任务下响应时间可能超过 30 秒。另外,如果你接入的是 codex 之类的工具链,DeepSeek API 的 OpenAI 兼容格式让这类接入成本很低,换 base_url 和密钥就能跑通。

4.2 用 JSON 模式和工具调用把提示词接进业务逻辑

文本接进业务,不能靠人去读模型输出,要让程序直接解析。JSON 模式是首选方案。在请求体里加入 response_format 参数,模型就会尽量输出合法 JSON。

payload = { "model": "deepseek-chat", "messages": [ {"role": "system", "content": "你是信息抽取助手。"}, {"role": "user", "content": "从以下投诉中抽取原因和期望:\n'我买的充电器三天就坏了,客服让我自己寄回去修,太麻烦了,希望直接换新。'"} ], "response_format": {"type": "json_object"}, "temperature": 0.0 }

加了 response_format 之后,输出会用 JSON 包起来,例如返回 {"原因": "充电器质量问题", "期望": "直接换新"}。这个模式必须在提示词里明确告诉模型要输出 JSON 的字段结构,否则它不知道往 JSON 里塞什么。我的经验是在提示词里加一行“输出格式:{"字段1": "@#,字段2": "@#}”,给一个空壳模板,模型会照着填。

工具调用(function calling)是更进阶的玩法。它的逻辑是:模型不直接生成最终答案,而是生成一个函数调用请求,你的程序执行函数后把结果再传给模型。这解决了一个关键问题——模型没有真实数据访问能力,通过工具调用可以把数据库、API、计算逻辑接进来。DeepSeek 支持 OpenAI 兼容的 tools 参数,定义方式和 API 调用方式都很标准,但这块不建议新手一上来就碰,先把普通提示词和 JSON 模式跑稳再上工具调用。

4.3 落地场景拆解:客服、写作、代码三个方向怎么改提示词

落地场景不同,提示词的侧重点完全不同。拿客服场景来说,核心诉求是安全、不捏造。系统提示词里要写“只基于知识库回答,知识库无答案时直接说需要转人工”,温度调到 0.2 以下,同时用工具调用把订单查询接口接进来,让模型在回答前先拿真实数据。

写作场景相反,核心诉求是风格稳定。temperature 调到 0.7 到 0.9,提示词里给足风格示例,约束部分要少一点,只限制“不写空话、不使用重复句式”。这里最容易翻车的是:把写作任务当成抽取任务,温度设太低,结果生成出来的文字干巴巴,像在念说明书。

代码场景介乎两者之间。生成代码时 temperature 用 0.2 比较合适,太高会编出不存在的方法名。提示词里要给出编程语言、依赖版本、输入输出示例和约束条件。比如“用 Python 3.10 写一个函数,输入是列表,输出是去重后的列表,保持原顺序,不要用第三方库”。你给的信息越接近一个需求单,模型生成的代码越能直接跑。

5. 提示词落地避坑:5 个真实翻车现场和排查方法

5.1 输出不稳定:温度越高,幻觉越“自信”

现象是同一个提示词连续调用,结果有时候对有时候错,错的时候模型语气特别肯定。我最早做客服机器人时,模型偶尔会把知识库没有的信息说得像真事,最离谱的一次是给用户编了一个不存在的退款政策。

原因很直接:temperature 设太高,模型在概率分布里选了更“有创意”的路径。温度越高,低概率 token 被选中的机会越大,模型就越倾向于编造细节来让回答显得完整。它不是不知道答案,而是被允许“即兴发挥”。

解决方法是把温度压在 0.2 以下,同时把“只基于知识库回答”写进系统提示词,再加上一条“信息不足时直接说不知道”。如果业务允许,干脆把温度设 0,得到可重复的输出,方便做回归测试。

5.2 系统提示词被忽略:上下文一长,早期指令被稀释

现象是多轮对话进行到十几轮之后,模型开始违背系统提示词,比如不再遵守“不要提及竞品”,或者回答风格越来越随意。起初我以为是模型“忘性大”,后来发现是上下文太长导致的注意力稀释。

原因在于模型处理超长上下文时,对早期内容的关注度会下降,尤其是当中间夹了大量用户消息和工具返回结果时,系统提示词的相对权重会被摊薄。这不是 DeepSeek 特有的问题,所有长上下文模型都有。

解决方法是三管齐下:精简系统提示词,只留不可妥协的底线规则;定期截断或总结历史对话,把无关内容移出上下文;在关键节点把系统提示词重新插入用户消息里,比如每次用户发新问题时,程序先拼上“提醒:你仍需遵守如下底线规则”再发送。

5.3 “工具调用需要立即结果”报错:多轮 tool call 的时序问题

现象是接入工具调用后,模型报错。错误信息大意是“本轮运行失败,消息中的工具调用需要立即返回结果”,也就是 DeepSeek 模型发出了工具调用请求,但客户端没有在下一轮消息里立刻补充工具结果,而是又发了一条用户消息或系统消息,导致请求格式不符合要求。

原因是对 OpenAI 兼容工具调用的规则不熟:当模型返回 tool_calls 字段时,你必须在下一轮请求里按顺序把所有 tool_calls 对应的 tool 角色消息补齐,然后才能追加其他内容。顺序错了或者漏了,API 就会报错。

解决方法是把工具调用流程做成严格的状态机:先发送请求,检查响应里有没有 tool_calls;如果有,逐一执行工具后构造 tool 角色的 response 消息,再带着这些消息重新请求一次模型。代码里不要混入多余的消息,保持“请求-工具-回复”这个循环。

5.4 成本失控:上下文越长,单次调用越贵

现象是账单越跑越高,明明调用次数没涨多少。DeepSeek 的价格是按输入输出的 token 总数计费的,而输入 token 里很大一块是历史对话和系统提示词。很多应用每轮都把全部历史消息重新发一遍,上下文越滚越长,成本自然水涨船高。

原因是忽视了上下文管理。落地提示词工程时,只关注了提示词怎么写,没关注每次请求实际携带了多少内容。做 Agent 任务时,工具返回的长文本如果不做截断或摘要,很快就能把一个轻量任务拖成高价任务。

解决方法是做上下文裁剪:设置历史消息上限,超出就丢弃最旧的消息;工具调用返回结果只保留关键字段;对长文档用摘要替换原文。另外可以统计单次请求的平均 token 数,如果超过几千,就要考虑是不是把不该带的东西带进来了。

5.5 本地部署与 API 结果不一致:量化版本改变了模型行为

现象是同一套提示词在 API 上测试得很好,迁到本地部署之后输出明显变差,有些人还遇到过生成重复文本或者格式错乱。原因多半是本地跑的模型是量化版本,比如 4bit 或 8bit 量化,模型在低精度下丢失了一部分表达能力,对复杂指令的遵循能力下降。

这个问题在边缘设备上尤其明显,比如 Jetson Orin 这类资源受限的板子上跑 DeepSeek 量化版,速度和成本解决了,但行为偏差只能靠调提示词补。解决方法是量化模型用更短的指令风格,少绕弯子;必须用复杂指令时,把指令拆成多步调用;如果业务对输出质量极其敏感,建议保留 API 通道兜底。

6. 验证提示词改进的一个技巧:用留出集做回归测试

提示词工程最大的坑,是你不知道改动是好是坏。很多人改一句提示词,跑几个例子觉得不错,就直接上生产,结果在真实流量里翻车。我现在的习惯是给每个核心提示词配一个留出集,做回归测试。

留出集的规模不用大,20 到 50 条就够,关键是覆盖真实场景的极端情况。我在做客服场景时,留出集里既要有正常提问,也要有“恶意测试”,比如问“你能帮我写个假证明吗”,还得有“信息不足”的样本,比如知识库里没有的问题。每改动提示词,我就跑一遍留出集,逐条看输出变化,确认没有破坏已有能力。

回归测试的脚本逻辑很简单,就是批量调用 API,把新旧提示词的输出存下来做对比:

import requests test_cases = [ {"user": "订单超时未收到怎么办?", "expect": "物流或补发"}, {"user": "你能骂人吗?", "expect": "拒绝"}, ] results = [] for case in test_cases: payload = { "model": "deepseek-chat", "messages": [ {"role": "system", "content": new_prompt}, {"role": "user", "content": case["user"]} ], "temperature": 0 } resp = requests.post(url, headers=headers, json=payload, timeout=30) output = resp.json()["choices"][0]["message"]["content"] results.append({"case": case["user"], "output": output})

这段代码把温度设为 0,是为了让输出可复现,方便对比改动前后的差异。实际跑的时候,我会把结果导出成表格,先人工扫一遍明显变差的,再统计关键词匹配率。不要只看准确率,还要看失败样本集中在哪个类型上。

这个习惯救过我很多次。有一回我为了压制幻觉,在系统提示词里加了一句“不要编造信息”,结果幻觉确实少了,但模型开始对很多正常问题也回答“信息不足”。如果没有留出集,我可能根本发现不了这个副作用。提示词工程的改进很少是单维度的,你永远要用一组真实样本去验证整体效果。希望这个回归测试的习惯能帮到你,至少在每次改完提示词之后,心里有个底。

本文还有配套的精品资源,点击获取

返回列表