mcpField
G
GoodMemory

GoodMemory

本地服务
github.com记忆与知识201 周前更新

关于 GoodMemory

GoodMemory 是面向 AI 产品和编码 Agent 的持久记忆层,可检索、写入、审查和删除用户或项目事实。它默认本地存储,并支持已安装的 Agent 主机及应用集成。

主要功能

  1. 01持久保存用户和项目记忆
  2. 02检索记忆并构建上下文
  3. 03可选启用记忆写入
  4. 04反馈、导出与删除记忆
  5. 05默认使用本地 SQLite 存储

适用场景

  1. 01在不同聊天会话间保留选定事实
  2. 02为编码 Agent 添加范围化记忆
  3. 03审查或删除错误的已存事实

MCP 相关

GoodMemory 为已安装的 Codex 和 Claude Code 提供只读 MCP 检查路径,也提供独立 MCP 服务供兼容客户端使用。其 MCP 工具支持检索上下文和可选写入记忆。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"hjqcan-goodmemory": {
"command": "npx",
"args": [
"-y",
"goodmemory"
]
}
}
}
启动命令npx -y goodmemory

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmgoodmemory0.7.5

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

GoodMemory

Language: English | 简体中文

GoodMemory 是面向 AI 产品和编码 Agent 的记忆层。

发布来源: 此源代码对应 0.8.3 稳定版本。 注册表命令要求已发布 [email protected]。发布工作流会根据本地准备的清单,验证 npm latest 和已发布的 GitHub 资源;不会重新构建或发布。

它为聊天应用、副驾驶和 Agent 宿主提供持久的用户/项目记忆闭环: 写入选定事实、检索合适的上下文、将其注入下一轮对话、审计发生的情况,并在记忆有误时将其删除。

GoodMemory 不是大模型、Agent 框架、向量数据库或通用 RAG 系统。它是位于应用或已安装的 Agent 宿主与模型运行时之间的产品记忆层。

你将获得

  • 持久记忆 API:remember、recall、buildContext、feedback、forget、exportMemory、importMemory 和 deleteAllMemory。
  • 通过 goodmemory setup、托管钩子、已安装的 Codex 前置操作、goodmemory status、只读 MCP 和可选写回,为 Codex 和 Claude Code 提供已安装 Agent 记忆。
  • 通过 GoodMemoryConfig.remember、RememberProfile、rememberRules、RememberInput.annotations 和命名提取器 ID,自定义公开写入行为。
  • 通过编译后的 dist 产物和 TypeScript 声明,导出 goodmemory、goodmemory/ai-sdk、goodmemory/host 和 goodmemory/http。
  • 本地优先存储:Bun 默认使用持久化 SQLite;需要时可添加显式 Postgres、注入式适配器和嵌入提供方。
  • 为确定性测试、实时评估、基于提供方的评估、包冒烟测试和质量门禁提供评估与发布证据路径。

OpenAI Build Week 2026

既有基础。 GoodMemory 在 OpenAI Build Week 之前就已存在。活动前的基础已包含核心记忆 API、本地 SQLite/Postgres 存储、已安装宿主集成和本地 Inspector。黑客松项目指提交期于 2026 年 7 月 13 日开放后新增的内容,而非整个代码库。

Build Week 期间新增。 带日期的提交完成并发布了 v0.6.0,强化了通用检索和迭代式回忆验证,增加了声明来源溯源覆盖,强化了已安装宿主的金丝雀测试和泄漏审计,并扩展了受控 Codex 编码效果评估路径。请查看活动前至 Build Week 的差异及其带日期的提交历史,了解确切的范围界定。

Codex 和 GPT-5.6 的使用方式。 Codex 与 GPT-5.6 是主要的实现和验证环境,用于探索代码库、实现和审查更改、编写回归测试、复现已安装宿主行为,以及执行发布和编码效果证据路径。GPT-5.6 也用于当前评估配置中已披露的非裁判模型调用;公开声明路径要么使用确定性评分,要么确保裁判与答案模型相互独立。

运行和验证。 发布后,从注册表安装 0.8.3 并检查其本地记忆界面:

npm install -g [email protected]
goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory inspector serve

使用 bun install --frozen-lockfile、bun test 和 bun run typecheck 从源代码验证代码库。请参阅 Devpost 提交和公开视频。

声明范围: 本项目展示了跨会话持久记忆、受治理的写回、回忆证据,以及检查/删除基础设施。它并未声称 GoodMemory 已证明能够改善 Codex 的编码结果;这项成对隐藏测试评估仍是正在进行且默认失败关闭的证据工作流。

从这里开始:Codex 或 Claude Code

npm install -g [email protected]
goodmemory setup

无需账号或托管服务。GoodMemory 默认使用 SQLite 在本地存储记忆,配置生命周期钩子和只读 MCP 检查功能,并将持久化写回设为可选项。运行 goodmemory status 验证安装。

使用其他 MCP 客户端或集成应用?选择集成路径。

基准测试结果

GoodMemory 将当前生产环境声明、带版本号的历史证据和内部研究区分开来。只有在 gate:public-benchmark-claim --strict 验证了适用于当前软件包版本的已提交声明后,某个数字才能列入当前声明表:覆盖完整、executionFailures: 0、无记忆基线、确定性评分或独立评审、已验证的数据集来源和许可证,以及可复现的运行(提交 + 命令 + 软件包版本)。目前没有端到端基准测试运行器获准列入白名单,因此当前和历史条目均无法晋升。对已存储答案重新评分,以及旧版展示投影,都无法突破这条边界,也无法将 README 中的分数和披露片段作为自我证明。

GoodMemory 0.8.3 没有当前基准测试声明或带版本号的历史基准测试声明。保留的 v0.7.3 LoCoMo 投影并非端到端运行器证据,因此属于内部诊断。v0.6.0 的 LoCoMo、BEAM 和 MemoryAgentBench 测量结果,以及 ImplicitMemBench,也在相同的失败即关闭边界下归为内部诊断。 LongMemEval 暂不采用,等待干净的重新运行:历史上仅使用规则的路径使用了答案标注,而后来的无标签路径则向检索器和读取器暴露了原始的 answer_* 会话 ID。ImplicitMemBench 的合并重试结果仍属于内部证据,因为它不能替代一次整体全新运行。HaluMem、MemGym 和 MINTEval 仍属于发布证据,而非公开基准测试声明。

目前没有任何基准测试结果被标示为在 0.8.3 上测得。

版本化证据

目前没有端到端基准测试运行器获准用于版本化证据。

目前没有任何基准测试结果符合版本化历史证据的条件。

保留的 v0.7.3 LoCoMo 投影仍存放在仓库中,可供审计,但它不会作为已验证的包制品发布,也不能用于证明公开或版本化声明。旧制品不会事后补齐;在开放晋级流程之前,必须同时实现未来的生成器及其验证器。

在两者都可用时,一行会报告两条轨道。严格轨道是确定性的或无需评审器的——这是任何 LLM 评审器都无法抬高的硬下限。第二条轨道会使用基准来源或行业标准提示词,对相同的已存储答案重新评分(而非重新生成答案)。只有在固定的评估器模型及其余基准配置也相同时,才声称数值具有可比性。所有逐协议的详细信息都记录在关联声明中。

LongMemEval 声明现在处于 paused_boundary 状态,不再是历史证据。其旧数值制品仅为保留审计轨迹而留存。在不透明会话 ID、无标签的完整重跑取代它们之前,不得将其作为 GoodMemory 结果引用;请参阅撤回声明。v0.6.0 的 BEAM、MemoryAgentBench 和 LoCoMo 测量仍是内部诊断数据。它们未通过空的端到端运行器许可名单,因此不属于版本化历史证据。

