@yottameta/yotta-memory 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/SKILL.md +7 -6
- package/USER_GUIDE.md +4 -4
- package/bin/yotta-memory.js +48 -9
- package/package.json +1 -1
- package/references/protocol.md +9 -5
package/README.md
CHANGED
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
### 画像与开工上下文(v0.6.0)
|
|
90
90
|
|
|
91
91
|
- **profile**:聚合 `private/<owner>/` 下 PREF / BOUND / COMMIT 原文,按 type + subject + tags 归组,写 `profile.md`;引擎零推断,画像结论由 AI 依据「记忆守则」内部形成,不当面贴标签。
|
|
92
|
-
- **context
|
|
93
|
-
- **记忆守则**:SKILL.md 内置规则层(类型红线 / 主动捕获触发信号 / 了解用户三阶段四手法 /
|
|
92
|
+
- **context**:一键生成开工上下文包——多智能体接入铁律 + 身份 + 用户画像摘要 + 近期记忆(按 importance 排序)+ 边界提醒 + 承诺 / 锚点;支持 `--budget` 字符预算(token 恒定,不随记忆膨胀)。
|
|
93
|
+
- **记忆守则**:SKILL.md 内置规则层(类型红线 / 主动捕获触发信号 / 了解用户三阶段四手法 / 心理学底座与对齐 / 底线与边界 / 宿主隔离 / 反模式),让 AI「越用越懂」有章法。
|
|
94
94
|
|
|
95
95
|
### 检索:索引 + 中文分词打分
|
|
96
96
|
|
|
@@ -183,10 +183,10 @@ npm i -g @yottameta/yotta-memory
|
|
|
183
183
|
| 命令 | 作用 |
|
|
184
184
|
|---|---|
|
|
185
185
|
| `yotta-memory init [--project] [--dir <目录>]` | 初始化记忆库(默认用户级 `~/.yottamemory/`;--dir 显式指定位置)|
|
|
186
|
-
| `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint]` | 写入记忆(同 subject+statement 自动更新;--owner 标注归属;--verify
|
|
186
|
+
| `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入记忆(同 subject+statement 自动更新;--owner 标注归属;--source 记录来源;--weight 重要性权重、去重取 max;--verify 写后回读;--no-hint 关闭类型提示)|
|
|
187
187
|
| `yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 检索记忆(索引+TF 打分,读取分区过滤;越界读其它智能体私密默认拒绝,需 grant / identity=user / `--unsafe`;`--agent <其它>` 仅作身份声明、不授予跨读;项目级优先)|
|
|
188
188
|
| `yotta-memory profile [--owner <id>]` | 生成用户画像(聚合 `private/<owner>/` 原文,零推断,写 `profile.md`;跨 owner 默认拒绝)|
|
|
189
|
-
| `yotta-memory context [--limit N] [--owner <id>]` | 生成开工上下文包(身份 + 画像 + 近期记忆 + 边界 +
|
|
189
|
+
| `yotta-memory context [--limit N] [--owner <id>] [--budget N]` | 生成开工上下文包(身份 + 多智能体铁律 + 画像 + 近期记忆 + 边界 + 承诺;--budget 近期记忆字符预算,token 恒定)|
|
|
190
190
|
| `yotta-memory forget <文件>` | 删除一条记忆(按类型目录路径或文件名)|
|
|
191
191
|
| `yotta-memory archive [--days 180] [--threshold 0.4]` | 归档旧记忆(盖棺分+年龄,immutable 除外)|
|
|
192
192
|
| `yotta-memory reindex` | 重建索引(手动改 .md 后校正)|
|
package/SKILL.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yotta-memory
|
|
3
3
|
description: "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚:让任何 AI 智能体活过会话,开工 recall 恢复上下文、重要信息 remember 落盘、收工归档。类型体系 FACT(公共共享)/ PREF / BOUND / COMMIT(私密隔离)。触发:记住、别忘了、记一笔、记忆、remember、recall、跨会话、上次说到、续测、交接、归档、记忆盘、共享记忆、局域网记忆、画像、开工上下文、记忆守则、profile、context、越用越懂"
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
license: MIT
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# yotta-memory(元忆)— 有权限边界的文件式智能体记忆
|
|
9
9
|
|
|
10
10
|
> 一句话:元忆 —— 有权限边界的文件式智能体记忆(不注入、可 diff、能回滚;FACT 共享、PREF / BOUND / COMMIT 私密隔离)。
|
|
11
|
-
> 版本:0.6.
|
|
11
|
+
> 版本:0.6.1 | 最后更新:2026-08-25
|
|
12
12
|
|
|
13
13
|
## 这是什么
|
|
14
14
|
|
|
@@ -73,6 +73,7 @@ license: MIT
|
|
|
73
73
|
- 共情至少到第 3 阶段:识别 → 理解 → 回应 → 验证。
|
|
74
74
|
- 诚实声明:AI 是模式匹配非真感受,不伪装、不编造伪情感记忆。
|
|
75
75
|
- 危机识别:不评判、持续在场、温和引导现实支持;不擅自越界联系第三方。
|
|
76
|
+
- 对齐:回应时让积累的理解自然影响语气与措辞(让用户感到「被记得、被懂」),而非机械引用记忆条目。
|
|
76
77
|
- 情感外包双刃剑:做增益真实生活的陪伴,不替代真实关系。
|
|
77
78
|
|
|
78
79
|
### 5. 写入时序(一次会话的节奏)
|
|
@@ -131,7 +132,7 @@ license: MIT
|
|
|
131
132
|
|
|
132
133
|
**D. 开工主注入(context)**:
|
|
133
134
|
|
|
134
|
-
- 身份就绪后运行 `yotta-memory context [--limit 10]`(远端经 MCP 用 `recall` 补细节):一键拿到「身份 + 用户画像摘要 + 近期记忆 + 边界提醒 + 承诺 /
|
|
135
|
+
- 身份就绪后运行 `yotta-memory context [--limit 10] [--budget 1800]`(远端经 MCP 用 `recall` 补细节):一键拿到「身份 + 多智能体铁律 + 用户画像摘要 + 近期记忆 + 边界提醒 + 承诺 / 锚点」;`--budget` 控制近期记忆字符预算(token 恒定,不随记忆膨胀)。
|
|
135
136
|
- 无画像时 context 自动生成一次或降级输出其余段,不报错。
|
|
136
137
|
- 需要深挖旧事再 `recall <关键词>`。
|
|
137
138
|
- 私密记忆(PREF / BOUND / COMMIT)**必须有 owner**:未声明身份写私密会被引擎拒绝(公共 FACT 不受影响)。
|
|
@@ -144,10 +145,10 @@ license: MIT
|
|
|
144
145
|
| 命令 | 作用 |
|
|
145
146
|
|---|---|
|
|
146
147
|
| `yotta-memory init [--project] [--dir <目录>]` | 初始化记忆库(默认用户级;--dir 显式指定位置)|
|
|
147
|
-
| `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint]` | 写入(同 subject+statement 自动更新;--owner 标注归属;--verify 写后回读校验;--no-hint 关闭类型启发式提示)|
|
|
148
|
+
| `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入(同 subject+statement 自动更新;--owner 标注归属;--source 记录来源;--weight 重要性权重默认 1.0、去重取 max;--verify 写后回读校验;--no-hint 关闭类型启发式提示)|
|
|
148
149
|
| `yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 检索(索引+TF 打分,读取分区过滤;越界读其它智能体私密默认拒绝,需 grant / identity=user / `--unsafe`;`--agent <其它>` 只作身份声明/展示,不授予跨读——读他人私密同样要授权;项目级优先)|
|
|
149
150
|
| `yotta-memory profile [--owner <id>]` | 生成用户画像(聚合 `private/<owner>/` 原文,零推断,写 `profile.md`;跨 owner 默认拒绝)|
|
|
150
|
-
| `yotta-memory context [--limit N] [--owner <id>]` | 生成开工上下文包(身份 + 画像 + 近期记忆 + 边界 +
|
|
151
|
+
| `yotta-memory context [--limit N] [--owner <id>] [--budget N]` | 生成开工上下文包(身份 + 多智能体铁律 + 画像 + 近期记忆 + 边界 + 承诺;--budget 近期记忆字符预算,0=不限)|
|
|
151
152
|
| `yotta-memory forget <文件>` | 删除(按类型目录路径或文件名)|
|
|
152
153
|
| `yotta-memory archive [--days 180] [--threshold 0.4]` | 归档旧记忆(盖棺分+年龄,immutable 除外)|
|
|
153
154
|
| `yotta-memory reindex` | 重建索引(手动改 .md 后校正)|
|
|
@@ -173,7 +174,7 @@ license: MIT
|
|
|
173
174
|
└── agents.json # 智能体身份登记表(唯一性)
|
|
174
175
|
```
|
|
175
176
|
|
|
176
|
-
记忆文件 `<YYYY-MM-DD>-<NNNN>.md`,frontmatter 含 `type / subject / statement / confidence / created / updated / tags / immutable / scope / owner / access_count / last_accessed
|
|
177
|
+
记忆文件 `<YYYY-MM-DD>-<NNNN>.md`,frontmatter 含 `type / subject / statement / confidence / created / updated / tags / immutable / scope / owner / source / weight / access_count / last_accessed`(`source` 记录来源、`weight` 重要性权重默认 1.0);正文为记忆内容。旧版根下平铺的 `prefs/` `bounds/` `commits/` 会在 `reindex`(或首次 recall 建索引)时按 frontmatter `owner` 自动迁移到 `private/<owner>/<type>/`。
|
|
177
178
|
|
|
178
179
|
自我档案(本智能体身份,强制落盘):PREF,`subject=自我接入档案`,`owner=<本智能体ID>`,statement 为 `; ` 分隔的 key:value——`agent_id / host / memory_home / mcp_mode(stdio|http)/ engine_url(仅远端)/ token(仅远端;本机不存 token)`,可含 `agent_name / user_name / relationship`(`iam --name/--user/--relationship` 写入)。
|
|
179
180
|
|
package/USER_GUIDE.md
CHANGED
|
@@ -72,12 +72,12 @@ yotta-memory config get # 查看记忆库位置
|
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
74
|
yotta-memory profile # 生成用户画像(写 private/<owner>/profile.md)
|
|
75
|
-
yotta-memory context --limit 10
|
|
75
|
+
yotta-memory context --limit 10 --budget 1800 # 生成开工上下文包(身份+铁律+画像+近期记忆+边界+承诺,预算控 token)
|
|
76
76
|
yotta-memory iam <id> --name 元忆 --user 老张 --relationship 伙伴 # 自我档案扩展显示名/用户/关系
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
- `profile` 引擎零推断:只按类型 / 主题 / 标签归组呈现原文,画像结论由 AI 内部形成,不当面贴标签。
|
|
80
|
-
- `context` 是每次会话开工的主注入,替代裸 `recall
|
|
80
|
+
- `context` 是每次会话开工的主注入,替代裸 `recall`;无画像时自动生成一次或降级,不报错;`--budget` 控制近期记忆字符预算(token 恒定)。
|
|
81
81
|
- `remember --verify` 写后回读校验;`remember --no-hint` 关闭「疑似偏好,建议 PREF」的提示。
|
|
82
82
|
|
|
83
83
|
### 记忆库位置:本机智能体如何找到记忆
|
|
@@ -244,10 +244,10 @@ yotta-memory remember FACT 主题 内容 # 智能体落盘
|
|
|
244
244
|
| 命令 | 作用 |
|
|
245
245
|
|---|---|
|
|
246
246
|
| `yotta-memory init [--project] [--dir <目录>]` | 初始化记忆库 |
|
|
247
|
-
| `yotta-memory remember <类型> <主题> <内容> [--owner <id>] [--verify] [--no-hint]` | 写入记忆(--verify 写后回读;--no-hint 关闭类型提示)|
|
|
247
|
+
| `yotta-memory remember <类型> <主题> <内容> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入记忆(--source 来源;--weight 重要性权重;--verify 写后回读;--no-hint 关闭类型提示)|
|
|
248
248
|
| `yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 检索记忆(读取分区过滤;`--agent <其它>` 仅作身份声明、不授予跨读;越界读其它智能体私密默认拒绝,需 grant / identity=user / `--unsafe`)|
|
|
249
249
|
| `yotta-memory profile [--owner <id>]` | 生成用户画像(零推断,写 `profile.md`)|
|
|
250
|
-
| `yotta-memory context [--limit N] [--owner <id>]` |
|
|
250
|
+
| `yotta-memory context [--limit N] [--owner <id>] [--budget N]` | 开工上下文包(身份+铁律+画像+近期记忆+边界+承诺;--budget 近期记忆字符预算)|
|
|
251
251
|
| `yotta-memory forget <文件>` | 删除一条记忆 |
|
|
252
252
|
| `yotta-memory archive [--days 180] [--threshold 0.4]` | 归档旧记忆 |
|
|
253
253
|
| `yotta-memory reindex` | 重建索引 |
|
package/bin/yotta-memory.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// v0.5.3 新增:CLI 选项可前置(--agent 等允许放在子命令前,不再误报"未知命令")/ lan enable 成功补"服务不会立刻启动"提示(v0.5.2 lan 引号修复无回归)
|
|
7
7
|
// v0.5.4 新增:lan enable 在非管理员(schtasks Access denied)时自动降级为用户级 Startup 静默自启(VBS sh.Run 窗口0 + autostart.cmd,node 路径 process.execPath 自动探测);lan disable/status 同时管理计划任务与 Startup 双机制
|
|
8
8
|
// v0.6.0 新增:灵魂盘核心——profile(用户画像聚合,零推断)/ context(开工上下文包)/ iam 扩展(--name/--user/--relationship)/ remember --verify(写后回读)与 --no-hint(关闭类型启发式提示)+ SKILL「记忆守则」
|
|
9
|
+
// v0.6.1 新增:灵魂盘机制精髓补齐——context --budget(token 预算,近记忆按剩余预算放行)/ context 内嵌「多智能体接入铁律」段 / remember --source/--weight(来源 + 重要性权重,去重 weight 取 max)/ 近期记忆排序融合 importance(confidence×recency+updated+weight+immutable)
|
|
9
10
|
'use strict';
|
|
10
11
|
|
|
11
12
|
const fs = require('fs');
|
|
@@ -15,7 +16,7 @@ const crypto = require('crypto');
|
|
|
15
16
|
const http = require('http');
|
|
16
17
|
const child_process = require('child_process');
|
|
17
18
|
|
|
18
|
-
const VERSION = '0.6.
|
|
19
|
+
const VERSION = '0.6.1';
|
|
19
20
|
const TYPES = ['FACT', 'PREF', 'BOUND', 'COMMIT'];
|
|
20
21
|
const TYPE_DIRS = { FACT: 'facts', PREF: 'prefs', BOUND: 'bounds', COMMIT: 'commits' };
|
|
21
22
|
const PUBLIC_DIR = 'facts';
|
|
@@ -24,7 +25,7 @@ const PRIVATE_LEAF = ['prefs', 'bounds', 'commits'];
|
|
|
24
25
|
const ARCHIVE_DIR = '.archive';
|
|
25
26
|
const INDEX_FILE = 'index.json';
|
|
26
27
|
const PRIVATE_TYPES = ['PREF', 'BOUND', 'COMMIT'];
|
|
27
|
-
const FIELD_ORDER = ['type', 'subject', 'statement', 'confidence', 'created', 'updated', 'tags', 'immutable', 'scope', 'owner', 'access_count', 'last_accessed'];
|
|
28
|
+
const FIELD_ORDER = ['type', 'subject', 'statement', 'confidence', 'created', 'updated', 'tags', 'immutable', 'scope', 'owner', 'source', 'weight', 'access_count', 'last_accessed'];
|
|
28
29
|
const CONFIG_FILE = 'config.json';
|
|
29
30
|
const SERVER_SUBDIR = '.server';
|
|
30
31
|
const TOKENS_FILE = 'tokens.json';
|
|
@@ -274,6 +275,8 @@ function readEntry(fp, root) {
|
|
|
274
275
|
access_count: parseInt(meta.access_count || '0', 10) || 0,
|
|
275
276
|
last_accessed: meta.last_accessed || '',
|
|
276
277
|
immutable: meta.immutable === 'true',
|
|
278
|
+
source: meta.source || '',
|
|
279
|
+
weight: (parseFloat(meta.weight) > 0 ? parseFloat(meta.weight) : 1.0),
|
|
277
280
|
tokens: buildTokens(subject, statement, tags),
|
|
278
281
|
meta: meta,
|
|
279
282
|
};
|
|
@@ -322,6 +325,21 @@ function vitality(meta) {
|
|
|
322
325
|
if (last) { const d = daysBetween(last, today()); recency = Math.max(0, 1 - Math.floor(d / 30) * 0.2); }
|
|
323
326
|
return 0.4 * conf + 0.3 * accScore + 0.3 * recency;
|
|
324
327
|
}
|
|
328
|
+
// 灵魂盘 importance 融合:confidence × (0.5 + recency) + updated 加分 + weight 乘子 + immutable 加分
|
|
329
|
+
function importanceScore(meta) {
|
|
330
|
+
const conf = parseFloat(meta.confidence || 1.0);
|
|
331
|
+
let ageDays = 999;
|
|
332
|
+
if (meta.created) {
|
|
333
|
+
const d = daysBetween(meta.created, today());
|
|
334
|
+
if (!isNaN(d)) ageDays = d;
|
|
335
|
+
}
|
|
336
|
+
const recency = 1.0 / (1.0 + Math.max(ageDays, 0) / 180.0);
|
|
337
|
+
let score = conf * (0.5 + recency);
|
|
338
|
+
if (meta.updated && meta.created && meta.updated !== meta.created) score += 0.5;
|
|
339
|
+
const w = parseFloat(meta.weight || 1.0); if (w > 0) score *= w;
|
|
340
|
+
if (meta.immutable === 'true') score += 2.0;
|
|
341
|
+
return score;
|
|
342
|
+
}
|
|
325
343
|
function loadGrants(root) {
|
|
326
344
|
const fp = path.join(root, 'grants.json');
|
|
327
345
|
try { return JSON.parse(fs.readFileSync(fp, 'utf8')) || {}; } catch (e) { return {}; }
|
|
@@ -386,6 +404,8 @@ function rememberCore(type, subject, statement, opts) {
|
|
|
386
404
|
const patch = { updated: today() };
|
|
387
405
|
if (owner && !meta.owner) patch.owner = owner;
|
|
388
406
|
if (scope && !meta.scope) patch.scope = scope;
|
|
407
|
+
if (opts.source && !meta.source) patch.source = opts.source;
|
|
408
|
+
const w = parseFloat(opts.weight); if (w > 0) patch.weight = Math.max(parseFloat(meta.weight || '1.0') || 1.0, w);
|
|
389
409
|
rewriteFrontmatter(fp, patch);
|
|
390
410
|
upsertIndexEntry(root, readEntry(fp, root));
|
|
391
411
|
let text = '已更新: ' + fp;
|
|
@@ -409,7 +429,10 @@ function rememberCore(type, subject, statement, opts) {
|
|
|
409
429
|
type: t, subject: subj, statement: stmt,
|
|
410
430
|
confidence: 1.0, created: today(), updated: today(),
|
|
411
431
|
tags: [], immutable: false,
|
|
412
|
-
scope: scope, owner: owner,
|
|
432
|
+
scope: scope, owner: owner,
|
|
433
|
+
source: opts.source || '',
|
|
434
|
+
weight: (parseFloat(opts.weight) > 0 ? parseFloat(opts.weight) : 1.0),
|
|
435
|
+
access_count: 0, last_accessed: '',
|
|
413
436
|
};
|
|
414
437
|
fs.writeFileSync(file, frontmatterToText(rec, stmt), 'utf8');
|
|
415
438
|
upsertIndexEntry(root, readEntry(file, root));
|
|
@@ -636,6 +659,8 @@ function importCore(root, src) {
|
|
|
636
659
|
updated: meta.updated || today(),
|
|
637
660
|
tags: parseTags(meta.tags),
|
|
638
661
|
immutable: meta.immutable === true || meta.immutable === 'true',
|
|
662
|
+
source: meta.source || '',
|
|
663
|
+
weight: (parseFloat(meta.weight) > 0 ? parseFloat(meta.weight) : 1.0),
|
|
639
664
|
scope: meta.scope || defaultScope(t),
|
|
640
665
|
owner: meta.owner || '',
|
|
641
666
|
access_count: parseInt(meta.access_count || '0', 10) || 0,
|
|
@@ -927,7 +952,9 @@ function contextCore(opts) {
|
|
|
927
952
|
const selfAgent = opts.selfAgent !== undefined ? opts.selfAgent : currentAgent();
|
|
928
953
|
const owner = opts.owner || selfAgent;
|
|
929
954
|
const unsafe = !!opts.unsafe;
|
|
955
|
+
const budget = opts.budget ? parseInt(opts.budget, 10) : 0;
|
|
930
956
|
const lines = [];
|
|
957
|
+
function usedChars() { return lines.reduce(function (s, x) { return s + String(x).length + 1; }, 0); }
|
|
931
958
|
lines.push('# 开工上下文包(yotta-memory context)');
|
|
932
959
|
lines.push('');
|
|
933
960
|
lines.push('## 1. 身份');
|
|
@@ -944,6 +971,12 @@ function contextCore(opts) {
|
|
|
944
971
|
lines.push('- memory_home: ' + root);
|
|
945
972
|
}
|
|
946
973
|
lines.push('');
|
|
974
|
+
lines.push('## 1.5 多智能体接入铁律');
|
|
975
|
+
lines.push('');
|
|
976
|
+
lines.push('- 可读:A. 公共 FACT(facts/)B. 本智能体私密(private/<owner>/)C. 其它智能体私密 = 禁区(grant / identity=user / --unsafe 显式授权除外)。');
|
|
977
|
+
lines.push('- 可写:FACT→公共;PREF / BOUND / COMMIT→仅本智能体私密区;禁止写其它智能体私密区。');
|
|
978
|
+
lines.push('- 违规红线:禁止搜索 / 读取 / 总结其它智能体私密;禁止把用户私密关系 / 心理健康 / 生活隐私写入公共区。');
|
|
979
|
+
lines.push('');
|
|
947
980
|
lines.push('## 2. 用户画像摘要');
|
|
948
981
|
lines.push('');
|
|
949
982
|
if (owner) {
|
|
@@ -973,14 +1006,16 @@ function contextCore(opts) {
|
|
|
973
1006
|
for (const r of roots) {
|
|
974
1007
|
for (const e of ensureIndex(r)) {
|
|
975
1008
|
if (classifyRead(e, owner, '', unsafe, selfAgent) === 'denied') continue;
|
|
976
|
-
recent.push({ e: e,
|
|
1009
|
+
recent.push({ e: e, s: importanceScore(e) });
|
|
977
1010
|
}
|
|
978
1011
|
}
|
|
979
|
-
recent.sort(function (a, b) { return b.
|
|
1012
|
+
recent.sort(function (a, b) { return b.s - a.s; });
|
|
980
1013
|
const recentShown = recent.slice(0, limit);
|
|
981
1014
|
if (!recentShown.length) lines.push('(暂无记忆)');
|
|
982
1015
|
for (const h of recentShown) {
|
|
983
|
-
|
|
1016
|
+
const line = '- [' + h.e.type + '] ' + h.e.subject + ': ' + h.e.statement;
|
|
1017
|
+
if (budget > 0 && usedChars() + line.length > budget) break;
|
|
1018
|
+
lines.push(line);
|
|
984
1019
|
}
|
|
985
1020
|
lines.push('');
|
|
986
1021
|
lines.push('## 4. 边界提醒(BOUND)');
|
|
@@ -1388,9 +1423,9 @@ function usage() {
|
|
|
1388
1423
|
' yotta-memory init [--project] [--dir <目录>] 初始化记忆库(默认用户级;--dir 显式指定位置)',
|
|
1389
1424
|
' yotta-memory config set memory_home <目录> 持久记住记忆库位置',
|
|
1390
1425
|
' yotta-memory config get 查看当前配置与生效位置',
|
|
1391
|
-
' yotta-memory remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint] 写入记忆(--verify 写后回读校验;--no-hint 关闭类型启发式提示)',
|
|
1426
|
+
' yotta-memory remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint] 写入记忆(--source 记录来源;--weight 重要性权重默认 1.0 去重取 max;--verify 写后回读校验;--no-hint 关闭类型启发式提示)',
|
|
1392
1427
|
' yotta-memory profile [--owner <id>] 生成用户画像(聚合 private/<owner>/ 原文,零推断,写 profile.md)',
|
|
1393
|
-
' yotta-memory context [--limit N] [--owner <id>]
|
|
1428
|
+
' yotta-memory context [--limit N] [--owner <id>] [--budget N] 生成开工上下文包(身份+铁律+画像+近期记忆+边界+承诺;--budget 近期记忆字符预算,0=不限)',
|
|
1394
1429
|
' yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe] 检索(索引+TF,读取分区;--agent 仅表示“以该身份检索/模拟”,跨智能体私密读取需 --unsafe / 授权)',
|
|
1395
1430
|
' yotta-memory forget <文件或文件名> 删除一条记忆',
|
|
1396
1431
|
' yotta-memory archive [--days 180] [--threshold 0.4] 归档(盖棺分+年龄)',
|
|
@@ -1418,7 +1453,7 @@ function main() {
|
|
|
1418
1453
|
if (!args.length) { usage(); return; }
|
|
1419
1454
|
const opts = {};
|
|
1420
1455
|
const positional = [];
|
|
1421
|
-
const valueOpts = new Set(['--type', '--limit', '--days', '--out', '--owner', '--agent', '--threshold', '--scope', '--host', '--port', '--dir', '--name', '--user', '--relationship']);
|
|
1456
|
+
const valueOpts = new Set(['--type', '--limit', '--days', '--out', '--owner', '--agent', '--threshold', '--scope', '--host', '--port', '--dir', '--name', '--user', '--relationship', '--source', '--weight', '--budget']);
|
|
1422
1457
|
for (let i = 0; i < args.length; i++) {
|
|
1423
1458
|
const a = args[i];
|
|
1424
1459
|
if (a === '--version' || a === '-v') { console.log(VERSION); return; }
|
|
@@ -1448,6 +1483,9 @@ function main() {
|
|
|
1448
1483
|
else if (a === '--name') opts.name = v;
|
|
1449
1484
|
else if (a === '--user') opts.user = v;
|
|
1450
1485
|
else if (a === '--relationship') opts.relationship = v;
|
|
1486
|
+
else if (a === '--source') opts.source = v;
|
|
1487
|
+
else if (a === '--weight') opts.weight = parseFloat(v);
|
|
1488
|
+
else if (a === '--budget') opts.budget = parseInt(v, 10) || 0;
|
|
1451
1489
|
} else if (a.startsWith('--')) {
|
|
1452
1490
|
console.error('未知选项: ' + a);
|
|
1453
1491
|
process.exit(2);
|
|
@@ -1511,6 +1549,7 @@ module.exports = {
|
|
|
1511
1549
|
recallCore: recallCore,
|
|
1512
1550
|
profileCore: profileCore,
|
|
1513
1551
|
contextCore: contextCore,
|
|
1552
|
+
importanceScore: importanceScore,
|
|
1514
1553
|
forgetCore: forgetCore,
|
|
1515
1554
|
archiveCore: archiveCore,
|
|
1516
1555
|
mcpTools: mcpTools,
|
package/package.json
CHANGED
package/references/protocol.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# yotta-memory 协议规范 v0.6.
|
|
1
|
+
# yotta-memory 协议规范 v0.6.1
|
|
2
2
|
|
|
3
3
|
> 本文件定义 yotta-memory 记忆标准:存储位置、目录结构、文件格式、类型体系与 CLI 命令参考。
|
|
4
4
|
> 目标:任何支持 Agent Skills 开放标准的智能体,装完即可读写同一份记忆。
|
|
@@ -74,6 +74,8 @@ immutable: false
|
|
|
74
74
|
| `immutable` | 否 | `true` 时 archive 不移动(用户级硬事实)|
|
|
75
75
|
| `scope` | 否 | `public` / `private`,默认按类型(FACT=public,其余 private)|
|
|
76
76
|
| `owner` | 否 | 归属 agent id,默认空;private+owner 非空默认仅供该 owner agent 读取,其它 agent 越界读需 grant 授权、identity=user 或 `--unsafe` |
|
|
77
|
+
| `source` | 否 | 记录来源(如 `对话` / `推断`),`remember --source` 写入 |
|
|
78
|
+
| `weight` | 否 | 重要性权重(默认 1.0,>1 提权 / <1 降权),去重时取 max |
|
|
77
79
|
| `access_count` | 否 | 命中次数,recall 命中展示集时 +1 |
|
|
78
80
|
| `last_accessed` | 否 | 最近访问日期 `YYYY-MM-DD` |
|
|
79
81
|
|
|
@@ -112,7 +114,7 @@ immutable: false
|
|
|
112
114
|
| 命令 | 行为 |
|
|
113
115
|
|---|---|
|
|
114
116
|
| `init [--project]` | 创建目录结构;默认用户级,`--project` 建项目级 |
|
|
115
|
-
| `remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint]` | 写入;同 subject+statement
|
|
117
|
+
| `remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入;同 subject+statement 已存在则更新 `updated` 且 `weight` 取 max;`--source` 记录来源;`--weight` 重要性权重;`--verify` 写后回读校验;`--no-hint` 关闭类型启发式提示 |
|
|
116
118
|
| `recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 索引+TF 打分匹配;读取分区过滤;越界(读其它智能体私密)默认拒绝,需 grant / identity=user / `--unsafe` 授权;项目级优先;默认 50 条 |
|
|
117
119
|
| `forget <文件>` | 删除(按路径或文件名)|
|
|
118
120
|
| `archive [--days 180] [--threshold 0.4]` | 按盖棺分+年龄移入 `.archive/`(`vitality < threshold` 且超过 N 天)|
|
|
@@ -120,7 +122,7 @@ immutable: false
|
|
|
120
122
|
| `export [--out f.json]` | 导出全部记忆为 JSON |
|
|
121
123
|
| `import <f.json>` | 从 JSON 导入(幂等)|
|
|
122
124
|
| `profile [--owner <id>]` | 用户画像聚合(零推断,写 `private/<owner>/profile.md`;跨 owner 默认拒绝)|
|
|
123
|
-
| `context [--limit N] [--owner <id>]` | 开工上下文包(stdout:身份 + 画像 + 近期记忆 + 边界 +
|
|
125
|
+
| `context [--limit N] [--owner <id>] [--budget N]` | 开工上下文包(stdout:身份 + 多智能体铁律 + 画像 + 近期记忆 + 边界 + 承诺;`--budget` 近期记忆字符预算)|
|
|
124
126
|
| `iam <id> [--name] [--user] [--relationship] [--force]` | 登记身份 + 自我档案(可选扩展显示名 / 用户 / 关系)|
|
|
125
127
|
|
|
126
128
|
|
|
@@ -133,10 +135,10 @@ immutable: false
|
|
|
133
135
|
|
|
134
136
|
### context(开工上下文包,v0.6.0)
|
|
135
137
|
|
|
136
|
-
- `context [--limit N] [--owner <id>]`:stdout
|
|
138
|
+
- `context [--limit N] [--owner <id>] [--budget N]`:stdout 输出开工上下文包(不落盘),含多智能体接入铁律段(可读 A/B/C、可写范围、违规红线)与五段:
|
|
137
139
|
1. 身份:agent_id / agent_name / user_name / relationship / host / memory_home(读自我档案)
|
|
138
140
|
2. 用户画像摘要:profile.md(不存在则自动生成一次或降级跳过)
|
|
139
|
-
3. 近期记忆:按
|
|
141
|
+
3. 近期记忆:按 importance(confidence × recency + updated + weight + immutable)排序前 N 条(默认 10),读取分区过滤;`--budget` 时按剩余字符预算逐条放行(身份/铁律/画像/边界/承诺 必保)
|
|
140
142
|
4. 边界提醒:BOUND 全列(可读范围内)
|
|
141
143
|
5. 承诺 / 锚点:COMMIT 全列(可读范围内)
|
|
142
144
|
|
|
@@ -144,6 +146,8 @@ immutable: false
|
|
|
144
146
|
|
|
145
147
|
- `remember ... --verify`:写后自动回读校验(recall 命中刚写入条目),输出「已写回读 OK」。
|
|
146
148
|
- `remember ... --no-hint`:关闭类型启发式提示。默认开启:statement 含主观/关系词(用户 / 偏好 / 喜欢 / 关系 / 称呼 等)且 type=FACT 时 stdout 提示「疑似用户偏好 / 关系,建议 PREF」,仅提示不拦截。
|
|
149
|
+
- `remember ... --source <来源>`:记录来源(如 `对话` / `推断` / `交接`)。
|
|
150
|
+
- `remember ... --weight <0..>`:重要性权重(默认 1.0,>1 提权 / <1 降权);去重更新时 `weight` 取 max(多次印证自动提权,与灵魂盘 record.py 一致)。
|
|
147
151
|
- `iam <id> [--name <显示名>] [--user <用户名>] [--relationship <关系>] [--force]`:自我档案 PREF 扩展 `agent_name / user_name / relationship`;不带新参数行为与 0.4.2 一致。
|
|
148
152
|
### 去重与更新
|
|
149
153
|
|