腾讯开源 Hy Memory 2.0:它不再把智能体记忆当成一份聊天记录

·11 分钟阅读·Evergreen Tools Team

10 月 16 日,腾讯混元把 Hy Memory 2.0 整个栈开源了:一个 30B-A3B 的记忆模型(连带 FP8 和 GGUF 量化版)、hy-memory 这个 Python SDK,以及 MemHub 一个本地优先的桌面应用。Apache 2.0,全部在 GitHub 上。开源记忆框架这两年会经常看到,我原本以为又是个向量库加个摘要器,直到看到它的场景划分:聊天、工作、编码是三套完全不同的流水线,而不是一个库加个 scene 字段。这个决定改变了整套系统的形状。

数据中心机房里成排的服务器

三层栈同时开源:模型、框架、应用。缺一层,记忆就只能停在演示阶段。

先看清装的是什么

三层东西:模型(Hy-Memory-30B-A3B,HuggingFace 上有权重,技术报告在 arXiv)、框架(hy-memory==2.0.4,PyPI)、应用(MemHub,v1.0.4 加 memhub-cli 1.0.5,有签名的 macOS 应用)。默认存储是 ChromaDB + Kuzu + SQLite,可以换 Qdrant、FAISS、Neo4j、MySQL。

好消息是它不绑定腾讯自己的 API:只需要一个 LLM 端点和一embedding 端点,任何 OpenAI 兼容服务都行。我拿 DeepSeek 做 LLM、阿里百炼做 embedding,直接就跑起来了。

一个必须先说清的坑:记忆写入会调用 LLM。这意味着「摄取」这一步入有成本、也有失败模式,和大部分人习惯的「向量库 + upsert」是完全不同的预算形状。

# Install is one line. The interesting part is what the package expects of you.
# Apache 2.0, current release 2.0.4. Default storage is ChromaDB + Kuzu + SQLite.

pip install hy-memory==2.0.4

# Optional backends, if you already run them:
#   pip install "hy-memory[qdrant]==2.0.4"
#   pip install "hy-memory[faiss]==2.0.4"
#   pip install "hy-memory[graph]==2.0.4"     # Neo4j instead of Kuzu
#   pip install "hy-memory[mysql]==2.0.4"
#   pip install "hy-memory[rerank]==2.0.4"

# You need an LLM endpoint and an embedding endpoint, both OpenAI-compatible.
# Any provider works; nothing is hard-wired to Tencent's own API.
export MEMORY_LLM_API_KEY="sk-..."
export MEMORY_LLM_BASE_URL="https://api.deepseek.com"
export MEMORY_LLM_MODEL="deepseek-chat"

export MEMORY_EMBEDDER_API_KEY="sk-..."
export MEMORY_EMBEDDER_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
export MEMORY_EMBEDDER_MODEL="text-embedding-v3"
export MEMORY_EMBEDDING_DIMS=1024

# One caveat before you point this at production: memory writes call an LLM.
# That means ingestion has a cost and a failure mode, which is the opposite of
# the vector-store-plus-upsert story most teams are used to budget for.

三个模式,选错是最常见的错误

lite 只做原始向量写入和检索,零 LLM 调用,scene 和 layers 参数会被忽略;pro 加上 LLM 抽取和冲突消解;ultra 再加 System 2 的模式归纳和跨域清扫。

我的建议是先 lite 把管道跑通,等到检索质量真的让你烦了再往上走。上来就开 ultra 因为「听起来更强」,通常的结局是先发现 embedding 账单,再发现检索延迟。

还有一个细节值得注意:search 返回的不是一个平铺的列表,而是三个通道——profile(这个用户是谁)、normal(相关条目)、proactive(你没问但该看见的东西)。这个形状本身就是设计,不是随手分的。

# Three modes, and picking the wrong one is the most common mistake.
#
#   lite  -> raw embedding only, zero LLM calls, scene and layers ignored
#   pro   -> adds LLM extraction and conflict reconciliation
#   ultra -> adds System 2 schema induction across domains (use evolve())
#
# Start with lite to prove the plumbing, then move up when the recall quality
# actually annoys you. Starting on ultra because it sounds better is how people
# discover their embedding bill before they discover their retrieval latency.

from hy_memory import HyMemoryClient

client = HyMemoryClient(mode="pro")

# Write: a plain string, or OpenAI-format messages. Both are supported.
client.add("I love sci-fi movies, especially Interstellar", user_id="user_1")
client.add([
    {"role": "user", "content": "Recommend a movie"},
    {"role": "assistant", "content": "Try Interstellar — a sci-fi masterpiece by Nolan"},
], user_id="user_1")

# Search returns three channels, not one flat list. That shape is the point:
#   results["memories"]["profile"]    - who this user is
#   results["memories"]["normal"]     - relevant items
#   results["memories"]["proactive"]  - things you did not ask for but should see
results = client.search("What movies does the user like?", user_ids=["user_1"], limit=10)
for mem in results["memories"]["normal"]:
    print(f"  [{mem['score']:.2f}] {mem['content']}")

client.close()

八层记忆里,真正关键的是「不可变」这一条

L0 基本信息、L1 原始对话(只追加)、L2 原子事实(有版本、不可变)、L3 会话摘要、L6 心智模型(图图层)、L7 预期意图(带过期时间,过期后降级为普通事实)。L4 和 L5 留着备用。

绝大多数记忆系统的 bug 不是「向量检索没找到」,而是「返回了一条过时的事实,还当成当前状态」。所以 L2 的不可变加 supersede 链才是关键——用户搬家了,不是覆盖「他住在成都」,而是让旧事实被取代,链条还在。

这也是它必须做冲突消解而不能用 last-write-wins 的原因。如果你的系统里只有 upsert,那你其实没有事实,只有最近一次写入。

# The claim worth testing is the eight-layer hierarchy, L0 through L7.
# Not marketing: each layer is a different table with different write rules.
#
#   L0 BASIC_INFO   basic information
#   L1 RAW          raw conversation, append-only
#   L2 FACT         atomic facts, versioned and immutable
#   L3 SUMMARY      session summaries
#   L4 IDENTITY     reserved
#   L5 KNOWLEDGE    reserved
#   L6 SCHEMA       mental models (graph layer)
#   L7 INTENTION    prospective intentions, with an expiry
#
# The design consequence: L2 facts are immutable and versioned, so "the user
# lives in Chengdu" does not get overwritten when they move, it gets superseded.
# That is why conflict reconciliation exists instead of last-write-wins.
#
# Why this matters for retrieval quality: most memory bugs are not "the vector
# search missed it". They are "the store returned a stale fact as current".
# Immutability plus a supersede chain is the standard fix, and it is baked in
# rather than bolted on by hand.

from hy_memory import HyMemoryClient

client = HyMemoryClient(mode="pro")
client.add("My address changed: I moved from Chengdu to Hangzhou last month",
           user_id="user_1")

# A well-built memory layer should answer the current state, not concatenate
# both facts into a paragraph and hope the reader sorts it out.
hits = client.search("Where does the user live now?", user_ids=["user_1"], limit=5)
for m in hits["memories"]["normal"]:
    print(f"[{m['score']:.2f}] {m['content']}")

client.close()
光纤线缆插在交换机端口上

聊天、工作、编码是三套流水线,不是一个向量库加个场景标签。

工作记忆和编码记忆是两层,不是一层

这两个场景只有在 pro 或 ultra 模式下才生效,而且写入必须带工具调用轨迹(tool_calls 或 role=tool)。这是硬要求:lite 模式会忽略 scene 参数,把所有东西当原始记忆存。

两层设计是我最想抄的部分。事实层(facts)记录这次会话做了什么——任务、方法、结果,每个会话恰好一条,没有阈值。经验层(experiences)记录下次遇到类似任务可以复用的做法——0 到 N 条,必须通过价值阈值。事实层保证做过的事被记住,经验层让学到的东西可复用,两层互相链接。

编码场景多出来的东西是版本演化链(diff chain)。为什么需要它?因为事实抽取故意不粘贴代码(预算花在更有信息量的坐标上,比如文件、函数、分支),于是被回退的版本永远不会出现在事实里,而它也不在工作树或 HEAD 上,事后根本读不回来。这条链用零 LLM 调用存下每个版本的真实 diff,正好补上摘要必然丢掉的信息。

# Working and coding memory only activate in pro or ultra mode, and writes
# must include a tool-call trace. That is a hard requirement, not a style note:
# lite mode ignores the scene argument entirely and stores everything raw.
#
# The three scenes, and why one pipeline would not cover them:
#
#   chat     small talk, preferences, personal info      -> L0-L7 hierarchy
#   working  docs, spreadsheets, research, analysis      -> facts + experiences
#   coding   code, debugging, tests, builds, SQL         -> same two layers
#                                                           + a diff chain
#
# The two-layer design is the part I would copy. Facts record what the session
# did (exactly one per session, no threshold). Experiences record what is
# reusable next time (zero to many, gated by a value threshold). One guarantees
# the work is remembered; the other makes what was learned reusable.

from hy_memory import HyMemoryClient

client = HyMemoryClient(mode="pro")

messages = [
    {"role": "user", "content": "Fix the timeout in the search client."},
    {"role": "assistant", "content": "", "tool_calls": [{
        "id": "call_1", "type": "function",
        "function": {"name": "apply_patch", "arguments": '{"path":"src/search.py"}'},
    }]},
    {"role": "tool", "tool_call_id": "call_1", "name": "apply_patch",
     "content": "Patch applied successfully"},
]

client.add(
    messages,
    scene="coding",                             # or "working"
    user_id="user_123",
    workspace_id="github.com/example/service",  # isolate per repo
    branch="fix/search-timeout",                # needs workspace_id
)

result = client.search(
    "Which timeout implementation was finally kept?",
    scene="coding",
    user_ids=["user_123"],
    workspace_id="github.com/example/service",
    branch="fix/search-timeout",
    limit=5,
)
result["facts"]          # fact layer
result["experiences"]    # experience layer
result["chain_block"]    # coding only, needs MEMORY_CODING_CHAIN_BLOCK_ENABLED
client.close()

MemHub 是大多数人真正会用的那块

它是一个本地优先的桌面应用加 CLI,把你已经授权的 AI 工具里的历史抓到一个本地目录里统一管理。官方文档列的支持范围包括 Claude Code、Cursor、Codex、OpenCode 和 Qwen Code。

在让它索引任何东西之前,我建议先做三个检查。

范围:一个能读编码轨迹的记忆工具,能读到源码,有时候还能读到粘进提示里的密钥。哪些仓库在范围内,要在第一次索引之前定,不是之后。

隔离:框架支持按来源分开(source 参数)并用 include_sources / exclude_sources 过滤。用它,别搞一个大混合池,否则你问 Codex 会话的时候会冒出 Cursor 时期的习惯。

成本:pro 模式下索引不是免费的,因为写入要调 LLM。先索引一周,测量,再决定。别在第一个下午索引两年的历史然后才去看账单。

最后说句实话。这是一个记忆运行时,不是一个记忆格式。如果你团队对「什么叫一个事实」都达不成共识,那这套流水线会非常忠实地把你们的分歧,整齐地存进八张规范化的表里。

# MemHub is the piece most people will actually touch day to day.
# It is a local-first desktop app plus CLI that pulls history from AI tools you
# already authorised and keeps it in one local directory.
#
# From the official docs, MemHub covers Claude Code, Cursor, Codex, OpenCode and
# Qwen Code. Current release is MemHub v1.0.4 with memhub-cli 1.0.5, and there
# is a signed macOS app plus verified macOS/Linux runtimes.

npx [email protected] --help
# then, per the MemHub README, point it at the tool sources you consent to
# and let it index into the local data directory

# Three practical checks before you let it index anything:
#
# 1. Scope. A memory tool that reads coding traces reads source code and
#    sometimes secrets pasted into prompts. Decide which repos are in scope
#    BEFORE the first index, not after.
#
# 2. Isolation. The framework separates memories by source (source="cursor",
#    "codex", "openclaw") and filters with include_sources/exclude_sources.
#    Use that instead of one mixed pool, or your Cursor habits will surface
#    while you are asking about a Codex session.
#
# 3. Cost. Indexing is not free in pro mode because writes call an LLM.
#    Index a week, measure, then decide. Do not index two years of history
#    on the first afternoon and check the bill afterwards.

# The honest framing: this is a memory *runtime*, not a memory *format*.
# If your team cannot agree on what a "fact" is, the pipeline will faithfully
# store your disagreement in eight well-normalised tables.
暗色背景上流动的代码字符

事实不可变、版本可追溯——这是记忆系统最常见 bug 的根治办法。

📌 常见问题 FAQ

Hy Memory 2.0 是什么时候开源的?许可是什么?

2026 年 10 月 16 日,腾讯混元宣布开放,Apache 2.0 许可。同时开源了三层:Hy-Memory-30B-A3B 模型权重(HuggingFace,另有 FP8 和 GGUF 量化版)、hy-memory Python SDK(PyPI,2.0.4)、以及 MemHub 应用。

必须用腾讯的模型或 API 吗?

不用。只需要一个 OpenAI 兼容的 LLM 端点和 embedding 端点,通过 MEMORY_LLM_* 和 MEMORY_EMBEDDER_* 环境变量配置。社区里常见组合是 DeepSeek 做 LLM 加其他厂商做 embedding。

lite、pro、ultra 三个模式怎么选?

lite 零 LLM 调用、只做原始向量检索,适合先验证管道;pro 加上 LLM 抽取和冲突消解,是常规工作负载的默认;ultra 再加 System 2 图图层和跨域归纳,由 evolve() 触发,需要图数据库。建议 lite → pro → ultra 逐步升,不要一次到位。

编码记忆和普通对话记忆到底差在哪?

编码场景和 working 用同一套两层结构(事实 + 经验),但多了版本演化链:记录同一段代码被改过几次、每次改了什么,存真实 diff 且不走 LLM。因为事实抽取刻意不存代码正文,被回退的版本否则无法复原。

MemHub 支持哪些工具?数据在本地吗?

官方文档列的是 Claude Code、Cursor、Codex、OpenCode 和 Qwen Code。MemHub 定位是本地优先(local-first),数据落在本地目录;当前版本 MemHub v1.0.4 加 memhub-cli 1.0.5,有签名 macOS 应用和验证过的 macOS/Linux runtime。具体隐私边界请读 MemHub README 原文。