ImplicitMemBench Full-300 已存储答案的重新评分使用规范的、零失败的 run-phase61-full300-rerun-20260706-codex-current 答案,然后使用 gpt-5.4 对相同的已存储答案重新评分(sourceAnswersUnchanged: true)。评审器跨版本,但与 gpt-5.5 答案模型属于同一 GPT 系列,并非跨系列评审器。记录分数为 0.691(207.35/300),上游聊天基线为 0.400(120/300);基线组和 GoodMemory 组共进行了 530 次需要评审器的行级判定。确定性的 structured_first_action 行沿用此前结果,不进行评审。较早的同模型诊断分数为 0.708,并非记录结果。近期代码更改后,最新一次干净的答案重新生成漂移检查得分为 0.6895,且 executionFailures: 0;它反映当前检出版本的漂移,不能取代已存储答案的可比性制品。其测量来源无法在明确的 JSON 路径中分别提供包版本和提交哈希,因此该结果暂停为内部诊断数据,不属于版本化历史证据。数据集采用 CC BY 4.0,在评估时获取,从未 vendored。

内部诊断(非公开声明)

LongMemEval 首个当前回忆组装开发切片已被取代:尽管其读取器上下文隐藏了原始会话 ID,但记忆构建器边界仍收到了包含答案信息的会话 ID 和轮次标记。更严格的 v2 协议现在会在构建记忆前移除答案、问题类型、答案标记和原始会话身份。必须在干净的提交版本上重新运行开发切片,之后才能打开仍处于封存状态的留出集;LongMemEval 的声明不会恢复。ImplicitMemBench 显式合并重试的检查达到 0.6923666667,且没有失败,但它不能取代新的单体 Full-300 完整运行。因此,两者都仍不列入当前声明表。相关报告位于被 gitignore 忽略的 reports/ 下,并可通过记录的命令重现。

使用 task-board/00-README.txt 查看执行顺序,使用 docs/GoodMemory-Current-Status-and-Evidence.md 了解声明边界。

选择你的集成路径

GoodMemory 有三个主要产品入口。它们并非全部 API: 较低层级的接口(例如 goodmemory/host)、自定义存储、评估工具和 运行时辅助工具也支持这些路径。这些是 README 层面用于决定从何处开始的方式。

自主 Agent?从这里开始

如果你是想为自己提供持久记忆的 Agent,请选择一种接入方式并运行。此流程的机器可读版本见 llms.txt 和 .well-known/goodmemory.json(已部署的桥接服务也会通过 /.well-known/goodmemory.json 提供该描述文件)。

  • 你是 Claude Code 或 Codex,或在其中运行 → npm install -g [email protected] && goodmemory setup。不确定已经配置了什么? 运行 goodmemory adopt(添加 --json 可生成机器可读的计划):它会检查 .claude/、.codex/ 和现有 MCP 配置,然后打印适用于你环境的准确下一条命令。
  • 你支持 MCP(Cursor、Windsurf、Cline、Claude Desktop、Gemini CLI、 OpenCode 或自定义客户端)→ 添加 独立 MCP 服务;你需要的两个工具是 goodmemory_get_context(回忆)和 goodmemory_remember(选择性写入)。
  • 你是框架 Agent 或后端 → 调用 HTTP 桥接服务:托管于 goodmemory.vibenest.net 或使用 goodmemory-http-bridge --recommended 自托管(或运行 GOODMEMORY_PROFILE=agent-recommended goodmemory-http-bridge);Python 调用方 可使用 pip install goodmemory-client。

下文将详细介绍每种接入方式。

1. 将记忆集成到 Agent、聊天框或 Copilot 中

当你拥有产品服务端和模型调用时,请使用此方式。在 Node/Bun 服务中安装 goodmemory,创建一个 memory 实例,并传入稳定的 scope,例如 userId、workspaceId、sessionId,以及可选的 agentId。

请求流程如下:

  1. 在调用模型前,针对当前范围和查询运行 recall()。
  2. 运行 buildContext(),将回忆结果转换为提示词片段。
  3. 使用该记忆上下文调用模型。
  4. 收到响应后,使用 memory.jobs.enqueueRemember() 或 remember() 写入选定的信号。
  5. 使用 feedback()、定向的 reviseMemory()、forget() 和 exportMemory() 进行更正、删除和用户审计;importMemory() 可恢复导出内容,或将 Markdown 页面目录作为 note 记忆导入。

如果你的服务已使用 Vercel AI SDK,可使用 goodmemory/ai-sdk 封装 generateText() 或 streamText(),无需手动连接整个流程。从 应用快速入门开始;如果你使用 AI SDK,再阅读 AI SDK 适配器。

2. 为 Codex 或 Claude Code 添加记忆

如果你希望已安装的编码 Agent 记住项目和用户上下文,又不想修改 Agent 本身,请使用此方式。安装全局 CLI 并运行 goodmemory setup。

已安装主机的工作流程如下:

  1. session-start 注入会话简报;user-prompt-submit 注入每条提示词的上下文(新安装时会按相关性进行筛选,避免低信号提示词污染上下文)。
  2. Claude Code 的 Stop 钩子会从会话转录(transcript_path)中捕获每轮对话,并将其写入受治理的候选项——内容有界、经过脱敏,绝不保存原始转录;对于 Codex,goodmemory codex writeback --from-rollout 会将最新的会话 rollout 送入同一流水线。
  3. Codex 的 pre-tool-use 可通过 goodmemory codex action,基于相同的已安装配置和存储路径,拒绝或重定向有风险的 Bash 操作。
  4. MCP 提供追踪、上下文、统计信息和工件检查;写入工具 goodmemory_remember 需通过 mcp.allowWrite 选择启用(或运行 goodmemory enable <host> --mcp-allow-write)。
  5. 脚本化安装默认关闭回写;交互式安装和 goodmemory setup --recommended(一次同意提示)会启用 selective 持久化写入——可通过 writeback inspect 审计,也可通过 writeback forget --event-id 撤销。
  6. 全新安装会使用经过测量的 BM25 混合检索层级,提供 1024-token 会话简报和 512-token 的门控提示词注入;goodmemory status 会显示检索层级、捕获运行证明和注入遥测信息。可选的 sharedAgents 配置允许一个主机读取另一个主机的记录(写入仍归属于各自主机)。

请从快速入门:Codex 或 Claude Code 记忆开始。准备好审核或启用写入时,请参阅已安装主机回写。

3. 将 GoodMemory 部署为后端记忆层服务

如果其他后端需要将 GoodMemory 作为服务调用,请使用此方式。尤其适用于产品后端使用 Python/FastAPI,或 OneLife 这类产品希望将记忆保留在服务器端,而不是将 GoodMemory 打包进移动端或浏览器客户端的情况。

在 Node/Bun sidecar 中部署打包好的 goodmemory-http-bridge。然后,后端可调用:

  • /memory/recall-context,在调用自己的模型之前调用
  • /memory/remember,在用户确认或产品批准某个信号后调用
  • /memory/feedback,用于修正流程性信息
  • /memory/export 和 /memory/forget,用于审计和删除
  • /memory/revise,用于通过明确指定的记忆 ID 进行定向修正
  • /memory/import,用于恢复导出内容或导入 Markdown 页面

你的服务仍负责身份验证、产品策略、UI 和模型编排。GoodMemory 负责记忆存储、召回、上下文组装、写入治理,以及审计、导出和删除行为。请从 Python/FastAPI HTTP Bridge开始——其中介绍了官方 Python 客户端(pip install goodmemory-client)以及托管的桥接实例 goodmemory.vibenest.net——然后查看运行时与存储,了解 SQLite/Postgres 的选项。

在一次模型对话过程中,GoodMemory 会完成四项工作:

  1. 为当前 scope 解析记忆。
  2. 构建可直接用于提示词的上下文片段。
  3. 在你的应用或主机允许时,记录选定的响应后信号。
  4. 提供审计、修正、导出和删除途径,供用户进行控制。

