小唯
a430a2b602
feat(skillgen): SkillEvaluator 四维评估器 + SkillEvolver 接口 + 规则过滤差距分析探针 (t_4594b632)
2026-11-09 01:12:49 +08:00
小唯
714df5d2a8
feat(zhiyi): L2全表检测探针 (t_d8830204) — 打通 L2 pattern 0行→非0 与 L3 草稿生成
...
背景:POST /patterns/detect 被 lancedb_scan 硬限 5000 且 DetectFromRecords 默认 MaxRecords=500
(物理序前500条是'不幸窗口'检出0)→ 已有 pattern-detect-daily cron(limit=500) 空转,graph_nodes
type='pattern' 恒 0。本探针走 sidecar IPC lancedb_scan_all(无5000上限)+ 全表 MaxRecords + 诚实阈值:
L2 conf>=0.5 写 graph_nodes(type='pattern',ns=daemon-distill),L3 conf>=0.85 才出草稿到
attachments/<pattern>/skill-draft.md([AUTO-DRAFT]标记,status=draft,绝不自动promote)。
-cwrite 才落库,默认 dry-run。
实测(全表45227行/distilled45096):6个tool_combo,仅 hermes+python (conf=1.0,13源) 过 L2/L3 双闸。
写库后 graph_nodes pattern 0→1, skills 0→1(draft);召回 top5 10query 前后逐位一致(零行为变化)。
本地2B(8081)生成草稿落盘。
2026-11-09 00:13:34 +08:00
小唯
6cbc49ca0e
fix(recall): E4.2 跨ns共享兜底补 ghost-ns 判据 — 修复传不存在的 ns 仍经 shared 补充搜泄漏
...
t_a243aefa 终审在**生产部署后实测**发现:传 ghost ns 仍返回 1 条 channel=shared 记忆
(mem_1793118290141936234, score=0.5 固定值)。根因 = core.go:724 E4.2「结果数 <3 时
补搜 shared」这一段没有 nsHasRows 判据 —— t_15d82af7 只修了 recall.go 的 namespaces
列表和 FTS 尾通道两处,漏了路由层这第三处。
判据与另两处对齐:storage.NamespaceHasRowsFor(与 recall.go 同一个函数,带 60s TTL 缓存)。
ghost ns ⇒ 不补搜;真实 ns ⇒ 行为逐位不变(回归测试 + go test 两包全绿)。
2026-11-07 06:05:40 +08:00
小唯
b5a6f4536e
perf(recall): namespaceHasRows 加 60s TTL 缓存(复用 RedisCache,t_a243aefa 终审)— ScanAll 每次带 ns 召回全表读 ⇒ 同 query 集 p50 2.13s→0.39s
2026-11-07 05:00:12 +08:00
小唯
199608a7d3
feat(intention-ttl): 意图 TTL — intention 类 + expires_at 跨五层落盘 + 过期负分降档(非删除,ZHIYI_INTENTION_TTL 门控)
...
- Go model/IPC/FTS 通道/SQLite/API 写入(RFC3339 严判 400)+ Rust struct/schema/builder/6×读侧 col_str
- recall 降档块在 MMR 之前(选择与展示共用同一套分数),过期 intention rerank 分置 -1 → 展示分 -0.445
- 关态 intentionExpired 恒 false ⇒ 降档块零赋值;AC2 HEAD vs 新版同库同 sidecar 现采基线 fresh 逐位一致
- 单测:关态逐位/开态下沉且在场/负分压过全部正常分/纯度(他类、未过期、空=永久)
- 回滚:env 置 0 或 unset(每调用读 env,无需重启);磁盘列 additive 保留不删
t_88cc9cb8
2026-11-07 04:09:06 +08:00
小唯
d5b82d5b19
feat(distill): 经验层 category=experience 灰控落地(默认关,t_2595b626)
...
- experience_gate.go 新增:env 门控 ZHIYI_DISTILL_EXPERIENCE(启动读一次,同 density_gate 写法)、
ExperienceRecord{Task,Solution,Boundary}(无 confidence 自评,质量复用五维 overall/VD/RU)、
独立 prompt 附加常量(1157B,拼在 outFmt 之后)、ParseExperienceLine(4 段硬约束 + 反回显)、
ExperienceGrounded(反张冠李戴:task 对象名必须在 episode 原文有影子,确定性零 LLM)
- engine/parser/server 接线:关态条件短路不可达 ⇒ 关态 prompt 逐字节不变
(sha256 三臂一致:head-off==tree-off=49295e70…,开态=关态+1157B)
- score_cache 门控开时加 \x00experience-v1 后缀,防旧 prompt 缓存短路灰度
- 落库:接地闸 → 近重复跳过(cosine≥0.98)→ 写现成 category=experience(不造新表/新列)
实测(40 条真实工作笔记,本地 2B):EXP 行出现 32/40=80%,但过格式闸仅 2/40=5%
⇒ 2B 会写 EXP 内容但用自然语言衔接、不拆竖线三段,属能力边界。故**默认关,未部署未 push**。
go test ./internal/distill/ ./internal/api/routes/ -count=1 全绿
2026-11-07 02:41:33 +08:00
小唯
0a05014a35
feat(memory-raw): 原文层下钻 — GET /api/v1/memory/{id}/raw + GetRecordByID 三层后端 + Rust get_by_id IPC + 插件 memory_raw 工具 (t_0f1d7be9)
...
- recall 响应带 derived_from 指针(既有列已直通,补回归闸门防回退)
- 新端点三态:200+raw_text / 200+no_provenance / 200+episode_missing / 404 memory_not_found / 503 存储故障(禁静默空)
- LanceDB 接口加 GetRecordByID(table,id):Rust IPC(lancedb_get_by_id 单行读,旧 sidecar 未升级=显式 error 不冒充不存在)/ SQLite / 内存三后端
- 旧实例同库同查询对比:recall 字段集合与结果顺序逐位不变(只多 derived_from 键)
- raw_text 4000 rune 截断标注;插件 memory_raw(id) 2000 字符截断标注,旧服务端 unsupported 显式区分
- 测试:memory_raw 路由 6 例 + IPC 契约 3 例(旧 sidecar 防静默 no-op)+ E2E 模板(ZHIYI_RAW_E2E_SOCK)+ 字段集合闸门
- 量化:30 条带指针样本经新端点取回 28/30(2 条=episode_missing 真实缺原文);28/28 原文含结论所无的数字/标识符
2026-11-06 23:56:22 +08:00
小唯
02bdfb572e
fix(recall): namespace 检索侧过滤失效修复 — ghost-ns 判据=ScanAll 全量表行存在性,与生产 IPC 客户端过滤同口径;ghost ns 不并 shared/不放行 shared FTS 尾部位/不补 wiki;真实 ns [ns,shared] 与全库路径逐位不变 + 三态回归用例 (t_15d82af7)
2026-11-06 22:49:47 +08:00
xiaoyi
dc2b9db683
feat(distill,recall): 蒸馏粒度三档 + skill 分节召回增强(t_afacc477,本地未部署)
...
- distill: ZHIYI_DISTILL_MODE 三档(current/context/merged)+ ZHIYI_DISTILL_CAP 可配
- distill: 信息密度灰度门 ZHIYI_DISTILL_DENSITY(默认关,关态 prompt 逐字节不变)
- recall: skillref 方案二,skill 文档进召回(新增 routes/skillref.go)
- memory: DerivedFrom 原文指针(derived_from 列),供回溯原始 episode
- 验证: go build ./... 通过 / go test storage+distill+routes 全 ok
- gitea 推送暂缓(家里服务器维修中)
2026-11-06 21:25:46 +08:00
小唯
8cd3793336
feat(recall): B1 第二路 skill 分节检索 skill_refs(t_e3f5cb79)
...
- routes/skillrefs.go:~/.hermes/skills/**/*.md 分节索引(H2~H4),
BM25(k1=1.5,b=0.75) + 停用字过滤 + 微型领域同义/中英扩展表 +
行级共现(最佳行主导)+ 文件名主题先验 + SKILL.md 权威先验;
纯 stdlib 零新依赖;索引 37k 节 ~300ms,10min 懒重建
- /api/v1/recall 响应新增顶层 skill_refs:[{path,snippet,matched}](n=5),
memories(results) 结构一字不动,两路不混排;键恒存在(含 system_template 早退路径)
- 开关 ZHIYI_RECALL_SKILLREFS 默认关;ZHIYI_SKILLS_DIR 可覆盖索引源
- 测试:开关语义/停用词/fixture 形状 + 真实语料 AC-2.3 探针①②
(缓存层→含 RedisCache 的 misc-topics.md;Go Rust 启动顺序→含
「先 Go」的 zhiyi-deploy-and-metrics.md)
- 调试教训:自造线性权重在真实语料被疑问句共现带偏 → 换 BM25;
线性行累加让目录页刷分 → 最佳行主导
2026-11-03 03:07:34 +08:00
小唯
d8c525b544
feat(write-ops): A2 真矛盾判据门 + MarkConflict 双向指针(t_e3f5cb79)
...
- SameAttrValueConflict:同主体+同属性+不同取值(ASCII/CJK 属性-取值对 +
governance.IsContradiction 否定对立复用),判不出=假,宁漏勿误
- JudgeWriteOp 出口:任何来源 CONFLICT-MARK 必须过门,不过门降级
UPDATE(sim≥更新阈值)/ ADD(幻觉 TargetID 同样拦下)
- MarkConflict(oldID,newID):旧行 freshness=superseded + superseded_by=[新id];
新行插入带 supersedes=[旧id](沿用既有字段,禁造新字段;不置 is_deleted)
- 回归 AC-1.3:testdata/conflict_stock_20261102.json(24 条 conflict 存量 +
top3 对手句,人工判读 0/24 真矛盾)→ 72 对新判据真矛盾计数=0;
正例对照 3/3(防恒 false 作弊)
- 依据:2026-10-31 方案 11-02 验证节;旧判据=相似检测器 100% 误报
2026-11-03 02:02:00 +08:00
小唯
93a11c2fb7
fix(core): 翻页令牌判据改看主路段 mainLen;carry 只在第一页(t_2891d689)
...
1774c31 把 carry 从切片里救出来之后,handler 的 nextCont 判据
`len(results) == req.Limit` 变成只要有 carry 命中就恒假 ⇒ nextCont 恒空,
带 pattern/peer 注入的 query 翻页链断裂(客户端拿不到 continuation,
第二页永远取不到)。与它修的行(carry 被切)同型、方向相反。
现 80/81 两个 conf.disabled 停着 carry 恒空所以没暴雷;一启用就翻不动。
两处修订:
① 判据收口 shouldEmitContinuation(totalFetched, fetchLimit, mainLen,
limit, offset),看 paginateRecallWithCarry 新返回的主路段长度
mainLen,不看 len(results)。保持 == 不用 >=:主路段未满一页
(offset 越界/尾页不满)不得错发令牌。
② carry 只在第一页回尾:offset>0 的续页只回主路段。carry 的 ID 在
第一页已随 returned 记进令牌 prev,续页再带必然逐页重复,
等于把去重成本转嫁给客户端。
测试:
- 新增 TestContinuationIssuedWithCarry(AC1:limit=5+1carry+满取数
⇒ nextCont != "",并锁死页形 len>limit 以覆盖旧病灶)
- 新增 TestCarryOnlyOnFirstPageAcrossPages(AC2:4 页链,续页无 carry、
主路段推进,尾页不满不发令牌)
- 新增 TestNoContinuationOnEmptyOrShortMainPage(AC3:越界空页不发令牌;
4主+1carry 撑满 len==limit 也不发 —— 钉死判据看 mainLen)
- 既有 TestPaginateRecallWithCarry 6 例全绿;其中 ⑤「续页carry回尾」
断言按本卡产品决定反转(原断言锁死的正是被改掉的每页重复 carry)
- 关态(无 carry)与 1774c31 差分:54 组 offset×prev×limit 探针输出
(页内容+令牌发放)diff 为空,逐位 delta=0
- routes 全包失败集与 1774c31 基线逐位一致(3 个预存在 pattern/skillgen
失败,非本改动引入);go build ./... OK
2026-11-02 21:45:39 +08:00
小唯
1774c310b1
fix(core): P0-3 翻页切片豁免 pattern/peer carry(t_58f9d476)
...
capRecallResults 把 pattern/peer carry 恒保留追加在 prim 之后(回填保证
主+扩展填满 limit ⇒ carry 恒在索引 limit 处),紧随的 P0-3 裸
results[:req.Limit] 把它恒切掉 —— t_e98cb1d6 的 carry 修复被作废,
ZHIYI_PEER_RECALL 结构性零产出(dbg 插桩实证注入发生 4087→4088 但响应无 peer)。
修法:翻页逻辑抽成纯函数 paginateRecallWithCarry —— carry(Category ∈
{pattern,peer},判据与 capRecallResults 同源)先摘出 → 主路段照旧做
offset 切片/prevIDs 去重/[:limit] 截断 → 最后把 carry 回尾。
关态(无 carry)与旧内联逻辑逐位 delta=0;主路段 ≤ limit 语义不变(t_9025b0eb)。
回归 TestPaginateRecallWithCarry(6 例):limit=5/50 末位 peer 存活、
pattern+peer 全存活、关态逐位一致、offset 越界空页、续页 carry 回尾、
端到端 cap→paginate 链路。全部既有测试绿(routes 失败集与 HEAD 逐位一致,
仅 3 个 pattern 预存在失败,非本改动引入)。
影子双臂(修复版二进制,独立数据副本+sidecar/redis/PORT):含 peer_id
query 在 limit=5/50 响应末位现 peer:muc;金标 20 query diff top1 翻转 0、
top5 主路丢失 0、主路顺序破坏 0,7 条 peer 注入全存活且 trigger_hit;
off 臂与生产活体 3/3 top1+主路 top5 逐位一致。
生产零改动(未部署未重启,prod :7821 health=200)。
2026-11-02 21:07:19 +08:00
小唯
75abce7cca
fix(graph): Prune 孤点删除加 14d 宽限期 + 删除前预告日志(t_31bb2992,从悬空 commit 17dc39fc 摘回)
...
17dc39fc 原提交不在任何分支(悬空),工作树/二进制均未包含该修复;
本次原样 cherry-pick 到 feature/knowledge-form 并提交。
- ZHIYI_GRAPH_PRUNE_GRACE_DAYS 默认 14(0=逃生阀回旧行为)
- 删除前 log will-delete 计数 + 5 样本
- 单测 TestPruneGracePeriod_OrphanSurvival / TestPruneLogsOrphanDeletionPreview PASS
2026-11-02 19:59:58 +08:00
小怡
826272f981
feat(graph): 合成边停写门 ZHIYI_GRAPH_AUTO_SYNTH(默认 0 = 停写 uses/related_to/configures/CO_OCCURS)
...
理由(实测 2026-11-02):
- graph.db 622,804 边中这 4 类占 619,825(99.5%,CO_OCCURS 284,020 / uses 222,471 / related_to 101,429 / configures 11,905)
- 400 条真实 query 抽样噪声率 88.5%;全库 retrieval_count>0 = 0 条(从未被消费加权)
- 写侧仍在长:16:44 622,398 → 17:48 622,804(+406/h,今日 +4,530)
改动:UpdateFromDistill §2a/§2b 加门(默认关);节点(§1)与确定性边(§3 CONFLICTS_WITH 等)不受影响;
RecordCoOccurrence 同样门控。恢复 = ZHIYI_GRAPH_AUTO_SYNTH=1(逐位回到改动前)。
测试:governance 包全绿;新增门关用例断言新增边=0 且节点仍创建(既有用例经 TestMain 保持开门语义)。
2026-11-02 17:52:59 +08:00
小唯
3102be6f65
fix(vprop): persistVProp 改增量写,消除每次 recall 9530 次 Redis 往返(p50 192ms→4.2ms)
...
根因:persistVProp() 全量遍历 decisions(7592)+memVValues(1938),每条一次 HSET,
且在全局写锁内 ⇒ 单次 recall 9530 次往返≈133ms,随运行时长线性恶化。
修法:只写本次 decision + 本次引用的 memVValues(语义等价,历史条目已在 Redis)。
2026-11-01 12:41:06 +08:00
小唯
7870b849cc
t_ab5b2461 density prompt: strengthen self-contained merge directive
2026-10-31 01:10:40 +08:00
小唯
afdab8fb6b
fix(pattern): workflow branch default-retired - memory body no longer emitted as pattern Data (t_639c5a03 round3, Path B)
...
Round3 review: data source (LanceDB memory body text) has no parseable structured
tool_use sequence; DetectFromRecords guessing tool combos from natural language =
cooking without ingredients. Path A (structured tool_use) proven absent: MemoryRecord
0 tool fields, episodes/hit_events schema no tool field, Scan projects no tool col.
Decided Path B (honest retirement).
This commit = retirement hygiene: workflow branch emits cluster-longest body as Data
(120-char cut) producing 'whole-sentence memory conf=1.0' pseudo-pattern, violating
hard constraint 'memory body must not be pattern name'.
- Config adds WorkflowPatterns, default false (channel retired)
- DetectFromRecords runs workflow clustering only when explicitly enabled
- unit test: TestDetect_WorkflowRetiredByDefault feeds the exact sentence from review => 0 pattern
- TestDetect_Workflow now opts into WorkflowPatterns=true (gate still verified)
tool_combo branch (whitelist-only + conf>=0.5 + >=2 sources) kept: returns 0 on this data, no pollution.
PATTERN_RECALL stays OFF (80-pattern-recall.conf.disabled-20261030 untouched, no env key).
2026-10-30 23:36:23 +08:00
小唯
3964f0332c
feat(distill): density prompt 增段加中性 few-shot 合并示例(防抄真实脚本名) (t_ab5b2461)
2026-10-30 22:17:26 +08:00
小唯
7562714819
feat(distill): 信息密度判据——三项判据≥2 才保持 distilled,不足降级 observe(env ZHIYI_DISTILL_DENSITY 默认关) (t_ab5b2461)
2026-10-30 22:01:39 +08:00
hermes-prof-dev
99cb22ba93
fix(pattern): 二轮判据收紧——白名单唯一来源+通用词黑名单+hash/数值/目录碎片过滤+conf≥0.5写入门槛+组合≥2成员 (t_639c5a03)
...
小怡 2026-10-30 二轮裁定 5 条全落:
1. ExtractTools 移除'命令式标识'兜底(hash/uuid/目录/文件名碎片的进入路径),成员=knownTools 白名单唯一来源
2. genericTools 黑名单(git/go/curl/grep/bot-chat/mcp/api 等)即使形态合格也拒
3. isValidTool 新增 isHashFragment/isNumericUnitFragment/isNumberedDirName 形态闸
4. UpsertPatterns conf<0.5 一律不写(MinWriteConfidence)
5. tool_combo 需≥2成员(组合语义);IsValidPatternName 同步收紧
单测:junk 类别逐项回归 + 写入门槛 + 幂等/门限值钉死
2026-10-30 20:59:04 +08:00
小唯
5709af0bfa
fix(pattern): detect 判据拒收垃圾工具组合 (.md/日期/标点) + 门槛≥2来源 + dry-run + 写入门闸 (t_639c5a03)
2026-10-30 20:04:31 +08:00
小唯
f178594402
fix(usage): 消费侧熔断根治——无窗积压计数改增量游标 (t_9143c968)
...
根因:CheckCommittedForUse 扫描前用无窗 count(consumed=0)>cap500 作熔断,
写入量涨至 40~200 万行/日后恒触发 ⇒ 10-19 起每 commit skip,consumed=0 已 8 天。
方案 A(增量游标,按卡体最终版):
- 删除无窗全表计数与整窗扫描;单轮代价 O(batch) 与表总量解耦
- expire 通道:出窗 pending 在线标 consumed=2(skipped_expired 留证据)
- retry 通道:退避到期失败行优先重试(t_20bfbd9a 退避语义不变)
- tail 游标:每次 commit 消费游标之上 ≤ZHIYI_USAGE_BATCH(默认200)行(DESC 先吃最新,因果对齐)
- sweep 游标:轮巡复查未消费行,到表尾回绕 0 并本轮补扫(保一次召回多 commit 逐个命中语义)
- TTL:consumed>=1 且 recalled_at<7d 分块删除(ZHIYI_USAGE_TTL_CHUNK 默认5000)
- ZHIYI_USAGE_BACKLOG_MAX 语义收窄:全表积压跳过 → 单次调用失败熔断
- usage_cursor 单行表 + 3 条部分索引(id,recalled_at WHERE consumed=0 等)
- 红线遵守:不动 FEEDBACK_BIAS/POS_MODE/K;不关 ZHIYI_USAGE_TRACK;commit P99 无涉(钩子本为异步)
测试:usage_cursor_test.go 5 例(AC5 窗口外1000+窗内1 / tail 有界+sweep 补齐 /
失败熔断替代 skip 的反证 / retry 通道 / expire+TTL);storage 包全量 ok
2026-10-30 18:47:09 +08:00
小唯
ca6be0063b
feat(distill): 程序性步骤判据——how-to 蒸馏答案无步骤则降级 observe (t_3636b872 阶段4)
...
- IsHowToContent/IsOperationContent:运维/修复/排查/重启类触发词覆盖真实问法
- HasExecutableSteps:事实含命令/路径/序号/端口/动词短语即算有步骤(宁可宽不错杀)
- ProceduralStepVerdict:how-to 命中但事实无步骤 ⇒ 降级 observe;影子默认开(只记不真降)
- 接入 distillOne:lane 判定后对 how-to 内容做步骤校验,keep→observe 记录
- 测试:6 用例(纯元描述降级/含命令放行/含序号放行/非 how-to 不受影响/空答案降级/纯元长句降级)+ 影子语义 + 触发词覆盖
判据动机(t_3636b872 实测):库 83% <60 字、仅 10.2% 含可执行内容,how-to top5 全元描述;
本闸防后续回灌/蒸馏再产出纯元描述。
2026-10-28 07:12:29 +08:00
小唯
40c27f4a95
chore(deploy): 批准 ff92b05 步骤卡 feature(部署清单机读,零代码)
2026-10-28 07:06:04 +08:00
小唯
ff92b0578a
feat(standing): 程序性记忆层步骤卡 schema + trigger 变体召回,命中即短路 (t_3636b872)
...
阶段1: schema + 存储/召回路
- StandingAnswer 增 Op *OpCard(trigger/steps/pre_check/verify/rollback/risk),
存量库 ALTER ADD COLUMN op(幂等)
- Upsert 签名加 op;op=nil 改写答案不丢结构卡(COALESCE op,op)
- LookupStandingAnswer 按 op.trigger 变体归一化精确匹配(零 fuzzy)
- RecallWithMetaTraced 前置短路:常设答案命中 ⇒ 零检索零 LLM 直接返回
- Upsert 后 refreshStandingAnswers 清缓存 ⇒ 写后新卡即时可见
- 测试:OpCardTrigger 命中/多变体/原句并存/无 fuzzy;Upsert 清缓存即时可见
验收实跑:op 落库 41 条,trigger 变体召回 live,评测 40/40 三连复现
2026-10-28 07:05:08 +08:00
小唯
7f7171ac14
feat(recall): 召回契约字段 + trace 回溯 + 生命周期/实体质量判据(工作树收口)
...
这批是 10-26~27 已在生产二进制(zhiyid-protectrails-20261027)里运行、
但一直留在工作树未提交的改动。收口原因:三件改造要开分支,工作树脏 =
分支基准与回滚点都不存在。
主要内容:
- api/routes/contract.go + trace.go:召回响应契约字段(trace_id/status/scope/
continuation/channel)与 /api/v1/trace 回溯端点
- governance/entity_quality.go:实体质量闸
- storage/trace.go + recall.go/recall_write_buffer.go:召回写入缓冲与轨迹
- 测试:contract/recall_contract_fields/recall_lifecycle/stale_lifecycle/
entity_quality/trace
同时修一个 flaky:recall_lifecycle_test 原本硬编码「今天 11:00 已过」,
凌晨跑就会把「已失效」fixture 当成仍有效。改成相对时间(过期=now-1h),
生命周期判据与运行时刻无关。修完 go test ./internal/api/routes ./internal/storage 全绿。
2026-10-28 02:09:19 +08:00
小唯
0b2b4f01d8
fix(storage): recall_seen_count 批更新加 COALESCE —— NULL 行不再吞召回观测值 (t_5aa7cb77)
...
批路径 .column("recall_seen_count", "recall_seen_count + delta") 下推 DataFusion,
SQL 语义 NULL+n=NULL ⇒ 17717 行(43.8%)观测值静默丢失。改 COALESCE(recall_seen_count,0)+delta。
逐条 fallback 路径本就 NULL-aware(读现值 unwrap_or(0))且其 split_whitespace 3 段
解析不容 COALESCE,故不动并加注释防后人误改。
2026-10-27 04:34:48 +08:00
prof-dev
37dcebfce4
fix(recall): 修 16:28 topkcap 引入的 pattern 截断回归 (t_e98cb1d6)
...
- capRecallResults 把 category=pattern/peer 的条目先摘出(recall.go Step 6.2/6.3
追加在 results 末尾),主结果截断到 limit 后再把附带条目放回末尾;
主结果仍收口,pattern/peer 不再被蒸馏结果挤掉。
- 新增 TestCapRecallResults_PatternAndPeerSurviveCap:断言 limit=50 时
pattern 计数 ≥1、peer 不被截断、主结果仍不超过 limit。
方案取舍:选 A(cap 内先摘出),不选 B(注入移到 cap 之后)——
注入在 storage.Recall() 而 cap 在 routes 层,B 需跨 storage/routes 重排
调用链并改缓存路径;A 是纯函数、最小、且与原 topkcap 修正在同一位置。
2026-10-26 19:42:57 +08:00
小唯
d7a73d7e6c
fix(recall): top_k 收口 + 恢复 main 可构建性
...
1) top_k 收口(t_9025b0eb)
/api/v1/recall 无视 top_k:top_k=5 实测返回 341 条(5 distilled + 336 graph_expanded),
top_k=10 返回 521 条。因 ExpandFromResults 扩展结果 append 无上限。
后果:插件记忆预取被撑爆(journal 实测单次 flush 合并 900/780/613/549/351 条),
真相关条目落在被截断段;count 失真;使用追踪按千级记账稀释指标。
修法:capRecallResults —— results = 主结果 ≤top_k;扩展单独走 graph_expanded 字段
(上限 top_k,能力仍可观测);主结果不足时用扩展补齐(稀疏查询仍受益)。
+ core_topk_test.go 5 例 6 断言钉住契约。
2) 恢复 main 可构建性(P0,非本卡范围但阻塞一切构建)
rebase 丢了 metrics.ConsolLastSuccessTime / ConsolConsecutiveFailures /
ConsolidateBusyWaitTotal / MetaNoteRejectTotal 的定义(只在 f96c828),
而调用方已进 main,且 consolidation_track.go 整个文件不在树上 ⇒ go build 失败。
从 f96c828 原样恢复 4 个指标定义并注册;从 2275b83 恢复 consolidation_track.go。
2026-10-26 16:29:43 +08:00
xiaoyi
9a4a734c19
fix(metrics): 计数器/率指标语义分清 + t8 阈值改由 Condition 承载(t_da03e910)
...
- 审计误读订正:deprecated_per_day 是计数器(无分母),不给 _samples/_valid 是对的
- 新增 deprecated_total:区分「今天 0 条」与「从未统计过」(0 的二义性)
- executor t8:原 Condition:0.1 从不生效(判据硬编码 >5)→ Condition:5.0 + 读 t.Condition,行为不变
- 单测钉住:RecordDeprecation 双计数、t8 阈值真的可配、计数器不带率键
- docs/metrics-semantics.md:counter/rate/mean 三种读法 + 0 的二义性铁律
2026-10-26 14:55:01 +08:00
xiaoyi
38d7ef147d
feat(selfcheck): pattern 段可见化 —— 零产出可被机器读到(写入端 0 生产者事故)
...
- governance.GraphStore 增 CountNodesByType(total, withID, lastUpdated),SQLite/内存/缓存三实现
- selfcheck cheap 增 pattern 段:rows / rows_with_id / last_produced_at / verdict
verdict ∈ producing|zero_output|no_id|unknown_age|no_graph_store|unsupported
- 实测:rows=0 verdict=zero_output(与 graph.db 只读复核一致),cheap 22ms
- 动机:pattern 召回 0 命中时只能靠翻 7 天日志才发现「实现了≠出过数」
2026-10-26 14:55:01 +08:00
xiaoyi
ab1452d06b
feat(selfcheck): /api/v1/selfcheck 统一取数端点 + tools/selfcheck_full.py 全量快照(牧尘批「三档」)
2026-10-26 14:55:01 +08:00
小唯
1c7882ce34
fix(graph): SQLiteGraphStore.ExpandFromResults 恒 0 产出 — from/to 是节点ID却拿裸名比对(t_724f31ad)
...
816/819 行把 Navigate 返回的节点 ID(n_织忆)与裸实体名 entity 做 == ⇒ 恒不相等 ⇒ 路径全被 continue ⇒ 结构性 0 条附加。
修:比对改用 nodeID(normalizeEntityID(entity));附加结果补 Category=graph_expanded + ID=邻居节点ID(非空,修复 recall.go ID 去重与审计计数);Content 用可读显示名(displayNodeName)。
补单测:正向(n_织忆→n_图谱 链+1条recall ⇒ 补入 graph_expanded 且 ID 非空) + 反向(图外实体 ⇒ 0 补入不凭空加)。
2026-10-26 14:55:01 +08:00
小怡
3cf3858f09
fix(peer): 画像推理器支持 peer 专用 LLM 端点,避免被全局 LLM_ENDPOINT 拖去鉴权腿
...
起因 t_a5ef04a5:zhiyid 的 LLM_ENDPOINT 由 90-llm.conf 定为 newapi 3000 + agnes-2.5-flash
(供蒸馏/skillgen/consolidate 共用),而 NewLocal2BReasoner 按设计不发 Authorization
⇒ peer refresh 必然 401、peers 表恒 0 行、peer 召回零产出。
不采用卡面建议的「把全局 LLM_ENDPOINT 改成 8081」——那会把蒸馏同时降级成 2B。
改法:新增 ZHIYI_PEER_LLM_ENDPOINT / ZHIYI_PEER_LLM_MODEL 优先读取,未设时行为与改动前逐位一致。
回滚:删 91-peer-llm.conf 即恢复旧行为。
2026-10-26 14:55:01 +08:00
小怡
33e16c1a61
fix(recall): agent_id 派生作用域候选过少时补一次全库搜索(ZHIYI_NS_FALLBACK_MIN,默认20,0=关)
...
问题:请求带 agent_id ⇒ resolveRecallNamespace 派生 <agent>-main,实测该 ns 只有
default-main 6 / xiaoyi-main 6 / prof-cloud-main 7 条,不传 agent_id 则 200 条
⇒ 带 agent_id 的调用静默劣化到个位数,不报错(09-23 只修了调用方,没修被调用方)。
改法:新增 RecallWithMetaOpts(..., allowNSFallback);仅 agent_id 派生作用域传 true,
显式 namespace 调用方传 false(防跨域泄漏)。候选 < 阈值时补一次全库搜索并合并 + 打日志。
回滚:ZHIYI_NS_FALLBACK_MIN=0。单测 4 条锁死:兜底生效/显式ns不兜底/env关/候选充足不兜底。
2026-10-26 09:56:38 +08:00
小怡
c84d968b02
feat(recall): 新增 ZHIYI_FUSE_MODE=proof(第二槽改用证据条数质量)
...
对应 t_9acaa74d §5 A' 的 nouse 臂:融合第二槽 = QualityFromProof(确定性 x/(x+K)),
彻底不含 importance=recency×(1+ln(seen))/V —— 老卡实测 usage 特征单独是负资产
(imp-only 0.0579 / seen-only 0.0335 NDCG@5)。
默认关 ⇒ 逐位等价现状;开启需配合 FUSION_W<1,否则第二槽权重 0。
单测锁两条:默认必须 false;证据分只依赖证据条数(同一证据数下改 seen/时间不得变)。
2026-10-26 08:42:40 +08:00
小怡
f4417c2f4d
fix(eval): 金标路径优先级 显式path > env > 内嵌(保留相对路径内嵌兜底)
...
旧顺序 env 优先 ⇒ ZHIYI_GOLDEN_SET 一设,请求里的 golden_path 全被静默忽略:
实测 7 个 chunk(304 条) 每块都报 53 条(env 那套),指标全 0 时极难察觉。
现:绝对路径读不到=报错(不许静默换题);相对路径读不到仍回落内嵌(AC5 既有行为)。
2026-10-26 01:53:50 +08:00
小怡
03cac702a8
fix(eval): 金标路径优先级改为 显式path > env > 内嵌
...
旧顺序 env 优先 ⇒ ZHIYI_GOLDEN_SET 一设,请求里传 golden_path 全部被静默忽略:
实测 7 个 chunk(304条) 每块都报 53 条(env 那套),且指标全 0 时极难察觉。
env 现在只作默认金标;显式路径读不到改为明确报错,不再静默回落内嵌。
2026-10-26 01:52:11 +08:00
小怡
0499c82965
feat(eval): RunGolden 支持 all_namespaces(跨 ns 评测)
...
旧逻辑 ns 为空强制 shared ⇒ 评的是「只看 shared 的召回」,与线上跨 ns 不是同一系统
(实测前 15 条金标里 15 条 top 结果不同)。新增 all_namespaces=true ⇒ ns=""(等同线上默认);
不传 = 旧行为,向后兼容。
2026-10-26 00:28:38 +08:00
小怡
d117102088
fix(recall): t_standing_recall 改严格相等匹配(上线即抓到换主语误命中)
...
留出集实测:「织忆的服务跑在哪个端口」被判为「出图的服务跑在哪个端口」的匹配
(Dice 0.82,仅主语两字之差),把 ComfyUI 8188 置顶成织忆端口——模板句换主语必错。
改为归一化后完全相等才返回;近似 ≥0.78 只打 near-miss 日志用于补变体;加回归测试。
2026-10-25 23:57:23 +08:00
小怡
1aaab764ba
feat(recall): t_standing_recall 常设答案精确通道(默认关)
...
实测基线(53 条真实提问):correct@1 20.8% / useful@5 88.7%;6 条跑偏案例里
5 条目标文档不在向量 top-50 —— 语义通道对端口/数字/标识符类提问够不着,补精确通道。
- storage/standing_match.go:归一化+bigram Dice 匹配(阈值 0.78,宁漏勿错)、30s 快照、置顶注入
- storage/recall.go:RecallWithMeta 拆为 wrapper + inner,开关 ZHIYI_STANDING_ANSWER=1 才生效
- 关闭时与旧行为逐位一致(可一行回滚)
- 单测:归一化/相似度/阈值/置顶 4 组全 PASS
2026-10-25 23:53:26 +08:00
小唯
2ac7c9d5a1
feat(write-ops): t_writeops_llm_judge — 写时判定器改 LLM 三分类 + apply 硬保护
...
问题(离线回放实测,非推测):
- 规则基 defaultJudge 以 ZHIYI_WRITE_SIM_UPDATE=0.70 判 UPDATE,17179 条影子日志里
14435 条(84%)被判「新事实应覆盖旧事实」
- 人工抽检 15 条低相似度样本,15/15 不是真覆盖(「用户查看知乎链接」vs「用户查看微信文章」
都被判成覆盖);低档 LLM 判定精度同样不足(0.70-0.85 档 REPLACE 精度约 25%)
- 结论:相似度只反映「话题相关」,不反映「是否同一属性的新旧值」
改动:
- 新增 llm_judge.go:REPLACE/DUPLICATE/KEEP 三分类,仅 sim>=ZHIYI_WRITE_JUDGE_SIM(0.95)
才问模型,低档短路 ADD;调用失败兜底 ADD(宁可不覆盖)
- JudgeWriteOp:judge 显式注入 > apply/llm 模式用 LLMJudge > 规则基
- writeOpsApply 硬保护:apply 强制要求 ZHIYI_WRITE_JUDGE=llm,否则降级 shadow 并留痕
(防止规则基 84% UPDATE 在 apply 下误覆盖上万条)
- 单测 8 条 + 真实 LLM e2e 3 条(ZHIYI_LIVE_JUDGE=1 才跑)
验收:go test ./internal/distill/ 全绿;live e2e 真覆盖→UPDATE / 假覆盖→ADD / 重复→NOOP 3/3
部署:shadow 模式(不改库),观察 2-3 天后 op 分布应从 84% UPDATE 降到 5-15% 再考虑 apply
2026-10-25 23:06:42 +08:00
小唯
66d5049151
feat(feedback): t_11245d30 区分人机信号 — MarkUseful 支持 source=auto → 记 auto_feedback
...
人工点「有用」仍 user_feedback(行为不变);插件自动反馈(_auto_feedback_for_reply)
传 source=auto → 记 auto_feedback,让 zhiyi:vprop_decisions 可辨「牧尘认可 vs 机器自评」。
纯观测,零行为变化:不改 V 权重/语义闸阈值/_MAX_PER_TURN。待 Go toolchain 重建后生效。
2026-10-24 04:34:25 +08:00
小唯
f979bd6ffc
feat(recall): 融合权重可配 ZHIYI_FUSION_W(默认0.7=零变化,1.0=纯向量)
...
t_5624c0ff → 牧尘 2026-10-21 批准「按推荐执行」。
依据(strict n=134,golden-v4):
- 现状 fuse 0.1125 vs 纯向量 0.1898 ⇒ 现状是负收益,比纯向量低 39%
- 去 usage 0.2019 但逐 query worst −100%(12/134 从答对变彻底答错)
- MoA expert-panel 4 槽:3 槽指向止血 + intern-s2 指出根因是召回不足(相关文档在 pool#10-14)
- A/C 绝对差 0.0121 在 n=134 上不显著 ⇒ 不为它背 9% 硬失败率
改动:三处硬编码 0.7/0.3 参数化为 fusionW(candidates.QualityScore / reranked.Score / base 展示分)。
回滚:ZHIYI_FUSION_W=0.7 或删除该 env(逐位回到改动前)。
2026-10-21 20:35:30 +08:00
小唯 and Claude Opus 4.8
8ea82fbec3
fix(storage): t_cf680fad SoftDelete 冲突耗尽静默丢 — 修「重试成功=0」+ 残留根治
...
根因(实证):runMerges O(n²) 软删 + 并发遗忘碎片器 在同一张 memories 单表上
制造 MVCC 写风暴;旧 3 次/~350ms 无 jitter 预算下每次重放都撞已推进的新版本
(单次 op 3 次重放 version 598346→598347→598348→598350 逐版推进仍耗尽),
失败软删被 consolidation_pipe.go:252 的 `_ =` 静默丢弃 ⇒ 源记录 is_deleted 停
false,每次重启窗口留新残留(检索重复命中)。
修(3 件,均 Go 侧 zhiyid):
① durable pending-softdelete 队列(softdelete_pending.go):MVCC 冲突耗尽 ⇒
把 (id, reason) 追加进 /var/lib/memoryweave/pending-softdelete.jsonl
(单写者 append + 原子 tmp/rename + 同 id 去重);zhiyid 启动 + 每 30s 触发器
tick 各 drain 一次(SET is_deleted=true 幂等、重读最新已提交版本),风暴退去
后重放必落盘 —— 根治「每次重启窗口都留新残留」。
② retrySoftDeleteRPC 预算 3→5 + 退避加 0~50% jitter:破 50+ 并发软删锁步雷群
(锁步本身是冲突持续的主因),多两次机会跨风暴窗口。
③ consolidation_pipe.go:252 `_ =` → 显式 log(观测、禁静默);队列负责最终落盘。
测试:storage 全绿(耗尽入队 / 非可重试不入队 / 同 id 去重 / 风暴退去 drain 落盘
清空 / 风暴未退 drain 保留队列)。6 文件:2 新 + 4 改。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-10-21 09:45:06 +08:00
小唯
2862f68631
feat(gate): 补提 t_bd63b641 门控复核资产 — quarantine 过滤 + junk 实体拒写 + ListPatterns 三返回值
...
- ListPatterns 改三返回值 (pats, skipped, err):单行 NULL/空 id 跳过计数不致全盘失败;
排除 quarantine 名空间;COALESCE 防 NULL Scan 错误
- SQLiteGraphStore 增 isQuarantinedNode + Navigate/NavigateBiDir 过滤 quarantine 节点
- graph_auto.go 蒸馏写库前拒 junk 实体 (IsJunkName)
- 新增 entity_guard.go (实体名拒写门禁) + shadow_diff_test.go (影-复量具)
- docs/ac-evidence/t_bd63b641-shadow-gate/ 验收证据
- .gitignore 增 /go/tmp/ /verify.go,删 17.9M 编译二进制临时产物
build+test 均通过:go build ./... exit0;pattern+routes 两包 ok
2026-10-20 07:10:29 +08:00
小唯
b8d77547de
chore: mark 79019bf (A10 huc 读侧+e2e) approved
2026-10-19 21:29:04 +08:00
小唯
79019bfc40
A10(t_d618dc7c): 补 human_useful_count 读侧接线 + 真实 LanceDB e2e 闸门
...
读侧静默 no-op 修复(t_4c810e02 同类:写进库但读不回):
- lancedb_ipc.go 读路径 unmarshal 结构体缺 human_useful_count 字段,
导致 /recall、/memories 读回恒 null(列真实写入但读侧解包丢弃,无报错)。
补 4 处:SearchWithTruncation 结构体+输出映射、Scan 结构体+输出映射、
GetSkillCandidates(mapInt)、新增 mapIntPtr 可空整数映射(NULL≠0)。
- ScanAll/embedded-model 路径经 models.MemoryRecord 已带字段,无需改。
新增 human_useful_count_e2e_test.go(真实 sidecar 写→读回闸门,
仿 bitemporal_e2e 模式,未设 ZHIYI_HUC_E2E_SOCK 自动 skip):
- AC#4 读非空:存量行读回 NULL(nil);
- AC#5 同步+反例:人工 useful×2⇒huc=2/useful=2;机器 dedup 路径不污染 huc;
人工 not-useful 只动 human_not_useful。
验证:go build 通过 + 全 storage 套件绿;真实 sidecar e2e 全绿
(AC4 读回 nil / AC5 huc=2 useful=2 / 反例隔离成立)。
git show --stat 212624a4341fac
2026-10-19 21:28:33 +08:00
小唯
a5bc27c3a4
feat(distill): 蒸馏落库前拒写空壳(t_e11207f8 治源①)— 共享判据 zhiyi_payload_guard_rules.json + Go payload_guard + OnDistillComplete 拦截 + /api/v1/payload-guard/stats + 3 单测;顺带修复 deploy-approved 清单坏行
...
- distill/payload_guard.go: 读共享 JSON(与 Python 同源),ShellCheck 带心跳/拦截计数
- api/server.go: OnDistillComplete fact 循环红act 后 ShellCheck 拒写空壳 + 启动加载 + stats 端点
- main_test.go: TestMain 加载共享规则供单测
- 修复 scripts/deploy-approved-commits.txt 尾行坏数据('appending:' 前缀 → 两条合法 SHA)
2026-10-19 21:16:57 +08:00