Skip to content

feat: 研究质量改进、谛听品牌与深空 Demo UI - #1

Merged
kdush merged 27 commits into
kdush:mainfrom
rainwalkerhu:feat/diting-research-quality-ui
Sep 28, 2026
Merged

kdush merged 27 commits into
kdush:mainfrom
rainwalkerhu:feat/diting-research-quality-ui

Conversation

@rainwalkerhu

@rainwalkerhu rainwalkerhu commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

变更说明

基于本地研究质量改进分支整理并推送,向原仓库 kdush/OpenClaw-MiroSearch 提交。主要内容:

  • 研究强度、线索跟踪、搜索置信度、LLM 超时降级与报告结构门
  • API 贯通研究强度参数与生效配置快照
  • Gradio 单列布局 / 设置弹窗 / 进度与停止交互修复
  • 总结失败时交付降级报告,避免占位结论块误导
  • 品牌更名为「谛听 / Diting」(技能包、镜像名、文档同步)
  • Demo 深空主题、玻璃搜索行与中等强度星空背景

影响范围

  • API
  • 检索路由
  • Demo 页面
  • 文档
  • 其他:品牌资产与技能包改名、Compose/镜像默认名

验证方式

cd apps/gradio-demo && uv run python -m py_compile main.py
# Demo 本地启动:http://127.0.0.1:8080/

配置变更

  • 有:Compose / build_images.sh 默认镜像改为 diting:latest、diting-api:latest;技能包路径改为 skills/diting/;导出前缀默认 diting-conclusion

兼容性提示

  • 已安装旧 openclaw-mirosearch 技能需按新路径重装
  • 既有部署需重建镜像或显式覆盖 IMAGE_TAG_*

@rainwalkerhu
rainwalkerhu requested a review from kdush as a code owner September 22, 2026 14:58

@kdush kdush left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我审查了当前提交 ded80ee,建议先修复以下问题,并处理页面列出的 6 个合并冲突后再合并:

  1. Compose 升级迁移(阻塞):compose.yaml 把顶层项目名从 openclaw-mirosearch 改为 diting。按现有部署文档直接执行 docker compose up -d --build 会创建另一组容器与新的 diting_valkey-data 卷;旧服务还在运行时会争用端口,停掉旧服务后新服务也读不到原有任务/缓存。请保留原项目名,或补充可验证的数据迁移、停机与回滚步骤。

  2. 并行抓取突破上限(阻塞):orchestrator.py 的并行工具调用在执行前没有预留抓取名额,_execute_regular_tool_call 只读取已完成次数。我复现了“上限 8、已用 7、同轮并行抓取 2 次”时两次都执行。请在调度前原子分配剩余名额,并补并发回归测试。

  3. 深度研究提前结束条件:_should_early_stop_clue_chase 把不同域名数量当成“多源一致”。两个来源即使观点相反,只要完成两轮搜索也会触发,随后可能强制总结。请根据同一事实的证据一致性或明确的冲突状态决定是否提前结束。

  4. searxng-only 置信度:该路由只允许 SearXNG,但 _evaluate_confidence 用所有已配置且可用的 provider 数量计算最低覆盖数。同时配置商业源时,实际只用一路却要求两路,passed 无法为真。请按本次路由允许的 provider 计算门槛,并补“只允许一路但环境中有多路凭据”的测试。

验证:代码编译通过;Compose 配置及上述三处逻辑均做了定向复现。完整 pytest 因隔离环境缺少 Playwright 依赖未运行。

rainwalkerhu and others added 5 commits September 23, 2026 12:19
…eload

Move theme/JS out of main.py, split CSS by concern, add watchfiles
dev_server and HOT static serving so UI iteration no longer needs full
process restarts for CSS edits.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep Compose project name openclaw-mirosearch with migration notes;
atomically reserve scrape slots before parallel tool execution; require
high-conf corroboration for deep early-stop; cap confidence provider
coverage by the current route's allowed providers (searxng-only).

Co-authored-by: Cursor <cursoragent@cursor.com>
Merge kdush/main bilingual documentation reorganization; keep Compose
project-name migration notes, diting skill paths, and research-quality
doc links while adopting the English/Chinese doc split.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Move tool/runtime labels into ui_i18n, drop unused scrape-budget helper
and watchfiles entry, stub tencentcloud for tools tests, and catch up
Chinese changelog plus Compose migration notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kdush

kdush commented Sep 23, 2026

Copy link
Copy Markdown
Owner

复查当前提交 396de8b:Compose 项目名、并行抓取上限和 searxng-only 置信度门槛已修复,合并冲突也已处理。