你的应用或已安装的 Agent 仍负责身份验证、UI、模型调用和产品策略。GoodMemory 负责记忆循环和存储边界。

安装

这些命令适用于发布后的 GoodMemory 0.8.3。如需可重复安装,请使用下面固定版本的注册表命令。

如果你想在已安装的编码 Agent 中增强记忆,请使用全局 CLI:

npm install -g [email protected]
goodmemory setup
goodmemory status

如果你正在构建应用,请使用包依赖:

npm install [email protected]

如果你想直接输入 goodmemory,请安装全局 CLI。 在项目本地运行 npm install [email protected] 不会将 goodmemory 添加到 shell 的 PATH 中。 请在该项目中改用 npx goodmemory、npm exec -- goodmemory 或 ./node_modules/.bin/goodmemory。

npx goodmemory -V

Bun 用户可以直接安装:

bun add [email protected]

此版本源代码的压缩包校验:

npm install ./goodmemory-0.8.3.tgz

已安装的 CLI 对非版本命令由 Bun 提供支持。软件包的 bin 可通过 Node 安全运行 goodmemory -V 和 goodmemory --version;其他命令会委托给 Bun。

快速入门:Codex 或 Claude Code 记忆

对大多数用户来说,最实用的第一步是为已安装的宿主配置记忆。

npm install -g [email protected]
goodmemory setup
goodmemory status

goodmemory setup 会检测 Codex 和 Claude Code,安装托管的宿主连接配置,并询问:

  • 宿主:codex、claude 或检测到的两个宿主
  • 激活范围:全局、当前工作区或手动启用
  • GoodMemory 用户 ID
  • 可选的 Postgres 存储
  • 可选的嵌入提供方
  • 可选的 LLM 提取提供方
  • 写回模式:off、observe、review 或 selective

交互式设置默认启用全局激活,并根据工作区进行隔离;对于新的宿主配置,建议使用 selective,这样高信号写入会立即生效,并支持审计和撤销。如果你希望持久化写入前由 Inspector 审批,请选择 review。接受交互式提示的默认值时,现有宿主配置会保留当前的写回模式。 使用 --json 或 --no-interactive 可确保脚本化安装安全。 跳过提供方设置也是有效的:GoodMemory 仍可使用本地 SQLite 和仅基于规则的提取功能。

常用命令:

goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory enable codex --workspace-root . --writeback observe
goodmemory enable codex --workspace-root . --writeback selective
goodmemory disable codex --workspace-root .
goodmemory uninstall codex

已安装的宿主路径包含四个部分:

  • Codex 的托管前置操作:pre-tool-use 可以拒绝或重定向有风险的 Bash 操作,而 goodmemory codex action 会在与召回和写回相同的已安装配置、存储、提供方和作用范围路径上执行经过审核的第一步。
  • 召回注入:session-start 和 user-prompt-submit 钩子会调用 recall() 和 buildContext();如果配置、解析或存储不可用,则会默认放行。
  • 深度检查:goodmemory mcp serve --host codex 和 goodmemory-mcp --host codex 会提供只读的上下文、追踪、统计和构件工具。
  • 可选写回:session-stop 和显式写回命令可以将选定的响应后信号转化为持久记忆。

适用于任意客户端的独立 MCP

对于没有托管安装路径的宿主(Cursor、Windsurf、Cline、Claude Desktop、 Gemini CLI、OpenCode 或你自己的 MCP 客户端),可以在独立模式下运行同一个 MCP 服务——无需 goodmemory setup,也无需宿主配置文件。范围和存储由标志/环境变量指定;提供的功能与原来的 8 个只读工具相同,另加一个可选启用的受治理写入工具:

{
  "mcpServers": {
    "goodmemory": {
      "command": "goodmemory-mcp",
      "args": ["--standalone", "--user-id", "YOUR_USER_ID"]
    }
  }
}

等效调用:goodmemory-mcp --standalone --user-id <id>(要求 PATH 中有 Bun;GOODMEMORY_USER_ID 可作为标志的环境变量回退值)。 --allow-write(或 GOODMEMORY_MCP_ALLOW_WRITE=1)会注册 goodmemory_remember,它通过常规的受治理记忆流程写入;还会注册 goodmemory_write_note,它将撰写的页面(散文或 Markdown,最多 8 KB)原样存储为 note,并在重写时按标题取代原页面。带有 Agent 标签、由已安装的宿主写入的记忆仍对其 Agent 保持私有;添加 --agent-id codex 和共享的 --storage-url,即可选择读取已安装宿主的存储。完整的标志/环境变量对照表、范围说明和各宿主的配置步骤见: docs/GoodMemory-Standalone-MCP-Setup-Guide.md (Cursor · Gemini CLI · OpenCode)。

已安装宿主写回

已安装宿主写回为可选功能。运行时配置默认值和新的脚本安装仍保持 off,除非用户明确选择一种写回模式。若未提供明确覆盖设置,现有配置会保留当前写回模式。新的交互式安装推荐使用 selective,以便立即启用高信号写入,并支持审计和撤销;若希望由 Inspector 在持久化写入前进行审批,请选择 review。

先使用 observe,再使用 selective:

goodmemory enable codex --writeback observe
goodmemory codex writeback --json

goodmemory enable codex --writeback review
goodmemory inspector serve

goodmemory enable codex --writeback selective
goodmemory codex writeback --json

goodmemory inspector serve 会打开内置的本地 React 控制台,用于查看用户和范围、分类记忆及取代历史、候选项决策、召回证据追踪和审计事件。启动令牌通过 URL 片段传递,随后立即清除并存入会话存储,且仅通过 Bearer 标头发送。修订和破坏性操作需要确认、ETag 和幂等键。请参阅 Inspector And Admin API。

写回规则:

  • off:不提取响应后的记忆。
  • observe:存储有界且经过脱敏的本地候选项预览以供审核,不存储原始对话记录或持久化记忆。
  • review:将有界且经过脱敏的候选项加入队列,等待 Inspector 审批;操作员批准候选项前,不会写入持久化记忆。
  • selective:通过公开的 remember 接口写入所选候选项。
  • 不会将原始对话记录作为记忆持久化。
  • 除非宿主确认或验证助手发起的持久化记忆,且当前配置文件允许,否则会阻止此类记忆写入。
  • remember: "never" 会在确定性、自定义或辅助提取之前遮蔽已标注内容。

审计和撤销:

goodmemory codex writeback inspect --json
goodmemory codex writeback forget --event-id <event-id> --review-outcome false_write

审计账本存储有界且经过脱敏的候选项预览、候选项键、带类型的关联记录 ID、状态、原因、宿主、模式、时间戳、范围/会话摘要,以及可选的人工审核元数据。它不会存储原始宿主载荷。forget --event-id 会先通过公开的 forget() 删除关联的记忆/证据记录,再将持久化审计事件标记为已遗忘;对于仅处于 observe 模式的事件,它会将候选项标记为已驳回,而不会调用 forget()。

Claude Code 的钩子和写回命令具备确定性的 CLI 对等功能; Codex 是规范的实时证据路径。

脚本化主机安装

如果你需要完全非交互式的设置,请使用 goodmemory install <host>:

goodmemory install codex \
  --user-id <user-id> \
  --activation-mode global \
  --writeback observe \
  --storage-provider postgres \
  --storage-url "postgres://user:pass@host:5432/goodmemory" \
  --embedding-provider openai \
  --embedding-model text-embedding-3-small \
  --embedding-api-key <key> \
  --llm-provider openai \
  --llm-model gpt-4o-mini \
  --llm-api-key <key> \
  --no-interactive

