Skip to content

本地模型路由优化 - #219

Open
yu-zhy wants to merge 2 commits into
itmisx:mainfrom
yu-zhy:TopicTracking
Open

本地模型路由优化#219
yu-zhy wants to merge 2 commits into
itmisx:mainfrom
yu-zhy:TopicTracking

Conversation

@yu-zhy

@yu-zhy yu-zhy commented Aug 1, 2026

Copy link
Copy Markdown

引入all-minilm-l6-v2进行语义识别替代关键词策略,优化本地模型路由方案
通过/ 预计算的"复杂任务"语义向量(一次性计算,缓存) 来优化路由策略
"重构代码架构", "分析系统依赖关系", "设计模块接口", "排查性能瓶颈", "review代码安全性", "多文件重构", "架构设计" 会路由到pro模型

于政洋 added 2 commits July 31, 2026 14:55
新增本地实时主题追踪系统(TopicGraph)和可插拔词典分词器:

- Segmenter 接口, 支持多语言扩展
- 中文词典分词(正向最大匹配, jieba 词典), 首次使用自动下载
- POS 词性标注过滤虚词(连词/介词/助词/代词等不纳入关键词)
- 单字二元组合并(补偿词典未收录的复合词)
- FMM 算法修复: 长词优先(修复前高频短词会错误替换长词)
- 安全加固: HTTP 30s 超时, 32MB 响应体限制, 缓存目录 0700

- TF-IDF + 余弦相似度实时追踪对话主题
- 会话侧重点摘要(SessionFocus)
- 话题切换检测: 与会话主导话题比对, 区分"切换"与"扩展"
- 虚词过滤基于 jieba POS 标注(删除硬编码词表)
- 会话隔离: /new 切换时 TopicGraph 自动重建

- segmenter.yaml 独立配置文件(不污染 model.yaml)
- language: zh 启用中文词典分词(默认不启用,零开销)
@yu-zhy yu-zhy changed the title 本地模块路由优化 本地模型路由优化 Aug 2, 2026
@itmisx

itmisx commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@yu-zhy
感谢投入,语义路由的方向是对的。但目前这版有几个阻断性问题,麻烦先处理:

1. 核心功能实际没生效(必修)

tui/model.go:1322if m.modelPin == "" 恒为 false。m.modelPin 全部 5 个赋值点(7434002401240324035)加上 restoreModelPindefault 分支(4038"" 归一成 "auto"),值域封闭在 {"auto","flash","pro"},不会是空串。

结果是 RouteWithContext / RouteBySemantic / complexTaskPatterns 一次都不会执行,effectiveRole 最终取到 "auto"StartStream 仍走原来的 RouteByKeyword —— 路由行为和改之前完全一致。PR 描述里那批词能路由到 pro,是原有关键词表的功劳。

改成 if m.modelPin == "" || m.modelPin == "auto"。改完请实测验证效果。

2. 修好 #1 后会暴露的问题

else 分支无条件设 activeModelRole = "flash",丢了原有的 activeModelID == "" 兜底(对比 setup_modal.go:318)。只配了 pro 的用户右栏会显示空模型名。

3. CI 是红的

go vet ./agent/...   agent/topic_tracker.go:59 self-assignment of tg.embedder
go test ./agent/...  FAIL TestTrackMessageSameTopic / TestExtractFileRefs / TestExtractFileRefsHTTP
gofmt -l             embedder.go keyword_router.go segmenter.go segmenter_dict.go topic_tracker.go topic_tracker_test.go i18n.go

TestTrackMessageSameTopic 的根因值得单独看:tfidfEmbedder.EmbedupdateDocFreq 再算 IDF,当前文档已计入 df,所以第一篇文档 log(2/2)=0整个向量全零,第一个 Topic 永远匹配不上任何后续消息。

4. 主题追踪与 main 冲突,建议整块移除

这个 PR 从 0c78be3 分叉,在 85f04de ✨ session topic 之前,所以不包含已合并的 tui/topic.gogit merge-tree 显示 tui/model.go 冲突。

两边做的是同一件事 —— 检测话题切换、提醒用户 /new。main 的方案是让模型每轮结尾输出 <topic shift="yes"> 元标签,零额外依赖;这个 PR 用词典分词 + TF-IDF/ONNX 余弦。合进来用户一次话题切换会收到两条提醒。tui/topic.go:17-20 的注释里写了当初为什么没走"代码自己判断语义"这条路。

5. ONNX 路径应该没跑通过

  • newONNXEmbedder~/.deepx/segmenter/ 当 libDir 传给 GetORTEngine,但 onnxruntime 动态库在 OCR 自己的 cacheDir,路径不通
  • ort_engine.goortLibName() 只按 GOOS 分支,Intel Mac 和 ARM Linux 都会取错文件名;仓库里已有 ocr/ort_{darwin,linux}_{amd64,arm64}.go 用 build tag 做对了,直接复用
  • all-MiniLM-L6-v2/onnx/model.onnx 输出的是 last_hidden_state [1,seq,384],不是句向量。当前代码把 seq*384 个 float 平铺成 d0..dN向量维度随输入长度变化,不同长度文本之间算余弦没有意义。需要按 attention_mask 做 mean pooling
  • Embed 里所有错误一律 return nil 吞掉,上面几种失败用户完全看不到

另外阈值(0.15 / 0.05 / 0.02 / 0.6)是按稀疏 TF-IDF 调的(无交集即 0)。换成 MiniLM 稠密向量后任意两句中文相似度普遍 0.3~0.7,这几个阈值全部失效,需要按 embedder 分档。

@yu-zhy

yu-zhy commented Aug 3, 2026

Copy link
Copy Markdown
Author

收到~~~

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