【Agent Harness】流马(Gliding Horse)DeepSeek Responses API 接入介绍
DeepSeek Responses API 接入说明
Commit:
4391ba3— update Responses API support
日期: 2026-08-04
范围:src/gateway/unified_gateway.rs、src/llm/sse.rs、src/config/settings.rs、apps/gliding_code/src/config.rs、config.yaml及测试适配
1. 背景
DeepSeek 官方推出 Responses API(POST /v1/responses)作为新一代接口,相比 Chat Completions 具备语义化的流式事件(response.*)、显式的工具调用往返结构、原生推理内容(reasoning)输出等能力。截至 2026-08-04,该接口仅支持 deepseek-v4-flash 模型(deepseek-v4-pro 预计 2026 年 8 月初启用)。
本次修改为 Gliding Horse 接入 Responses API,同时保持对 Chat Completions 的完全兼容:
deepseek-v4-flash请求默认路由到/v1/responses;- 其余模型(含
deepseek-v4-pro)自动回退到/v1/chat/completions; - 下游调用方(Agent Runner、工具执行器、TUI 等)无感知——两种协议在网关层统一收敛为内部
ChatCompletionResponse/StreamEvent词汇表。
2. 整体架构
设计要点:Responses API 是网关内部的一条协议适配分支,所有 Responses 特有的结构(input items、semantic events)都在网关 / SSE 解析层完成转换,业务层看到的数据形状与 Chat Completions 完全一致。
3. 配置与开关
3.1 配置项
| 位置 | 字段 / 变量 | 默认值 | 说明 |
|---|---|---|---|
src/config/settings.rs |
GatewaySettings.use_responses_api |
false(程序化默认)/ true(CLI 默认) |
是否启用 Responses API 路由 |
config.yaml |
gateway.use_responses_api |
true |
YAML 配置入口 |
apps/gliding_code/src/config.rs |
USE_RESPONSES_API |
true |
环境变量,1 / true 视为开启 |
| 同上(兼容) | AGENT_OS_GATEWAY_USE_RESPONSES_API |
— | 兼容别名 |
unified_gateway.rs |
set_use_responses_api(&self, enabled: bool) |
— | 运行时动态切换 |
# config.yaml 示例
gateway:
base_url: "https://api.deepseek.com"
api_key: "sk-..."
timeout_seconds: 300
max_retries: 3
retry_base_ms: 500
# deepseek-v4-flash 走 Responses API (/v1/responses),deepseek-v4-pro 继续走 chat completions
use_responses_api: true
model_mapping:
planning: "deepseek-v4-pro"
execution: "deepseek-v4-flash"
# 环境变量方式
export USE_RESPONSES_API=1 # 显式开启
export USE_RESPONSES_API=0 # 强制走 chat completions
3.2 模型能力判定
/// 仅 deepseek-v4-flash 支持 Responses API;
/// deepseek-v4-pro 在 DeepSeek 启用前继续使用 chat completions。
fn is_responses_capable_model(model: &str) -> bool {
let m = model.to_lowercase();
m == "deepseek-v4-flash" || m.starts_with("deepseek-v4-flash-")
}
fn should_use_responses_api(&self, model: &str) -> bool {
*self.use_responses_api.read().unwrap() && Self::is_responses_capable_model(model)
}
即使
use_responses_api为true,非deepseek-v4-flash模型也绝不会被路由到/v1/responses——这是硬性安全边界,防止对尚不支持该接口的模型产生 400 错误。
4. 非流式请求(chat / chat_with_model / chat_with_params)
4.1 消息转换:responses_input_items
| Chat Completions 消息 | Responses API input item |
|---|---|
第一条非空 system |
instructions(顶层字段) |
其余 system / developer / user |
{type: message, role, content:[{type: input_text, text}]} |
assistant(无工具调用) |
{type: message, role: assistant, content:[{type: output_text, text}]} |
assistant(有工具调用) |
message item + 每个调用一个 {type: function_call, call_id, name, arguments} |
tool |
{type: function_call_output, call_id, output} |
4.2 工具定义转换:convert_responses_tools
Chat Completions 将函数定义嵌套在 function 键下,Responses API 要求扁平结构:
// chat completions(入参)
{ "type": "function", "function": { "name": "get_weather", "description": "...", "parameters": {...} } }
// responses(转换后)
{ "type": "function", "name": "get_weather", "description": "...", "parameters": {...} }
非函数工具(web_search、自定义工具)原样透传。
4.3 响应解析:parse_responses_response
关键点:Responses API 的 usage 字段是 input_tokens / output_tokens,而 Chat Completions 是 prompt_tokens / completion_tokens——解析层完成归一化,下游统计与计费展示无需改动。
4.4 重试与错误处理:send_with_retry
两种协议共享同一重试骨架(重构自原有逻辑):
- 指数退避:
retry_base_ms * 2^(attempt-1); - 4xx 客户端错误立即终止(不重试),并将请求体前 8K 字符嵌入错误信息便于 TUI 直接排查;
- 5xx / 网络错误按
max_retries重试; - 解析失败(JSON 无效 / 结构不符)也会重试并记录响应长度日志。
5. 流式请求(stream_chat_with_params)
5.1 事件映射:parse_responses_api_event
Responses API 流由语义事件组成(type: "response.*"),且没有 data: [DONE] 终止帧——终止由 response.completed / response.incomplete / response.failed 承担。parse_frame 通过 type 前缀分流到 Responses 解析器:
| Responses API 事件 | 内部 StreamEvent | 备注 |
|---|---|---|
response.created |
MessageStart { id, model } |
记录 message_id / model |
response.output_item.added(function_call / custom_tool_call) |
ContentBlockStart { ToolUse{id, name} } |
工具块开始 |
response.output_text.delta |
ContentBlockDelta { TextDelta } |
正文增量 |
response.reasoning_text.delta |
ContentBlockDelta { ThinkingDelta } |
推理内容(TUI 中以思考步骤呈现) |
response.function_call_arguments.delta |
ContentBlockDelta { ToolCallDelta{arguments} } |
工具参数增量 |
response.custom_tool_call_input.delta |
ContentBlockDelta { ToolCallDelta{arguments} } |
自定义工具参数增量 |
response.completed |
MessageDelta { finish_reason } |
completed+有工具调用 → tool_calls;否则 → stop;附 usage |
response.incomplete |
MessageDelta { finish_reason: "length" } |
输出截断 |
response.failed |
MessageDelta { finish_reason: "error" } |
失败 |
5.2 流式终止语义
5.3 与 Chat Completions 流式路径的关系
SseParser/MessageStream/StreamAccumulator完全复用;- 差异仅在
parse_frame内部:response.*前缀走新解析器,其余走原有parse_openai_stream_event; [DONE]帧仍被兼容处理(parse_frame中payload == "[DONE]"返回None),因此两种协议可在同一代码路径内共存。
6. 调用链全景
7. 配置与使用示例
7.1 完整启用配置
# 1) API Key
export DEEPSEEK_API_KEY="sk-..."
# 2) 显式启用 Responses API(v4-flash 默认已开启,可省略)
export USE_RESPONSES_API=1
# 3) 运行 Gliding Code,默认模型 deepseek-v4-flash 即走 /v1/responses
./glidingcode "设计一个知识图谱的 schema"
# 4) 切换到 v4-pro(自动回退 chat completions)
./glidingcode --model deepseek-v4-pro "分析这段代码的时间复杂度"
7.2 运行时动态切换(编程接口)
// 任意时刻可切换,无需重建网关
gateway.set_use_responses_api(false); // 强制全部模型走 chat completions
gateway.set_use_responses_api(true); // 恢复 v4-flash 走 responses
7.3 观察点
| 现象 | 说明 |
|---|---|
日志出现 LLM API call successful |
非流式调用完成(含 usage) |
流式正常结束、无 [DONE] 依赖 |
说明 response.completed 终止事件被正确解析 |
| TUI 中出现可展开的思考步骤 | response.reasoning_text.delta → ThinkingDelta → thinking 聚合 |
| 工具调用正常往返 | function_call items / function_call_arguments.delta 转换正确 |
| 4xx 错误附 8K 请求体预览 | 便于直接定位请求构造问题 |
8. 测试覆盖
新增 / 适配的测试(cargo test --lib,全量 1193 项通过):
| 测试 | 位置 | 验证点 |
|---|---|---|
test_build_responses_body_converts_messages |
unified_gateway.rs |
messages → instructions + input items 转换 |
test_responses_api_text_stream |
sse.rs |
文本流全链路(created + delta + completed)聚合正确 |
test_responses_api_no_done_terminator |
sse.rs |
不依赖 [DONE],completed 即终止 |
test_responses_api_reasoning_delta |
sse.rs |
推理增量 → thinking 聚合 |
test_responses_api_tool_call_stream |
sse.rs |
function_call_arguments.delta → 工具调用聚合 |
test_responses_api_custom_tool_call_delta |
sse.rs |
自定义工具参数增量解析 |
test_responses_api_incomplete_sets_length |
sse.rs |
response.incomplete → finish_reason: length |
test_responses_api_failed_sets_error |
sse.rs |
response.failed → finish_reason: error |
test_responses_api_live_non_streaming / _streaming / _tool_call |
unified_gateway.rs |
真实 API 端到端(无 DEEPSEEK_API_KEY 时自动跳过) |
各模块 use_responses_api: false 适配 |
4 处测试结构体 | 新字段向后兼容 |
9. 边界与限制
- 模型支持面:Responses API 目前仅
deepseek-v4-flash;deepseek-v4-pro在官方启用前自动走 chat completions(is_responses_capable_model硬性判定)。 - 温度等参数:思考模式下
temperature等参数不生效(DeepSeek 文档说明,兼容性静默忽略,不报错);网关仍透传参数,由 API 侧处理。 - 无降级重试:若
/v1/responses返回 4xx(如参数不合法),不会自动降级到 chat completions——这是有意设计,避免掩盖请求构造错误;可通过set_use_responses_api(false)手动回退。 - 流式终止:Responses 流没有
[DONE];若服务端异常断流且无终止事件,MessageStream依赖底层 HTTP 流结束(None)自然终止。 - usage 归一化:
input_tokens/output_tokens→prompt_tokens/completion_tokens的映射在解析层完成,计费展示沿用原有逻辑。
10. 文件变更清单
| 文件 | 变更 | 说明 |
|---|---|---|
src/gateway/unified_gateway.rs |
+678 | Responses API 非流式/流式接入、消息与响应转换、重试重构、运行时开关、测试 |
src/llm/sse.rs |
+323 | parse_responses_api_event 语义事件解析、流式测试 |
src/config/settings.rs |
+5 | GatewaySettings.use_responses_api 字段 |
apps/gliding_code/src/config.rs |
+8 | 环境变量读取(USE_RESPONSES_API / 兼容别名),默认开启 |
config.yaml |
+2 | 配置项与注释 |
src/core/agent_runner/tests.rs |
+1 | 结构体字段适配 |
src/core/sa/tests.rs |
+1 | 结构体字段适配 |
src/skill_graph/skill_creator.rs |
+4 | 结构体字段适配 |
src/tools/tool_executor/tests.rs |
+1 | 结构体字段适配 |
src/worker/agent_os_worker.rs |
+2 | 结构体字段适配 |
浙公网安备 33010602011771号