跳到正文
Hacker News· gonzar79·· 7 天前AI 评分62

IHMT:面向 AI 编码智能体的无限层级记忆树开源发布

Show HN: IHMT – Infinite Hierarchical Memory Tree for AI Agents

AI 导读

作者发布 IHMT(Infinite Hierarchical Memory Tree),一个以本地纯文本文件树存储的 LLM 长期记忆系统,作为 stdio MCP server 接入 Claude Code、Codex 和 opencode,多个智能体可共享同一份记忆。

正文 · AI 翻译

IHMT — 无限层级记忆树

Listed on mcpservers.org

为你的 AI 编程代理提供长期记忆。只需告诉你的代理一次——某个决定、你的环境如何运作、某个更正——它就会在未来的每个会话、任何项目、任何代理中记住它。

IHMT 的功能

  • 跨会话记忆。决定及其原因、你的环境、你的偏好、人物和项目、更正。你的代理在回答前会搜索记忆,并保存持久的内容,这样你就不必反复重复。
  • 所有代理和模型共享一份记忆。Claude Code、Codex 和 opencode 可以共享同一份记忆:一个保存的内容,其他都能找到。已用来自 Anthropic、OpenAI、Google 和 Meta 的模型测试。
  • 节省 token。无需每个会话都粘贴你的笔记或重新解释上下文,代理只检索问题所需的内容——通常 200–900 个 token,无论记忆中有 50 条还是 50,000 条,因为搜索是遍历树而不是读取全部内容。 诚实的数字,包括它不节省的情况。
  • 理解时间。当某些内容发生变化(“我搬到了 Valencia”,“staging 现在用的是 PostgreSQL 17”)时,旧记忆会作为历史保留,标记为 OUTDATED,搜索时会优先用当前记忆回答。你居住的地方、工作的地方和技术栈会被自动跟踪;任何其他更正会在代理用 replaces 保存时被关联。当问题有歧义时(“Luis”——哪一个?),它会询问而不是猜测。
  • 可移植。你的记忆就是一个纯文本文件夹。把它复制到另一台电脑、备份,或纳入版本控制——放在哪里都能用。
  • 本地、私密、可读。没有云、没有数据库、没有账户:IHMT 把所有内容存在你的磁盘上,不向任何地方发送任何东西。(你的代理检索到的记忆会像其他上下文一样到达其模型。)每条记忆都是你可以打开的文本文件,每个安装 IHMT 的人都从自己的空记忆开始。

兼容性。官方支持:Claude Code。也已测试:Codex(CLI 和 ChatGPT 桌面应用——设置)和 opencode (设置)。IHMT 是一个标准的 stdio MCP 服务器,所以任何支持本地 MCP 服务器的代理都应该能用——GitHub Copilot、Antigravity、Cursor、Windsurf、Gemini CLI、Claude Desktop……——并且 INSTALL.md 知道如何配置它们,但我们尚未测试这些。它们都可以共享一份记忆。

安装

开始之前

你需要 为什么
Python 3.10 或更新版本 IHMT 是用 Python 编写的
git 用于下载 IHMT 并保持更新
一个能运行命令的 AI 代理(Claude Code、Codex、opencode、agent 模式下的 Copilot……) 它安装 IHMT 然后使用记忆
安装期间需要联网 用于下载代码和 MCP 包;之后不再需要

缺少 Python 或 git?你的 AI 代理会为你安装(它被指示先询问你)。 Python 会安装到你的用户文件夹,无需管理员密码,因此不会更改系统范围内的任何内容。在全新的 Mac 上,git 可能需要点一下: Apple 会显示一个窗口,要求安装其命令行工具。

在 Mac 上,请注意 macOS 自带的 python3 是 3.9 版本,太旧了——这就是为什么即使 python3 存在,你的代理也可能说缺少 Python。

你不需要管理员权限、数据库、账户,也不需要除你的 agent 之外的任何付费服务。已在 macOS 和 Linux(Ubuntu)上测试;在 Windows 上包含说明但尚未测试。详情:GUIDE.md §3。

让你的 AI agent 来安装它

把这段内容粘贴到你想要赋予记忆的 AI agent 中——Claude Code、Codex 和 opencode 已测试;GitHub Copilot、Antigravity、Cursor、Windsurf、Gemini CLI、Claude Desktop 以及其他 MCP 客户端应该也能用:

Install the IHMT memory MCP server for me from https://github.com/gonzaroman/IHMT-MEMORY — follow the instructions in its INSTALL.md.

agent 会遵循 INSTALL.md:它将 IHMT 下载到 ~/IHMT-MEMORY,把你的记忆保存在 ~/.ihmt,仅向自身注册该服务器,添加使用说明,并告诉你它做了什么。然后启动一个新会话,以便加载记忆工具。

使用多个 agent? 随时把同样的提示词粘贴到每一个中。如果 IHMT 已经安装——比如你已经用 Claude 用了几个月,现在想在 Codex 中使用——agent 会找到那个安装,在能安全操作时更新它,并连接到同一份记忆,因此它从第一天起就知道你告诉过其他 agent 的内容。

它需要一个能运行终端命令或编辑文件的 agent;浏览器中仅能聊天的助手无法安装任何东西。

手动安装

要求:Python 3.10+、git,以及你的 agent 的 CLI。

git clone https://github.com/gonzaroman/IHMT-MEMORY.git ~/IHMT-MEMORY
cd ~/IHMT-MEMORY
python3 -m venv .venv
.venv/bin/pip install -r requirements-mcp.txt
mkdir -p ~/.ihmt

Claude Code

claude mcp add ihmt-memory -s user -e IHMT_HOME="$HOME/.ihmt" -- "$PWD/.venv/bin/python" "$PWD/mcp_server.py"
claude mcp list                     # ihmt-memory … ✔ Connected

服务器名称必须位于 -e 之前。然后将 templates/memory-instructions.md 追加到 ~/.claude/CLAUDE.md。

Codex — codex mcp add ihmt-memory --env IHMT_HOME="$HOME/.ihmt" -- "$PWD/.venv/bin/python" "$PWD/mcp_server.py",然后将 default_tools_approval_mode = "approve" 添加到 ~/.codex/config.toml 中的 [mcp_servers.ihmt-memory] 表(位于其 env 表之上),并将模板追加到 ~/.codex/AGENTS.md。详情。

opencode — 向 ~/.config/opencode/opencode.json 的 "mcp" 对象添加一个 "ihmt-memory" 条目("type": "local"、"command": [<python>, <mcp_server.py>]、"environment": {"IHMT_HOME": <memory folder>}),并将模板追加到 ~/.config/opencode/AGENTS.md。详情。

Windows、项目范围、图形化设置和故障排除都在指南中。

新手?请阅读 GUIDE.md——日常使用,一步一步,附真实输出。本 README 的其余部分是技术参考。


工作原理

一种通用、与领域无关的 LLM 长期记忆,以本地磁盘上的纯文件递归树形式存储。没有向量数据库,没有服务器,没有第三方依赖——只需 Python 3.10+ 和标准库。

IHMT 不是把所有内容嵌入到一个扁平索引中并扫描它,而是将知识组织成一棵树:底部是原始文本叶子,其上是递归的 JSON 摘要,顶部是一个单一的 root.json 主干。查询会沿着这棵树行走——根 → 分支 → 分支 → 叶子——因此打开的文件数量随树的深度(≈ beam × log_B(n))增长,而不是随存储量增长。

扁平 RAG IHMT
检索成本 对所有 n 个块进行扫描 / ANN beam × log_B(n) 次文件读取
结构 无——一堆向量 显式层级,可检查
分块 固定字符窗口 语法、场景和日期感知
过时事实 静默提供 被取代、标注日期并标记
歧义 返回一个看似合理的猜测 向你询问线索
存储 二进制索引 UTF-8 .txt + 可读的 JSON

快速开始

python3 gui.py                       # graphical interface: set up, browse, inspect
python3 init_ihmt.py                 # or from the terminal: create ./ihmt_memory
python3 main.py demo                 # full walkthrough in ./demo_workspace
python3 -m unittest discover -v      # stdlib only; MCP tests skip without the SDK