仍需修改提前结束研究的条件:_should_early_stop_clue_chase 只检查是否出现两个高可信域名,没有判断它们是否支持同一结论。两个可信来源观点相反时,仍可能触发提前结束;我用两轮搜索和 reuters.com、apnews.com 两个高可信域名定向复现,结果仍为 True。深度模式随后可能强制总结。

请根据同一事实的证据一致性或关键冲突的处理状态决定是否早停,并补充“两个高可信来源相互矛盾”的回归测试。此项完成前,我保留 Request changes。

停止后立刻点「开始研究」会没反应,根因是取消链路上三处相互放大的缺陷:
被取消的 run 事件仍卡在 finally 里等 pipeline 线程收尾(线程被一次同步
LLM/抓取调用整段占住,实测 74s),于是它继续占着 Gradio 的按事件并发位、
并把新任务的界面状态覆盖回旧任务;此时界面里的 task_id 可能已失效,
下一次停止就静默 no-op。

- stream_events_optimized:取消已请求时立即返回,不再等 pipeline 线程
- gradio_run 本地路径:取消后跳过终态帧,避免覆盖后续新任务
- stop_current_ui:task_id 不在活动表时回退到当前界面任务
- run/submit 事件加 trigger_mode="multiple",中间流式帧用 gr.skip() 跳过按钮
…n presence

Two trusted domains appearing in search results no longer fire deep
early-stop by themselves (reuters.com + apnews.com could contradict).
A no-tool LLM adjudication must return VERDICT: AGREE before the gate
opens; conflict/unknown fail closed and the Round 7 turn cap stays
inactive. Conflicts are re-evaluated on new search rounds (max 3 checks
per run), so a resolved contradiction restores early-stop. Adds
regression tests for the contradicting-sources scenario.
…draft

Roadmap gains the confirmed product positioning, Q4 topology
enrichment item, and softened review status on deferred items.
Adds the jev-search borrowing review draft (multi-source concurrency,
engine routing, timeout budgeting) as evaluation input, not committed work.
@kdush

kdush commented Sep 24, 2026

Copy link
Copy Markdown
Owner

复查 dcacc9b:感谢补上证据一致性裁决和“两个可信来源相互矛盾”的测试。目前还有一个会导致旧裁决被继续使用的边界问题,建议本轮一并修复后再合并。

可复现场景:第 3 轮取得 AGREE,并记录提前结束起始回合;第 4 轮搜索或抓取带来与核心结论相反的新证据。_maybe_evaluate_evidence_agreement() 遇到 evidence_agreement == "agree" 直接返回,不再检查新证据;_should_force_summary_after_early_stop() 仍读取旧 AGREE,于是可能发出“立即写报告”提示并强制总结。我用当前方法定向复现:第 4 轮裁决调用次数仍为 1,force_summary=True。

建议的实现方案:

  1. 在 Orchestrator 为进入主会话的有效证据维护版本号,例如 evidence_revision;成功返回的搜索、网页抓取,以及提供研究证据的子代理/其他检索工具结果,在写入 message_history 后使版本递增。并行工具调用按整批处理,最多裁决一次。不要只依赖 search_rounds,因为新抓取内容也可能推翻旧结论;失败、空结果不算新证据。
  2. 把裁决结果绑定到版本号,例如 agreement_checked_revision。_should_early_stop_clue_chase() 只有在数值门满足、裁决为 AGREE、且已裁决版本等于当前证据版本时才返回 True。新证据到来先让旧裁决失效,再在更新主历史之后、任何追线索跳过/强制总结判断之前,对最新证据做一次无工具裁决。CONFLICT、UNKNOWN、调用异常和次数上限耗尽都必须保持 fail closed,不能沿用旧 AGREE。每批/每轮最多裁决一次,以控制额外开销。
  3. 旧 AGREE 失效时,同时撤销本轮仍在生效的提前结束计时和收敛提示状态(deep_early_stop_triggered、deep_early_stop_turn、_deep_convergence_nudge_sent 等);如果“立即写报告”的提示已进入会话,需要确保后续新证据和继续核查指令能覆盖它。只有基于最新证据再次取得 AGREE,才从当前回合重新计时。请区分“曾触发早停”的运行指标与当前有效的倒计时,避免旧回合导致再次确认后立即退出。

请补回归测试:① 先 AGREE,下一轮搜索出现关键冲突 → 重新裁决为 CONFLICT,不沿用旧结果、不强制总结;② 仅新抓取出现冲突也一样;③ 后续证据化解冲突并重获 AGREE → 从新回合计时;④ 新证据出现时裁决失败、不可解析或次数已用尽 → 不提前结束;⑤ 没有新证据时不重复裁决,并行结果每批最多裁决一次。验收重点:第 4 轮新增相反证据后,旧 AGREE 不能通过早停门,_should_force_summary_after_early_stop() 必须返回 False。

