Prhub

#44391 [Rust Frontend] Support include_reasoning=false

原始 PR 作者 ricky-chaoju 合并时间 2026-06-05 16:47 文件变更 4 提交数 4 评论 7 代码增减 +544 / -26

执行摘要

支持 Rust 前端 include_reasoning=false

关联 issue #44280(Rust Frontend 特征路线图)指出 include_reasoning=false 是 OpenAI API 的标准参数,Python 前端已支持,Rust 前端需要补齐。用户在与推理模型交互时可能需要选择不暴露推理链,该 PR 填补了这一功能缺口。

该 PR 是 Rust 前端特征补齐的关键一步,代码设计清晰,特别是在防止信息泄露方面考虑周全。建议 Rust 前端开发者精读,尤其是流式响应中元数据抑制的实现模式。也可作为参考,了解如何安全地隐藏敏感内容而不留下旁路。

讨论亮点
  • BugenZhao 关于变量命名与设计:建议将 suppress_output_metadata 改为正面命名 include_output_metadata,并添加注释;建议将 suppressed_reasoning 状态维护为局部变量,避免 PendingChunk 依赖 include_reasoning。提交者采纳了建议。
  • Codex 自动审查发现 logprobs 泄露风险(P1 级别):指出 stream=true, include_reasoning=false, logprobs=true 时 LogprobsDelta 可能泄露隐藏推理 token。提交者通过添加 suppress_current_update_metadata 条件修复,并增加了对应测试。

实现拆解

  1. 移除验证阶段拒绝:在 validate.rsvalidate_request_compat 函数中删除原来对 include_reasoning=false 的拒绝检查,使该参数通过兼容性验证。新增单元测试 validate_request_compat_accepts_include_reasoning_false

  2. 添加请求字段传递:在 convert.rsPreparedRequest 结构体中新增 include_reasoning: bool 字段,并在 prepare_chat_request 函数中从请求中提取并保存。单元测试 prepare_chat_request_preserves_include_reasoning_false 验证保留行为。

  3. 非流式响应处理:在 chat_completions.rscollect_chat_completion 函数中,引入 include_output_metadata = include_reasoning || reasoning.is_none() 条件,控制 reasoning 字段、logprobstoken_ids 的输出,避免隐藏推理 token 通过逐 token 元数据泄露。

  4. 流式响应处理:在 chat_completion_chunk_stream 函数中利用 inside_hidden_reasoningsuppress_current_update_metadata 局部状态,抑制推理块增量并跳过对应的 LogprobsDelta,正确处理 delimiter-only 块场景。

  5. 测试覆盖:新增 include_reasoning_false_suppresses_reasoning_in_non_stream_chatinclude_reasoning_false_suppresses_non_stream_output_metadata 等测试,覆盖非流式、流式及 logprobs 边缘情况。

文件 模块 状态 重要度
rust/src/server/src/routes/openai/chat_completions.rs 路由处理 modified 8.14
rust/src/server/src/routes/tests.rs 测试 modified 7.48
rust/src/server/src/routes/openai/chat_completions/validate.rs 请求验证 modified 6.08
rust/src/server/src/routes/openai/chat_completions/convert.rs 请求转换 modified 5.98

关键符号

validate_request_compat prepare_chat_request collect_chat_completion chat_completion_chunk_stream PendingChatChunk::push_block_delta include_reasoning_false_suppresses_reasoning_in_non_stream_chat include_reasoning_false_suppresses_non_stream_output_metadata

关键源码片段

rust/src/server/src/routes/openai/chat_completions.rs core-logic

核心逻辑文件,实现非流式和流式响应中 `include_reasoning=false` 的抑制逻辑,包括 `include_output_metadata` 条件和流式状态管理。

// 从引擎收集的 assistant 消息中提取 reasoning 内容
let reasoning = message.reasoning();// 当用户指定了 include_reasoning=false 且消息包含 reasoning 时,
// 不仅隐藏 reasoning 字段,还必须隐藏关联的逐 token 元数据,
// 例如 logprobs 和 token_ids,防止信息泄露。
let include_output_metadata = include_reasoning || reasoning.is_none();// 仅在 include_output_metadata 为 true 时输出 logprobs
let logprobs = if requested_logprobs && include_output_metadata {
    Some(decoded_logprobs_to_openai_chat(
        logprobs.as_ref().ok_or_else(|| {
            server_error!("chat response requested logprobs but generation returned none")
        })?,
        return_tokens_as_token_ids,
    )?)
} else {
    None
};// 构造最终响应时,reasoning 字段受 include_reasoning 直接控制
ChatCompletionResponse {
    choices: vec![ChatCompletionResponseChoice {
        reasoning: if include_reasoning { reasoning } else { None },
        logprobs,
        token_ids: (return_token_ids && include_output_metadata).then_some(token_ids),
        // ... 其他字段
    }],
    // ... 其他字段
}

评论区精华

变量命名与 PendingChunk 状态设计 设计

BugenZhao 建议将 `suppress_output_metadata` 改为正面命名 `include_output_metadata`,并添加注释说明。同时建议将 `suppressed_reasoning` 状态作为局部变量维护,避免 `PendingChunk` 依赖 `include_reasoning`。

结论:提交者采纳了建议,修改为 `include_output_metadata`,并将隐藏 reasoning 抑制状态移入 `chat_completion_chunk_stream` 的局部变量。 · 已解决

Logprobs 泄露隐藏推理 token 安全

Codex 自动审查指出当 stream=true, include_reasoning=false, logprobs=true 时,logprobs 块会泄露推理 token 的文本内容。深度优先安全审查也确认了非流式路径中 logprobs 泄露风险。

结论:提交者通过添加 `suppress_current_update_metadata` 条件修复,确保当推理被隐藏时,对应的 LogprobsDelta 也被跳过。并增加了对应测试。 · 已解决

风险与影响

主要风险:

  • logprobs/token_ids 泄露隐藏推理 token:非流式和流式路径已通过 include_output_metadatasuppress_current_update_metadata 条件过滤,但需持续关注其他元数据字段是否完全覆盖。
  • 流式 delimiter-only 块边缘情况:单独的推理分隔符 token 可能触发元数据残留,当前已处理,但不同 tokenizer 行为可能引入未预期情况。
  • 行为一致性:Rust 前端与 Python 前端在 include_reasoning=false 下的行为需对齐,当前缺乏交叉对比测试。

用户影响:Rust 前端用户现在可以使用 include_reasoning=false 参数隐藏推理内容,与 OpenAI API 规范一致。系统影响:无向后兼容性问题,默认 include_reasoning=true 行为不变,性能开销可忽略。团队影响:后续需维护与 Python 前端的行为一致性,并在新增推理模型时确保相容。

logprobs 泄露 流式边缘情况 行为一致性

关联 Issue

#44280 [Roadmap] Rust Frontend Feature Parity

完整报告

参与讨论