为什么“声明工具”会改变模型回答风格?一次排查记录
最近在对比 OpenRouter 与直连 DeepSeek 原生接口时,我遇到了一个非常容易让人误判的问题:
同一个问题,OpenRouter 上的回答明显更完整、更结构化;而直连 DeepSeek 时,即使 prompt 基本一致,回答却明显更短。
问题示例:
请介绍港英时期的立法局。
在 OpenRouter 上,模型通常会给出一篇结构清晰、分节完整的长回答;但在原生调用时,回答明显简短。
起初我怀疑了很多方向,最后却发现真正影响风格的变量是:tools 字段的存在。
即使工具从未被真正调用,模型的输出风格也会发生明显变化。
下面是完整排查过程与当前判断。
一、问题是如何出现的
测试问题非常简单:
请介绍港英时期的立法局。
在 OpenRouter 上,回答通常包含:
- 历史沿革
- 议员构成
- 权力变化
- 关键改革节点
- 制度转型
而直连 DeepSeek 时,即便做了如下处理:
- system prompt 为空或接近为空
- 显式设置
reasoning_effort=high max_tokens拉到 128000- 检查流式输出是否丢 chunk
结果仍然是:回答偏短。
当时最困惑的一点是:
prompt 差不多,为什么输出风格差这么多?
二、排除的几个错误方向
1️⃣ 不是 max_tokens 问题
即使把 max_tokens 提到 128000,回答依然简短。
✅ 排除“被截断”的可能。
2️⃣ 不是流式输出解析问题
我将完整请求与响应全部落盘,包括原始流式事件。
回溯后确认:
✅ 数据没有在解析过程中丢失。
3️⃣ 不只是 reasoning_effort=high
怀疑 OpenRouter 默认推理强度更高。
但测试发现:
✅ 单纯提高推理强度,并不能稳定复现那种“像写完一篇文章”的结构化输出。
三、关键发现:OpenRouter 不是“裸请求”
翻查 OpenRouter 的对话链后发现:
- assistant 曾发起
tool_calls - 调用了
openrouter_datetime - 存在 tool 角色返回
也就是说,我对比的并不是:
用户提问 → 模型回答
而更像是:
带 agent 环境的上下文运行模式
模型知道自己:
- 可以调用工具
- 处于 agent 执行环境
- 需要先规划再交付结果
于是我做了一个对照实验:
在原生 DeepSeek 请求中,也注册同名工具 openrouter_datetime。
结果:
✅ 输出风格立即变长
✅ 出现提纲式推理
✅ 正文结构明显更完整
而这个工具——根本没有真正被调用。
四、真正起作用的是什么?
不是工具返回的信息。
而是:
工具的“存在”本身改变了模型的任务理解。
工具字段并不是可以忽略的小参数。
它是一个强环境信号:
- 你现在不只是聊天
- 你处在 agent 环境
- 你拥有外部行动能力
- 你需要先判断是否要调用工具
- 你应该规划答案,而不是随口给个简答
五、为什么没调用工具也会影响输出?
LLM 并不是按代码分支执行:
if 调用工具:
进入 A 模式
else:
忽略 tools
模型会把整个请求体当作上下文的一部分。
包括:
- 用户问题
- 工具名称
- 工具描述
- 参数 schema
- 当前支持 tool calling 的环境
即使最后没发起 tool_call,这些信息已经影响了行为方式。
六、我观察到的三层效应
1️⃣ 规划倾向增强
模型更像“执行任务的助手”,而非闲聊机器人。
更容易:
- 先分析任务
- 列出回答结构
- 再展开正文
2️⃣ 完整性标准提高
普通问答模式:
给个正确简答就够。
Agent 模式:
需要交付一份完整结果。
于是背景、分期、定义、结论自动补齐。
3️⃣ Tool-calling 训练“溢出”
现代模型大量训练过:
- tool use
- function calling
- agent workflow
这些训练带来的不仅是“会调工具”,还包括:
- 审题
- 找信息缺口
- 规划步骤
- 组织结构
- 最终交付
即便没有真正调用工具,这套行为模式可能已经被触发。
七、工具名本身也可能是变量
实验中使用的工具名:
openrouter_datetime
这个名字语义很强,暗示:
- 类似 OpenRouter 的环境
- agent 框架内置工具
对比:
openrouter_datetimeget_timef1
直觉上,第一个更像真实 agent 环境。
虽然无法百分百证明工具名权重,但它很可能也是影响因子。
八、对开发者的启示
很多人做模型对比时,只对齐:
- prompt
- model 名字
- token 限制
但真正影响模型状态的还包括:
- 是否声明 tools
- 工具名称
- 工具描述
- 是否存在多轮 agent 上下文
- 平台是否注入隐藏 system prompt
- 是否允许 function calling
- 是否存在 planner / router / middleware
很多“模型质量差异”,本质可能是:
运行时环境差异。
九、一句话总结
工具不一定要被调用,光是“工具存在”,就足以把模型从普通问答模式推向 agent 模式。
于是现象变得合理:
- OpenRouter 更详细
- 原生 DeepSeek 裸调用更短
- 加上 tools 后风格突然靠近
十、可以继续做的对照实验
1️⃣ 有工具 vs 无工具
只改 tools 字段,其余完全不变。
2️⃣ 工具名有语义 vs 无语义
对比:
- openrouter_datetime
- get_time
- f1
3️⃣ 工具描述详细 vs 敷衍
对比:
Get the current datetime in UTC.tool
4️⃣ 有 thinking vs 无 thinking
拆开控制:
- 工具模式
- 推理模式
看两者是叠加关系还是单一主导。
结语
对大模型来说,API 参数不是“纯配置”。
很多字段本身就是 prompt 的一部分。
tools 表面是功能开关,实际上在告诉模型:
- 你扮演什么角色
- 你处在什么环境
- 你的能力边界
- 输出应该达到什么标准
有时候改变输出的不是“信息变多”,而是:
模型意识到这次不能随便答一下。
如果你也遇到:
- 同样问题在不同平台回答风格差很多
- prompt 很像但一个版本更完整
- 开了 function calling 之后模型突然“变聪明”
建议回头检查:
你比较的可能不是同一个 prompt,甚至不是同一种任务模式。