[GH-ISSUE #349] DeepSeek-v4-flash接入Codex无法使用子代理的问题的排查与解决方法 #116

Open
opened 2026-10-26 09:45:38 +00:00 by bsakaguchi · 5 comments
Owner

Originally created by @asnndpro on GitHub (Aug 4, 2026).
Original GitHub issue: https://github.com/deepseek-ai/awesome-deepseek-agent/issues/349

DeepSeek Codex 适配:子代理(Subagent)任务消息(agent_message/encrypted_content)无法被模型读取

摘要

使用 DeepSeek 为 Codex 适配的接口(/responses,wire_api = responses,模型
deepseek-v4-flash)时,主代理通过 spawn_agent 派发子代理,任务正文被封装在
输入项的 agent_message + encrypted_content 结构中。DeepSeek 适配层不把
agent_message 项的内容喂给模型,且不识别 encrypted_content 内容类型
,
导致子代理模型只能看到空的任务信封(Payload: 为空),收不到任何任务指令。

环境信息

  • Codex Desktop:0.146.0-alpha.9.2(26.727.51351,Windows)
  • 模型提供商:DeepSeek(base_url = https://api.deepseek.com/,wire_api = responses)
  • 模型:deepseek-v4-flash(GET /models 确认存在)
  • 子代理接口:spawn_agent / followup_task / send_message
    (features.multi_agent 默认开启)

问题表现

  • 子代理回复泛泛的"我还没有收到具体任务 / 请告诉我你想做什么"或
    STATUS:NO-TASK,从不回显消息中的唯一 token;
  • spawn_agent、followup_task、send_message 三条通道同样受影响;
  • 与 fork_turns(none/all/1)、消息语言(中/英/JSON)、模型选择、推理强度
    等参数无关;
  • 若工作区存在任务收件箱文件(AGENTS.md 约定的 .agents/TASKS.md),
    子代理会退而读取文件执行任务,造成"时好时坏"假象,实际消息通道仍坏;
  • 抓包显示:任务正文随子代理首轮请求发出,但位于 agent_message 项的
    encrypted_content 中,模型读不到;
  • 直接发送含 encrypted_content 内容项的请求,DeepSeek 返回 400
    unknown variant encrypted_content。

复现步骤

步骤 1:派发子代理

主线程调用:

spawn_agent(
  task_name = "repro_test",
  message = "REPRO-TOKEN-1234:收到本消息请只回复 REPRO-TOKEN-1234。",
  fork_turns = "none"
)

实际结果:子代理回复"我还没有收到具体任务",而不是 REPRO-TOKEN-1234。

步骤 2:抓包子代理首轮请求(可选,用于确认载荷)

把 config.toml 的 base_url 指向本地转发代理后重启 Codex,再次派发,
子代理首轮请求体中可见任务消息的封装方式:

{
  "type": "agent_message",
  "id": "amsg_xxxxxxxx",
  "author": "/root",
  "recipient": "/root/repro_test",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: NEW_TASK\nTask name: /root/repro_test\nSender: /root\nPayload:\n"
    },
    {
      "type": "encrypted_content",
      "encrypted_content": "REPRO-TOKEN-1234:收到本消息请只回复 REPRO-TOKEN-1234。"
    }
  ]
}

步骤 3:直接验证 DeepSeek 对 encrypted_content 的处理

POST https://api.deepseek.com/v1/responses

请求体:

{
  "model": "deepseek-v4-flash",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        { "type": "input_text", "text": "Message Type: NEW_TASK\nPayload:\n" },
        { "type": "encrypted_content", "encrypted_content": "REPRO-TOKEN-1234" }
      ]
    }
  ],
  "stream": false
}

响应(400):

{
  "error": {
    "message": "Failed to deserialize the JSON body into the target type: input: unknown variant `encrypted_content`, expected one of `input_text`, `output_text`, `input_image`, `input_file`",
    "type": "invalid_request_error",
    "code": "invalid_request_error"
  }
}

步骤 4:确认模型读不到任务正文

原样重放步骤 2 的子代理首轮请求(不修改载荷),模型推理原文:

The user hasn't sent a message yet in this conversation. Wait, actually looking at
the context, I see there's no actual user request. The last message is just the system…

随后模型只能调用 shell 读取工作区的任务文件兜底。

预期行为 vs 实际行为

  • 预期:子代理模型能读到 spawn_agent 消息正文(如同 OpenAI 官方 Codex + OpenAI
    模型的组合);
  • 实际:子代理模型只看到空的任务信封,收不到任务指令。

根因分析

子代理首轮请求中任务消息的封装(见上文步骤 2)存在两个问题:

  1. agent_message 项未被喂给模型:DeepSeek 适配层把它当作平台元数据跳过,
    模型上下文里只有空的 Payload: 信封;
  2. encrypted_content 不是 OpenAI 官方内容类型:OpenAI 官方 Responses API
    内容类型只有 input_text / output_text / input_image / input_file,
    DeepSeek 严格校验直接拒绝(400),或在校验宽松路径下静默忽略。

修复方案(已验证)

在 Codex 与 DeepSeek 之间加本地转发代理,转发前把 agent_message 项改写为
OpenAI 官方 message(role="user") 项、把 encrypted_content 改写为
input_text。核心逻辑:

// 关键修复函数(Node.js)
function normalizeSubagentMessage(body) {
  if (!body || typeof body !== 'object' || !Array.isArray(body.input)) return body;
  const unwrap = (content) => (Array.isArray(content)
    ? content.map((c) => c && c.type === 'encrypted_content' && typeof c.encrypted_content === 'string'
      ? { type: 'input_text', text: c.encrypted_content }
      : c)
    : content);
  for (let i = 0; i < body.input.length; i++) {
    const item = body.input[i];
    if (item && item.type === 'agent_message') {
      body.input[i] = {
        type: 'message',
        role: 'user',
        content: unwrap(item.content),
        id: item.id,
      };
    } else if (item && Array.isArray(item.content)) {
      item.content = unwrap(item.content);
    }
  }
  return body;
}

验证结果(对步骤 2 同一请求重放):

  • 修复前模型推理:"The user hasn't sent a message yet… there's no actual user request";
  • 修复后模型推理:"The task says: wiring test, reply with WIRE-9502"——
    模型明确引用了任务正文;
  • 端到端双通道验证:收件箱文件任务(CHANNEL=FILE)与消息正文任务
    (CHANNEL=MSG)并存时,子代理回复 CHANNEL=MSG,确认消息通道修复。

建议 DeepSeek 侧修复

  1. 支持 agent_message 输入项:将其 content 合并进模型可见的 user 输入
    (与 OpenAI 协作协议一致);
  2. 支持或转换 encrypted_content 内容类型:至少将其按明文 input_text
    处理(或按协议解包),而不是拒绝/忽略;
  3. 若两端格式必须一致,建议同步 OpenAI 官方 Codex 协作层的消息封装规范。

补充证据

  • 抓包样本:子代理真实首轮请求(含 agent_message + encrypted_content,
    任务 token WIRE-9502),请求/响应均通过本地代理完整记录;
  • 修复前后模型推理对比、400 拒绝响应均在上文内联。

其他

  • 具体排查代码已通过822155262qq.com邮箱发送至api-service@deepseek.com邮箱或是通过
https://github.com/asnndpro/Codex-DeepSeek-Subagent

查看对应排查方式与解决方法

Originally created by @asnndpro on GitHub (Aug 4, 2026). Original GitHub issue: https://github.com/deepseek-ai/awesome-deepseek-agent/issues/349 # DeepSeek Codex 适配:子代理(Subagent)任务消息(`agent_message`/`encrypted_content`)无法被模型读取 ## 摘要 使用 DeepSeek 为 Codex 适配的接口(`/responses`,`wire_api = responses`,模型 `deepseek-v4-flash`)时,主代理通过 `spawn_agent` 派发子代理,任务正文被封装在 输入项的 `agent_message` + `encrypted_content` 结构中。DeepSeek 适配层**不把 `agent_message` 项的内容喂给模型,且不识别 `encrypted_content` 内容类型**, 导致子代理模型只能看到空的任务信封(`Payload:` 为空),收不到任何任务指令。 ## 环境信息 - Codex Desktop:0.146.0-alpha.9.2(26.727.51351,Windows) - 模型提供商:DeepSeek(`base_url = https://api.deepseek.com/`,`wire_api = responses`) - 模型:`deepseek-v4-flash`(`GET /models` 确认存在) - 子代理接口:`spawn_agent` / `followup_task` / `send_message` (`features.multi_agent` 默认开启) ## 问题表现 - 子代理回复泛泛的"我还没有收到具体任务 / 请告诉我你想做什么"或 `STATUS:NO-TASK`,从不回显消息中的唯一 token; - `spawn_agent`、`followup_task`、`send_message` 三条通道同样受影响; - 与 `fork_turns`(none/all/1)、消息语言(中/英/JSON)、模型选择、推理强度 等参数无关; - 若工作区存在任务收件箱文件(`AGENTS.md` 约定的 `.agents/TASKS.md`), 子代理会退而读取文件执行任务,造成"时好时坏"假象,实际消息通道仍坏; - 抓包显示:任务正文随子代理首轮请求发出,但位于 `agent_message` 项的 `encrypted_content` 中,模型读不到; - 直接发送含 `encrypted_content` 内容项的请求,DeepSeek 返回 400 `unknown variant encrypted_content`。 ## 复现步骤 ### 步骤 1:派发子代理 主线程调用: ```text spawn_agent( task_name = "repro_test", message = "REPRO-TOKEN-1234:收到本消息请只回复 REPRO-TOKEN-1234。", fork_turns = "none" ) ``` 实际结果:子代理回复"我还没有收到具体任务",而不是 `REPRO-TOKEN-1234`。 ### 步骤 2:抓包子代理首轮请求(可选,用于确认载荷) 把 `config.toml` 的 `base_url` 指向本地转发代理后重启 Codex,再次派发, 子代理首轮请求体中可见任务消息的封装方式: ```json { "type": "agent_message", "id": "amsg_xxxxxxxx", "author": "/root", "recipient": "/root/repro_test", "content": [ { "type": "input_text", "text": "Message Type: NEW_TASK\nTask name: /root/repro_test\nSender: /root\nPayload:\n" }, { "type": "encrypted_content", "encrypted_content": "REPRO-TOKEN-1234:收到本消息请只回复 REPRO-TOKEN-1234。" } ] } ``` ### 步骤 3:直接验证 DeepSeek 对 `encrypted_content` 的处理 ```text POST https://api.deepseek.com/v1/responses ``` 请求体: ```json { "model": "deepseek-v4-flash", "input": [ { "type": "message", "role": "user", "content": [ { "type": "input_text", "text": "Message Type: NEW_TASK\nPayload:\n" }, { "type": "encrypted_content", "encrypted_content": "REPRO-TOKEN-1234" } ] } ], "stream": false } ``` 响应(400): ```json { "error": { "message": "Failed to deserialize the JSON body into the target type: input: unknown variant `encrypted_content`, expected one of `input_text`, `output_text`, `input_image`, `input_file`", "type": "invalid_request_error", "code": "invalid_request_error" } } ``` ### 步骤 4:确认模型读不到任务正文 原样重放步骤 2 的子代理首轮请求(不修改载荷),模型推理原文: > The user hasn't sent a message yet in this conversation. Wait, actually looking at > the context, I see there's no actual user request. The last message is just the system… 随后模型只能调用 shell 读取工作区的任务文件兜底。 ## 预期行为 vs 实际行为 - 预期:子代理模型能读到 `spawn_agent` 消息正文(如同 OpenAI 官方 Codex + OpenAI 模型的组合); - 实际:子代理模型只看到空的任务信封,收不到任务指令。 ## 根因分析 子代理首轮请求中任务消息的封装(见上文步骤 2)存在两个问题: 1. **`agent_message` 项未被喂给模型**:DeepSeek 适配层把它当作平台元数据跳过, 模型上下文里只有空的 `Payload:` 信封; 2. **`encrypted_content` 不是 OpenAI 官方内容类型**:OpenAI 官方 Responses API 内容类型只有 `input_text` / `output_text` / `input_image` / `input_file`, DeepSeek 严格校验直接拒绝(400),或在校验宽松路径下静默忽略。 ## 修复方案(已验证) 在 Codex 与 DeepSeek 之间加本地转发代理,转发前把 `agent_message` 项改写为 OpenAI 官方 `message(role="user")` 项、把 `encrypted_content` 改写为 `input_text`。核心逻辑: ```js // 关键修复函数(Node.js) function normalizeSubagentMessage(body) { if (!body || typeof body !== 'object' || !Array.isArray(body.input)) return body; const unwrap = (content) => (Array.isArray(content) ? content.map((c) => c && c.type === 'encrypted_content' && typeof c.encrypted_content === 'string' ? { type: 'input_text', text: c.encrypted_content } : c) : content); for (let i = 0; i < body.input.length; i++) { const item = body.input[i]; if (item && item.type === 'agent_message') { body.input[i] = { type: 'message', role: 'user', content: unwrap(item.content), id: item.id, }; } else if (item && Array.isArray(item.content)) { item.content = unwrap(item.content); } } return body; } ``` 验证结果(对步骤 2 同一请求重放): - 修复前模型推理:"The user hasn't sent a message yet… there's no actual user request"; - 修复后模型推理:"The task says: wiring test, reply with WIRE-9502"—— 模型明确引用了任务正文; - 端到端双通道验证:收件箱文件任务(`CHANNEL=FILE`)与消息正文任务 (`CHANNEL=MSG`)并存时,子代理回复 `CHANNEL=MSG`,确认消息通道修复。 ## 建议 DeepSeek 侧修复 1. **支持 `agent_message` 输入项**:将其 content 合并进模型可见的 user 输入 (与 OpenAI 协作协议一致); 2. **支持或转换 `encrypted_content` 内容类型**:至少将其按明文 `input_text` 处理(或按协议解包),而不是拒绝/忽略; 3. 若两端格式必须一致,建议同步 OpenAI 官方 Codex 协作层的消息封装规范。 ## 补充证据 - 抓包样本:子代理真实首轮请求(含 `agent_message` + `encrypted_content`, 任务 token `WIRE-9502`),请求/响应均通过本地代理完整记录; - 修复前后模型推理对比、400 拒绝响应均在上文内联。 ## 其他 - 具体排查代码已通过822155262qq.com邮箱发送至api-service@deepseek.com邮箱或是通过 ```text https://github.com/asnndpro/Codex-DeepSeek-Subagent ``` 查看对应排查方式与解决方法
Author
Owner