@kdush

kdush commented Sep 24, 2026

Copy link
Copy Markdown
Owner

补读 de3d1ee 新增的两份评审稿后,以下几点建议先在文档中改正/写清,避免后续按文档实现时把“检索覆盖”误写成“事实验真”。这是文档评审,不要求本 PR 现在实现路线图 M1–M5。

  1. 路线图 M1 的来源口径与现有 serp-first 策略不一致。 M1 写的是“与实际抓取 URL 注册表对账”,但 docs/DEEP_EFFICIENCY.md 明确优先使用搜索摘要,只抓取冲突关键页;现有 answer_generator._collect_evidence_sources() 也同时收集 organic 搜索命中和成功抓取 URL。请把注册表范围写成“实际返回的搜索命中 + 成功抓取”,记录 URL/规范化 URL、域名、来源工具、摘要或正文、抓取状态;报告只能引用已登记来源,并清楚区分“仅搜索摘要”与“已阅读全文”。如果只收全文抓取 URL,会误拒绝合法的摘要引用。
  2. M3/Q4 缺少结论到证据的前置映射,实施顺序应调整。 路线图 M3 说每条结论标“N 个独立域名支持”,却只列 summarize prompt 与 report_structure.py;目前后者只数 [N] 标记及章节,无法验证某个引用是否支持该结论。Q4 又计划先在拓扑图中宣称“每个结论可溯源”,而 §7 把 M3 放在 M1 前。建议先有最小来源注册表及“结论→引用 ID→来源 URL/主张”的可校验映射,再展示支持数和溯源图;不能确认独立性的情况标“未核实/来源不足”,不要由提示词直接生成看似精确的 N。
  3. jev-search B1 的“共识”不能当成独立证据。 对标仓库的 mergeItems 将同一规范化 URL 的结果合并,engines.length 只表示同一页面被几个搜索引擎找到。它可作检索排序信号;同一报道经两个 provider 命中,仍只有一个原始来源。请保留 URL 归一化作为去重参考,但删除/改写“provider × 域名”可提升 M3 结论支持数的建议;先按实际独立的原始来源和对该结论的明确支持去重计数。源码:merge.ts、rank.ts。
  4. 对标文档有两处事实需更正。 jev-search 的 cacheKey 直接拼接查询文本,并非“派生哈希”;其代码有 402/429/5xx 的供应商切换,但没有内建总预算熔断。README 明说 IP 限流不是全局支出上限,建议部署者另配供应商消费限额。请将“预算熔断”改成谛听未来可自行设计的候选能力,别写成已验证的借鉴实现。
  5. 路线图 §2.3 对 API 现状的推论需要收窄。 profile_resolver.get_mode_overrides_for_output_detail() 已为 API 各档设置 research_report_mode=true,_build_main_summary_prompt() 会覆盖短 \boxed{} 模板并输出研究报告;因此不能从基础 prompt 推出“API 只有短答”。更准确的待办是核对 API 与 demo 的内联 [N] 引用格式和来源校验是否一致,再界定 M2 的改动范围。

另外,路线图 §5 已指出 reasoning token 成本;与前一条早停修复建议对齐时,请保留每轮/每批最多一次、整次运行最多 3 次裁决,并把额外调用耗时与 token 纳入验收。

@kdush

kdush commented Sep 24, 2026

Copy link
Copy Markdown
Owner

我按最新提交 de3d1ee 的两份文档(research-depth-roadmap 与 jev-search-borrowing)以及现有实现,把后续路线整理成可执行的顺序。总体方向同意:先把证据真实性、结论可核查性做好,再扩展多源和更重的智能能力。下面是建议你按小 PR 推进的完整方案;M1–M5 是后续路线,不要求塞进当前 PR。

