{"_id":"@bzpovo/agent-memory","_rev":"7-1f3535cc72c673a1d4fb00208c51b770","name":"@bzpovo/agent-memory","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.0":{"name":"@bzpovo/agent-memory","version":"0.1.0","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","_id":"@bzpovo/agent-memory@0.1.0","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"bin":{"lingix-memory":"bin/lingix-memory.mjs"},"dist":{"shasum":"1247455ff4ad54f1a7fbf9a3d46f149cbde021c1","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.0.tgz","fileCount":20,"integrity":"sha512-60/XaIggUAmTezTrDpeisPhYbXFaq6NskpUzEJJoarCdNHGuicE2UCQgdSeH8Id8kfE1UXdg7PIuT7sJLrpVIQ==","signatures":[{"sig":"MEUCIBCYBdZTQBa0OZuMapeFPug4FymaNu2lGOnFc6DEBP7OAiEAmBM1bAGCh0sySaWbLPAuv2ByFLc94OmD2WrHi5oG9CU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":401073},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":"./dist/index.js"},"gitHead":"e1a6e2f31396c662cadb5a0844d312334e66db9d","scripts":{"test":"python -m unittest discover -s tests -v","build":"tsc -p tsconfig.json","pack:check":"npm run plugin:validate && npm pack --dry-run","plugin:build":"npm run build && openclaw plugins build --entry ./dist/index.js","plugin:validate":"npm run build && openclaw plugins validate --entry ./dist/index.js"},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"openclaw":{"extensions":["./dist/index.js"]},"_npmVersion":"11.13.0","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","directories":{},"_nodeVersion":"24.16.0","dependencies":{"typebox":"^1.1.38"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"peerDependencies":{"openclaw":">=2026.5.17"},"_npmOperationalInternal":{"tmp":"tmp/agent-memory_0.1.0_1786285893385_0.5344684945709404","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bzpovo/agent-memory","version":"0.1.1","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","_id":"@bzpovo/agent-memory@0.1.1","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"bin":{"lingix-memory":"bin/lingix-memory.mjs"},"dist":{"shasum":"14a629480e8f636d4dad4e9b154c3732846a7551","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.1.tgz","fileCount":20,"integrity":"sha512-ufv1A/Y487RpJk8owCMram4UKu1Q0Sc/zJvynDuVqKeOoSUGpci9WEr8nscdIta5ZuTMDONs1lZR/S8jg4j3ig==","signatures":[{"sig":"MEQCIFIsJe3+BFUM7tQI9rCSyjM174m+m+OxoSuiWzXA+IsYAiBtzaMLe6grkWSn/l8PKn42FDLn+Wu8nfktz95oXXGAkg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":403147},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":"./dist/index.js"},"gitHead":"cb570b3993f6e6e9454ac43949b43eb86dac77b7","scripts":{"test":"python -m unittest discover -s tests -v","build":"tsc -p tsconfig.json","pack:check":"npm run plugin:validate && npm pack --dry-run","plugin:build":"npm run build && openclaw plugins build --entry ./dist/index.js","plugin:validate":"npm run build && openclaw plugins validate --entry ./dist/index.js"},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"openclaw":{"extensions":["./dist/index.js"]},"_npmVersion":"11.13.0","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","directories":{},"_nodeVersion":"24.16.0","dependencies":{"typebox":"^1.1.38"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"peerDependencies":{"openclaw":">=2026.5.17"},"_npmOperationalInternal":{"tmp":"tmp/agent-memory_0.1.1_1786328625284_0.36237186720043635","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bzpovo/agent-memory","version":"0.1.2","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","_id":"@bzpovo/agent-memory@0.1.2","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"bin":{"lingix-memory":"bin/lingix-memory.mjs"},"dist":{"shasum":"8975d1afc7174e7d19adb97281171b07d0f46b81","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.2.tgz","fileCount":21,"integrity":"sha512-0L30g93pD5/XuRtI3Iu2Ma1oxeVqtR2rsSN49OkxLpKul1Sb5FduG2u5NsC9N7m+89ZCiy5Boqmi2Gdw7gFEVQ==","signatures":[{"sig":"MEQCIBO4HwHuOi6HX/pH71jHoCgbKna8PSEGFgrFESXjfboxAiBqtMLc7le0Ah/jeduaoygzd6iD06qawO3vNIgA3XD3Ug==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":461946},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":"./dist/index.js"},"gitHead":"acb6aaf6e771f48874db474fe8cc13914f60dece","scripts":{"test":"python -m unittest discover -s tests -v","build":"tsc -p tsconfig.json","prepack":"npm run plugin:validate","pack:check":"npm run plugin:validate && npm pack --dry-run","plugin:build":"npm run build","plugin:validate":"npm run build && node --input-type=module -e \"import('./dist/index.js').then(({ default: entry }) => { if (!entry || typeof entry.register !== 'function') throw new Error('插件入口未导出 register(api)'); console.log('Native OpenClaw plugin entry is valid.'); })\""},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"openclaw":{"extensions":["./dist/index.js"]},"_npmVersion":"11.13.0","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","directories":{},"_nodeVersion":"24.16.0","dependencies":{"typebox":"^1.1.38"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"peerDependencies":{"openclaw":">=2026.5.17"},"_npmOperationalInternal":{"tmp":"tmp/agent-memory_0.1.2_1787657361994_0.751537050285048","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bzpovo/agent-memory","version":"0.1.3","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","_id":"@bzpovo/agent-memory@0.1.3","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"bin":{"lingix-memory":"bin/lingix-memory.mjs"},"dist":{"shasum":"012d83b7a4637aa328823ea3fb251610d833e86f","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.3.tgz","fileCount":21,"integrity":"sha512-oKj48N2gA9TkSc6f5BDA+qW9eLCW6JHZBsILpYANgmDUDj9avTttocG2Pm/vx/Qw2EiXjq8cf4lycLfHzSg6iw==","signatures":[{"sig":"MEUCIHZXX3RAMVmDYhoebkD7gOpvMjx1nRUkMSMTqkCjgz75AiEAu/JlteIX6J/D4Om1ShLp+3VyEXkq3snj6LJb62o0uJ0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":462653},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":"./dist/index.js"},"gitHead":"acb6aaf6e771f48874db474fe8cc13914f60dece","scripts":{"test":"python -m unittest discover -s tests -v","build":"tsc -p tsconfig.json","prepack":"npm run plugin:validate","pack:check":"npm run plugin:validate && npm pack --dry-run","plugin:build":"npm run build","plugin:validate":"npm run build && node --input-type=module -e \"import('./dist/index.js').then(({ default: entry }) => { if (!entry || typeof entry.register !== 'function') throw new Error('插件入口未导出 register(api)'); console.log('Native OpenClaw plugin entry is valid.'); })\""},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"openclaw":{"extensions":["./dist/index.js"]},"_npmVersion":"11.13.0","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","directories":{},"_nodeVersion":"24.16.0","dependencies":{"typebox":"^1.1.38"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"peerDependencies":{"openclaw":">=2026.5.17"},"_npmOperationalInternal":{"tmp":"tmp/agent-memory_0.1.3_1787660642973_0.3347765277278265","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@bzpovo/agent-memory","version":"0.1.4","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","_id":"@bzpovo/agent-memory@0.1.4","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"bin":{"lingix-memory":"bin/lingix-memory.mjs"},"dist":{"shasum":"84518bbf35cd5eea4b8da372f6b817622f793c9e","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.4.tgz","fileCount":21,"integrity":"sha512-El+pVRIFsvRXuzuxbFF2WZJX1Tn2k3pAps4O1szQGcDCUIUT1cB+qs1VXBrrYj03skkXq7A/9KgwEEwmxEpBhg==","signatures":[{"sig":"MEYCIQCvXLyPj7j2DaY42eU0pcYXd3lxSXioVCtiqv/PMp16BgIhAJQKudT0Vjpyc1tdL1kJVH5tSjjcizNp8zjmMZTiEBJ6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":463487},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":"./dist/index.js"},"gitHead":"acb6aaf6e771f48874db474fe8cc13914f60dece","scripts":{"test":"python -m unittest discover -s tests -v","build":"tsc -p tsconfig.json","prepack":"npm run plugin:validate","pack:check":"npm run plugin:validate && npm pack --dry-run","plugin:build":"npm run build","plugin:validate":"npm run build && node --input-type=module -e \"import('./dist/index.js').then(({ default: entry }) => { if (!entry || typeof entry.register !== 'function') throw new Error('插件入口未导出 register(api)'); console.log('Native OpenClaw plugin entry is valid.'); })\""},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"openclaw":{"extensions":["./dist/index.js"]},"_npmVersion":"11.13.0","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","directories":{},"_nodeVersion":"24.16.0","dependencies":{"typebox":"^1.1.38"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"peerDependencies":{"openclaw":">=2026.5.17"},"_npmOperationalInternal":{"tmp":"tmp/agent-memory_0.1.4_1787661025390_0.696945783995536","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@bzpovo/agent-memory","version":"0.1.5","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","_id":"@bzpovo/agent-memory@0.1.5","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"bin":{"lingix-memory":"bin/lingix-memory.mjs"},"dist":{"shasum":"d8e0bb323e1b90ead20fe81422b055985f0dee2c","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.5.tgz","fileCount":21,"integrity":"sha512-TdYyrmRJbR6GB6Kxc3M2vc1TM6Eqw0B7Rjtb0XNNyqJPXRBUdwC7Mkmg/F/9/LpUmomJwFrP18P6a8EN+wFiPw==","signatures":[{"sig":"MEUCIQD62ITsmF7w0P/KZ0MMOSmvcMwMMItDwcsor4abd/h7jQIgQPOZBhtAI8qA4AggHtxwmxyZxJiZySQ0UO2mBVDVpLU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":463519},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":"./dist/index.js"},"gitHead":"acb6aaf6e771f48874db474fe8cc13914f60dece","scripts":{"test":"python -m unittest discover -s tests -v","build":"tsc -p tsconfig.json","prepack":"npm run plugin:validate","pack:check":"npm run plugin:validate && npm pack --dry-run","plugin:build":"npm run build","plugin:validate":"npm run build && node --input-type=module -e \"import('./dist/index.js').then(({ default: entry }) => { if (!entry || typeof entry.register !== 'function') throw new Error('插件入口未导出 register(api)'); console.log('Native OpenClaw plugin entry is valid.'); })\""},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"openclaw":{"extensions":["./dist/index.js"]},"_npmVersion":"11.13.0","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","directories":{},"_nodeVersion":"24.16.0","dependencies":{"typebox":"^1.1.38"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"peerDependencies":{"openclaw":">=2026.5.17"},"_npmOperationalInternal":{"tmp":"tmp/agent-memory_0.1.5_1787661745517_0.09369224659274922","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@bzpovo/agent-memory","version":"0.1.6","description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","type":"module","main":"./dist/index.js","bin":{"lingix-memory":"bin/lingix-memory.mjs"},"exports":{".":"./dist/index.js"},"scripts":{"build":"tsc -p tsconfig.json","plugin:build":"npm run build","plugin:validate":"npm run build && node --input-type=module -e \"import('./dist/index.js').then(({ default: entry }) => { if (!entry || typeof entry.register !== 'function') throw new Error('插件入口未导出 register(api)'); console.log('Native OpenClaw plugin entry is valid.'); })\"","test":"python -m unittest discover -s tests -v","pack:check":"npm run plugin:validate && npm pack --dry-run","prepack":"npm run plugin:validate"},"keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"engines":{"node":">=20"},"peerDependencies":{"openclaw":">=2026.5.17"},"dependencies":{"typebox":"^1.1.38"},"devDependencies":{"openclaw":"^2026.5.17","typescript":"^5.9.0"},"openclaw":{"extensions":["./dist/index.js"]},"gitHead":"acb6aaf6e771f48874db474fe8cc13914f60dece","types":"./dist/index.d.ts","_id":"@bzpovo/agent-memory@0.1.6","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-yqtJQqi0eVhihz9EphEzJhVY4KMXn2/TKSguxJAWWK0CuiqEQp9BdyOSY9/jwKUbN6AWBiB2m0bio5v4iC1IjA==","shasum":"eafa759889eae72fdf0db93cdb99742a42bd5204","tarball":"https://registry.npmjs.org/@bzpovo/agent-memory/-/agent-memory-0.1.6.tgz","fileCount":21,"unpackedSize":463782,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDPhGMDX2UmCJOKPoHecMhH+GfGoyPSERhy68iPw26ReQIgIWMa9rRk9eT+gecEWP4tOAYjPIBztI5EiZCyOgCKq1Y="}]},"_npmUser":{"name":"bzpovo","email":"2024202110041@whu.edu.cn"},"directories":{},"maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-memory_0.1.6_1787661927782_0.8955725138711732"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-09T14:31:33.221Z","modified":"2026-08-25T12:45:28.074Z","0.1.0":"2026-08-09T14:31:33.542Z","0.1.1":"2026-08-10T02:23:45.435Z","0.1.2":"2026-08-25T11:29:22.143Z","0.1.3":"2026-08-25T12:24:03.104Z","0.1.4":"2026-08-25T12:30:25.543Z","0.1.5":"2026-08-25T12:42:25.660Z","0.1.6":"2026-08-25T12:45:27.917Z"},"author":{"name":"Lingix Agent Memory Team"},"license":"MIT","keywords":["openclaw","openclaw-plugin","agent-memory","advertising","llm-judge","embedding","sqlite"],"description":"Faithfulness-gated four-layer advertising agent memory plugin for OpenClaw","maintainers":[{"name":"bzpovo","email":"2024202110041@whu.edu.cn"}],"readme":"# Lingix Agent Memory\n\n面向广告投放 Agent 的四层长期记忆系统，同时可作为 OpenClaw 工具插件使用。它以 SQLite 持久化记忆，提供忠实性门控、LLM Judge、Embedding/FTS 混合检索、实时记忆 TTL、受控更新、策略模板晋升以及完整审计链路。\n\n> 当前版本：`0.1.0`。OpenClaw 插件 ID：`lingix-agent-memory`；npm 包名：`@bzpovo/agent-memory`。\n\n## 核心能力\n\n- **四层记忆**：L1 工作上下文（TTL 驱动过期）、L2 策略经验（情节记忆）、L3 核心记忆（系统规则 + 客户画像 + 品类公理）、L4 技能模板。\n- **DoubtMem Guard**：三层串行架构——规则先行（确定性拦截未经用户确认的 Assistant 建议/推荐、试探性偏好、Agent 推断直写 L2/L3、无依据数值结论）→ LLM Judge 或本地 DoubtMem 模型（语义归因、grounding 复核、一致性判定）→ 分层策略器（L1–L4 各自的来源/条件/时效约束，L3/L4 硬性限制可覆盖 LLM 结论）。四种决策动作：WRITE / UPDATE / REJECT / PENDING_REVIEW（高风险转人工审核）。\n- **LLM Judge / ValueScorer / ConflictDetector（必需）**：通过 OpenAI-compatible API 处理语义归因、一级价值打分和语义冲突检测；未配置 `MEMORY_LLM_API_KEY` 时系统会直接报错拒绝启动，不再静默降级为规则判定。\n- **factuality_check 事实检测工具（可选）**：`LLMJudge` 可注入 `tool_verifier`（默认实现 `DefaultFactualityToolVerifier`），在候选记忆命中数值/效果/时效性表述或已有相关记忆时，先用 `campaign_analysis`/`memory_search`/`industry_benchmark` 做一次客观核验，再据此对 `grounding` 做升级/降级，减少对 LLM 自身数值判断的依赖；未注入时行为与之前完全一致。\n- **混合检索**：结构化筛选 + SQLite FTS5 关键词检索 + 可注入的真实 Embedding 余弦相似度。\n- **记忆治理**：L3 默认 24 小时 TTL；高质量新证据可以版本化 UPDATE；成熟 L2 才能晋升 L4。\n- **质量闭环**：Trace 审计、抽样复核、Guard 精度/召回/误拒率指标（`MemoryStorage.guard_metrics`，依赖人工复核）、护栏指标（`MemoryStorage.guardrail_metrics`，REJECT 率/记忆库增长率，直接由已有数据计算，无需人工复核）、反思和容量淘汰。\n\n## 架构\n\n记忆写入支持两种入口（见下文「快速开始」第 5 步），最终都会汇聚到同一套四级\n筛选漏斗（`memory/trigger.py::process_event`），依次回答四个问题：值不值得记、\n是不是真的、和已有记忆是否重复/矛盾、质量够不够：\n\n```text\nOpenClaw Tool / CLI\n        │\n        ├── ingest(description)          ──┐  自由文本，无需预先判断事件类型\n        │       ⓪ 自动分类 (LLMEventClassifier)\n        │          → trigger_type + 结构化 raw_data\n        │          置信度不足/无法分类 → 直接拒绝，不进入下方漏斗\n        │                                  │\n        └── trigger(event_type, data) ─────┘  已有结构化数据，跳过分类\n                    │\n                    ▼\n            MemoryTrigger.process_event()\n    ① 价值判断 (LLMValueScorer)      —— 这条信息是否包含可沉淀的知识\n    ② 忠实性门控 (DoubtMem Guard)     —— 这条信息是不是真的、该写到哪一层\n    ③ 冲突检测 (LLMConflictDetector) —— 和已有记忆是否重复/矛盾\n    ④ 质量评估 (MemoryValidator)     —— 五维度加权复核，产出 importance_score\n        │\n        ▼\nSQLite Storage（FTS5 + Embedding 混合检索）\n        │\n        └──────────── Trace / Review / Metrics ────┘\n```\n\n第②级 DoubtMem Guard 内部采用三层串行处理：先由确定性规则做前置拦截——未经\n用户确认的 Assistant 建议/推荐（正则匹配 \"建议\"/\"推荐\"/\"you should\" 等表达后无\n用户确认信号）直接 REJECT，不调用任何 LLM Judge；Agent 推断（`source_attribution\n= agent_inference`）不允许直接写入 L2/L3；L3 仅接受权威来源（`rule_source`/\n`tool_return`，广告主画像类额外允许 `user_statement`），非权威来源转\nPENDING_REVIEW；L4 不接受外部写入，仅由 L2 受控晋升。规则阶段给出\nWRITE/UPDATE 但需要语义复核时才调用 LLM Judge（网关 `LLMJudge` 或本地\n`DoubtMemLocalJudge`），L3/L4 的硬性层级限制不受 Judge 结论影响——即使 LLM\n判定 WRITE，L3/L4 的分层约束仍由确定性代码最终把关。\n\n`importance_score` 统一来自第④级 `MemoryValidator` 的五维度加权评分（0-1 换算\n为 0-10），不再由第一级价值判断赋固定基准分——第一级只做“值不值得记”的二元\n判断，真正的重要度/质量差异由第四级评分体现，参与后续 `retention_score`（留存\n排序）和检索相关度排序。\n\n第一级信息价值判断以 **4 类操作场景**（`memory/models.py::TriggerType` /\n`OperationType`，两者枚举值完全一致）为判断框架，采用\"程序硬规则先行 +\nLLM 做单次 true/false 判断\"的确定性流程（`memory/ai_provider.py::apply_program_hard_rules` /\n`LLMValueScorer`）：程序侧只做一件事——校验 `operation_type` 是否属于四类合法枚举，\n不合法则直接 REJECT（不调用 LLM）；合法后由 LLM 判断候选记忆的\n`skill_result_summary` 是否包含值得长期沉淀的有效信息（返回单次 true/false）。\n不满足以上任一条件即在第一级被拒绝：\n\n| 触发类型 / 操作场景 | 说明 | 典型 Skill |\n|---|---|---|\n| `plan_operation` | 投放操作：创建计划、修改预算/出价/状态等用户投放动作 | `advendor-campaign-sg-brand.update_budget/update_bid/update_status`、`advendor-campaign-create-sg-brand.create_plan` |\n| `diagnostic_analysis` | 诊断分析：计划诊断、效果报告、异常归因、洞察分析 | `advendor-campaign-sg-brand.diagnosis/report/insight/trend_analysis` |\n| `data_query` | 查询数据：计划/账户/报表/余额/日志/洞察等读取操作 | `advendor-campaign-sg-brand.query_balance/query_flow/list_plans/plan_info/suggest` |\n| `advice_request` | 询问建议：营销方案、出价/预算建议、全域策略、机会点分析 | `advendor-plan-advisor-sg-brand.analyze`、`advendor-planning-strategy-sg-brand.analyze` |\n\n| 层级 | 用途 | 写入约束 |\n|---|---|---|\n| L1 `working_context` | 冷启动、ROI 异常、活动等实时信号（TTL 24h 自动过期） | 必须有工具/系统来源；自动补全 `observed_at` 与 TTL |\n| L2 `strategy_exp` | 成功策略、失败教训、品类规律（情节记忆） | 需要来源与适用条件，复杂案例由 Judge 裁决 |\n| L3 `core_memory` | 合规/预算规则、系统规范、广告主画像、品类公理（稳定语义认知） | 仅接受权威来源；广告主画像额外允许用户声明；冲突转人工审核 |\n| L4 `skill_template` | 可复用策略模板 | 仅由成熟、验证通过的 L2 受控晋升 |\n\n## 快速开始：本地 Python CLI\n\n### 1. 安装依赖\n\n要求 Python 3.10+：\n\n```bash\npython3 -m pip install -r requirements.txt\n```\n\n### 2. 配置 LLM Provider（必需，否则无法启动）\n\n系统的语义检索、忠实性审核、价值打分和冲突检测均依赖真实 LLM/Embedding 服务，**必须**先配置：\n\n```bash\nexport MEMORY_LLM_API_KEY='your-secret'\nexport MEMORY_LLM_BASE_URL='https://aigc.sankuai.com/v1/openai/native'   # 可选，默认即此值\nexport MEMORY_JUDGE_MODEL='gpt-4o-mini'                                    # 可选\nexport MEMORY_EMBEDDING_MODEL='text-embedding-3-small'                    # 可选\n```\n\n未设置 `MEMORY_LLM_API_KEY` 时，`memory_skill.py` 的任何子命令都会直接抛出 `RuntimeError` 并退出，不会静默降级。\n\n### 2.5 配置行为参数（可选）\n\n阈值、权重、容量等数值参数均集中在项目根目录的 **`config.yaml`** 中，无需修改代码即可调整。启动时自动加载，缺失的配置项使用 `memory/config.py` 中的 Python 默认值。\n\n```yaml\n# config.yaml 示例——只写需要修改的部分即可\nvalidator:\n  threshold_admit: 0.6      # 记忆写入准入线\n  decay_half_life_strategy_exp: 90.0  # L2 策略经验时效衰减半衰期（天）\n\ntrigger:\n  conflict_sim_threshold: 0.85   # 第三级冲突检测相似度阈值\n  working_context_ttl_hours: 24.0  # L1 工作上下文默认 TTL\n\nguard:\n  promoter_min_validations: 3   # L2→L4 晋升最低验证次数\n\nstorage:\n  capacity_common: 300    # 通用业务线记忆容量上限\n  semantic_weight: 0.70   # 混合检索语义权重\n```\n\n也可通过环境变量指定自定义配置文件路径：\n\n```bash\nexport MEMORY_CONFIG_PATH='/etc/memory/prod.yaml'\n```\n\n完整参数列表与各字段说明见 `config.yaml` 内注释及 `memory/config.py`。\n\n### 3. 查看状态\n\n```bash\npython3 catclaw_skill/memory_skill.py status\n```\n\n首次运行会在 `data/lingix_memory.db` 创建 SQLite 数据库，并默认写入种子数据。\n\n### 4. 检索记忆\n\n```bash\npython3 catclaw_skill/memory_skill.py search \"医药OTC冷启动出价策略\" \\\n  --advertiser brand_A \\\n  --business-line medical \\\n  --top-k 4\n```\n\n### 5. 写入记忆\n\n优先使用 `ingest`：只需一段自然语言描述，事件分类（4 类操作场景之一）和结构化\n字段抽取均由系统内部的 `LLMEventClassifier` 完成：\n\n```bash\npython3 catclaw_skill/memory_skill.py ingest \\\n  \"本次医药OTC冷启动计划用三阶段出价策略，目标ROI 3.0，实际做到3.4\" \\\n  --advertiser brand_A\n```\n\n已经拿到结构化数据时（如任务系统直接返回 `plan_id`/`roi` 等字段），可以用\n`trigger` 显式指定事件类型，跳过分类步骤：\n\n```bash\npython3 catclaw_skill/memory_skill.py trigger plan_operation \\\n  --advertiser brand_A \\\n  --summary \"医药OTC冷启动计划完成三周投放\" \\\n  --data '{\n    \"plan_id\":\"plan_001\",\n    \"category\":\"医药OTC\",\n    \"business_line\":\"medical\",\n    \"strategy_used\":\"三阶段冷启动\",\n    \"target_metric\":{\"roi\":3.0},\n    \"actual_metric\":{\"roi\":3.4,\"cpc\":2.8},\n    \"duration_days\":21\n  }'\n```\n\n更多日常操作、事件字段和排障说明参见 [用户手册](USER_MANUAL.md)。\n\n## 作为 OpenClaw Skill 部署（无需修改 AGENTS.md）\n\n如果不需要 npm 插件那一层 TypeScript/Node 适配（例如沙箱容器里直接部署源码），可以把 `catclaw_skill/` 目录作为一个标准 Skill 接入：\n\n```bash\n# 1. 把整个项目部署到持久化目录，例如：\ncp -r memory_sample ~/.openclaw/memory_sample\n\n# 2. 把 catclaw_skill/ 链接（或复制）进 Skill 扫描目录\nln -s ~/.openclaw/memory_sample/catclaw_skill ~/.openclaw/skills/lingix-agent-memory\n\n# 3. 配置必需的环境变量（容器环境变量面板，或 shell profile）\nexport MEMORY_LLM_API_KEY='...'\nexport MEMORY_SKILL_ROOT=~/.openclaw/memory_sample\n```\n\nOpenClaw 会通过 `skills.load.extraDirs`（默认包含 `~/.openclaw/skills`）自动扫描到 `catclaw_skill/SKILL.md`，把其中的 `description` 注入系统提示词，Agent 据此判断何时调用 `memory_search`/`memory_trigger` 等命令——**全程不需要编辑全局 `AGENTS.md`**，Skill 目录本身就是能力声明的来源。完整工具说明和环境变量清单见 [`catclaw_skill/SKILL.md`](catclaw_skill/SKILL.md) 与 [`catclaw_skill/REFERENCE.md`](catclaw_skill/REFERENCE.md)。\n\n## OpenClaw 插件安装\n\n### 前置条件\n\n- Node.js 20+；\n- OpenClaw `2026.5.17+`；\n- Python 3.10+；\n- Python 依赖已安装。\n\n发布包中包含 Python 源码和 `requirements.txt`，但不会自动执行 `pip install`。安装后请在插件目录或受控虚拟环境中安装 Python 依赖。\n\n### 本地开发安装\n\n```bash\nnpm install\nnpm run plugin:build\nopenclaw plugins install . --dangerously-force-unsafe-install\nopenclaw plugins enable lingix-agent-memory\n```\n\n插件通过 Node `child_process` 调用其包内的 Python CLI，因此 OpenClaw 会识别为“执行外部进程”。`--dangerously-force-unsafe-install` 是对此行为的显式信任确认；请只安装可信来源的发布包。\n\n### 从 npm 安装\n\n发布后使用：\n\n```bash\nopenclaw plugins install @bzpovo/agent-memory --dangerously-force-unsafe-install\nopenclaw plugins enable lingix-agent-memory\n```\n\n使用 `openclaw plugins inspect lingix-agent-memory --json` 查看安装信息；使用 `openclaw plugins doctor` 检查加载问题。\n\n### OpenClaw 配置\n\n插件配置使用键 `lingix-agent-memory`。下例展示运行时核心配置；具体配置文件位置由 OpenClaw 部署方式决定：\n\n```json\n{\n  \"plugins\": {\n    \"entries\": {\n      \"lingix-agent-memory\": {\n        \"enabled\": true,\n        \"config\": {\n          \"pythonCommand\": \"python3\",\n          \"dataDir\": \"/absolute/path/to/lingix-memory-data\",\n          \"autoSeed\": true,\n          \"recallTopK\": 4,\n          \"judge\": {\n            \"enabled\": true,\n            \"baseUrl\": \"https://aigc.sankuai.com/v1/openai/native\",\n            \"model\": \"gpt-4o-mini\"\n          },\n          \"embedding\": {\n            \"enabled\": true,\n            \"model\": \"text-embedding-3-small\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n未设置 `dataDir` 时，适配层默认使用 `~/.openclaw/lingix-agent-memory/lingix_memory.db`。生产环境建议指定绝对持久化路径，并纳入备份策略。\n\n`judge`/`embedding` 字段用于覆盖网关地址和模型名（`enabled: true` 时生效，会被映射为 `MEMORY_LLM_BASE_URL`/`MEMORY_JUDGE_MODEL`/`MEMORY_EMBEDDING_MODEL` 环境变量传给 Python 子进程）；两者省略或 `enabled: false` 时使用 Python 侧默认值，**不代表禁用 LLM**。\n\n> ⚠️ **启用插件前必须先配置 `MEMORY_LLM_API_KEY` 环境变量**（见下文\"LLM Judge 与 Embedding\"）。出于安全考虑，API Key **不支持**通过 `config` 字段配置，只能来自宿主环境变量；未设置时，`src/index.ts` 会在调用 Python 子进程前直接抛出错误，所有 `lingix_memory_*` 工具调用都会失败。\n\nOpenClaw 可调用以下工具：\n\n- `lingix_memory_search`\n- `lingix_memory_ingest`：自由文本自动分类 + 写入，无需预先判断触发类型（推荐 Agent 优先使用；分类器内部映射到 4 类操作场景）\n- `lingix_memory_trigger`：需显式指定 `event_type`（4 类之一）+ 结构化 `data`，适合调用方已掌握操作场景和结构化字段的场景\n- `lingix_memory_status`\n- `lingix_memory_reflect`\n- `lingix_memory_review`\n\n> 当前 OpenClaw 适配器提供显式工具调用。自动 Prompt 注入不由工具插件入口启用，建议由 Agent 提示词规定“回答前先调用 `lingix_memory_search`”。\n\n## LLM Judge 与 Embedding\n\n`MEMORY_LLM_API_KEY` 是启动 Python 核心的**必需**环境变量（见前文\"快速开始\"第 2 步）；OpenClaw 插件场景下同样需要在启动 OpenClaw 主进程前 `export` 好该变量，插件通过 `child_process.spawn` 继承父进程环境变量透传给 Python 子进程，无需在 `openclaw.plugin.json` 的 `config` 字段中重复填写密钥。\n\n网关地址（`MEMORY_LLM_BASE_URL`）和模型名（`MEMORY_JUDGE_MODEL`/`MEMORY_EMBEDDING_MODEL`）可以二选一配置：\n\n- **本地 Python CLI**：直接 `export` 对应环境变量；\n- **OpenClaw 插件**：在 `config.judge` / `config.embedding` 中设置 `enabled: true` 并填写 `baseUrl`/`model`，`src/index.ts` 会将其映射为同名环境变量再传给 Python 子进程；若同时设置了环境变量和插件 config，插件 config 会覆盖继承自宿主进程的环境变量。\n\n不要将 API Key 提交到 Git、写入 README、`openclaw.plugin.json` 或 SQLite 数据库。Embedding 模型名必须替换为所接入网关真实支持的模型。\n\n### 记忆提取阶段接入本地 DoubtMem 模型（可选）\n\n主 Agent 的其余任务（对话、Embedding 检索、一级价值打分、冲突检测）默认始终走 `MEMORY_LLM_*` 配置的网关模型；如果本地已部署训练好的 [DoubtMem](../DoubtMem) 忠实性判定模型（局部 GRPO / Axis-GRPO 方案，动作空间 `WRITE/UPDATE/REJECT` + 强制 `<doubt-check>` 推理链），可以让**记忆提取阶段的忠实性判定单独切换到该本地模型**，其余能力不受影响：\n\n```bash\n# 1. 部署 DoubtMem 模型（ms-swift/vLLM OpenAI 兼容 server，详见 ../DoubtMem/docs/USAGE.md 第 6 节）\npython3 /path/to/ms-swift/swift/cli/deploy.py \\\n  --model DoubtMem/checkpoints/doubtmem/axis_grpo_qwen3_4b_v1_8gpu/global_step_150/actor/huggingface \\\n  --model_type qwen3 --served_model_name DoubtMem-AxisGRPO-Qwen3-4B-step150 \\\n  --infer_backend vllm --host 0.0.0.0 --port 8005 --gpu_memory_utilization 0.85\n\n# 2. 配置本地模型地址（其余 MEMORY_LLM_* 保持不变，继续服务主 Agent）\nexport MEMORY_DOUBTMEM_BASE_URL='http://localhost:8005/v1'\nexport MEMORY_DOUBTMEM_MODEL='DoubtMem-AxisGRPO-Qwen3-4B-step150'   # 可选，默认即此值\n```\n\n配置 `MEMORY_DOUBTMEM_BASE_URL` 后，`DoubtMemGuard` 内部使用的 Judge 会自动切换为 `memory.ai_provider.DoubtMemLocalJudge`（见该类 docstring），把候选记忆 + 触发事件拼装为 DoubtMem 训练时的对话/已有记忆格式，调用本地服务并解析 `<doubt-check>` + JSON 动作，再按规则映射为 `WRITE/UPDATE/REJECT` 及 `source_attribution`/`grounding`/`consistency` 等字段；未配置该变量时行为与之前完全一致（使用 `MEMORY_JUDGE_MODEL` 网关模型）。L3/L4 的硬性层级限制、以及规则先行拦截（试探性偏好、Agent 推断禁止直接写入 L2/L3）不受 Judge 来源影响，仍由 `DoubtMemGuard` 的确定性代码把关。\n\n> 事实检测工具（`campaign_analysis`/`industry_benchmark`/`memory_search`）目前只接入了走美团网关的 `LLMJudge`，`DoubtMemLocalJudge` 的忠实性判定完全由本地专训模型的 `<doubt-check>` 推理链完成，暂不叠加工具核验。\n\n### factuality_check 事实检测工具（可选）\n\n`LLMJudge` 在 `factuality_check` 阶段可以调用客观工具核验候选记忆中的数值/效果结论，而不是完全依赖模型自身判断，用法：\n\n```python\nfrom memory.ai_provider import LLMJudge, DefaultFactualityToolVerifier\n\njudge = LLMJudge(provider, tool_verifier=DefaultFactualityToolVerifier(storage))\n```\n\n触发条件（命中任一即触发）：候选记忆包含具体数值、包含效果类表述（提升/下降/ROI 等）、包含时效性表述（当前/最新/近期等），或已检索到同范围的相关记忆。触发后依次尝试：\n\n1. `campaign_analysis`：核对候选记忆引用的数值是否能在事件原始数据（`event.raw_data`/`candidate.supporting_data`）中找到依据，并根据复现次数判断是「多次复现」还是「仅单次」；\n2. `memory_search`：复用已检索到的相关记忆，核查候选是否与其完全重复/矛盾；\n3. `industry_benchmark`：核对是否有行业大盘数据支撑（本仓库未内置行业大盘数据源，默认恒为“无相关数据”）。\n\n核验结果按以下规则调整 `grounding`（与 LLM 自身判断的规则叠加，工具结论优先）：\n\n| 工具核验结果 | grounding 调整 |\n|---|---|\n| 数值吻合且多次复现 | 升级为 `grounded` |\n| 数值吻合但仅单次 | 维持/降为 `weakly_grounded` |\n| 数值不符 | 降级为 `unsupported` |\n| 无相关数据 | 维持 LLM 原判断 |\n\n`DefaultFactualityToolVerifier` 只依赖系统内已有数据（不依赖外部投放数据服务/行业大盘服务）；生产环境如需接入真实的投放数据/行业大盘查询服务，应实现同名方法（`campaign_analysis`/`industry_benchmark`/`memory_search`，参数与返回结构一致）替换默认实现。不注入 `tool_verifier` 时，`LLMJudge` 行为与引入本机制之前完全一致。\n\n历史数据回填：\n\n```bash\npython3 catclaw_skill/memory_skill.py embed-backfill --batch-size 50\n```\n\n## 示例与测试\n\n想快速理解\"一段对话如何一步步变成一条记忆\"，运行最简场景演示（推荐首次接触本项目时看这个）：\n\n```bash\npython3 -m demo.minimal_demo\n```\n\n该演示只用一段真实的用户纠错对话，手动串联打印第 0～4 级的每一步中间产物（自动分类抽取 → 候选记忆 → 价值判断 → 忠实性门控 → 冲突检测 → 质量评估 → 写入 → 检索验证），忠实性门控默认优先使用本地 `DoubtMemLocalJudge`（配置 `MEMORY_DOUBTMEM_BASE_URL` 后生效），未配置时自动回退网关 `LLMJudge`，脚本顶部注释包含完整的运行前配置说明。\n\n运行当前能力全链路演示（覆盖更多分支场景）：\n\n```bash\npython3 -m demo.current_features_demo\n```\n\n演示会使用独立数据库 `data/current_features_demo.db`，覆盖 Guard 拒绝、L3 TTL、混合检索、Judge 审核、UPDATE、L2→L4 晋升、Trace 复核和向量回填。\n\n运行测试：\n\n```bash\npython3 -m unittest discover -s tests -v\nnpm run plugin:validate\n```\n\n## 开发与发布\n\n```bash\nnpm install\nnpm run plugin:build\nnpm run plugin:validate\nnpm run pack:check\n```\n\n发布前请确认：\n\n1. `package.json` 的版本号符合发布策略；\n2. `openclaw.plugin.json` 已由 `npm run plugin:build` 更新；\n3. Python 与插件校验均通过；\n4. 未提交 `.env`、SQLite 数据库或密钥；\n5. npm scope `@bzpovo` 已具备发布权限（`publishConfig.access` 已设为 `public`）。\n\n发布：\n\n```bash\nnpm publish --access public\n```\n\n## 目录说明\n\n```text\nmemory/                 Python 记忆核心：模型、Guard、存储、反思、校验\ncatclaw_skill/          Python CLI 入口 + 标准 Skill 定义（SKILL.md，可被 Agent 自动发现，无需修改全局 AGENTS.md）\ndemo/                   可重复运行的功能演示\nsrc/index.ts            OpenClaw Tool Plugin 适配器\ndist/                   编译后的 OpenClaw 插件入口\nbin/                    npm CLI 包装器\nopenclaw.plugin.json    OpenClaw 插件清单\nUSER_MANUAL.md          用户操作手册\n```\n\n## 安全与数据治理\n\n- LLM Judge 不是安全边界；规则先行拦截（未经用户确认的 Assistant 建议、Agent 推断直写 L2/L3）、L3/L4 分层约束、数据格式和审计规则均由确定性代码执行，不受 Judge 结论影响。\n- L1 工作上下文数据默认会在 24 小时后过期；业务上需要不同生命周期时应通过事件/数据模型扩展。\n- 所有高风险写入、拒绝和审核决策会记录 Trace；建议定期执行复核并关注 Guard 指标。\n- SQLite 数据库包含广告策略、偏好和审计数据，生产环境应设置访问控制、备份与保留策略。\n","readmeFilename":"README.md"}