Commit 9818aa95 by luoqi

docs(助手): 撤回「qwen 结构上做不到边写边调工具」—— 那是伪证据,且早被裸台验过

产品指出后复核,8-14 写在 use-assistant-chat 里的那段"能力判断"两处推理都断:

① 「百炼文档示例里出 tool_calls 那轮 content 为空 ⇒ 那一步写不了字」——
   示例是一次示范、不是契约;"某个示例没写字"推不出"写不了"。
② 「一旦某步没有工具调用多步循环就结束 ⇒ 所以它只能先把工具全调完再一口气写完」——
   前半句对**任何模型都成立**(deepseek 也一样),而且恰恰不推出后半句:
   文字+工具、文字+工具、末步只有文字,循环照样结束、输出照样交错。这个「所以」是空的。

🔴 **而且它早就被验过了,结论相反。** assistant-lab 就是为这件事建的裸台,
   里面专门开了 qwenThinking provider(只塞 enable_thinking, 不碰 response_format),
   目的写在那儿:「这一轮只是要验开了思考 qwen 会不会好起来」。
   产品实测:**开了思考的 qwen 能边写正文边调工具**。⇒ 那条结论已被推翻, 别再引用。

️ 更该记的是:反证**当时就摆在旁边**。同一天的注释写着"共用 provider 无条件给
   每个 qwen 请求塞 enable_thinking=false,连 agent 这条带工具的链路也塞 ⇒ 这几天
   拿 qwen 跟 DeepSeek 比要不要边写边调工具,其实是「便宜档+会思考」对「最高档+不许思考」,
   比较本身不成立" —— 而"这几天"正是那条结论的产出期。两份注释直接打架,日期都是 8-14。
    根子在:结论只留在人脑子里,被它推翻的旧结论却用硬语气写在代码里,
   下一个人(包括 AI)读到的必然是错的那份。

顺带修正 assistant-chat 里那条退化保护的**归因**:原文写"实测 qwen 会把 tool-call
全提到文本之前,deepseek 则正常交错",当成模型差别。不对 —— 当天在 **deepseek** 上
抓到过同一形状(golden 的 guidance-opens-in-place,失败形状 [工具×3][文本]),
是补了工具描述里「可动手的事**一件一件**开放」才稳住的,那是**提示词缺口**。
⇒ 那条保护**与模型无关,一直留着**:退化时主管看到的是一排没头没尾的按钮。

现在只保留一句站得住的:**默认 deepseek,因为跑批基线都在它上面测的。**
 别写成"另一个不行"。要比就在裸台上开着思考比,或 GOLDEN_MODEL=qwen3.8-max
跑 guidance-opens-in-place 比通过率。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
parent 5ce0ec6e
...@@ -715,10 +715,18 @@ function MessageView({ ...@@ -715,10 +715,18 @@ function MessageView({
* 🔴 **选项上面必须有话** —— 引导块落在第一个文本块之前时它是无根的: * 🔴 **选项上面必须有话** —— 引导块落在第一个文本块之前时它是无根的:
* 主管看到四个按钮,而"这是在说哪件事"还没写出来。 * 主管看到四个按钮,而"这是在说哪件事"还没写出来。
* *
* ⚠️ 这不是又去猜位置,是一条**退化保护**:实测 qwen 会把这一轮的 tool-call * ⚠️ 这不是又去猜位置,是一条**退化保护**:模型会把这一轮的 tool-call
* 全部提到文本之前(`[工具×4][文本]`),deepseek 则正常交错 * 全部提到文本之前(`[工具×4][文本]`),而正常形态是交错的
* (`[文本][工具][文本][工具]…`)。⇒ 无根的一律挪到正文之后、卡片之前。 * (`[文本][工具][文本][工具]…`)。⇒ 无根的一律挪到正文之后、卡片之前。
* ⛔ 别把有根的也一起挪 —— 那就把模型定的位置又推翻了。 * ⛔ 别把有根的也一起挪 —— 那就把模型定的位置又推翻了。
*
* 🔴 **2026-08-15 修正归因**:这条原文写的是「实测 **qwen** 会…,deepseek 则正常交错」,
* 把它当成了模型之间的差别。**不对** —— 当天在 **deepseek** 上抓到过同一个形状
* (golden 的 `guidance-opens-in-place`,失败形状 `[工具×3][文本]`),
* 是补了工具描述里「可动手的事**一件一件**开放」才稳住的。
* ⇒ 这是**提示词缺口**的表现,⛔ 不是某个模型的特性;那次观察从没把两者分开。
* ⚠️ 所以这条保护**与模型无关,一直要留着**:即便换了模型、改好了提示词,
* 它仍然有概率退化,而退化时主管看到的是一排没头没尾的按钮。
*/ */
const firstText = rest.findIndex((b) => b.kind === 'text'); const firstText = rest.findIndex((b) => b.kind === 'text');
const isRooted = (i: number) => firstText !== -1 && i > firstText; const isRooted = (i: number) => firstText !== -1 && i > firstText;
......
...@@ -81,17 +81,45 @@ export function useAssistantChat() { ...@@ -81,17 +81,45 @@ export function useAssistantChat() {
*/ */
const [busyIntent, setBusyIntent] = useState<string | null>(null); const [busyIntent, setBusyIntent] = useState<string | null>(null);
/** /**
* 默认模型 —— 🔴 2026-08-14 由 `qwen` 改成 `deepseek`,**这是能力判断,不是偏好** * 默认模型 = `deepseek`(2026-08-14 由 `qwen` 改过来)
* *
* 助手的排版靠模型在写字的**同一条消息里**顺手调 `show_sheet` / `show_guidance` * 助手的排版靠模型在写字的**同一条消息里**顺手调 `show_sheet` / `show_guidance`
* (content 与 tool_calls 并存),前端按到达顺序追加块,位置由此确定。 * (content 与 tool_calls 并存),前端按到达顺序追加块,位置由此确定。
* · DeepSeek:官方文档的多轮拼接示例里 content / reasoning_content / tool_calls 三者并存 ⇒ 做得到。
* · 百炼 qwen:文档示例里出 tool_calls 那一轮 `"content": ""` ⇒ 那一步写不了字;
* 而一旦某步没有工具调用,多步循环就结束(finishReason='stop')——
* **所以它只能"先把工具全调完、再一口气写完",是结构上被逼的,⛔ 不是提示词能改的。**
* *
* ⚠️ 换默认模型**不是**给 qwen 打补丁:qwen 仍可在下拉里选,只是它那条链路上 * 🔴 **2026-08-15 撤回原来那段"能力判断"** —— 它是**伪证据**,两处推理都断:
* 位置永远是退化态(无根 → 挪到正文之后 + 补小标题)。 * ① 「百炼文档的示例里出 tool_calls 那轮 `"content": ""` ⇒ 那一步写不了字」——
* 示例是一次示范、不是契约;"某个示例没写字"推不出"写不了"。
* ② 「一旦某步没有工具调用,多步循环就结束 ⇒ 所以它只能先把工具全调完再一口气写完」——
* 前半句对**任何模型都成立**(deepseek 也一样),而且它恰恰不推出后半句:
* 文字+工具、文字+工具、末步只有文字,循环照样正常结束、输出照样交错。这个「所以」是空的。
* ⚠️ 它当时还带着 ⛔「不是提示词能改的」这种硬结论 —— 而**今天的实测正好反证**:
* DeepSeek 在旧提示词下也会出一模一样的形状(`[工具×3][文本]`,见 golden 的
* `guidance-opens-in-place`),是补了工具描述里那句「可动手的事**一件一件**开放」
* 才稳住的。⇒ 8-14 那次观察从没把「模型能力」和「提示词缺口」分开。
*
* 🔴 **而且它早就被验过了 —— 结论相反。**(产品指出,2026-08-15)
* `assistant-lab`(`lab.controller.ts`)就是为这件事建的裸台,里面专门开了一个
* `qwenThinking` provider(只塞 `enable_thinking`,⛔ 不碰 response_format),
* 目的写在那儿:「这一轮只是要验**开了思考 qwen 会不会好起来**」。
* **产品实测结果:开了思考的 qwen 能边写正文边调工具。**
* ⇒ 「结构上做不到」这条**已被推翻**,⛔ 别再引用。
*
* ⚠️ 那条被推翻的结论**当时就有反证摆在旁边**:同一天的注释写着
* 「共用 provider 无条件给每个 qwen 请求塞 `enable_thinking = false`,连 agent 这条
* 带工具的链路也塞 ⇒ 这几天拿 qwen 跟 DeepSeek 比'要不要边写边调工具',其实是
* **「便宜档 + 会思考」对「最高档 + 不许思考」**,比较本身不成立」——
* 而"这几天"正是本条结论的产出期。两份注释直接打架,日期都是 2026-08-14。
*
* ⇒ 现在只保留一句能站住的:**默认是 deepseek,因为跑批基线都在它上面测的**。
* ⛔ 别把它写成"另一个不行"。要比就在裸台上开着思考比,或
* `GOLDEN_MODEL=qwen3.8-max` 跑 `guidance-opens-in-place` 比通过率。
* ⚠️ 裸台那次的**具体数没落进代码**(只有机制和开关)—— 这正是这次出错的根:
* ⛔ 结论只留在人脑子里,而被它推翻的旧结论却用硬语气写在代码里,
* 下一个人(包括 AI)读到的必然是错的那份。
*
* ⚠️ 下面那条**退化保护**(无根 → 挪到正文之后 + 补小标题)**照旧留着**:
* 它防的是"按钮出现在解释之前"这个现象本身,与是哪个模型造成的无关 ——
* 今天证明 deepseek 也会。
* ⛔ 别为了"两个模型看起来一样"再往 `assistant-chat` 的排版里加分支 —— * ⛔ 别为了"两个模型看起来一样"再往 `assistant-chat` 的排版里加分支 ——
* 2026-08-14 已经为此翻过一次车(历史里留位置空壳,模型把标记当正文写了出来)。 * 2026-08-14 已经为此翻过一次车(历史里留位置空壳,模型把标记当正文写了出来)。
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment