Skip to content

[Bug] autoDream 在记忆量较大且路由为思考型模型时 100% 失败:no json array in llm output #9

Closed

Description

@483218131

环境

  • dsh-mneme 0.1.x ~ 0.4.2 均存在(dream.js 的 streamText 逻辑全版本一致)
  • DeepSeek Harness 0.1.0-rc.7,dsh web profile
  • dream 路由:基元律动 / deepseek-v4-flash-0731(思考型模型)
  • dreamMaxTokens: 32768(已确认传入请求)

现象

  • dream_runs 140+ 次运行全部失败(applied=0),错误均为 "no json array in llm output"
  • 记忆从不自动合并/去重,重复条目持续累积,库越大越严重
  • 记忆较少时(约 50 条内)dream 可正常输出 JSON

根因(代码级)

  • lib/dream.js 的 streamText() 只收集 text-delta chunk:

    if (chunk.type === "text-delta" && typeof chunk.text === "string") text += chunk.text;

  • 思考型模型在大量输入下把全部输出预算用于思考,正文(text-delta)为 0:

    • 诊断日志实测 chunk 分布:{ "reasoning-delta": 32768, "text-delta": 0 }(思考内容吃满 maxTokens)
    • 直连 API 严格解析(区分 content / reasoning_content):content=0 字符,reasoning=80577 字符,finish_reason=length
  • 即:runDream 一次全量处理全部记忆(~125KB 输入)+ 无思考控制参数 → 思考型模型必然把预算耗尽在 thinking 上,正文为空 → no json array

复现步骤

  1. 开启 autoDream(默认配置),记忆增长到 500+ 条(dream 输入约 125KB)
  2. 等待 dream 自动触发(达到 dreamThresholdCount)
  3. 查看 dream_runs 表:全部 failed,applied=0,error="no json array in llm output"

影响

  • autoDream(记忆巩固/去重)在记忆量较大时完全失效
  • 记忆只增不减(无合并),重复条目累积
  • 随记忆库增长问题必然加剧(输入越大思考越久)

修复建议(按优先级)

方案 A:dream 请求支持思考控制(关闭思考)

已实测:全量输入(~125KB)+ thinking: {type: "disabled"} → 52 秒输出 JSON 决策(配合充足输出上限则完整)。建议 streamText 调用支持透传 thinking 参数,或提供 dreamReasoningEffort 配置。

方案 B:提高 dreamMaxTokens 上限(32768 → 更大)

已实测:全量输入 + 32768 → 正文为空(finish_reason=length);提高到 131072 → 正文完整输出(finish_reason=stop)。当前 schema z.max(32768) 限制了用户自救空间。

方案 C(长期):升级为「增量巩固 + 分批窗口」

只处理自上次 checkpoint 的新增/变更记忆,或分批巩固——使 dream 成本与记忆库规模解耦(当前一次全量处理,记忆越多越慢/越容易失败)。

备注

  • 以上验证均为同一网关、同一模型、严格解析(content 与 reasoning_content 区分)的直连 API 实测
  • 现象与直连结果完全一致,排除请求链路差异

Activity

  1. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    感谢提供极其详尽的根因分析与实测数据!我们完全认可你的判断:当前 streamText() 仅捕获 text-delta,而思考型模型在大输入下会将预算全数用于 reasoning-delta,直接导致正文归零与 JSON 解析失败。你记录的 chunk 占比与 API 截断数据极具参考价值。

    修复推进如下:

    • 方案 B 优先级最高,将作为热修快速放宽 dreamMaxTokens 与 schema 约束;
    • 方案 A 同步开发,后续作为路由层开关开放调用;
    • 方案 C 已列入长期重构路线,旨在彻底解耦处理成本。

    为加速合入,想确认两点:1. 当前路由是否仍需保留思考能力用于其他非 JSON 链路?2. 若我们优先提交 B+A 的修复分支,是否方便协助本地回归验证?期待反馈,再次感谢!

  2. 483218131 commented on Aug 18, 2026

    @483218131
    ContributorAuthor

    感谢提供极其详尽的根因分析与实测数据!我们完全认可你的判断:当前 仅捕获 ,而思考型模型在大输入下会将预算全数用于 ,直接导致正文归零与 JSON 解析失败。你记录的 chunk 占比与 API 截断数据极具参考价值。streamText()``text-delta``reasoning-delta

    修复推进如下:

    • 方案 B 优先级最高,将作为热修快速放宽 与 schema 约束;dreamMaxTokens
    • 方案 A 同步开发,后续作为路由层开关开放调用;
    • 方案 C 已列入长期重构路线,旨在彻底解耦处理成本。

    为加速合入,想确认两点:1.当前路由是否仍需保留思考能力用于其他非 JSON 链路?2.若我们优先提交 B+A 的修复分支,是否方便协助本地回归验证?期待反馈,再次感谢!

    感谢认可!两个问题答复如下:

    1. 当前路由需要保留思考能力

    deepseek-v4-flash-0731 是我们主对话的默认模型(agent-default-model),主对话大量使用且需要正常推理思考。因此建议方案 A 实现为请求级/用途级开关(dream 请求关闭思考、主对话保持默认),而非路由级全局关闭——否则会波及主对话。mneme 侧可在 dream 的 LLM 调用中透传 reasoningEffort 参数实现按需关闭(我们本地已在 streamText 调用处验证了该透传字段)。

    2. 愿意协助本地回归验证

    我们的环境就是完整复现环境:

    • dsh web + dsh-mneme(0.3.9 / 0.4.2)+ token-rhythm / deepseek-v4-flash-0731,记忆库 500+ 条(dream 输入约 125KB)
    • 现有 148 次失败记录可作基线对照(dream_runs 全 failed,applied=0)
    • 本地已预验证:方案 B(max_tokens=131072)思考模式 438s 完整输出(finish=stop);方案 A(thinking disabled)52s 输出 JSON 决策
    • 回归通过标准:dream_runs 出现 applied>0
  3. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    感谢确认,两点都清楚了!

    关于方案 A 的实现方式:完全采纳「请求级/用途级开关」的建议——我们会让 dream 的 LLM 调用透传 reasoningEffort 参数实现按需关闭思考,主对话保持默认思考能力不受影响,绝不做成路由级全局关闭。你提供的透传字段验证结果很有帮助。

    修复推进(按你确认的优先级):

    • 方案 B:放宽 dreamMaxTokens 的 schema 上限(当前 z.max(32768) → 提高到 131072 档),让思考型模型在大输入下有机会完整输出正文;
    • 方案 A:dream 请求支持思考控制(reasoningEffort / disabled),作为配置开关开放。

    修复分支准备就绪后,我们会以 PR 形式提交并在此 issue 回帖。届时方便的话,麻烦你在复现环境里按你提到的回归标准协助验证(dream_runs 出现 applied>0)。感谢你的耐心与详尽配合!

  4. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    0.4.3-beta.1 已就绪,B+A 两项修复都已落地:

    方案 B:dreamMaxTokens schema 上限 32768 → 131072,大记忆量下思考型模型有充足预算输出正文。

    方案 A:新增 dreamReasoningEffort 配置(low/medium/high/none,默认 none),dream 的 LLM 调用按需透传 reasoningEffort;主对话思考不受影响。同步新增 sleepReasoningEffort(sleep 链路同逻辑)。实现细节:none 时字段会省略不传(直接传 none 会在 dsh-llm 抛 UNSUPPORTED_REASONING_EFFORT)。

    本地回归 478 条全绿(含新增 reasoningEffort 透传用例)。验证要点:

    • 思考型模型 + 500+ 条记忆(~125KB)触发 autoDream
    • 通过标准:dream_runs 出现 applied>0

    正式发布 0.4.3 后可直接 npm install @modusensus/[email protected] 回归验证;如果你想提前用 beta 包,我们也可以把 0.4.3-beta.1.tgz 提供给你。期待你的回归结果!

  5. 483218131 commented on Aug 18, 2026

    @483218131
    ContributorAuthor

    0.4.3-beta.1 已就绪,B+A 两项修复都已落地:

    方案 B:dreamMaxTokens schema 上限 32768 → 131072,大记忆量下思考型模型有充足预算输出正文。

    方案 A:新增 dreamReasoningEffort 配置(low/medium/high/none,默认 none),dream 的 LLM 调用按需透传 reasoningEffort;主对话思考不受影响。同步新增 sleepReasoningEffort(sleep 链路同逻辑)。实现细节:none 时字段会省略不传(直接传 none 会在 dsh-llm 抛 UNSUPPORTED_REASONING_EFFORT)。

    本地回归 478 条全绿(含新增 reasoningEffort 透传用例)。验证要点:

    • 思考型模型 + 500+ 条记忆(~125KB)触发 autoDream
    • 通过标准:dream_runs 出现 applied>0

    正式发布 0.4.3 后可直接 npm install @modusensus/[email protected] 回归验证;如果你想提前用 beta 包,我们也可以把 0.4.3-beta.1.tgz 提供给你。期待你的回归结果!

    收到,B+A 落地辛苦了!npm 上还没看到 0.4.3-beta.1(当前 latest 仍是 0.4.2),方便的话请提供 0.4.3-beta.1.tgz,或告知正式 0.4.3 的发布时间——拿到后我立即部署回归验证(dream_runs applied>0 标准)。

    另:我们在本地 131072 验证中发现了一个待同步的问题(涉及 validateDecisions 的决策覆盖,详见回归结果),将随验证一并反馈。

  6. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    更新:0.4.3-beta.1 已发布到 npm(beta tag),可直接安装验证:

    npm install @modusensus/[email protected]

    验证要点同前:思考型模型 + 500+ 条记忆(~125KB)触发 autoDream,通过标准 dream_runs 出现 applied>0。期待你的回归结果,确认后我们即发布正式 0.4.3!

  7. 483218131 commented on Aug 18, 2026

    @483218131
    ContributorAuthor

    0.4.3-beta.1 回归验证完成(npm 官方 registry 安装,note:npmmirror 镜像尚未同步该版本):

    结果:B+A 生效——大输入(636 条记忆,~137KB)下 dream 正常完成正文输出(text-delta 16125 chunk / 30889 字符,无 llm failed),方案 B(131072 预算)+ A(effort 透传)达到设计目标。

    但通过标准(applied>0)未达成:invalid decisions: 677 errors——validateDecisions 报大量 memory missing from decisions。模型输出了完整正文,但无法为 636 条记忆逐条生成决策(漏掉大部分 keep)→ 全量覆盖要求拒绝。这与预算无关(正文已完整),是独立于 B+A 的第二层约束。

    建议:B+A 合并后,记忆量大时仍会卡在决策覆盖。两个方向:

    1. 方案 C(增量/分批/按重要性采样)——决策窗口缩小后「覆盖全部」才现实
    2. 或放宽 validateDecisions 的「全量覆盖」约束(未覆盖记忆隐式 keep)

    已确认 0.4.3 的 B+A 修复有效;决策覆盖问题建议作为 0.4.4+ 或方案 C 的重点。

  8. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    正式版 0.4.3 已发布(npm latest)!可直接安装:

    npm install @modusensus/[email protected]

    感谢你的回归验证与补充分析。关于决策覆盖问题(validateDecisions 全量覆盖在 636 条记忆下拒绝),我们已记录为 0.4.4+ / 方案 C 的重点方向:增量/分批/按重要性采样(缩小决策窗口),或放宽全量覆盖为「未覆盖记忆隐式 keep」。B+A 修复已验证有效,决策窗口是下一步优化点。

    再次感谢社区贡献!

  9. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    决策覆盖问题(validateDecisions 全量覆盖拒绝)已按方案C修复,发布 0.4.4-beta.1 请你复验 👀

    修复内容(三件套)

    • 滑动窗口:autoDream 每次只对最近 dreamMaxSnapshotSize(默认 200)条记忆做 consolidation(按 updated_at 倒序截断),窗口外的旧记忆不进 snapshot,从源头控制 LLM 输入规模
    • 隐式 keep:LLM 未提及的 snapshot 记忆自动补 {action:"keep"},不再未覆盖即全拒(677 errors / applied=0 的根因);配 dreamImplicitKeep:false 可恢复严格全量校验
    • 覆盖率下限:显式决策覆盖比例低于 dreamMinExplicitCoverage(默认 50%)时整单拒绝——防止截断的残缺输出被静默应用

    安装:npm install @modusensus/[email protected]

    方便的话麻烦在你的 636 条记忆真实环境复验一下 applied>0 是否恢复、旧记忆是否仍被正确 archive/merge。通过后我尽快发正式 v0.4.4 🙏

  10. Anans-Amarre commented on Aug 18, 2026

    @Anans-Amarre
    Collaborator

    正式版 v0.4.4 已发布 🎉(npm i @modusensus/dsh-mneme@latest)

    方案C 三件套 + 决策 schema 固定均已落地(详见 CHANGELOG)。本地用真实 LLM(qwen3-coder-plus / kimi-k2.7-code)在 636 记忆场景复验通过:成功轮 applied=142、input_count=200(窗口截断生效)、零 677 errors。若你那边仍有异常欢迎继续提 issue 🙏

  11. 483218131 commented on Aug 18, 2026

    @483218131
    ContributorAuthor

    感谢维护者,v0.4.4 在本机复验通过 ✅

    环境:Windows 11 / DSH 0.1.0-rc.7 / dsh web profile / token-rhythm / deepseek-v4-flash-0731(思考型)。dreamMaxSnapshotSize=200(默认窗口)、dreamMaxTokens=131072(patch.yml 配置,其余默认)。

    beta 阶段根因(本机实锤):deepseek-v4-flash-0731 把每条决策输出成 {"merge": {"ids": [...]}} 键名包装形式,而非 {"action": "merge", ...} → validateDecisions 逐条 invalid action undefined(12/05 轮 19 条决策 = 19 个错误全同类;此前 202/185/177 errors 同因,数量随当轮输出量波动)。qwen/kimi 无此问题,属模型输出习惯差异——schema 固定对我们这个模型生效。

    v0.4.4 复验结果(未改任何配置,仅新增诊断日志):

    • dream_runs:status=ok, input_count=200, applied=20, summary_stored=1(历史 169 次失败后首次成功)
    • 模型输出已切换为标准 {"action": "merge", ...} 形式(日志 GOT head 证实),24 条决策全部通过校验
    • 旧记忆 merge/archive 已生效:本轮 1 条 merge 合并了 15 条「DSH 工具面丢失根因」相关重复记忆,outcome 记录 1 merge-keep + 14 merge-archived
    • 窗口外的旧记忆按滑动窗口设计未在本轮处理,会随后续轮次滚动覆盖(若需加速可调大 dreamMaxSnapshotSize)
    • applied=20 vs 你们 qwen/kimi 环境的 applied=142:差异来自模型单轮决策输出量(deepseek 本轮 24 条决策),非功能问题

    结论:方案 C 三件套 + 决策 schema 固定在本环境(deepseek-v4-flash-0731 + 200 窗口 + 131072 预算)完全生效,问题解决 🎉 后续若在更大窗口或其他思考模型上复现异常,我们带明细再反馈。感谢快速修复!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions