---
layout: single
title:  "DeepSeek-V4 预览版：迈入百万上下文普惠时代"
date:   2026-04-28 08:00:00 +0800
categories: [AI 与大模型]
tags: [DeepSeek-V4, DeepSeek, LLM]
---

## DeepSeek-V4

![](/images/2026/DeepSeek-V4/v4-spec.png)

### DeepSeek-V4-Pro：性能比肩顶级闭源模型

- **Agent 能力大幅提高**：相比前代模型，DeepSeek-V4-Pro 的 Agent 能力显著增强。在 Agentic Coding 评测中，V4-Pro 已达到当前开源模型最佳水平，并在其他 Agent 相关评测中同样表现优异。目前 DeepSeek-V4 已成为公司内部员工使用的 Agentic Coding 模型，据评测反馈使用体验优于 Sonnet 4.5，交付质量接近 Opus 4.6 非思考模式，但仍与 Opus 4.6 思考模式存在一定差距。

- **丰富的世界知识**：DeepSeek-V4-Pro 在世界知识测评中，大幅领先其他开源模型，仅稍逊于顶尖闭源模型 Gemini-Pro-3.1。

- **世界顶级推理性能**：在数学、STEM、竞赛型代码的测评中，DeepSeek-V4-Pro 超越当前所有已公开评测的开源模型，取得了比肩世界顶级闭源模型的优异成绩。

### DeepSeek-V4-Flash：更快捷高效的经济之选

- 相比 DeepSeek-V4-Pro，DeepSeek-V4-Flash 在世界知识储备方面稍逊一筹，但展现出了接近的推理能力。而由于模型参数和激活更小，相较之下 V4-Flash 能够提供更加快捷、经济的 API 服务。

- 在 Agent 测评中，DeepSeek-V4-Flash 在简单任务上与 DeepSeek-V4-Pro 旗鼓相当，但在高难度任务上仍有差距。

### API 访问模型

![](/images/2026/DeepSeek-V4/v4-price.png)

### 开源权重和本地部署
- DeepSeek-V4 模型开源链接：
    - https://huggingface.co/collections/deepseek-ai/deepseek-v4
    - https://modelscope.cn/collections/deepseek-ai/DeepSeek-V4
- DeepSeek-V4 技术报告：
    - https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro/blob/main/DeepSeek_V4.pdf


## 安装 Claude Code

```bash
npm install -g @anthropic-ai/claude-code
```

```bash
# 临时切换淘宝镜像安装（推荐，只对本次命令生效）
npm install -g @anthropic-ai/claude-code --registry=https://registry.npmmirror.com
```

### 配置环境变量

```bash
vim ~/.claude/settings.json
```

```json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic",
    "ANTHROPIC_AUTH_TOKEN": "<your-deepseek-api-token>",
    "ANTHROPIC_MODEL": "deepseek-v4-pro[1m]",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek-v4-pro[1m]",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek-v4-pro[1m]",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek-v4-flash",
    "CLAUDE_CODE_SUBAGENT_MODEL": "deepseek-v4-flash",
    "CLAUDE_CODE_EFFORT_LEVEL": "max"
  }
}
```


## DeepSeek API 文档
### [模型 & 价格](https://api-docs.deepseek.com/zh-cn/quick_start/pricing)

![](/images/2026/DeepSeek-V4/deepseek-v4-model-details.png)

### [思考模式](https://api-docs.deepseek.com/zh-cn/guides/thinking_mode)

DeepSeek 模型支持思考模式：在输出最终回答之前，模型会先输出一段思维链内容，以提升最终答案的准确性。

#### 思考模式开关与思考强度控制

![](/images/2026/DeepSeek-V4/thinking-reasoning-effort.png)

#### 多轮对话拼接

在每一轮对话过程中，模型会输出思维链内容（`reasoning_content`）和最终回答（`content`）。如果没有工具调用，则在下一轮对话中，之前轮输出的思维链内容不会被拼接到上下文中，如下图所示：

![](/images/2026/DeepSeek-V4/deepseek_r1_multiround_example_cn.jpeg)

#### 工具调用

DeepSeek 模型的思考模式支持工具调用功能。模型在输出最终答案之前，可以进行多轮的思考与工具调用，以提升答案的质量。其调用模式如下图所示：

![](/images/2026/DeepSeek-V4/thinking_with_tools.jpeg)

### [上下文硬盘缓存](https://api-docs.deepseek.com/zh-cn/guides/kv_cache)

DeepSeek API 上下文硬盘缓存技术对所有用户默认开启，用户无需修改代码即可享用。

用户的每一个请求都会触发硬盘缓存的构建。若后续请求与之前的请求在前缀上存在重复，则重复部分只需要从缓存中拉取，计入 **“缓存命中”**。

#### 缓存落盘与命中规则

缓存命中的前提是相应前缀已被“落盘”（写入硬盘缓存）。受 Sliding Window Attention 机制的影响，缓存前缀的存取与判别与之前有所不同。每条缓存前缀是一个独立的完整单元。后续请求只有在完整匹配**缓存前缀单元**时，才能命中缓存。

##### 缓存前缀落盘时机：

1. **请求结束位置落盘**：每次请求的**用户输入结束位置**与**模型输出结束位置**，会产生两个**缓存前缀单元**。后续请求若**完整**匹配了它们，则可命中。
2. **公共前缀检测落盘**：当系统检测到多次请求之间存在公共前缀时，会将该公共前缀作为一个独立的**缓存前缀单元**进行落盘。后续请求若**完整**复用了该**缓存前缀单元**，则可命中。
3. **按固定 token 间隔落盘**：在长输入或长输出中，系统会以一定的 token 数量为间隔，截取**缓存前缀单元**，避免长前缀因迟迟未达到结束位置而完全无法被缓存。

##### 示例说明

**举例 1**：用户第一轮请求内容为 `A + B`，第二轮请求内容为 `A + B + C`，则第二轮请求能完整匹配 `A + B` 这个**缓存前缀单元**，可以命中 `A + B` 的缓存。

**举例 2**：用户第一轮请求内容为 `A + B`，第二轮请求内容为 `A + C`，则第二轮请求无法命中缓存（因为 `A + C` 不能完整匹配 `A + B`）。但此时系统会识别到两轮请求存在公共前缀 `A`，并将 `A` 作为**缓存前缀单元**落盘。当第三轮请求 `A + D` 到来时，能完整匹配 `A` 这个**缓存前缀单元**，可以命中 `A` 的缓存。

#### 硬盘缓存与输出随机性

硬盘缓存只匹配到用户输入的前缀部分，输出仍然是通过计算推理得到的，仍然受到 temperature 等参数的影响，从而引入随机性。其输出效果与不使用硬盘缓存相同。

#### 其它说明

1. 缓存系统是“尽力而为”，不保证 100% 缓存命中
2. 缓存构建耗时为秒级。缓存不再使用后会自动被清空，时间一般为几个小时到几天

### [Anthropic API](https://api-docs.deepseek.com/zh-cn/guides/anthropic_api)


## DeepSeek-V4 源码分析

### encoding

#### 一、目录结构

```
encoding/
├── README.md                 # 编码格式规范文档
├── encoding_dsv4.py          # 核心编码/解码实现（745 行）
├── test_encoding_dsv4.py     # 测试套件
└── tests/                    # 测试数据
    ├── test_input_1.json     # 场景1：thinking + tool calls
    ├── test_input_2.json     # 场景2：thinking 无工具
    ├── test_input_3.json     # 场景3：thinking + search + latest_reminder
    ├── test_input_4.json     # 场景4：chat 模式 quick task
    ├── test_output_1.txt     # 场景1 期望输出
    ├── test_output_2.txt     # 场景2 期望输出
    ├── test_output_3.txt     # 场景3 期望输出
    └── test_output_4.txt     # 场景4 期望输出
```

#### 二、encoding_dsv4.py 核心源码分析

##### 2.1 特殊 Token 定义（第 14-35 行）

```python
bos_token = "<｜begin▁of▁sentence｜>"
eos_token = "<｜end▁of▁sentence｜>"
thinking_start_token = "<think>"
thinking_end_token = "</think>"
dsml_token = "｜DSML｜"
```

| Token 常量 | 值 | 用途 |
|-----------|-----|------|
| `bos_token` | `<｜begin▁of▁sentence｜>` | 序列开始标记，每个对话开头插入 |
| `eos_token` | `<｜end▁of▁sentence｜>` | 序列结束标记，每个 assistant 轮次结尾 |
| `thinking_start_token` | `<think>` | 推理块开始 |
| `thinking_end_token` | `</think>` | 推理块结束 |
| `dsml_token` | `｜DSML｜` | DSML 标记语言命名空间 |

**Task 特殊 Token**（内部分类任务）：

| Task | Token | 说明 |
|------|-------|------|
| action | `<｜action｜>` | 判断是否需要搜索 |
| query | `<｜query｜>` | 生成搜索查询 |
| authority | `<｜authority｜>` | 判断来源权威性需求 |
| domain | `<｜domain｜>` | 识别问题领域 |
| title | `<｜title｜>` | 生成对话标题 |
| read_url | `<｜read_url｜>` | 判断 URL 是否需要获取 |

##### 2.2 模板系统（第 39-95 行）

编码使用字符串模板拼接，核心模板包括：

- `system_msg_template`: `{content}` — system 角色直接输出内容
- `user_msg_template`: `{content}` — user 角色直接输出内容
- `assistant_msg_template`: `{reasoning}{content}{tool_calls}<｜end▁of▁sentence｜>`
- `thinking_template`: `{reasoning_content}` — 推理内容包装
- `TOOLS_TEMPLATE`: 工具使用说明和 Available Tool Schemas 的完整模板
- `tool_call_template`: 单个工具调用的 DSML XML 格式
- `tool_calls_template`: 工具调用块包裹
- `REASONING_EFFORT_MAX`: Max 推理模式的前缀系统提示

##### 2.3 工具格式转换（第 99-206 行）

- `tools_from_openai_format`
从 OpenAI 格式 `tools: [{"type": "function", "function": {...}}]` 中提取 `function` 定义列表。

- `tool_calls_from_openai_format` / `tool_calls_to_openai_format`
工具调用格式在内部格式和 OpenAI 格式之间双向转换：
    - **内部格式**: `{"name": "...", "arguments": "json_string"}`
    - **OpenAI 格式**: `{"type": "function", "function": {"name": "...", "arguments": "..."}}`

- `encode_arguments_to_dsml`
将工具调用参数编码为 DSML XML：
    ```xml
    <｜DSML｜parameter name="$KEY" string="true|false">$VALUE</｜DSML｜parameter>
    ```
    - 字符串类型：`string="true"`，值原样输出
    - 非字符串：`string="false"`，值序列化为 JSON

- `decode_dsml_to_arguments`
反向解析 DSML 参数回 JSON 格式参数对象。

- `render_tools`
渲染完整的 Tools 说明块，插入到 system/developer 消息中。

##### 2.4 消息渲染核心：`render_message`（第 223-394 行）

这是编码的核心函数，处理每条消息的格式转换：

**参数**：
- `index`: 消息在列表中的索引
- `messages`: 完整消息列表（用于上下文判断）
- `thinking_mode`: `"chat"` 或 `"thinking"`
- `drop_thinking`: 是否丢弃早期 reasoning_content（默认 True）
- `reasoning_effort`: `"max"`, `"high"`, 或 `None`

**关键逻辑流程**：

1. **Max 推理前缀**：当 `index == 0` 且 `thinking_mode == "thinking"` 且 `reasoning_effort == "max"` 时，插入 `REASONING_EFFORT_MAX` 前缀

2. **角色分支处理**：
   - **system**: 直接输出 content，可选追加 tools 和 response_format
   - **developer**: 包装为 `USER_SP_TOKEN + content`，支持 tools/response_format
   - **user**: 输出 `USER_SP_TOKEN`，支持 content_blocks（tool_result 混合文本）
   - **latest_reminder**: 输出 `LATEST_REMINDER_SP_TOKEN + content`
   - **tool**: 抛出 NotImplementedError（要求预先用 `merge_tool_messages` 合并）
   - **assistant**: 最复杂的逻辑

3. **Assistant 消息处理**：
   - 构造 `thinking_part`：若 `thinking_mode="thinking"` 且不是 task 输出，则包裹 `<think>{rc}</think>`
   - `drop_thinking` 逻辑：在最后一个 user 消息之前的 assistant reasoning 会被丢弃
   - 工具调用内容通过 `tool_call_template` 拼接为 DSML XML
   - `wo_eos` 控制是否输出 EOS token