托管配置位于 ~/.goodmemory/<host>.json。使用提供方标志重新运行 install 会更新同一配置,并确保 MCP/钩子注册具有幂等性。卸载软件包不会删除 ~/.goodmemory、仓库本地的 .goodmemory、本地 SQLite 文件或远程 Postgres 数据。使用 goodmemory uninstall <host> 移除托管主机配置;使用 goodmemory forget ... 或显式删除存储来移除记忆数据。

应用快速入门

如果你正在构建聊天框、copilot 或产品 Agent,请使用根软件包。推荐的 Node 服务方案采用与 Express 和 Fastify 示例相同的精简循环。更详细的操作指南见 docs/GoodMemory-15-Minute-App-Integration.md。

import type { GoodMemoryTraceSpan } from "goodmemory";
import { createGoodMemory } from "goodmemory";

const traceSpans: GoodMemoryTraceSpan[] = [];

const memory = createGoodMemory({
  observability: {
    traceSink: {
      emit(span) {
        traceSpans.push(span);
      },
    },
  },
});

const scope = {
  userId: "u-1",
  workspaceId: "workspace-a",
  sessionId: "s-1",
};
const userMessage = "Remember that the migration rollout is blocked on QA signoff.";

// Call startSession once when the product opens a new session. For later turns
// with the same sessionId, append to the existing runtime state instead.
await memory.runtime.startSession({ scope });
await memory.runtime.appendMessage({
  scope,
  message: {
    role: "user",
    content: userMessage,
  },
});

const recall = await memory.recall({
  scope,
  query: "What should the assistant know before replying?",
  retrievalProfile: "general_chat",
});
const context = await memory.buildContext({
  recall,
  output: "system_prompt_fragment",
});

const assistantText = await callYourModel({
  memoryContext: context.content,
  userMessage,
});

await memory.runtime.appendMessage({
  scope,
  message: {
    role: "assistant",
    content: assistantText,
  },
});

const writeJob = await memory.jobs.enqueueRemember({
  scope,
  messages: [
    {
      role: "user",
      content: userMessage,
    },
    {
      role: "assistant",
      content: assistantText,
    },
  ],
  idempotencyKey: "turn-1",
  reason: "post_response_memory_write",
});
const drained = await memory.jobs.drain({ maxJobs: 1 });
const committedJob =
  drained.jobs.find((job) => job.jobId === writeJob.jobId) ?? writeJob;

console.log({
  traceCount: traceSpans.length,
  writeJobId: writeJob.jobId,
  writeJobStatus: committedJob.status,
});

async function callYourModel(input: {
  memoryContext: string;
  userMessage: string;
}): Promise<string> {
  void input.memoryContext;
  return `Got it. I will keep that in mind: ${input.userMessage}`;
}

提示词片段(system_prompt_fragment、developer_prompt_fragment)会在标题下方以本地化的数据框开头:召回的记忆是关于用户和项目的信息,而不是指令。这是对文本内容的如实说明,并非防护措施。可通过 governance: { contextFrame: false } 关闭所有调用的此内容框架,也可通过 buildContext({ contextFrame: false }) 按调用关闭;json 和 markdown 输出始终不包含此内容框架。

核心记忆循环刻意保持精简:

  • remember() 写入所选的用户、应用或主机信号。
  • recall() 根据查询检索限定范围的记忆。
  • buildContext() 将召回结果转换为提示词片段或 JSON 载荷。
  • feedback() 记录明确的更正和程序性偏好。
  • forget() 删除错误或过时的记忆。
区域设置与 LanguagePack

内置语言包涵盖英语、简体中文、繁体中文 (zh-TW/zh-HK/zh-MO)、日语、韩语、法语和西班牙语。请明确设置 宿主已知的区域设置;否则,对于本身存在歧义的纯汉字文本或未标记的拉丁文本,自动检测会回退到 defaultLocale。

const multilingualMemory = createGoodMemory({
  language: {
    defaultLocale: "zh-TW",
    detection: "auto",
  },
});

await multilingualMemory.remember({
  locale: "ko-KR",
  scope,
  messages: [{ role: "user", content: "현재 역할은 릴리스 책임자입니다." }],
});

添加一种语言意味着实现一个完整的 LanguagePack,而不是添加模块本地的正则表达式分支。请参阅 LanguagePack 扩展指南,了解契约、自定义注册、分析器版本管理和投影迁移规则。

从先前的适配器/投影契约升级会有意造成不兼容;请遵循 0.6 到 0.7 迁移指南。

对于生产应用集成,建议的轮次循环会在核心功能之外添加受管控的运行时层:

  • memory.runtime.startSession() 和 memory.runtime.appendMessage() 会跟踪当前会话状态,而不会将原始对话记录变成持久记忆。
  • memory.jobs.enqueueRemember() 会安排响应后的记忆写入,并提供幂等性和可见的任务状态。
  • memory.jobs.drain() 会在此内存调度器中提交排队的写入。在生产服务中,请在工作线程或请求相关的任务循环中运行任务排空。
  • GoodMemoryConfig.observability.traceSink 会接收涵盖 remember、recall、context、revise、forget、export 和任务事件的脱敏安全跟踪信息。
  • memory.reviseMemory({ target: { memoryId } }) 会通过明确的 ID 修正已知记忆,而不是通过模糊文本选择。
  • exportMemory() 为用户提供审计/导出途径。其 pages/ 包是一个与 memoryfield 兼容的笔记页面目录,包含 SHA-256 清单。
  • memory.importMemory({ source }) 会按 ID 重新导入该导出内容,或将页面作为 note 记忆摄取;expectedSha256 会在任何写入发生前固定输入内容。
  • governance.fileMirror: { root, scope } 会在 scope 内每次持久写入后,在磁盘上保留该导出包的只读副本(防抖、原子目录交换)。一个根目录对应一个持久范围;镜像是投影:绝不会被读回,也不会导致写入失败。

运行时归档持久化默认关闭。如果调用 memory.runtime.endSession({ scope, archive: "off" }),会话状态会被清除,且不会写入归档。如果选择启用归档持久化,请仅保留摘要,绝不要将原始对话记录视为默认记忆来源。

对于服务集成,请从精简示例开始: examples/express-chat-server.ts 或 examples/fastify-chat-server.ts。 对于 Python/FastAPI 后端,请使用下文所述、已打包的 goodmemory-http-bridge 路径。

可选的召回调优:广义融合、多跳、可选嵌入与对话式提取

以下调节项均为可选,且在设计上较为保守。默认召回采用单轮处理且仅基于规则,默认提取行为不变;除非选择启用,否则不会发生任何变化。推荐预设提供无需服务提供方的本地路径;嵌入和提取服务提供方会增加可选通道,但并非必需。

一键启用推荐检索预设

retrieval.preset: "recommended" 只需一个标志,即可启用通用检索和条件式对话提取:

const memory = createGoodMemory({
  retrieval: { preset: "recommended" },
});

启用后,它会:(a) 为记忆、字段和句子粒度的召回文档建立索引;(b) 使用 RRF 融合 BM25、直接实体邻接关系以及所有可用的神经稠密候选;(c) 应用有界动态候选预算;(d) 将 auto 召回路由偏向混合检索。显式指定的单次调用策略仍优先生效,包括会跳过通用融合的 strategy: "rules-only"。解析到神经嵌入时,会添加一个 topK: 16 的稠密通道;若未解析到,则检索仍为本地、确定性且零网络访问。仅当提取模型已解析且未显式设置模式时,该预设还会将辅助提取切换为 mode: "conversational"。它绝不会注入提供方。将 preset 留空可保留现有的仅规则默认行为。

