兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
# 为什么“声明工具”会改变模型回答风格?一次排查记录 最近在对比 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_datetime` - `get_time` - `f1` 直觉上,第一个更像真实 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,甚至不是同一种任务模式。
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章