然后在你自己的材料上使用它:

python3 main.py ingest ~/notes ~/project/src/Main.java
python3 main.py consolidate --force
python3 main.py search "how did we handle stock reservations"
python3 main.py ask "Luis"                    # interactive clue loop
python3 main.py conflicts                     # what changed over time

作为库:

from ihmt import IHMT

memory = IHMT.initialize("./workspace")
memory.ingest_file("examples/InventoryService.java")
memory.ingest_file("examples/journal_personal.txt")
memory.flush()                                # close the tree up to the root

answer = memory.search("reserveStock soft hold")
print(answer.best.content)                    # the leaf
print(answer.best.path)                       # ['root', 'N1-software.java-…', 'L-software.java-…']
print(answer.node_reads)                      # how many branch files were opened

for notice in memory.notices():
    print(notice)   # "On 2024-03-11 you said user location = 'Madrid', but on 2026-02-03 you updated to 'Valencia'."

图形界面

python3 gui.py                       # opens a browser at 127.0.0.1
python3 gui.py --path ~/my-memory --port 8765 --no-browser

仍然零依赖——服务器是标准库中的 http.server,它只监听回环接口,并且每次 /api/* 调用都需要它打开的 URL 中携带的随机令牌。

四个界面:设置(用系统对话框选择记忆文件夹,创建存储,在按项目注册和全局注册之间选择,在写入任何内容之前预览确切的命令或 JSON)、浏览(可折叠的树,向下到存储的文本,带有取代通知)、诊断(一个报告置信度、已打开文件数与总数、以及下降路径的搜索),以及时间线(活跃值与历史值以及检测到的矛盾)。界面是双语的(ES/EN),并且对记忆是只读的:它从不删除或编辑叶子。


从 Claude Code(MCP)使用它

mcp_server.py 将树作为三个家族中的九个工具暴露给 Claude Code:长期记忆、项目索引和会话暂存记忆。核心保持无依赖;SDK 是可选的附加项:

python3 -m venv .venv
.venv/bin/pip install -r requirements-mcp.txt        # mcp[cli]>=2.0

对于单个项目,将 .mcp.json.example 复制到该项目的 .mcp.json 并填写绝对路径;Claude Code 会在那里的下一次会话时要求你批准它(在此之前,claude mcp list 将其显示为待批准):

{
  "mcpServers": {
    "ihmt-memory": {
      "command": "/absolute/path/to/IHMT-MEMORY/.venv/bin/python",
      "args": ["/absolute/path/to/IHMT-MEMORY/mcp_server.py"],
      "env": { "IHMT_HOME": "/absolute/path/to/IHMT-MEMORY" }
    }
  }
}

或者用一条命令:

claude mcp add ihmt-memory --scope user \
  -e IHMT_HOME=/absolute/path/to/IHMT-MEMORY \
  -- /absolute/path/to/IHMT-MEMORY/.venv/bin/python /absolute/path/to/IHMT-MEMORY/mcp_server.py

IHMT_HOME 选择存储($IHMT_HOME/ihmt_memory),在首次使用时创建。将所有项目指向一个共享目录以获得单一的跨项目记忆,或者给每个项目自己的目录。

工具 行为
search_memory(query, clue=None, detail="compact") 遍历树。紧凑输出:最佳记忆及其日期和 OUTDATED 通知,其他匹配每行一个;detail="full" 添加 id、树路径和摘录。模糊查询返回一个 AMBIGUOUS 块列出候选,而不是猜测——用 clue 再次调用。没有匹配的查询会说明这一点,最接近的条目只与它共享一个无关词的查询也会说明这一点(NOT FOUND)。
save_memory(content, domain="general", content_type="auto", replaces="") 对文本进行分类、拆分和存储,提取带日期的事实,并保持树合并。报告它是如何归档的,以及——如果保存与之前记住的内容矛盾——要转达给用户的通知。使用 replaces(几个词描述一个较早的记忆)时,保存被记录为它的更正:旧记忆被标记为 OUTDATED,搜索首先用新记忆回答。
mark_outdated(old_id, new_id) 将一个记忆标记为被另一个更正,当 save_memory 为 replaces 找到多个候选并列出它们的 id 时。
project_map(path, detail="files", subpath="") 代码库的紧凑映射:文件及其以 token 计的大小,以及使用 detail="symbols" 时,每个方法及其行范围。从同步清单构建,不打开叶子。
find_code(query, path, scope="main", subpath="", clue=None, max_tokens=1500) 只返回回答查询的符号,作为 file:first-last + 代码。scope 是 main(跳过测试)、test 或 all。
read_file(path, force=False) 读取一个文件并记住它本次会话分发了什么:重复读取回答 UNCHANGED 或仅一个统一 diff。
note(text) / recall(query, clue=None) 会话暂存记忆:在上下文压缩后存活,在会话结束时消失。
digest_output(text, label="output") 将长日志浓缩为其首行、错误、失败、测试总计和末行;全文仍可召回。

在会话内节省 token

长期记忆在会话之间节省 token。项目工具在会话内节省它们,其中成本是反复读取相同的文件。ProjectIndex(ihmt/project_index.py)在 $IHMT_PROJECTS_DIR 下为每个项目保留一个私有存储(默认 $IHMT_HOME/ihmt_projects):

  • 每个符号一个叶子——code_chunk_mode="symbol",因此查找返回一个方法,而不是一个文件;
  • 每次调用时校验和同步——先看大小和 mtime,仅对移动过的内容做 SHA-256;更改的文件被重新摄取,删除的文件被删除,分支被重建。代码从不提供过时的;
  • 路径排序的分支——每个文件被标记其在路径顺序中的排名,因此每个分支覆盖相邻文件,其摘要对下降保持有意义;
  • 代码感知排序 — 导航器根据目录中的 scope/path_prefix 进行过滤,优先选择查询中提到的文件,除非被要求否则降低测试的优先级,并降低 import 行的优先级。

在一个 55 个文件的 Spring Boot 项目上测量(8 个典型问题):读取包含答案的文件需要 3,613 个 token;find_code 在 1,071 个 token 内为全部 8 个问题返回确切的方法。项目地图需要 660 个 token,而完整读取它需要 13,157 个 token。

这些节省是相对于读取整个文件的 agent 而言的。在一项包含 22 个真实无头 Claude Code 会话的 A/B 测试中,Claude 更偏好批量 grep/sed -n,并且从不自行调用项目工具;强制调用它们会使会话成本增加 42–71%。保持服务器启用每轮对话约花费 460 个 token,因为 Claude Code 按需加载 MCP 工具。IHMT 的主要价值在于会话之间的记忆;将项目工具视为可选,不要在 CLAUDE.md 中强制要求它们。

该服务器透明地支持 MCP SDK 2.x(MCPServer)、1.x(FastMCP)以及独立的 fastmcp 包。

你的 ~/.claude/CLAUDE.md(模板)中的使用说明告诉 Claude Code 何时使用每个工具:在回答任何依赖先前会话的问题之前先搜索,保存持久事实时附带其日期,在 AMBIGUOUS 上绝不猜测,始终转发 OUTDATED,并且绝不存储机密。


存储布局

所有内容都存放在一个可重定位的目录中:

ihmt_memory/
  root.json                 # the trunk: domains, topics, top branches, counters
  layer_0/<domain>/*.txt    # the leaves: raw UTF-8 text + a strict JSON header
  layers/1/*.json           # branches: summaries of leaves
  layers/2..N/*.json        # branches: summaries of summaries
  state/catalog.json        # index: id -> path, domain, parent, timestamp
  state/facts.json          # the fact timeline
  ihmt.config.json          # branch factor, token budgets, backend

root.json 位于 ihmt_memory/ 内部,因此存储是自包含的:复制该目录,记忆也随之迁移。

叶子节点是一个描述自身的普通文本文件,因此即使目录丢失它仍然有意义:

<<<IHMT-META
{
  "leaf_id": "L-software.java-0001-84130ee123",
  "timestamp": "2026-09-09T17:45:00Z",
  "data_type": "CODE",
  "domain": "software.java",
  "tags": ["method:reserveStock", "class:InventoryService", "lang:java", "type:code"],
  "parent_id": "N1-software.java-5571a7baac",
  "span": {"start_line": 43, "end_line": 68},
  "checksum": "sha256:…",
  "extra": {"context": "public final class InventoryService {"}
}
IHMT-META>>>
    public Optional<String> reserveStock(Sku sku, int quantity) {
        …

分支节点嵌入每个子节点的标题、摘录和关键词。正是这一细节使得下降过程成本低廉:一个分支可以在不打开任何子节点的情况下被排序。


五个组件

1. UniversalIngestor — 检测、拆分、丰富、存储

DomainDetector 根据扩展名以及英语和西班牙语的词汇特征,将每个文档按类型(CODE、NARRATIVE、CLINICAL、PERSONAL、PROCESS、GENERIC)和领域(software.java、medicine.clinical、process.cooking、personal、……)进行分类。两者都可以用 --domain / --type 覆盖。

类型决定拆分器,而每个拆分器都遵循一个不变式:

逻辑块绝不被切断。如果单个块超过 max_tokens,则整体存储并标记为 oversized。块的正确性优先于达到 token 预算。

  • 代码(chunkers/code.py)— Python 通过标准库 ast;Java/JS/TS/C/C++/C#/Go/Rust/Kotlin/Swift/PHP 通过 BraceScanner,这是一个字符级扫描器,在跳过注释、字符串字面量、字符字面量、模板字面量和预处理器行的同时跟踪花括号深度。import 会被合并;每个类/函数是一个块;过大的类按每个成员拆分,而外层类头随叶子的 extra.context 一起传递,而不是被拼接到文本中。将文件的叶子节点拼接起来可以逐字节重现该文件——这一点在测试中已断言。
  • 叙述性文本 — 段落原子化,以 ***、---、Chapter/Capítulo 作为硬边界。只有大于 max_tokens 的段落才会被拆分,且按句子边界拆分。
  • 时间性(日志、聊天、临床记录)— 一条带日期的条目是原子的,日期变化是硬边界,因此一个叶子节点绝不会混合两次相遇。文本中找到的日期成为叶子节点的时间戳,这正是使新近度加权意味着某事何时为真而非何时被摄取的原因。
  • 流程(配方、协议、操作手册)——步骤和配料清单始终与其标题保持关联。

叶子 id 派生自 (domain, source, position, content),因此重新摄取未更改的文档会重写相同的叶子,而不是复制它们。

2. RecursiveSummarizer —— 摘要事件

它监视第 0 层。当一个域中的 branch_factor 个叶子没有父节点时,它会触发一个 摘要事件:它们被压缩为一个第 1 层节点,该节点被写入,只有在这之后 子节点才会被标记上它们的 parent_id —— 因此中断的运行会重新处理一个组, 而不是将其孤立。同样的规则适用于从第 1 层到第 2 层,依此类推,直到树收敛; 然后 root.json 被重写。

consolidate() 是幂等的。flush()(--force)也会提升部分组,以便树完全闭合。 任何仍未合并的内容都由主干直接引用,因此存储中的任何内容 都不会从根节点不可达。

3. SemanticNavigator —— 下降与交互式线索循环

排序使用 Okapi BM25 对每个候选的标题、关键词、标签和摘要进行评分,字段权重 和文档频率在当前层的兄弟节点之间计算 —— 这正是 下降所需的区分度,且没有额外的 I/O 成本。遍历在每一层保持一个 beam_width 分支的束。

置信度融合了两个独立的信号:

confidence = 0.6 × coverage + 0.4 × margin

覆盖率问的是“这个叶子是否真的包含所询问的内容?”;边际问的是“它 是否能与竞争对手区分开来?”。一个常见的名字在第一项上得分很高,而在第二项上 接近零 —— 这正是系统绝不能猜测的时候:

$ python main.py ask "Luis"

"Luis" is ambiguous (3 memories match this query equally well, confidence 0.62).
It could belong to any of these branches:
  1. [personal] journal_personal.txt · 2024-07-22 — Vacaciones en Benidorm con Luis, mi primo…
  2. [personal] journal_personal.txt · 2026-08-30 — Fin de semana en la playa de El Saler con Luis…
  3. [personal] journal_personal.txt · 2024-11-30 — Cierre de trimestre… Luis Marín revisó el pull request…
Give me a clue to narrow it down (e.g. a place, a date, a project):
> vacaciones en Benidorm

query: "Luis + vacaciones en Benidorm" · confidence 0.74 · 5 node reads, 3 leaf reads, depth 2
  1. [personal] journal_personal.txt · 2024-07-22
     path  root → N2-personal-ea34db33ae → N1-personal-59bf8bc291 → L-personal-0002-a17b3c8f35

线索触发一个联合交叉引用:同时匹配两个词组的候选被提升 (×1.6),只匹配一个的候选被降级(×0.7)。循环最多运行 max_clue_rounds 次,如果用户拒绝则提前停止,并且绝不会默默地将一个模糊查询转换为一个 自信的答案。

clue_provider 是任何可调用对象,因此该循环适用于终端前的人类(input)或 让 LLM 提供自己的后续问题的代理。

4. ConflictResolver —— 新近度加权与时间线

事实是 (subject, attribute, value, timestamp, source_leaf),通过 record_fact() 以编程方式记录,或在摄取时通过模式规则提取(vivo en X / I live in X, mi stack es Y,trabajo en Z,Diagnóstico:,Tratamiento:,Medicación: …;用 add_pattern 扩展)。

每个 (subject, attribute) 保留一个带日期的时间线。最新的值是 ACTIVE;每个更早的值 变成 HISTORICAL,带有 superseded_by 和一个 valid_from/valid_to 区间。没有任何内容被 删除,因此两个问题都保持可回答:

memory.resolver.active_state()["user::location"].value      # 'Valencia'  (now)
memory.resolver.state_at("2024-12-31")["user::location"].value  # 'Madrid'  (back then)

在较晚的日期重复一个值是确认,而不是矛盾。真正的变化会产生一个 透明的通知 —— “在 2024-03-11 你说用户位置 = 'Madrid',但在 2026-02-03 你更新为 'Valencia'。” —— 并且被取代的叶子会被标注,因此检索过时的材料时总是 附带其更正(SearchResult.notices)。

叶子本身保持 ACTIVE:它所说的在其自身日期是真实的,并且这仍然是 历史问题的正确答案。变化的是它不能再被解读为当前信息。

5. 摘要后端

class SummarizerBackend(Protocol):
    name: str
    def summarize(self, children, *, domain: str, layer: int) -> NodeSummary: ...
  • HeuristicSummarizer(默认)—— 标准库提取式摘要:使用 EN/ES 停用词的 TF 词项排名 加上代表性句子选择。离线、确定性,这正是测试 套件能够对树形结构进行断言的原因。
  • AnthropicSummarizer(可选)—— 仅在选中且 anthropic 包和 ANTHROPIC_API_KEY 都存在时使用。每条失败路径(缺少 SDK、缺少密钥、网络错误、 无法解析的回复)都会回退到启发式后端,因此合并绝不会因为 模型不可达而丢失。
python3 init_ihmt.py --backend anthropic     # model set by summarizer_model in ihmt.config.json

任何其他模型或本地运行时只要实现同一协议并把它作为 IHMT(..., backend=MyBackend()) 传入,就能接入。


CLI 参考

命令 用途
init [--branch-factor N] [--target-tokens N] [--force] 创建存储
ingest <paths…|-> [--domain D] [--type T] [--tag X] [--no-consolidate] 摄取文件、目录或标准输入
consolidate [--force] 运行待处理的摘要事件
search <query> [--top-k N] [--full] 遍历树
ask <query> [--clue TEXT] [--top-k N] 用线索循环进行搜索
tree [--depth N] 层级大纲
stats、facts [--subject S]、conflicts [--subject S] 检查
rebuild 从文件重建目录、时间线和主干
demo 端到端演练

--path 选择存储目录,--json 输出机器可读的结果;两者在子命令之前或之后都可用。

配置

ihmt_memory/ihmt.config.json:

键 默认值 含义
branch_factor 8 每个分支的子节点数;检索开销的对数底数
target_tokens / max_tokens 2000 / 3000 叶节点大小目标和超大阈值
beam_width 3 每层保持存活的分支数
confidence_threshold 0.45 低于此值,就请求线索
ambiguity_margin 0.18 低于此分数差距的候选视为并列
max_clue_rounds 3 线索循环迭代次数
summarizer_backend / summarizer_model heuristic / claude-sonnet-5 摘要
code_chunk_mode pack symbol 为每个类成员存储一个叶节点(供项目索引使用)

小语料库适合小的分支因子——演示使用 branch_factor=4, target_tokens=400,这样少量文档仍能构建出真正的多层树。

测试

python3 -m unittest discover -v          # from the project root

187 项测试——其中 25 项针对 MCP 服务器,在没有 SDK 时跳过——覆盖:Java 和 Python 的字节级精确重建与边界深度不变量、场景/日期/章节原子性、超大块处理、叶节点头部往返、目录恢复、摘要阈值、向上传播、幂等性、从根节点的完全可达性、下降成本界限、线索循环、新近度加权、历史保留、项目索引、MCP 工具、图形界面和 CLI。

设计说明与限制

  • 检索是下降,不是扫描。这正是关键所在,这意味着在主干处被剪掉的分支不会被重新访问。只有当查询在主干处有实际信号时,才会进行领域级剪枝;如果没有信号,所有领域都保持参与,束搜索在下一层应用。当下降范围过宽时,线索循环就是恢复机制。
  • 词法匹配,而非语义匹配。匹配是在去除重音、按 CamelCase 拆分后的词元上运行 BM25:它适用于任何语言且无需模型,但无法匹配同义词。将嵌入重排序器接入 BM25Ranker 是自然的升级方式;树结构不会改变。
  • 词元数是估算的,约为每词元 4 个字符。预算只需保持一致,不必精确。
  • 事实提取基于模式。内置规则覆盖常见的英语/西班牙语表述和临床标题;record_fact() 是可靠的路径,add_pattern() 可扩展规则。
  • 单写入者。写入是原子的(tmp + os.replace),目录重建会获取锁文件,但存储假定一次只有一个写入者。
  • initialize(force=True) 只丢弃派生状态——分支、目录、时间线——并分离存活的叶节点,以便下一次合并重建层级。叶节点内容永远不会被删除。

布局

ihmt/
  api.py                    IHMT facade wiring everything together
  config.py                 IHMTConfig
  models.py                 MemoryLeaf, BranchNode, ChildRef, RootIndex, Fact, Contradiction
  storage.py                MemoryStore: atomic I/O, catalog, recovery
  textutils.py              tokenizing, keywords, entities, extractive summary, timestamps
  detectors.py              DomainDetector
  chunkers/                 base · code · narrative · temporal · process · generic
  summarizers.py            SummarizerBackend · Heuristic · Anthropic
  universal_ingestor.py     UniversalIngestor
  recursive_summarizer.py   RecursiveSummarizer
  semantic_navigator.py     SemanticNavigator, BM25Ranker, ClueRequest, scope/path filters
  project_index.py          ProjectIndex: per-project code cache with checksum sync
  conflict_resolver.py      ConflictResolver + timeline manager
ihmt_gui/                   local graphical interface (stdlib only)
mcp_server.py               MCP server: the nine tools
init_ihmt.py · main.py · gui.py · examples/ · tests/
GUIDE.md                    installation and usage guide
INSTALL.md                  installation instructions for AI agents
templates/                  memory-instructions.md: the usage rules agents append to CLAUDE.md / AGENTS.md

许可证

MIT © 2026 Gonzalo Román Márquez (gonzaroman)

来源:Hacker News · github.com