要求与限制:

  • 不需要提供方。神经嵌入端点(GOODMEMORY_EMBEDDING_*、providers.embedding 或 adapters.embeddingAdapter)会添加可选的稠密通道。零外发流量的神经路径见下方的 Ollama 配置示例。
  • 与该预设配合使用时,createLocalEmbeddingAdapter() 会被拒绝:哈希词汇向量会重复提供词汇证据,却被当作稠密语义通道。
  • 检查 inspectGoodMemoryRuntime(memory).retrievalPreset——其 extraction 字段会报告写入时的部分是否已启用("conversational"),或提取器是否不可用/保持原样。
  • 该预设仅涵盖记忆检索和条件式提取。回答端的提示和拒答策略仍由应用负责。
  • 除非你有意启用单独的旧版加法式 BM25 槽位,否则不要与 bm25Ranking: true 搭配使用;通用融合已包含 BM25 通道。
  • 如果你使用通过环境变量解析的提取器并采用该预设,写入时的输出会变为对话式原子声明;要退出此行为,可显式设置 providers.extraction 对象并指定 mode: "default"。
可选的逐项重排器

当融合后的候选集有用,但最终排序不够稳定时,可添加一款一方提供的 OpenAI 兼容逐项重排器:

const memory = createGoodMemory({
  retrieval: { preset: "recommended" },
  providers: {
    reranking: {
      provider: "openai",
      model: process.env.RERANKING_MODEL!,
      apiKey: process.env.RERANKING_API_KEY!,
      baseURL: process.env.RERANKING_BASE_URL,
    },
  },
});

const result = await memory.recall({ scope, query });
console.log(result.metadata.retrievalTrace?.reranker);

每条选中的事实都会通过独立的查询-文档调用进行评分;并列候选项绝不会放在同一个重排器提示中。重排器只会调整已由确定性召回纳入的事实顺序,因此不会扩大候选范围,也不会放宽基于依据的拒答策略。若提供方超时、响应架构有误或网关故障,系统会返回原始确定性顺序,并在 retrievalTrace 中记录 status: "fallback" 和稳定的原因。可在单次召回中设置 rerank: false 以跳过重排。显式配置的 adapters.reranker 优先于 providers.reranking。基于提供方的重排默认请求超时为 15 秒;如果所选网关需要不同的延迟预算,可在 providers.reranking 中设置可选的正整数 requestTimeoutMs。

跟踪信息包含有界的通道/RRF 归因、模型角色、经过净化的网关、延迟、分数以及前后排名。它不包含 API 密钥、查询文本或记忆内容。这是可选功能,会为有界重排窗口中的每条事实增加一次模型调用;无需提供方的推荐路径保持不变。

可选的本地嵌入端点(Ollama)

推荐预设无需嵌入即可运行。若要添加零出站流量的神经稠密通道,GOODMEMORY_EMBEDDING_BASE_URL 可接受任何兼容 OpenAI 的 /v1/embeddings 端点,包括本地 Ollama 服务。

ollama pull nomic-embed-text        # or bge-m3 for stronger multilingual recall

export GOODMEMORY_EMBEDDING_PROVIDER=openai
export GOODMEMORY_EMBEDDING_BASE_URL=http://localhost:11434/v1
export GOODMEMORY_EMBEDDING_MODEL=nomic-embed-text
export GOODMEMORY_EMBEDDING_API_KEY=ollama   # any placeholder; Ollama ignores it, the variable stays required

# smoke-check the endpoint before starting your app
curl http://localhost:11434/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{"model": "nomic-embed-text", "input": "hello"}'
  • provider 保持为 openai:它用于选择兼容 OpenAI 的线路协议, 而非选择供应商。
  • 每个存储只使用一个嵌入模型:不同模型或维度生成的向量不可比较,切换模型意味着需要重新记忆(重新嵌入) 语料库。
  • 本地嵌入的质量与 text-embedding-3-small 不同;公开的 LoCoMo 数值是在 OpenAI 端点上测得的。此方案以零出站流量复现 实现机制,而非复现确切数值。
  • 这不是下文的 createLocalEmbeddingAdapter():它采用 哈希词汇方法,而非语义方法,且不受推荐预设支持。
长记录准入

默认情况下,召回会根据事实与查询共享的词元数占两者中较大词元集合的比例来评分,因此较长的导入事实即使涵盖整个查询,得分仍可能接近零。 retrieval.longRecordAdmission: true 会为超过长记录下限(32 个重叠词元)的记录增加第二个 查询侧覆盖率信号:当记录匹配至少 60% 的查询词元且至少匹配两个词元时,即可准入。它先执行传统召回,且只填补经校准的事实选择后剩余的容量;不会重新排序已有条目;追踪信息会显示 fallback=long_record_coverage 或 below long-record coverage floor。笔记使用自己的召回通道,不受此标志影响。最终渲染的上下文仍受其词元预算约束。

在 v0.8 中,Codex 和 Claude 的全新安装在完整的 LongMemEval/LoCoMo 成对保护门槛测试通过后会启用此标志。重新安装会保留现有设置,包括键不存在或显式设为 false 的情况。该库仍需选择启用,且默认关闭文件镜像。Phase 75 证据 记录了范围和限制;它不会改变公开的基准测试声明。

const memory = createGoodMemory({ retrieval: { longRecordAdmission: true } });
选择启用多跳召回

默认情况下,recall() 执行单次检索。传入 multiHop: true 可选择启用两轮检索:GoodMemory 执行查询,从第一轮证据中提取提及的桥接实体,用这些实体扩展查询,然后执行第二轮检索。

const recall = await memory.recall({
  scope,
  query: "Who manages the project Alice started?",
  multiHop: true,
});

当答案需要一个只有第一跳才提及的实体时,可使用此功能(第 1 跳找到“Alice 启动了 Project Atlas”;第 2 跳需要知道“谁负责管理 Project Atlas”)。

  • 这是选择启用的功能。默认召回仍为单次检索;不设置 multiHop 不会改变任何行为。
  • 它不是通用语义检索器。它通过词汇方式桥接已命名实体;不会按含义排序。
  • 第一轮召回较弱时,它可能引入噪声:如果第 1 跳找到的证据有误,提取出的桥接实体也会有误,扩展后的查询会稀释召回效果。在 LoCoMo 上测得(其基础检索效果很低),multiHop 降低了召回率,因此不要用它来解决对话式或措辞差异导致的检索问题——这需要真正的语义检索,而非多跳桥接。
离线本地嵌入适配器

createLocalEmbeddingAdapter() 是一个确定性、离线、无依赖的 嵌入适配器(哈希字符 n-gram 向量)。注入此适配器即可在不配置嵌入提供方的情况下, 通过词汇/形态学方式打破平局:

import { createGoodMemory, createLocalEmbeddingAdapter } from "goodmemory";

const memory = createGoodMemory({
  adapters: { embeddingAdapter: createLocalEmbeddingAdapter() },
});
  • 它不是神经语义检索。向量是哈希后的词汇特征,因此只能在词汇相似的候选项之间打破平局;它们无法理解含义。
  • 不要用它来宣称语义基准测试有所提升。对于表层词汇重叠已无法捕捉的问题,即问题与文本之间的措辞差异,它无法弥合。
  • 若要进行真正的语义排序,请改为通过 GOODMEMORY_EMBEDDING_* 配置神经嵌入提供方。
可选启用的对话事实提取

默认情况下,辅助提取(配置了 providers.extraction 模型时)会提取持久的产品记忆——用户档案、偏好、引用和事实。将 providers.extraction.mode: "conversational" 设为启用对话式提取,在写入时将对话拆解为独立完整、消解指代、统一实体和日期格式的原子化陈述,让后续检索匹配规范化事实,而不是原始对话轮次。

const memory = createGoodMemory({
  providers: {
    extraction: {
      provider: "openai",
      model: "gpt-5.6-terra",
      apiKey: process.env.GOODMEMORY_ASSISTED_EXTRACTOR_API_KEY!,
      baseURL: process.env.GOODMEMORY_ASSISTED_EXTRACTOR_BASE_URL,
      mode: "conversational",
    },
  },
});

适用于记忆来源于多轮对话、且提问方式与原话不同的聊天/Agent 产品(“用户的经理是谁?”与“嗯,我老板 Dana 批准了”)。

  • 此功能需选择启用。若不设置 mode(或省略 providers.extraction),则保持默认提取行为;召回排序路径不受影响。
  • 这是一个写入时的 LLM 处理步骤:它使用已配置的聊天模型,因此会增加提取延迟和令牌成本;与任何 LLM 步骤一样,也可能遗漏或错误表述某项陈述。原始对话轮次仍是事实依据。
  • 这不是语义检索。它会规范化存储的文本,让词法检索更容易找到匹配内容;但不会按含义排序。它是弥补对话措辞差异的免嵌入方案,而非神经嵌入提供方的替代品。
  • 未经留出验证,不要引用此功能的基准测试数值,也不要针对特定基准测试的措辞调整提取提示词。

运行时与存储

createGoodMemory({}) 遵循本地优先的自动存储约定:

  • 若提供了 storage.provider,则优先使用该设置。
  • 未显式指定存储时,只有在配置的目标能够引导启动 GoodMemory 后端时,GoodMemory 才会使用 Postgres。
  • 在 Bun 上,零配置持久化存储为本地 SQLite,路径是 ./.goodmemory/memory.sqlite。
  • 在不含内置本地 SQLite 适配器的 Node 运行时上,零配置存储会回退到内存。
  • 显式选择不受支持的内置 sqlite 或 postgres 时,会报告为不可用,而不会误标为持久化存储。
  • 注入的 documentStore、sessionStore 或 vectorStore 适配器会报告为由适配器定义的存储。
  • 未设置检索预设时,无论嵌入配置如何,运行时行为都保持为 rules-only。recommended 预设会将 auto 路由到不依赖提供方的混合融合路径,并在已配置时加入稠密证据。
  • 受支持的本地运行时可使用 sqlite-vss 为 SQLite 建立语义索引;不受支持的运行时则会保持持久化但不加速的回退行为。

自定义 DocumentStore 适配器继续遵循原有的 set/get/update/query/delete 契约。recommended 通用融合预设等原子化功能,以及选择启用的行为结果记录器,还要求使用 ProjectionCapableDocumentStore。其 projectionBatchSemantics 必须等于导出的 PROJECTION_BATCH_SEMANTICS 版本,并且其 writeBatchIfUnchanged() 必须原子化地验证 expected/unchanged 行,并应用批次中的每个 set 和 delete。现有适配器可以在不支持投影的情况下继续运行;不会将旧版同名方法视为当前原子化契约。只有在适配器实现全部语义后,才添加版本标记。内置的内存、SQLite 和 Postgres 存储已实现该契约。

检查已解析的运行时,而非凭空猜测:

import { createGoodMemory, inspectGoodMemoryRuntime } from "goodmemory";

const memory = createGoodMemory({});
const runtime = inspectGoodMemoryRuntime(memory);

console.log(runtime.storage);

SQLite 向量控制项:

  • GOODMEMORY_SQLITE_VECTOR_MODE=off|prefer|require
  • GOODMEMORY_SQLITE_CUSTOM_LIBRARY_PATH
  • GOODMEMORY_SQLITE_VECTOR_EXTENSION_PATH
  • GOODMEMORY_SQLITE_VECTOR_EXTENSION_ENTRYPOINT
  • GOODMEMORY_SQLITE_VECTOR_SEARCH_FUNCTION

公共 remember 定制

产品集成应通过公共的 remember 接口定制写入。不要将仅供测试使用的提取器接口用于产品行为。

import { createGoodMemory, rememberRules } from "goodmemory";

const memory = createGoodMemory({
  remember: {
    preset: "default",
    profiles: [
      {
        id: "life-coach",
        when: { agentId: "life-coach" },
        rules: [
          rememberRules.fact(/my top priority this quarter is (.+)/i, {
            id: "life-goal-priority",
            category: "goal",
            tags: ["life_coach", "long_term_goal"],
            attributes: { horizon: "quarter" },
            content: ({ match }) => match[1] ?? "",
          }),
          rememberRules.preference(/please coach me with (.+)/i, {
            id: "life-coaching-style",
            category: "coaching_style",
            value: ({ match }) => match[1] ?? "",
          }),
        ],
        assistantOutputs: { mode: "confirmed_or_verified_only" },
      },
    ],
  },
});

await memory.remember({
  scope: { userId: "u-1", agentId: "life-coach" },
  messages: [
    {
      role: "user",
      content: "My top priority this quarter is rebuilding my sleep routine.",
    },
  ],
  annotations: [
    {
      messageIndex: 0,
      remember: "always",
      metadataPatch: { tags: ["confirmed_by_host"] },
    },
  ],
});

Profile extractors 可以是原始 MemoryExtractor 对象,也可以是命名的 { id, extractor } 条目。实际集成应使用命名提取器,这样即使 Profile 组合发生变化,remember 事件和评估报告也能保留稳定的 extractorIds。remember 事件还会携带已解析的 profileId 和 presetId 元数据。

手写笔记(原文页面)

提取适用于对话,但如果 Agent 想要保留一篇页面(操作指南、运行手册、来之不易的经验),就不应该把它拆成句子事实。note 类型会逐字存储消息正文,绝不拆分句子;存在嵌入适配器时,会对整篇内容进行嵌入;在默认配置下,会将其作为单独且有上限的通道召回(对标题和正文执行 BM25,因此涵盖查询内容的长篇页面也能被纳入)。正文上限为 8,192 个 UTF-8 字节;更长的页面请拆分。再次写入相同标题会通过沿袭关系取代之前的页面;内容完全相同的页面则会合并。

await memory.remember({
  scope,
  messages: [{ role: "assistant", content: pageMarkdown }],
  annotations: [
    {
      messageIndex: 0,
      remember: "always",
      confirmed: true,
      kindHint: "note",
      metadataPatch: { noteTitle: "Reading MediaWiki sites as an agent" },
    },
  ],
});

同样的形式也可通过 MCP 工具 goodmemory_write_note、HTTP POST /memory/remember 上的 kindHint: "note" 注解,以及 goodmemory remember --kind note --title "..." --message "..." 使用。召回的笔记会显示在 Notes 部分,其正文在所有输出模式(包括提示词片段)中都会保留 Markdown 结构。笔记与其他所有类型遵循相同的管理规则:按范围限定、脱敏、可修订、可遗忘、导出到 durable.notes,并按标题索引到 MEMORY.md。

AI SDK 适配器

GoodMemory 面向 Node 的 AI SDK 路径,是基于 createGoodMemory() 和 createGoodMemoryAISDK() 构建的纯 Request -> Response 服务端处理程序。

import { createGoodMemory } from "goodmemory";
import type { GoodMemoryStreamTextInput } from "goodmemory/ai-sdk";
import { createGoodMemoryAISDK } from "goodmemory/ai-sdk";

const memory = createGoodMemory({});

const aiSDK = createGoodMemoryAISDK({
  memory,
});

type MemoryChatRequest = Pick<
  GoodMemoryStreamTextInput,
  "messages" | "query" | "scope" | "system"
>;

function isMemoryChatRequest(value: unknown): value is MemoryChatRequest {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return false;
  }

  const candidate = value as Record<string, unknown>;
  const scope = candidate.scope;
  return Array.isArray(candidate.messages)
    && !!scope
    && typeof scope === "object"
    && !Array.isArray(scope)
    && typeof (scope as { userId?: unknown }).userId === "string"
    && (scope as { userId: string }).userId.trim().length > 0;
}

export async function handleMemoryChat(request: Request): Promise<Response> {
  const body: unknown = await request.json();
  if (!isMemoryChatRequest(body)) {
    return new Response(
      JSON.stringify({
        error: "Expected a request body with a messages array and scope.userId.",
      }),
      {
        headers: { "content-type": "application/json; charset=utf-8" },
        status: 400,
      },
    );
  }

  const result = aiSDK.streamText({
    messages: body.messages,
    query: body.query,
    scope: body.scope,
    system: body.system,
    model: {} as never,
  });

  return result.toTextStreamResponse();
}

说明:

  • 标准服务端示例是 examples/plain-ai-sdk-server.ts。
  • 精简的 Express 和 Fastify 示例分别是 examples/express-chat-server.ts 和 examples/fastify-chat-server.ts。
  • examples/vercel-ai-chat.ts 仍是较底层的封装/API 示例。
  • Next.js App Router 可将 export async function POST(request: Request) 映射到相同的处理程序主体。
  • 第一个公共服务端路径以 ModelMessage 为先。
  • 封装会通过 recall() 和 buildContext() 增强 system;如果记忆层出错,则会软失败。

Python/FastAPI HTTP 桥接

当 Python 后端需要将 GoodMemory 用作服务端记忆服务时,请使用打包的 HTTP 桥接。

GOODMEMORY_HTTP_BRIDGE_TOKEN="replace-with-service-token" \
GOODMEMORY_STORAGE_PROVIDER=postgres \
GOODMEMORY_STORAGE_URL="postgres://user:pass@host:5432/goodmemory" \
./node_modules/.bin/goodmemory-http-bridge --profile life-coach

Python 调用方发送 Authorization: Bearer <token> 和 x-goodmemory-* 作用域标头,以调用 POST /memory/recall-context、/memory/remember、/memory/feedback、/memory/export、/memory/import、/memory/forget 以及定向的 /memory/revise。TypeScript 桥接 API 可从 goodmemory/http 使用。

要通过桥接提供推荐的检索预设(多粒度 BM25 + 实体 + RRF,并可选密集通道),启动时使用开关 --recommended(或设置 GOODMEMORY_PROFILE=agent-recommended 或 GOODMEMORY_HTTP_BRIDGE_RECOMMENDED=1)。无需嵌入端点;配置 GOODMEMORY_EMBEDDING_* 后会添加密集通道。GET /healthz 会报告 retrievalTier 和 embeddingEnabled,召回请求默认使用 strategy: "auto",该预设会将其路由到 hybrid。显式请求 strategy: "rules-only" 仍会选择严格下限。

也可以通过一条命令使用 Docker 部署(包含 SQLite 卷;添加 compose postgres 配置以使用 pgvector):

GOODMEMORY_HTTP_BRIDGE_TOKEN="replace-with-service-token" docker compose up -d
curl -fsS http://127.0.0.1:8739/healthz

GET /healthz 是无需身份验证的存活检测端点,供容器、负载均衡器和客户端就绪等待使用。Python 后端应使用官方客户端 — pip install goodmemory-client(PyPI)— 它会根据一个 Scope 对象生成调用方标头,遵循各端点的幂等规则,并提供召回 routing 信息(从而能发现策略被静默降级的情况)。详情请见: docs/GoodMemory-Python-HTTP-Integration-Bridge.md。

托管实例。 GoodMemory 桥接服务在线运行于 https://goodmemory.vibenest.net(存活检测: /healthz)。将任意客户端通过 GOODMEMORY_BRIDGE_HOST / --goodmemory-host(或 GoodMemoryClient 的 host 参数)指向该服务,而非本地 URL;该服务强制使用 Bearer 令牌身份验证,因此请自备服务令牌。它是支持写入的单进程 API — 在公开暴露前,请添加速率限制并使用可丢弃的作用域数据,切勿公开共享写入令牌。

主机适配器 API

当外部主机需要使用构件或特定于主机的契约,而不导入内部模块时,请使用 goodmemory/host。

import { createGoodMemory } from "goodmemory";
import { createHostAdapter } from "goodmemory/host";

const memory = createGoodMemory({});

const adapter = createHostAdapter({
  id: "codex-handoff",
  hostKind: "codex",
  memory,
  readableArtifactTypes: ["session_memory"],
});

const result = await adapter.readArtifacts({
  scope: {
    userId: "u-1",
    workspaceId: "workspace-a",
    sessionId: "s-1",
  },
  includeRuntime: true,
});

