ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

DeepSeek实战全解:从API接入、提示词工程到智能体开发

DeepSeek实战全解:从API接入、提示词工程到智能体开发 简介由清华大学新闻与传播学院新媒体研究中心元宇宙文化实验室团队编写的《DeepSeek从入门到精通》是一份104页的PDF技术指南适合希望系统掌握DeepSeek提示语设计与应用技巧的AI使用者、内容创作者及研究者。压缩包内含1个PDF文件约6.45MB已吸引3049人学习下载。文档从DeepSeek-R1的文本生成、语义理解、代码生成等核心能力切入对比推理模型与通用模型的差异重点讲解提示语设计策略、元素组合矩阵、常见陷阱与应对方法并完整介绍提示语链的CIRS模型、SPECTRA模型以及逻辑链、知识链、创意链三链融合思路。还涵盖气候变化文章撰写、智能家居产品设计等实战案例帮助读者从基础使用进阶到创新应用实现从‘使用者’到‘创新者’的转变。内容完整、结构清晰不同层级的读者均可按需学习。1. 清华这份 104 页 PDF 究竟在讲什么一份能照着走的 DeepSeek 学习地图2025 年初一份标注清华大学出品、整整 104 页的《DeepSeek从入门到精通》PDF 在技术社群和网盘里被转疯了。大部分人的第一反应是先存进收藏夹吃灰但真正做应用的人关心的问题是这份材料把 DeepSeek 讲到了哪个深度照着走能不能真的落到项目里它的定位不是模型原理科普也不是官方文档的翻译版而是从网页聊天、API 接入、提示词工程一路延伸到工作流集成的一条完整路线。这篇文章我就沿着这条路线把每一层该怎么做、参数怎么设、哪些环节容易翻车用我能直接复现的方式讲清楚。适合刚接触 DeepSeek 的开发者也适合想把它接进内部系统的产品和技术负责人。2. DeepSeek 的能力边界与上下文工程动手前先搞懂这三件事2.1 能力边界R1 强在推理通用任务别用错模型DeepSeek 在 API 层面对外提供两个主要模型名deepseek-chat和deepseek-reasoner。这俩对应的是底层不同的模型行为差异非常大。很多人刚上手时只用默认配置结果在同一道题上得到完全不同的体验就开始怀疑自己提示词没写对其实问题多半出在选型上。deepseek-reasoner的特点是会在正式回答前生成一段内部推理链适合数学证明、代码调试、逻辑谜题这类需要多步推导的任务。代价也很明显首字延迟高整段输出更长单价更贵。而deepseek-chat更偏通用对话和文本处理日常问答、内容改写、信息抽取、结构化输出都比 reasoning 模型来得干脆。我做过一次对比同一个 Prompt 要求做会议纪要抽取chat 模型 3 秒返回干净结果reasoner 光思考就花了 20 多秒输出里还带一大段推理过程反而增加了解析成本。还要记住一个边界DeepSeek 是纯文本模型不支持图像输入。网上不少人拿它做票据识别翻车的原因不是模型笨而是图片里的信息根本没有喂进去。凡是要处理图片 PDF、截图这类材料必须先做 OCR 转成文本再送进模型这一点在后面文档处理章节还会展开。2.2 提示词工程把「角色、任务、材料、约束、输出格式」写进第一轮104 页资料里占比最大的部分就是提示词这也是很多人觉得看了就会、用了就废的地方。我的经验是与其记一堆花哨的提示词技巧不如先把一个稳定模板跑通再往里面加变化。这个模板的顺序是有讲究的DeepSeek 对指令位置比很多模型更敏感越靠前的指令权重越高。# 角色 你是一名熟悉制造业质量管理体系的高级工程师。 # 任务 根据下面这段巡检记录提取不符合项并给出整改建议。 # 已知材料 {粘贴巡检记录原文用分隔线包起来} # 约束 1. 只能基于材料中的事实回答禁止推断缺失信息 2. 每条不符合项标注严重级别高/中/低 3. 每条整改建议不超过 3 句话。 # 输出格式 严格按以下 JSON 结构输出 {items: [{issue: , level: , suggestion: }]}逻辑说明角色定义放在最前面是让模型先进入专业状态任务紧随其后告诉它要干什么材料放中间避免前置指令被大段文本冲淡约束和输出格式放在最后因为它们是检查项模型在生成时会优先遵循离输出位置最近的指令。这个模板我用了大半年在信息抽取类任务上的稳定性明显好过把约束写在开头。输出格式写死成 JSON 这一点值得单独说。LLM 的返回是自然语言直接解析很容易被多余的解释文字干扰。把格式约束放在 Prompt 末尾再加上严格按结构输出这句话返回内容基本就是干净的 JSON省去大量清洗工作。如果模型偶尔在 JSON 前后加了说明文字我会用json.loads抛异常时截取第一对大括号之间的内容兜底。2.3 温度与采样参数同一个问题参数不同结果能差一个量级采样参数是很多人忽略的变量。DeepSeek API 里最常用的是temperature、top_p和max_tokens三个。temperature 控制随机性取值越大回答越发散top_p 控制候选词累积概率跟 temperature 功能有重叠通常只调一个就行。场景建议模型temperaturetop_pmax_tokens代码生成、数据抽取deepseek-chat0.1 ~ 0.30.8按输出长度设 1000~4000通用问答、改写deepseek-chat0.7 ~ 0.9默认默认即可数学推理、逻辑题deepseek-reasoner固定 1.0不调建议 4000 以上注意deepseek-reasoner这一行官方明确建议 temperature 固定为 1.0不要手动调低。Reasoning 模型内部有一套采样策略调低 temperature 不会让它更理性反而可能截断推理链。我在做数学题评测时试过把 temperature 调到 0.1结果准确率反而往下掉浪费了半天调参时间这就是血泪经验。另外要正视上下文长度。DeepSeek 的上下文窗口从 64K 一路扩到过 1M 的档位官方宣传得很响亮但支持 1M不等于1M 都好用。上下文拉长之后模型对中间段落的注意力会明显稀释50 页 PDF 全部塞进去它可能只记得开头和结尾中间细节全被忽略。长文本场景的正确做法不是硬塞而是切片再加检索具体方案放在第 4 章讲。3. 从网页到 API 的完整落地路径三个入口怎么选、参数怎么调3.1 网页端和 App零门槛入口但对话不会自动导出网页端是目前使用门槛最低的入口打开对话页面就能用支持上传 PDF、Word、Excel、TXT 文件系统会自动抽取文字内容。要注意的是这个自动抽取只对带文本层的文件有效扫描版 PDF 传上去模型照样看不到字。网页端还提供联网搜索开关需要手动开启才会把实时信息纳入回答默认是关的。很多人用网页端做了一段长时间对话之后想把这些内容保存下来结果发现没有导出对话按钮。常见做法有两个一是用浏览器自带的打印功能把对话页面打印成 PDF目标存储器选Microsoft Print to PDF或系统自带的 PDF 虚拟打印机二是直接选中对话内容复制粘贴到 Markdown 编辑器里整理。我自己更推荐第二种因为打印出来的 PDF 会带上各种交互元素的样式排版并不好看。网页端还有个隐性坑对话一多上下文占用越来越长响应速度会变慢甚至开始答非所问。这是因为旧对话内容仍然占据上下文窗口。我一般是每完成一个主题就开新对话需要留档的内容直接复制到项目笔记里。别指望网页端替你管理上下文这事得自己来。3.2 API 调用用 Python 写一个最小可用请求先跑通再谈封装从网页端切换到 API本质是把人肉提问变成程序提问。DeepSeek API 兼容 OpenAI 的消息格式所以直接用 OpenAI Python SDK 改个 base_url 就能调通不需要额外引入 SDK。这是一个最小可用的示例import os from openai import OpenAI client OpenAI( api_keyos.environ.get(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com ) resp client.chat.completions.create( modeldeepseek-chat, messages[ { role: system, content: 你是一个只输出 JSON 的助手。 }, { role: user, content: 把这句话转成 JSON后天下午三点在会议室A开评审会。 } ], temperature0.3, max_tokens1024, streamFalse ) print(resp.choices[0].message.content)逻辑说明先用OpenAI构造客户端api_key从环境变量读取避免把密钥硬编码进代码base_url指向 DeepSeek 的接口地址。然后调用chat.completions.create传入的messages是一个消息列表system消息设定助手行为user消息是实际请求。temperature这里调到 0.3保证结构化输出足够稳定max_tokens限制返回长度防止模型跑飞。一个容易踩的细节API Key 在创建时只会完整显示一次丢了只能重新生成。另外不要在代码里写死 key我见过不止一个人把带密钥的脚本直接提交到 Git 仓库然后被扫描机器人捞走盗刷。把 key 放进环境变量或者用 dotenv 加载.env文件是底线操作。跑通这一步之后请求失败时看三处401 说明 key 或接口地址不对429 说明触发频率限制需要在代码里加退避重试400 说明消息格式有问题通常是 messages 里缺了必需的字段或者 role 写错。3.3 本地部署与第三方接入Codex、VSCode 和社区工具的分寸API 之外另一个热门话题是本地部署。很多人看了一些教程想在自有机器上跑一个 DeepSeek图的是数据不出内网。常见做法是用 Ollama 一键拉模型跑起来比如ollama run deepseek-r1:7b这条命令会下载 7B 参数的 deepseek-r1 蒸馏版并进入交互模式。参数说明:7b是模型规模标签社区里还有 1.5b、8b、14b、32b 等版本数字越大效果越好但显存占用和推理延迟也越高。7B 量化版在 6~8GB 显存的消费级显卡上勉强能跑速度大概是每秒几个 token能接受这个速度再用它做二次开发。这里必须说一句得罪人的话本地跑的是蒸馏小模型和 API 背后的满血版671B 参数完全不是一个量级。小模型应付文本分类、格式整理这类简单任务还行一上长链推理就明显变笨。所以我的选型标准是涉及复杂推理、数据分析这类高价值任务走 API只有纯隐私敏感、任务简单、可接受慢速的场景才考虑本地部署。第三方接入则是另一条路。因为 DeepSeek 提供 OpenAI 兼容接口很多支持自定义 provider 的工具都能直接接进去。比如把 Codex CLI 或 VSCode 里的 Continue、Cline 插件的 base URL 改成 DeepSeek 的兼容地址填上 key就能在编辑器里用 DeepSeek 补代码。社区里还有网关注入工具比如名字里带 ccswitch 这类切换供应商的工具以及第三方托管平台提供免部署调用。这类工具的判断标准就三条配置里密钥怎么存、支不支持流式输出、上下文长度有没有被写死。至于名字里带 harness、hermes 的第三方壳我一般持观望态度——先确认它是不是只做了层转发有没有隐藏收费密钥是不是明文躺在本地配置里。为了省几行代码引入一个看不透的依赖不值得。4. 把 DeepSeek 接进真实工作流文档解析、函数调用与 PDF 场景4.1 用 DeepSeek 处理 PDF 长文档先抽文本、再切片、后提问PDF 是办公场景里最绕不开的格式也是使用 DeepSeek 时最容易翻车的地方。模型本身读不了 PDF 二进制所有读 PDF的能力都建立在先把文本抽出来这个前提下。常见的正确流程是三步抽文本、切片、再提问。抽文本我一般用 PyMuPDF速度快对文本型 PDF 的还原度好import fitz # PyMuPDF doc fitz.open(report.pdf) text \n.join(page.get_text() for page in doc) print(len(text)) CHUNK_SIZE 1000 # 每个切片的字符数 OVERLAP 150 # 相邻切片重叠字符数避免切断语义 chunks [] start 0 while start len(text): chunks.append(text[start:start CHUNK_SIZE]) start CHUNK_SIZE - OVERLAP print(f共 {len(chunks)} 个切片)逻辑说明page.get_text()把每一页的文字层提取出来拼成一个长字符串然后按固定字符数切片切片之间保留 150 字符的重叠防止一个完整句子恰好被切断。CHUNK_SIZE设成 1000 是因为这个长度既能保留完整段落语义又不会超出模型的单次处理舒适区。两个参数都可以按文档类型调整代码文档可以切小一点到 800合同协议这类连续叙述文本建议 1200。切完片之后不是把所有切片都丢给模型而是要先生成切片摘要或做关键词检索只把相关的几片喂进去。这也是很多人用 API 处理长文档时的核心误区——以为上下文够大就能全塞。塞 50 页合同进去模型看到后面忘前面还会一本正经地编造条款这是 LLM 处理长文本的固有缺陷不是调参能解决的。还有一种特殊 PDF 是扫描件用page.get_text()提取出来是空字符串。这类必须先走 OCR常见做法是用 Tesseract 或商用 OCR 服务把图片转成文字再把识别结果按上面流程切片。别指望 DeepSeek 直接识别图片内容它是纯文本模型没有视觉能力。网上那些把图片 PDF 拖进 DeepSeek 让它总结的截图背后要么是网页端偷偷做了 OCR要么就是演示效果。至于 PDF 转 Word、PDF 编辑器这类格式转换需求我的建议是交给专业工具别用 LLM 做排版。模型擅长的是从文档里提取知识不是还原版面格式。4.2 function calling 细节为什么 tool call 之后必须立刻回结果把 DeepSeek 接进工作流绕不开 function calling也就是让模型在回答过程中调用你提供的工具。DeepSeek 的 function calling 协议与 OpenAI 兼容先定义工具再让模型决定要不要调用。tools [ { type: function, function: { name: get_weather, description: 查询指定城市的实时天气, parameters: { type: object, properties: { city: {type: string, description: 城市名如北京、上海} }, required: [city] } } } ] resp client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: 北京今天适合跑步吗}], toolstools, tool_choiceauto ) msg resp.choices[0].message print(msg.tool_calls)逻辑说明tools列表里声明了get_weather这个函数包括函数名、描述和参数结构。模型收到用户问题后如果判断需要天气信息返回的msg.tool_calls就是一个包含函数名和参数的调用请求此时msg.content通常为空finish_reason是tool_calls。tool_choiceauto表示让模型自己决定是否调用工具。这里有一个高频报错很多人第一次写都会遇到messages tool calls need immediate results。这个错误的意思是模型发出了 tool call 之后你必须在下一次 API 请求里立即用roletool的消息返回执行结果不能在中间插入新的用户消息也不能空着不处理。协议要求工具调用是一个先调用、后回填、再续聊的闭环。messages [{role: user, content: 北京今天适合跑步吗}] resp client.chat.completions.create( modeldeepseek-chat, messagesmessages, toolstools ) msg resp.choices[0].message messages.append(msg) # 把带 tool_calls 的助手消息放回对话历史 if msg.tool_calls: for tc in msg.tool_calls: # tc.function.arguments 是 JSON 字符串需要先解析 args json.loads(tc.function.arguments) result get_weather(args[city]) messages.append({ role: tool, tool_call_id: tc.id, content: json.dumps(result, ensure_asciiFalse) }) resp client.chat.completions.create( modeldeepseek-chat, messagesmessages, toolstools ) print(resp.choices[0].message.content)逻辑说明先把模型返回的msg原样追加到messages这一步不能省因为对话历史必须包含这次 tool call 的记录。然后遍历msg.tool_calls逐个执行真实函数结果用roletool的消息返回tool_call_id必须与请求里的tc.id对应否则会报错。最后再调用一次接口让模型拿到工具结果后生成最终回答。我在这上面踩过一次很深的坑第一次写的时候把工具结果塞进了roleuser的消息里结果 API 直接报错。后来才明白OpenAI 兼容协议对 tool call 的回合顺序有硬性校验工具结果必须放在tool角色的消息里并且紧跟对应请求。4.3 一个吃透 tool calls 的最小智能体骨架理解了 function calling 的协议闭环就可以往上搭一层做一个最小可用的智能体。核心逻辑是一个循环调用模型 → 判断是否有 tool call → 有就执行工具并回填结果 → 再次调用模型直到模型不再请求工具。def run_agent(user_input, tools, max_rounds5): messages [{role: user, content: user_input}] for _ in range(max_rounds): resp client.chat.completions.create( modeldeepseek-chat, messagesmessages, toolstools ) msg resp.choices[0].message if not msg.tool_calls: return msg.content messages.append(msg) for tc in msg.tool_calls: fn_name tc.function.name fn_args json.loads(tc.function.arguments) result run_tool(fn_name, fn_args) messages.append({ role: tool, tool_call_id: tc.id, content: json.dumps(result, ensure_asciiFalse) }) return 达到最大轮数未完成参数说明max_rounds是循环上限防止模型陷入工具调用的死循环run_tool是一个函数分发表根据fn_name找到对应实现注意这里一定要用白名单映射绝不能让模型直接决定执行哪个函数。实际项目里我会在run_tool里加日志把每次工具调用的入参和结果都打出来调试智能体时这部分日志是唯一的黑匣子探测器。这个骨架虽然只有二十几行但已经是多数AI 自动处理场景的核心。再往上加记忆、加多轮对话、加向量检索都是在messages里做文章。先把闭环跑通再去追求复杂度这是我在这个方向上的最大体会。5. DeepSeek 实战避坑记录五个高频翻车点与排查顺序5.1 接口返回 401API Key 明明没写错现象代码报401 Authentication Fails检查了 key 没有问题复制粘贴也没多空格。原因多数情况是base_url配错指向了旧地址或者多加了路径前缀也有环境变量没生效的情况比如代码跑在 IDE 里而 key 是在终端里 export 的。解决先把base_url固定为官方接口地址不要画蛇添足然后在代码里打印os.environ.get(DEEPSEEK_API_KEY)确认环境变量真的读到了。最后重启终端或 IDE让环境变量重新加载。5.2 同一个 Prompt两个模型结果天差地别现象同样一段要求做会议纪要的 Promptdeepseek-chat输出干净利落deepseek-reasoner输出一大段推理过程还要从里面捞正文。原因不是模型坏了是两个模型定位不同。Reasoning 模型是为复杂推理设计的通用抽取任务用它属于杀鸡用牛刀。解决选型先行。结构化抽取、改写、分类用deepseek-chat数学、代码调试、逻辑分析用deepseek-reasoner。不要迷信带推理能力的更强任务匹配比模型能力强弱更重要。5.3 max_tokens 设太小R1 输出为空或截断现象调用deepseek-reasoner时返回内容为空或者只有一半答案。原因Reasoning 模型在回答前要生成一大段内部推理这部分也会消耗max_tokens。如果设成 1024推理链就把配额吃光了正文一个字都没剩下。解决用 reasoning 模型时把max_tokens提到 4000 以上超时时间也要相应加长。这个是投入产出比最高的修法改一行参数就能解决。5.4 工具调用报错messages tool calls need immediate results现象第一次写 function calling执行完工具函数后把结果拼进messages再调用报错messages tool calls need immediate results。原因协议要求 tool call 之后必须用roletool的消息立即返回结果并且tool_call_id要匹配。把结果放在下一轮roleuser消息里或者跳过了助手那条带tool_calls的消息都会触发这个错误。解决按第 4 章的闭环写法先把模型返回的msg追加到messages再循环处理每个tool_calls用roletool回填结果最后再调一次接口。记住这个顺序就不会再翻车。5.5 本地部署的小模型表现变笨现象用 Ollama 跑deepseek-r1:7b实际效果远不如 API稍微复杂点的任务就开始胡编。原因本地跑的是蒸馏小模型参数量只有满血版的百分之一还叠加了量化损失。它不是缩水版 DeepSeek而是另一套能力等级的东西。解决调整预期。本地小模型适合做文本清洗、格式转换、关键词提取这类模式简单的任务高价值推理任务走 API。如果必须本地部署且需要更强效果至少上 14B 或 32B 的版本同时准备好一张 24GB 以上显存的卡。别拿 7B 去跑业务分析那是为难它也是为难自己。6. 进阶验证搭一套自己的评测集给 DeepSeek 打分很多人调提示词靠感觉感觉这次回答比上次好就留下感觉不对就改两句再试。这种方式在简单问答上没问题一旦进入 API 接入和智能体开发阶段就必须用评测集说话。我的做法是维护一个十个问题的固定评测集覆盖六个维度代码生成、逻辑推理、文档提炼、JSON 输出、多轮记忆、指令服从。每个问题配一个标准答案的评分要点总共花半小时就能跑完一轮。评测脚本没必要写复杂一个循环加一个文件输出就够questions { code: 用 Python 写一个读取 CSV 并输出每列平均值的函数, logic: 有三个人A说B在说谎B说C在说谎C说A和B都在说谎谁说真话, extract: 从这段合同文本里提取甲方、乙方、金额和付款节点, json: 把这句话转成 JSON明天上午十点和小王在会议室C对齐进度, memory: 记住我的项目代号是 Ares然后回答我的项目代号是什么 } results {} for key, question in questions.items(): resp client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: question}], temperature0.3 ) results[key] resp.choices[0].message.content for key, content in results.items(): print(f {key} ) print(content)说明评分阶段我不用自动打分而是人工按 1 到 5 分记录。因为 LLM 输出质量里有很多看着像对、实际错了的情况自动指标很难捕捉。每次改完提示词、换模型版本、调整温度参数都跑一遍这组问题。这样做的好处是效果变化不再靠体感而是有一组可对比的分数。我也会把temperature0.3和temperature0.9各跑一遍对比看哪组参数在当前任务上更稳。最后一个习惯分享每次换模型版本或者升级 API SDK我都会先把评测集跑一遍再上生产。这套流程不复杂但能拦住大部分回归问题。搭建这套评测本身也是理解模型能力边界最快的方式——你会亲眼看到它在哪些问题上稳定满分在哪些问题上永远拿不到高分。希望帮到你。本文还有配套的精品资源点击获取
返回列表