@DoiiarX commented on GitHub (Aug 6, 2026):

官方你们快点修啊。

<!-- gh-comment-id:5201175939 --> @DoiiarX commented on GitHub (Aug 6, 2026): 官方你们快点修啊。
Author
Owner

@hairyf commented on GitHub (Aug 10, 2026):

提供一个已验证的本地转发代理实现,正好落地本 issue 描述的修复方案:

https://github.com/hairyf/codex-deepseek-subagent-proxy

  • 在 Codex 与 DeepSeek 之间做本地转发(base_url 指向 http://127.0.0.1:8787/)
  • 转发前把 agent_message item 改写为标准 message(role=user),encrypted_content 解包为 input_text,再原样转发给 https://api.deepseek.com/
  • 覆盖 spawn_agent / followup_task / send_message 三条通道,无需重编 codex-core,不依赖具体版本
  • 只改写含 agent_message 的请求,主会话与 OpenAI 路径不受影响;不保存密钥,仅监听 127.0.0.1

已在 deepseek-v4-flash(wire_api = "responses")上端到端验证:子代理(fork_turns="none")能收到任务并按要求回复 PONG,代理日志确认 agent_message -> user message 改写生效。Windows 下直接运行 start-proxy.ps1 即可。

<!-- gh-comment-id:5236758099 --> @hairyf commented on GitHub (Aug 10, 2026): 提供一个已验证的本地转发代理实现,正好落地本 issue 描述的修复方案: **https://github.com/hairyf/codex-deepseek-subagent-proxy** - 在 Codex 与 DeepSeek 之间做本地转发(`base_url` 指向 `http://127.0.0.1:8787/`) - 转发前把 `agent_message` item 改写为标准 `message(role=user)`,`encrypted_content` 解包为 `input_text`,再原样转发给 `https://api.deepseek.com/` - 覆盖 `spawn_agent` / `followup_task` / `send_message` 三条通道,无需重编 codex-core,不依赖具体版本 - 只改写含 `agent_message` 的请求,主会话与 OpenAI 路径不受影响;不保存密钥,仅监听 127.0.0.1 已在 `deepseek-v4-flash`(`wire_api = "responses"`)上端到端验证:子代理(`fork_turns="none"`)能收到任务并按要求回复 PONG,代理日志确认 `agent_message -> user message` 改写生效。Windows 下直接运行 `start-proxy.ps1` 即可。
Author
Owner

@lovelmh13 commented on GitHub (Aug 14, 2026):

我也遇到这个问题了,然后用 cc switch ,配置为 chat completions 同时开启路由解决了

<!-- gh-comment-id:5290258020 --> @lovelmh13 commented on GitHub (Aug 14, 2026): 我也遇到这个问题了,然后用 cc switch ,配置为 chat completions 同时开启路由解决了
Author
Owner

@nothing0here commented on GitHub (Sep 16, 2026):

补充(2026-09):OpenCode Go 网关 + deepseek-v4.1-flash 上复现,以及精简后的修复

原报告是 DeepSeek 官方端点(严格校验 → 400 unknown variant 'encrypted_content')。
补一条同类但更隐蔽的路径:OpenCode Go 网关(base_url = https://opencode.ai/zen/go/v1,
wire_api = "responses")+ deepseek-v4.1-flash(Codex Desktop 0.154.0-alpha.6.2,macOS)。

症状相同,但网关不报错

同一个 agent_message(input_text 信封 + encrypted_content 正文) 请求:

直连网关        → HTTP 200,无 error,模型只看到 <environment_context>,
                  回复"没看到任务 / 你想做什么"
经代理改写后    → 模型在推理里直接复述出正文中的唯一 token

也就是说这个网关对 agent_message 是静默忽略,比 400 更难排查:客户端不报错,
子代理线程被正常唤醒(trigger_turn: true),只是模型拿到的是空信封。
所以本地日志里看到的"任务发不出去但也不失败",和本 issue 是同一个根因。

v4 时代针对该网关的 workaround,现在多半已过时

社区代理的核心改写思路是对的(下文建议保留),但它同时带了几个针对 v4 时代网关行为的
hack;在同一网关 2026-09-16 的实测中这些已经不需要,照搬反而引入新问题:

workaround 现状实测 照搬后果
删除没有 name 的 tool 网关已放行:带 {"type":"web_search"} 的请求返回 200(v4 时代是 400 tools[N].function: missing field 'name') 静默禁用 web_search 等内置工具,且对所有请求生效,不限于子代理派发
重写 SSE(补 response.output_item.added / content_part.added、补 response.completed.output) 网关已按标准发出这些事件,completed.output 里 reasoning + message 齐全 脚手架重复、消息项翻倍;并用合成 output 覆盖掉上游的 reasoning item
assistant content 数组 → 字符串 数组形式已被接受(200) 多模态 part / annotations 被削成纯文本
400/500 时自动用 reasoning.effort="none" 重试 与本次问题无关 在用户配置的 max 上静默降级推理强度,还可能掩盖真实错误

建议的最小修复

只保留一处改写,其余请求体/头/响应流字节透传:agent_message item → message(role="user"),
encrypted_content part → input_text part。

// 只做这一件事:把 Codex 派发消息改写成端点能消费的普通 user message
const unwrapParts = (parts) => {
  let changed = false;
  const out = [];
  for (const p of parts) {
    if (p && p.type === 'encrypted_content') {
      changed = true;
      if (typeof p.encrypted_content === 'string' && p.encrypted_content.length > 0) {
        out.push({ type: 'input_text', text: p.encrypted_content });
      }
    } else {
      out.push(p); // input_image 等非文本 part 原样保留,否则派发消息里的图片会丢
    }
  }
  return { out, changed };
};

function transformBody(body) {
  if (!body || !Array.isArray(body.input)) return { body, changed: false };
  let changed = false;
  const input = body.input.map((item) => {
    if (item && item.type === 'agent_message' && Array.isArray(item.content)) {
      changed = true;
      const { out } = unwrapParts(item.content);
      const mapped = { type: 'message', role: 'user', content: out.length ? out : [{ type: 'input_text', text: '' }] };
      if (item.id) mapped.id = item.id;
      return mapped;
    }
    if (item && Array.isArray(item.content)) {
      const { out, changed: partChanged } = unwrapParts(item.content);
      if (partChanged) { changed = true; return { ...item, content: out }; }
    }
    return item;
  });
  return changed ? { body: { ...body, input }, changed: true } : { body, changed: false };
}

即:tools、assistant.content、reasoning、SSE 响应一律不动。实测不需要改写的请求
上游收到的 body 与发送端 sha256 完全一致。

多模态注意事项

  • input_image(data URI PNG)走该网关正常,模型能正确识别;
  • 展平 agent_message 时不要只收集 input_text,否则随派发消息携带的图片/附件会被丢掉;
  • 1×1 之类的极小图会被 provider 拒绝(unsupported image ... webp, png, jpeg, gif),
    那是尺寸限制,与协议无关。

上游正解

网关侧把 agent_message 按 OpenAI 协作层语义并入模型可见输入(至少把 encrypted_content
当明文 input_text 消费)后,这类本地转发代理就可以下线。

<!-- gh-comment-id:5698071464 --> @nothing0here commented on GitHub (Sep 16, 2026): ## 补充(2026-09):OpenCode Go 网关 + `deepseek-v4.1-flash` 上复现,以及精简后的修复 原报告是 DeepSeek 官方端点(严格校验 → 400 `unknown variant 'encrypted_content'`)。 补一条同类但更隐蔽的路径:**OpenCode Go 网关**(`base_url = https://opencode.ai/zen/go/v1`, `wire_api = "responses"`)+ **`deepseek-v4.1-flash`**(Codex Desktop 0.154.0-alpha.6.2,macOS)。 ### 症状相同,但网关不报错 同一个 `agent_message(input_text 信封 + encrypted_content 正文)` 请求: ``` 直连网关 → HTTP 200,无 error,模型只看到 <environment_context>, 回复"没看到任务 / 你想做什么" 经代理改写后 → 模型在推理里直接复述出正文中的唯一 token ``` 也就是说这个网关对 `agent_message` 是**静默忽略**,比 400 更难排查:客户端不报错, 子代理线程被正常唤醒(`trigger_turn: true`),只是模型拿到的是空信封。 所以本地日志里看到的"任务发不出去但也不失败",和本 issue 是同一个根因。 ### v4 时代针对该网关的 workaround,现在多半已过时 社区代理的**核心改写思路是对的**(下文建议保留),但它同时带了几个针对 v4 时代网关行为的 hack;在同一网关 2026-09-16 的实测中这些已经不需要,照搬反而引入新问题: | workaround | 现状实测 | 照搬后果 | | --- | --- | --- | | 删除没有 `name` 的 tool | 网关已放行:带 `{"type":"web_search"}` 的请求返回 200(v4 时代是 400 `tools[N].function: missing field 'name'`) | 静默禁用 `web_search` 等内置工具,且对所有请求生效,不限于子代理派发 | | 重写 SSE(补 `response.output_item.added` / `content_part.added`、补 `response.completed.output`) | 网关已按标准发出这些事件,`completed.output` 里 reasoning + message 齐全 | 脚手架重复、消息项翻倍;并用合成 output **覆盖**掉上游的 reasoning item | | assistant `content` 数组 → 字符串 | 数组形式已被接受(200) | 多模态 part / annotations 被削成纯文本 | | 400/500 时自动用 `reasoning.effort="none"` 重试 | 与本次问题无关 | 在用户配置的 `max` 上静默降级推理强度,还可能掩盖真实错误 | ### 建议的最小修复 只保留一处改写,其余请求体/头/响应流字节透传:`agent_message` item → `message(role="user")`, `encrypted_content` part → `input_text` part。 ```js // 只做这一件事:把 Codex 派发消息改写成端点能消费的普通 user message const unwrapParts = (parts) => { let changed = false; const out = []; for (const p of parts) { if (p && p.type === 'encrypted_content') { changed = true; if (typeof p.encrypted_content === 'string' && p.encrypted_content.length > 0) { out.push({ type: 'input_text', text: p.encrypted_content }); } } else { out.push(p); // input_image 等非文本 part 原样保留,否则派发消息里的图片会丢 } } return { out, changed }; }; function transformBody(body) { if (!body || !Array.isArray(body.input)) return { body, changed: false }; let changed = false; const input = body.input.map((item) => { if (item && item.type === 'agent_message' && Array.isArray(item.content)) { changed = true; const { out } = unwrapParts(item.content); const mapped = { type: 'message', role: 'user', content: out.length ? out : [{ type: 'input_text', text: '' }] }; if (item.id) mapped.id = item.id; return mapped; } if (item && Array.isArray(item.content)) { const { out, changed: partChanged } = unwrapParts(item.content); if (partChanged) { changed = true; return { ...item, content: out }; } } return item; }); return changed ? { body: { ...body, input }, changed: true } : { body, changed: false }; } ``` 即:`tools`、`assistant.content`、`reasoning`、SSE 响应一律不动。实测不需要改写的请求 上游收到的 body 与发送端 sha256 完全一致。 ### 多模态注意事项 - `input_image`(data URI PNG)走该网关正常,模型能正确识别; - 展平 `agent_message` 时**不要只收集 `input_text`**,否则随派发消息携带的图片/附件会被丢掉; - 1×1 之类的极小图会被 provider 拒绝(`unsupported image ... webp, png, jpeg, gif`), 那是尺寸限制,与协议无关。 ### 上游正解 网关侧把 `agent_message` 按 OpenAI 协作层语义并入模型可见输入(至少把 `encrypted_content` 当明文 `input_text` 消费)后,这类本地转发代理就可以下线。
Author
Owner

@nothing0here commented on GitHub (Sep 16, 2026):

补一句上下文:上面表格里的「社区代理」指的是 hairyf/codex-deepseek-proxy。

它把根因定位到 agent_message / encrypted_content 这一步是完全正确的 —— 那也正是这次修复必须保留的核心;被列出的四条只是当时针对 v4 时代网关行为写的 workaround,在我这次实测的网关版本上已经不需要,属于「可以精简」,而不是写错。

<!-- gh-comment-id:5698116308 --> @nothing0here commented on GitHub (Sep 16, 2026): 补一句上下文:上面表格里的「社区代理」指的是 [hairyf/codex-deepseek-proxy](https://github.com/hairyf/codex-deepseek-proxy)。 它把根因定位到 `agent_message` / `encrypted_content` 这一步是完全正确的 —— 那也正是这次修复**必须保留**的核心;被列出的四条只是当时针对 v4 时代网关行为写的 workaround,在我这次实测的网关版本上已经不需要,属于「可以精简」,而不是写错。
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
deepseek-ai/awesome-deepseek-agent#116
No description provided.