模式:

  • file-assisted:读取编译后的构件,例如 MEMORY.md、user.md、session-memory/<sessionId>.md 和 playbooks/*.md,但不将文件视为规范存储。
  • file-authoritative:适用于最小可写子集。目前,该子集是规范的 playbooks/*.md 文件格式,会将结构化差异写回有效的活动模式反馈记录。

可写操作的防护措施:

  • 提示词和技能片段文件仍是派生的只读输出。
  • 编辑高风险指南需要明确的 verifyWrite 批准。
  • 对 appliesTo 和 Why 等低风险元数据的编辑,无需额外批准即可写回。
  • 可写操作失败时会返回诊断信息和回滚指南。

当前 Claude/Codex 示例默认仍使用 file-assisted 模式。

CLI 参考

shell PATH 上的 goodmemory 命令是通过 npm install -g [email protected] 安装的全局 CLI。在本地依赖安装中,可通过 npx goodmemory、npm exec -- goodmemory 或 ./node_modules/.bin/goodmemory 调用软件包 bin。仓库本地的 bun run goodmemory 脚本 仅用于开发。

以记忆为先的命令:

./node_modules/.bin/goodmemory inspect --user-id <user-id> --workspace-id <workspace-id>
./node_modules/.bin/goodmemory trace --user-id <user-id> --workspace-id <workspace-id> --query "Which runbook is the source of truth?"
./node_modules/.bin/goodmemory export-memory --user-id <user-id> --workspace-id <workspace-id> --output ./tmp/export
./node_modules/.bin/goodmemory import-memory --user-id <user-id> --workspace-id <workspace-id> --input ./tmp/export --dry-run
./node_modules/.bin/goodmemory stats --user-id <user-id> --workspace-id <workspace-id>
./node_modules/.bin/goodmemory remember --user-id <user-id> --workspace-id <workspace-id> --session-id <session-id> --message "Remember that the deploy is blocked on smoke verification."
./node_modules/.bin/goodmemory remember --user-id <user-id> --kind note --title "Reading MediaWiki sites as an agent" --message "$(cat page.md)"
./node_modules/.bin/goodmemory feedback --host codex --workspace-root . --session-id <session-id> --signal "Keep coding summaries short and list explicit next steps."
./node_modules/.bin/goodmemory forget --host codex --workspace-root . --session-id <session-id> --memory-id <memory-id>

已安装宿主的命令:

goodmemory -V
goodmemory --version
goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory install codex --activation-mode global --writeback observe --user-id <user-id>
goodmemory enable codex --workspace-root . --writeback selective
goodmemory mcp serve --host codex
goodmemory-mcp --host codex
goodmemory codex bootstrap --user-id <user-id> --workspace-id <workspace-id>
goodmemory claude bootstrap --user-id <user-id> --workspace-id <workspace-id>

Hook 和回写示例:

printf '%s' '{"cwd":".","session_id":"s-1","hook_event_name":"SessionStart","source":"startup"}' \
  | goodmemory codex hook session-start

printf '%s' '{"cwd":".","session_id":"s-1","tool_name":"Bash","tool_input":{"command":"./tools/DeepAnalyzer --detailed"}}' \
  | goodmemory codex hook pre-tool-use

goodmemory codex action -- ./tools/DeepAnalyzer --detailed

printf '%s' '{"cwd":".","session_id":"s-1","messages":[{"role":"user","content":"Next step is to finish the release smoke."}]}' \
  | goodmemory codex writeback --json

printf '%s' '{"cwd":".","session_id":"s-1","event_id":"stop-1","summary":"Keep coding summaries short."}' \
  | goodmemory codex hook session-stop

Eval 产物检查:

./node_modules/.bin/goodmemory eval inspect --run-dir reports/eval/live/<run-id> --case-id <case-id>
./node_modules/.bin/goodmemory eval trace --run-dir reports/eval/live/<run-id> --case-id <case-id>
./node_modules/.bin/goodmemory eval export-case --run-dir reports/eval/live/<run-id> --case-id <case-id> --output /tmp/case.json

CLI 命令列表:

  • goodmemory -V
  • goodmemory --version
  • goodmemory setup
  • goodmemory status
  • goodmemory install
  • goodmemory uninstall
  • goodmemory enable
  • goodmemory disable
  • goodmemory inspect
  • goodmemory trace
  • goodmemory export-memory
  • goodmemory import-memory
  • goodmemory stats
  • goodmemory --schema(以 JSON 格式输出完整 CLI 命令列表,供 Agent 和工具使用;goodmemory <command> --help 仍显示面向用户的形式)

已安装的宿主还可以将导出包保存在磁盘上:goodmemory setup --file-mirror(或 install <host> --file-mirror)会在每次持久写入后写入 <workspace>/.goodmemory/memory/,以便无需运行 CLI 即可搜索 MEMORY.md、 topics/*.md 和 pages/*.md。

  • goodmemory remember
  • goodmemory feedback
  • goodmemory forget
  • goodmemory mcp serve
  • goodmemory-mcp
  • goodmemory codex hook
  • goodmemory codex writeback
  • goodmemory claude hook
  • goodmemory claude writeback
  • goodmemory codex bootstrap
  • goodmemory claude bootstrap
  • goodmemory eval inspect
  • goodmemory eval trace
  • goodmemory eval export-case

示例

已安装软件包的指南:

仓库本地示例:

从此仓库运行示例:

bun run example:chat
bun run example:coding-agent
bun run example:ai-sdk-server
bun run example:express-chat
bun run example:fastify-chat
bun run example:vercel-ai
bun run example:life-coach-profile
bun run example:host-claude
bun run example:host-codex

测试与评估

默认本地门禁:

bun test
bun run typecheck
bun run test:coverage

如需准备完整的软件包、覆盖率、运行时使用方、大小和来源信息,请使用一个明确的输出目录:

bun run release:prepare -- --output-dir <dir>

该命令会冻结源代码身份、运行必需的检查、准确打包一个压缩包,使用 Node 和 Bun 验证同一个压缩包,并写入权威的 release-manifest.json 以及确定性证据归档。summary.md 是便于阅读的概述。准备过程不会晋级或发布。此源代码树没有通用的晋级命令。稳定版发布会在维护者授权下使用这些完全相同的本地工件;只读发布工作流会验证已发布的资产和 npm 完整性,不会再次打包,也不需要注册表凭据。

仓库研究协议从静态注册表中选择:

bun run research:list
bun run research:run -- <id> --root <path>
bun run research:verify -- <id> --root <path>

历史阶段和发布验证器仍可通过其绑定的标签或提交直接运行脚本来重放;它们以前的软件包别名有意不包含在当前命令界面中。

仅当你有意要对 vendored 或第三方测试树进行更广泛的检查时,才使用 bun run test:all。

评估命令:

bun run eval:smoke
bun run eval:fallback
bun run eval:live
bun run eval:live-memory
bun run eval:live-auto-memory
bun run eval:live-provider-memory
bun run eval:summary

含义:

  • eval:smoke:测试工具自检。
  • eval:fallback:不调用在线模型的确定性验证。
  • eval:live:使用内存后端的在线生成器与在线评审器。
  • eval:live-memory:使用自动存储语义的在线生成器与在线评审器;除非解析到提供方存储,否则默认使用本地 SQLite。
  • eval:live-auto-memory:当脚本需要明确指定自动存储时,作为 eval:live-memory 的别名。
  • eval:live-provider-memory:使用提供方支持的证据路径,需要 Postgres、嵌入和辅助提取;不会静默回退到 SQLite。
  • eval:summary:汇总现有评估输出目录。

在线评估环境变量:

  • GOODMEMORY_EVAL_PROVIDER
  • GOODMEMORY_EVAL_BASE_URL,用于 OpenAI 兼容网关
  • GOODMEMORY_EVAL_MODEL
  • GOODMEMORY_EVAL_API_KEY
  • GOODMEMORY_EVAL_MAX_CONCURRENCY 可选并行度上限
  • GOODMEMORY_JUDGE_PROVIDER
  • GOODMEMORY_JUDGE_BASE_URL,用于 OpenAI 兼容网关
  • GOODMEMORY_JUDGE_MODEL
  • GOODMEMORY_JUDGE_API_KEY

eval:live-memory 和 eval:live-auto-memory 还需要嵌入和辅助提取器配置:

  • GOODMEMORY_EMBEDDING_PROVIDER
  • GOODMEMORY_EMBEDDING_BASE_URL,用于 OpenAI 兼容网关
  • GOODMEMORY_EMBEDDING_MODEL
  • GOODMEMORY_EMBEDDING_API_KEY
  • GOODMEMORY_ASSISTED_EXTRACTOR_PROVIDER
  • GOODMEMORY_ASSISTED_EXTRACTOR_BASE_URL,用于 OpenAI 兼容网关
  • GOODMEMORY_ASSISTED_EXTRACTOR_MODEL
  • GOODMEMORY_ASSISTED_EXTRACTOR_API_KEY

eval:live-provider-memory 还需要:

  • GOODMEMORY_TEST_POSTGRES_URL

输出目录:

  • 在线运行:reports/eval/live/run-*
  • 自动存储的在线记忆运行:reports/eval/live-memory/run-*
  • 提供方支持的在线记忆运行:reports/eval/live-provider-memory/run-*
  • 回退运行:reports/eval/fallback/run-*

策略推出

GoodMemory 将 rules-only 作为受支持的基线。新的检索行为会依次经过 observe -> assist -> promote。

操作指南:

  • observe:收集隔离的影子证据,不改变实际执行路径。
  • assist:允许在受控评估运行中执行候选方案。
  • promote:需要 strategy-promotion-gate.json、干净的 regression-dashboard.json,以及 strategy-promotion-authorization.json。
  • 如果评估证据不完整、提供方支持的依赖不可用,或存在回滚条件,请保持 rules-only。

当前状态

当前稳定的公开接口:

  • 通过 goodmemory 提供的根记忆 API
  • 通过 goodmemory/ai-sdk 提供的 AI SDK 适配器
  • 通过 goodmemory/host 提供的宿主适配器和宿主契约
  • 通过 goodmemory/http 提供的 HTTP 桥接 API,以及打包的 goodmemory-http-bridge
  • 已安装的 CLI 和通过 goodmemory setup 管理的宿主设置
  • 用于召回的 Codex 和 Claude Code hooks
  • 用于检查和调试的只读 MCP
  • 可选择启用的已安装宿主回写,支持审计和撤销
  • Bun 上的本地 SQLite 持久化回退
  • 在配置后支持 Postgres、嵌入、辅助提取和由提供方支持的评估

内部 API、记忆、召回和 CLI 编排按照 ADR-009 中的职责边界进行了拆分。这是一项保持行为不变的维护变更:公开 API/CLI 输出、默认值、持久化顺序、回退、跟踪和序列化契约均保持不变。HTTP 桥接、已安装宿主回写和基准测试声明策略不在此次重构范围内。

仍不属于已接受的公开声明范围:

  • 默认启用的自动回写
  • 原始对话记录归档
  • 仪表板或托管云服务
  • 将导出的制品文件视为规范存储
  • 扩大根导出范围,纳入内部提案或晋升机制

有关当前状态和证据的详细映射,请参阅 docs/GoodMemory-Current-Status-and-Evidence.md。

文档

有关执行顺序、待处理后续工作和各阶段的验收边界,请参阅 task-board/00-README.txt。归档的设计输入并非当前依据,相关内容请通过 docs/README.md 查阅。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。