0. 先收敛本 PR 与路线图事实

  • 当前 PR 的合并门槛是“新证据使旧 AGREE 失效”问题:第 3 轮取得 AGREE 后,第 4 轮新搜索或新抓取带来相反证据时,必须使旧裁决及早停倒计时失效;在新证据进入主历史后对当前证据版本重裁决,CONFLICT/UNKNOWN/调用失败/次数耗尽均不能强制总结。冲突解除并重新获得 AGREE 时从当前回合重新计时。请覆盖搜索、仅抓取、冲突解除、裁决失败和并行批次回归测试;每批最多裁决一次、整次运行维持 3 次上限。后续 M1–M5 不必混进这次修复。
  • 更新路线图的现状描述:当前 _evaluate_confidence 已按本次路由可用 provider 数量钳制覆盖门槛,并有单 provider 可通过的测试。因此“只有一个 Serper key 时 provider 覆盖门槛必然为 2、parallel-trusted 结构上不可通过”已过期。M5 仍有价值,但要基于实际可用/健康 provider、查询质量和降级行为来论证。API 当前也已有 research_report_mode;M2 应聚焦内联引用契约与校验,而非笼统说 API 只能生成短答。
  • 先用现有验收脚本固定基线:至少保留一组 SERP 摘要足够、一组需要全文核查、一组相互矛盾来源的样例。记录报告、来源列表、搜索/抓取次数、模型调用与 token、耗时、失败路径。后续每阶段与同一基线对比。

1. 先定义共同的数据契约,再动 UI(M1 的前置设计)

把“检索命中”“可引用来源”“支持某结论的独立证据”分开。搜索 provider/引擎只是发现渠道;同一 URL 被多个引擎命中不增加独立支持数,同一报道被转载也不能简单按域名加一。建议在工具返回到 Orchestrator/报告层之间建立不依赖 LLM message_history 的来源注册表,至少保存稳定 source_id、原始/规范化 URL、原始发布方或域名、发现 provider、获取时间、模态、仅摘要/已抓正文/抓取失败状态、摘要或正文定位。历史压缩或 summary_keep_tool_result 丢掉旧工具 JSON 后,来源与引用映射仍须可用。

URL 规范化只用于去重与关联,规则要保守:可以处理 scheme/host 大小写、片段和明确的跟踪参数;不要直接照搬 jev-search 对整个路径转小写的做法,也不要删除可能区分内容的查询参数。给重定向、不同路径大小写、同文多 URL 各留 fixture。报告中仅允许引用注册表内、确实返回过的来源;搜索摘要可以被引用,但必须显式标“仅摘要”,不能伪装成读过全文。

2. 来源与引用闭环(M1 → M2,同时交付 Q2/Q3)

先落 M1 的来源收集/去重/持久映射,再把 Gradio 中的 [N] 规则上移到核心报告生成与 API 输出;API 和 Demo 共用同一 source_id → [N] → URL 契约。References 至少展示标题、可读摘要、链接及“仅摘要/已核查全文”状态;搜索过程 Q3 展示实时返回摘要,但这些文本是外部不可信内容,渲染要转义,且未进入注册表的临时命中不可被报告引用。报告校验不能只数 [N] 或章节:要验证每个 [N] 存在、指向实际返回来源,且链接与状态一致;无法解析的引用应删除/降级标注,不造 URL。

本阶段验收:仅搜索命中、抓取成功/失败、相同 URL 多 provider 命中、重定向、无有效来源、历史压缩后引用旧来源;API 与 Demo 对同一运行展示相同编号/目标链接;恶意摘要不能注入 HTML。交付一份字段契约、单元/集成测试和一份可查看的真实报告。

3. 结论核验与拓扑(M3 → Q4)

先产出结构化的“结论/关键主张 → source_id → 支持、反驳、未知 → 依据片段”映射,才计算独立支持数。计数单位应是能明确支持该主张的独立原始来源;provider 数、检索命中数、域名数都不能直接代替。转载/同一原文要合并,互相矛盾的可靠来源要在报告里显式保留。证据不足或无法判定独立性时写“未核实/来源不足”,不要让 prompt 猜一个精确 N。report_structure.py 可先承担可机械验证的结构检查;语义支持判断需要明确的裁决结果与失败回退,不要把结构门称作事实核验。

验收 fixture:同一 URL 被两引擎返回、跨域转载、两个来源支持同一主张、两个可信来源互相反驳、摘要与全文冲突、无依据结论。Q4 只能画已验证的结论—来源关系;未知/反驳边要有不同标记,不把“可点击”误呈现为“已证实”。

4. 可并行的小轨道

  • Q1 渲染器:可先做 Mermaid 的安全渲染和纯文本回退;它只是展示,不赋予图中关系真实性。Q2/Q3 等来源契约稳定后再接数据。M4 线索链记录搜索、追问、跳转与结果的 trace/event,展示“为什么继续查”,不要与“什么证实了结论”混用。
  • M5 基础配置自适应:先只覆盖检索 provider 与 profile 选择。显式选择 searxng-only 等严格路由时保持严格;自动模式按实际可用且健康的 provider 选档,记录生效档位、原因和降级,明确超时/缺凭据的回退规则。测单 Serper、单 SearXNG、多 provider、无凭据及运行中一路超时;各路线的置信度门槛应可达到且有搜索次数上限。LLM 网关、视觉能力与复杂多源排序留给后续独立设计。jev-search 的 lane 隔离可参考,但其多引擎命中只作检索排序信号;对标文档还需更正:jev-search 的 cacheKey 直接拼接查询文本,并非哈希;其 402/429/5xx 回退也不是总预算熔断。后者是我们要自行设计的候选功能,不是它已经提供的能力。低配环境下的推测性并发会消耗配额,先测收益再开。

