素材
- 《大模型应用开发极简入门》第 2 章和【内部:以前的完整笔记】。
- DeepSeek 当前官方文档:模型、Chat Completions、多轮对话、Thinking Mode、Tool Calls、JSON Output 和错误码。
FDE/HarnessX/src/deepseek.js、src/agent-loop.js,以及本地 JD 对模型 API、多轮对话、Function Calling、稳定性和 Token 成本的要求。
先说结论
DeepSeek API,我只需要记住一条主线:
我的程序把
当前任务、对话历史和工具说明交给 DeepSeek;
DeepSeek 返回回答或 Tool Call;
真正保存状态、执行工具、校验结果并对用户负责的,始终是我的程序。
Tool Call:模型不直接执行工具,只返回“我想调用哪个工具、参数是什么”。
- DeepSeek 像一个坐在封闭会议室里的远程工程师。
- 每次请求,我要把它需要的材料送进会议室。
- 它看不到我的数据库、文件和上一轮对话,也不能自己操作业务系统。
- 它只能返回一段回答,或者一张申请调用工具的“工作申请单”。
Agent Runtime才是会议室外真正干活的人。- 准备材料、保存历史。
- 审批并执行工具。
- 记录结果。
- 决定继续、重试还是停止。
一次最小请求到底是什么
- DeepSeek 当前提供兼容 OpenAI 和 Anthropic 的接口格式。
- 可以复用对应 SDK 和请求结构。
- 兼容不代表不同厂商的模型、参数和能力完全一样。
以 OpenAI 格式为例,Node.js、Python SDK 和 curl 最终都在发送这样的 HTTP 请求:
POST https://api.deepseek.com/chat/completions
Authorization: Bearer $DEEPSEEK_API_KEY
Content-Type: application/json{
"model": "<从配置读取>",
"messages": [
{
"role": "system",
"content": "你是一个严谨的代码分析助手。"
},
{
"role": "user",
"content": "读取 README.md,告诉我项目入口。"
}
],
"thinking": {
"type": "disabled"
},
"stream": false
}- 最小请求只需要看懂四个字段。
model:这次使用哪个模型。messages:这次真正交给模型的上下文。thinking:要不要先进行更深入的推理。stream:等完整结果,还是边生成边接收。
- 做 Agent 时,再增加
tools。- 它告诉模型
有哪些工具可以申请调用,不会把工具执行权交给模型。
- 它告诉模型
- SDK 只是帮我组装请求、解析响应。
- 真正稳定的知识是 HTTP 请求、消息协议和失败语义,不是某个 SDK 的方法名。
messages 就是模型这次能看到的全部材料
- DeepSeek 的
/chat/completions是无状态接口。- 服务端处理完当前请求,不会替应用保存完整会话。
- 用户继续追问时,Runtime 必须
重新发送需要的历史消息。
用户第二轮问“它做了什么”,Runtime 必须把第一轮问题和回答重新放进 messages:
- 四种角色只需要这样理解。
system:这次任务的总规则。user:用户或 Runtime 提交的新输入。assistant:模型之前的回答或 Tool Call。tool:Runtime 执行工具后得到的真实结果。
messages不是越多越好。- 历史消息、System Prompt、RAG 材料、工具说明和工具结果共享同一个
Context Window。 - 保存历史是
Runtime 的责任,截断、摘要和压缩历史也是Runtime 的责任。
- 历史消息、System Prompt、RAG 材料、工具说明和工具结果共享同一个
Context Window:模型一次最多能处理的 Token 预算。
- 模型“忘了”一条规则时,先检查输入,不要先怪模型。
- 这条规则有没有进入本次
messages? - 它是否已经被截掉?
- 这条规则有没有进入本次
返回结果不能只读 content
- 一次响应必须同时看三块。
message:模型生成了什么。finish_reason:模型为什么停。usage:这次用了多少 Token。
finish_reason:不是回答内容,而是这次生成结束的原因。
- 只读取
content,会漏掉真正的状态。- 可能把被截断的半段回答当成完整答案。
- 也可能在模型已经返回 Tool Call 时,把它当成“没有内容”。
usage不只是账单。- 它能帮助判断本次请求为什么更慢、更贵。
- 也能暴露历史消息或推理 Token 是否失控。
一次普通对话怎样变成 Agent Loop
- Runtime 把
read_file(path)的Schema交给 DeepSeek。- DeepSeek 可能返回
read_file({"path":"README.md"})。 - 这不代表文件已经被读取,只代表模型提交了一张
工作申请。
- DeepSeek 可能返回
- Runtime 必须负责三层校验。
- 调用前:工具是否在白名单,
arguments能否解析,用户是否有权限。 - 执行时:路径或业务参数是否安全,副作用、超时和重复执行是否可控。
- 回填时:
tool_call_id与工具结果能否正确对应。
- 调用前:工具是否在白名单,
- 即使 Schema 很严格,模型参数也只是候选输入,不是执行授权。
JSON Output 和 Tool Call 不是一回事
两者都会出现 JSON,但解决的问题不同。
- JSON Output 解决“程序怎样读取模型结果”。
- 我要模型返回一份便于程序解析的数据。
response_format: {"type":"json_object"}只保证返回合法 JSON 字符串。- 程序仍要做
JSON.parse、Schema 校验和业务规则校验。
- Tool Call 解决“模型怎样申请外部动作”。
- 模型提出动作,Runtime 决定是否执行。
- 两条边界必须守住。
- 结构合法不等于数据真实、金额正确或业务合法。
- 模型能生成调用参数,也不等于它有执行权限。
Thinking Mode 是“先打草稿,再交答案”
截至 2026-07-28,DeepSeek V4 默认启用 Thinking Mode。
Thinking Mode:模型先生成reasoning_content,再生成给用户看的最终content。
- 可以把它想成考试。
- 非思考模式:看到题目后直接作答。
- 思考模式:先在草稿纸上尝试、检查,再写最终答案。
- 思考模式只需要记住三条。
- 适合复杂推理和多步 Agent 任务;简单提取、改写和分类不一定需要。
- 当前思考模式下,
temperature和top_p不生效,不要照搬旧参数配方。 - 发生 Tool Call 时,后续请求必须按官方协议把对应的
reasoning_content一起回填,否则可能得到 400。
- 思考越久,通常首字更慢、Token 更多、成本更高。
- 是否启用要看真实任务效果,不是默认追求“想得更多”。
Streaming 是边送边看,不是模型变聪明
Streaming:模型生成一小段,服务端就通过 SSE 发一小段,不必等完整回答生成完。
它像送一整箱书和一本一本送:
Streaming改变传输和等待体验,不改变模型能力。- 客户端负责把分段重新拼成完整结果。
- 按顺序拼接
delta。 - 区分
reasoning_content和content。 - 处理
[DONE]、最终finish_reason和usage。 - 用户取消时中断连接,不能把半截结果冒充完整答案。
- 按顺序拼接
- 是否开启看交互方式。
- 聊天界面通常需要 Streaming。
- 离线批处理和简单后台任务可以先使用完整响应。
HTTP 200 只是模型调用成功
在 FDE 交付里,API 调通只完成了中间一步。
- DeepSeek 返回 HTTP 200,只能说明这次接口请求成功。
- 不能证明模型理解对了任务。
- 不能证明 JSON 字段和业务数据正确。
- 不能证明 Tool Call 有权限、工具执行成功。
- 更不能证明用户得到想要的结果。
错误处理先按类型分:
- 一条能进入生产的调用链至少要守住四件事。
- 可恢复:超时、取消、瞬时故障的有限重试。
- 不重复伤害:有副作用工具的幂等保护。
- 可追踪:请求 ID、模型、耗时、
finish_reason和 Token 日志。 - 可验收:Schema、权限、工具结果、业务结果和持续评测。
FDE 真正需要证明的不是“我会调用 DeepSeek”,而是:
我能把模型接进真实系统,守住状态、权限、可靠性和成本,并让用户得到可以验收的结果。
我只记住这六句话
- DeepSeek API 是无状态模型服务,不是完整 Agent。
messages是模型这次真正能看到的上下文。- 响应要同时检查
message、finish_reason和usage。 Tool Call只是模型提出动作,Runtime 才能校验和执行。- Thinking Mode 改变推理过程,Streaming 只改变传输方式。
- HTTP 200 不是交付完成,最终还要检查工具结果、业务结果和用户结果。
一分钟怎么讲清楚
DeepSeek API 可以理解成一个坐在封闭会议室里的远程工程师。我的程序每次把 messages 和工具说明送进去,它只根据这些材料返回回答或 Tool Call,不会自动记住历史,也不会自己访问文件和业务系统。
多轮历史由 Runtime 保存并重新发送。模型返回 Tool Call 后,Runtime 要校验工具名、参数、权限和副作用,真正执行工具,再用 role=tool 把结果回填给模型。
生产环境不能只读取 content。还要检查 finish_reason、Token、错误、结构化结果和工具结果。Thinking Mode 是先推理再回答,Streaming 是边生成边传输。最终是否成功,要看用户和业务结果,不是只看 HTTP 200。
考考你
DeepSeek API 和完整 Agent 有什么区别?
DeepSeek API 只根据当前输入生成回答或 Tool Call。
完整 Agent 还需要 Runtime 保存上下文、执行工具、管理状态和权限、处理错误并验证结果。
为什么多轮对话必须重新发送历史消息?
因为 /chat/completions 是无状态接口。服务端不会替应用保存完整会话,Runtime 必须把上一轮 user 和 assistant 消息放回本次 messages。
为什么不能只读取 response.choices[0].message.content?
因为模型可能返回 Tool Call,也可能因为 length 被截断。程序还要检查 finish_reason 和 usage,才能知道这次返回是否完整、为什么停止以及消耗了多少 Token。
Tool Call 为什么不是执行授权?
Tool Call 只是模型生成的工具名和参数。Runtime 仍要校验 Schema、权限、路径、业务规则、幂等和副作用,然后才能真正执行。
JSON Output 和 Tool Call 有什么区别?
JSON Output 让模型返回便于程序解析的数据;Tool Call 让模型提出一个外部动作。前者仍要校验数据,后者还要由 Runtime 决定是否执行。
Thinking Mode 和 Streaming 分别改变了什么?
Thinking Mode 改变模型生成答案前的推理过程,通常会增加时间和 Token;Streaming 只改变传输方式,让客户端边生成边接收,不会让模型更聪明。
为什么 HTTP 200 不能证明 Agent 已经完成任务?
HTTP 200 只说明模型接口调用成功。模型判断、JSON 数据、Tool Call 权限、工具执行和最终业务结果仍可能失败,必须继续校验和验收。
对 FDE 来说,掌握 DeepSeek API 的完成标准是什么?
不是背参数或跑通 Hello World,而是能把模型接入真实系统,讲清模型与 Runtime 的边界,并处理上下文、工具、权限、错误、成本、评测和用户结果。
参考
- 《大模型应用开发极简入门》第 2 章,以及【内部:以前的完整笔记】。
- DeepSeek 官方:模型与价格、Chat Completions、多轮对话、Thinking Mode、Tool Calls、JSON Output和错误码;当前事实截至 2026-07-28。
- 【内部:HarnessX DeepSeek 请求实现】、【内部:Agent Loop】和【内部:本地 JD 原始材料】。
上一篇:GPT-1 到 GPT-5.6,我最少需要知道什么?
下一篇:待下一个主题完成后决定