4. **Transition Token 追加**：
   - user/developer 消息后追加 `ASSISTANT_SP_TOKEN + thinking_token`
   - task 为 action 时追加 `ASSISTANT_SP_TOKEN + thinking_token + action_token`
   - 其他 task 直接追加对应 token

##### 2.5 预处理函数（第 401-499 行）

- `merge_tool_messages`
将 OpenAI 格式的独立 `tool` 角色消息合并到前一个 `user` 消息中：
    - tool 消息转为 `{"type": "tool_result", "content": ...}` block
    - 连续的 tool 结果合并到同一个 user 消息的 `content_blocks`
    - 连续的 user 消息（无 task）也合并 content_blocks

- `sort_tool_results_by_call_order`
根据前一个 assistant 消息中的 `tool_calls` 顺序，对 user 消息中的 `tool_result` blocks 排序。确保工具执行结果按调用顺序呈现。

##### 2.6 主入口：`encode_messages`（第 506-571 行）

**流程**：
1. 合并 tool 消息
2. 排序 tool 结果
3. 拼接 context 和 messages
4. 判断是否启用 `effective_drop_thinking`（若存在 tools 则禁用）
5. 若启用 drop_thinking，过滤掉早期 reasoning
6. 逐条调用 `render_message` 生成 prompt 字符串
7. 返回完整编码字符串

##### 2.7 辅助函数：`_drop_thinking_messages`（第 575-599 行）

在 drop_thinking 模式下精简消息列表：
- 保留所有 user/system/tool/latest_reminder 消息
- 保留最后一个 user 之后的所有消息
- 最后一个 user 之前的 assistant 消息删除 `reasoning_content`
- 最后一个 user 之前的 developer 消息直接丢弃

##### 2.8 解析（Decoding）系统（第 606-744 行）

- `_read_until_stop`
从指定索引读取文本，直到遇到 stop 字符串之一。返回 `(new_index, content, matched_stop)`。

- `parse_tool_calls`
解析 DSML 格式的工具调用块：
1. 循环读取 `<｜DSML｜invoke` 或 `</｜DSML｜tool_calls>`
2. 提取工具名（`name="..."`）
3. 循环读取参数（`<｜DSML｜parameter ...>value</｜DSML｜parameter>`）
4. 解析 `string="true|false"` 和参数值
5. 返回工具调用列表（内部格式）

- `parse_message_from_completion_text`
主解析函数，将模型原始输出转为结构化消息：

**解析流程**：
1. 若 `thinking_mode="thinking"`，先读取 `<think>...</think>` 之间的内容作为 `reasoning_content`
2. 读取 `</think>`（或开头）到 `eos_token` 或 `tool_calls` 之间的内容作为 `content`
3. 若遇到 `tool_calls` 起始标记，调用 `parse_tool_calls` 解析工具调用
4. 验证文本完整消费，无残留内容
5. 返回字典：`{"role": "assistant", "content": ..., "reasoning_content": ..., "tool_calls": [...]}`

#### 三、关键设计决策

##### 4.1 为什么不用 Jinja Chat Template？

README 明确说明：本版本不提供 Jinja 格式的 chat template，而是提供独立的 Python 脚本。原因：
- DSML 工具调用格式较为复杂，难以用纯模板表达
- Thinking 模式的动态 drop_thinking 逻辑需要程序判断
- Task special tokens 的条件插入需要运行时决策

##### 4.2 Tool Message 合并设计

OpenAI API 使用独立的 `tool` 角色消息，但 DeepSeek-V4 内部编码要求工具结果嵌入 user 消息的 `<tool_result>` 标签中。`merge_tool_messages` 提供了兼容层。

##### 4.3 drop_thinking 的智能切换

当对话中存在 tools 定义时，drop_thinking 自动关闭。因为工具调用对话需要完整的推理链来跟踪多步逻辑。

#### 四、使用示例

```python
from encoding_dsv4 import encode_messages, parse_message_from_completion_text

# 编码
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "What's 2+2?"}
]
prompt = encode_messages(messages, thinking_mode="thinking")

# 解码
completion = "Simple reasoning.</think>The answer is 4.<｜end▁of▁sentence｜>"
parsed = parse_message_from_completion_text(completion, thinking_mode="thinking")
# -> {"role": "assistant", "reasoning_content": "Simple reasoning.",
#     "content": "The answer is 4.", "tool_calls": []}
```