5. 延后项与统一完成标准

P1 图片先只作弱/辅助证据,待图片检索凭据、VLM 成本及出处校验齐备后再试;D1 递归子代理必须先与简单的线索预算方案对比质量、延迟与 token,确认增益再上;D2 实体图谱、D3 高级多 provider 调优暂缓。建议的顺序是:本 PR 阻塞项与文档事实修正 → 基线/数据契约 → M1 → M2 + Q2/Q3 → M3 → Q4;Q1、M4、M5 按上述依赖并行做独立小 PR。

每个 PR 写清输入/输出契约、失败回退、对应 fixture 与可观察指标;跑相关自动测试和有凭据时的 run_acceptance_live.py --out-dir 复测。与基线比较无依据结论、错误引用、冲突处理、p50/p95 耗时、模型调用/token、检索/抓取量和实际供应商费用。先证明质量提升与成本边界,再确定默认开启和优化目标;不必在文档里预设未经实测的工期。

如果按这个顺序推进,下一步最有价值的是:先修本 PR 的旧 AGREE 问题,并把两份文档改成上述依赖关系与验收口径。之后从来源注册表和引用契约开第一条后续 PR。

Bind the agreement verdict to an evidence revision: successful searches,
non-empty scrapes, and evidence-bearing sub-agent results bump
evidence_revision, and a verdict on an older revision fails closed. On
invalidation the orchestrator revokes the early-stop countdown and
convergence nudge (appending an override message when the nudge already
entered the history), then re-adjudicates the latest evidence before any
follow-up-skip or force-summary decision. Keeps one adjudication per
turn and 3 per run.
Rebuild the roadmap as v2 (data-contract stage before M1, unified
completion standard, PR merge gate in section 0) and correct two
jev-search facts: cacheKey concatenates the query text directly, and
provider fallback is not a budget circuit breaker; the provider x
domain counting proposal is voided in favor of independent original
sources.
@kdush

kdush commented Sep 24, 2026

Copy link
Copy Markdown
Owner

@rainwalkerhu 复查最新 8aa2b9c(0334af2 修复 + 路线图回填)后,旧 AGREE 的版本门、倒计时撤销与工具结果入主历史后的重裁决顺序基本对上了;但下面两处仍需修完再合并:

  1. 失败/空抓取被当成新证据。 orchestrator.py 的 _record_scrape_metric 只看外层 error 和 result 是否非空;scrape_url 的超时、HTTP 错误等却是非空 JSON 字符串,形如 {"success": false, "error": "request timed out"},由 ToolManager 包在外层 result 里。我按当前方法定向复现:失败抓取仍使 scrape_count=1、evidence_revision 从 2 变 3。这会撤销有效 AGREE 并消耗有限的重裁决次数,违反“失败、空结果不算新证据”的契约。请按各抓取工具的返回协议判断实际成功且正文非空后才递增证据版本;补内层 success=false、success=true 但 content 为空、真正有正文三组测试,并核对抓取计数语义。

  2. 撤销提示预先断言“新证据相冲突”。 orchestrator.py 的 _revoke_stale_early_stop_countdown 在任何新证据到来时,向主历史追加“与此前结论相冲突的新证据、化解冲突”。这条用户角色消息随后进入 generate_agreement_check 的输入;即使新结果其实支持旧结论,也会给裁决预设冲突。请改成中性的“出现新证据,旧收敛指令暂作废;先重新核查它支持、反驳还是与结论无关”,再用“新证据继续支持原结论”的用例验证可重新取得 AGREE。

另外,路线图 v2 的状态和 §0 仍写“代码在工作区、未提交”,但 0334af2 已提交;请顺手改成当前状态。两笔提交的静态编译与 diff --check 通过;本地 pytest 依赖安装未完成,尚无可报告的测试结果。修复后我再复核并合并。

rainwalkerhu and others added 2 commits September 28, 2026 09:23
Parse scrape tool inner JSON so failures and empty bodies no longer bump
evidence_revision or leak scrape reservations; neutralize the stale-AGREE
revoke nudge so it does not presuppose conflict. Ignore .workbuddy-ai/.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@kdush
kdush merged commit 1bdfc1d into kdush:main Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants