mcpField
S
Semurg agent memory

Semurg agent memory

本地服务
one.semurg.io记忆与知识1今天更新

关于 Semurg agent memory

Semurg agent memory 是面向 AI Agent 的可自托管记忆层,将知识图谱、向量和图 RAG 结合起来。它适用于需要按范围存储和检索记忆并保留来源引用的编码 Agent 与应用。

主要功能

  1. 01存储文本、对话、段落、实体和关系
  2. 02通过 MCP 或 HTTP 工具检索记忆
  3. 03按范围组织共享或私有记忆
  4. 04为检索到的信息返回来源引用
  5. 05运行于用户管理的 Linux x86_64 硬件

适用场景

  1. 01在编码 Agent 会话间保存事实
  2. 02为不同范围或终端用户隔离记忆
  3. 03检索存储文档中的溯源信息

MCP 相关

在自托管节点上通过 Streamable HTTP MCP 端点提供记忆操作,并使用节点 API 令牌认证。可选的范围标头用于设定连接的默认记忆命名空间。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"io-semurg-agent-memory": {
"command": "uvx",
"args": [
"semurg"
],
"env": {
"SEMURG_URL": "<SEMURG_URL>",
"SEMURG_API_TOKEN": "<SEMURG_API_TOKEN>",
"SEMURG_SCOPE": "<SEMURG_SCOPE>"
}
}
}
}
启动命令uvx semurg
需要配置的环境变量
SEMURG_URLYour Semurg node (http://127.0.0.1:4000 by default)
SEMURG_API_TOKEN密钥Your node API token
SEMURG_SCOPEA default memory scope for this connection

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

安装包
pypisemurg0.1.6

工具

20

收录的工具列表 · 更新于 今天

参数类型必填说明
scopestring否命名空间。在同一节点上使用相同 scope 的 Agent 会共享这些事实;其他 scope 为私有。如果连接设置了 X-Semurg-Scope 标头,则此参数为可选。
user_idstring否可选的 END USER,作为你的键的一部分(一个应用,多个最终用户):此时你指定的每个 scope 都属于该最终用户,两个最终用户之间互不可见。按应用级别隔离,与 mem0 的 user_id 相同;每用户令牌仍是安全边界。如果连接设置了 X-Semurg-User 标头,该标头所指用户就是最终用户,传入不同的 user_id 会被拒绝。不得包含 ':',最多 256 字节。

详细介绍

Semurg

面向 AI Agent 的记忆层:在同一个引擎上实现知识图谱、向量和图 RAG,完全从零编写。可在自己的硬件上运行。本文面向编码 Agent,介绍如何安装节点、如何连接编码 Agent、Agent 通过 MCP 或 HTTP 调用的记忆工具、各客户端中的相同调用、Semurg 发布的内容,以及基于节点构建的应用应遵循的规则。本文中列出的每条命令、每个工具、路由和客户端调用都取自源代码,并在本文发布前经过核对;每个已发布版本的命令也都会实际运行验证。

安装节点

安装前须知:Semurg 可在配备 AVX2 或更新指令集的 Intel 和 AMD x86_64 处理器上运行,至少需要 2 个 CPU 线程和 4 GB 内存:使用安装程序时,支持 Ubuntu 24.04;其他 x86_64 Linux 系统可通过 Docker 运行(安装程序在其他系统上会停止运行,并输出适用于该系统的 docker run 命令)。目前尚无 Mac、Windows 或 ARM 版本(这些版本正在开发中,将基于同一版本发布);在 Mac 或 Windows 电脑上,可在一台能够访问的 Linux 机器上运行节点。Mac 和 Windows 上的 Docker Desktop 仍在测试中。安装程序需要 root 权限。

在你掌控的 Linux 机器上运行一条命令。第一行会显示脚本,但不会运行它。

curl -fsSL https://one.semurg.io/install | less
curl -fsSL https://one.semurg.io/install | sudo bash

安装程序结束时会显示 SUCCESS 横幅,其中包含节点的 API 令牌。数据目录必须位于本地 ext4 或 xfs 文件系统上;安装程序会对此进行检查,不符合要求时会停止运行。单个节点无需许可证密钥。

将令牌放入 shell,然后验证访问控制已启用(不带令牌时返回 401,带令牌时返回 200):

TOKEN=$(sudo grep '^SEMURG_API_TOKEN=' /etc/semurg/semurg.env | cut -d= -f2-)
curl -si http://127.0.0.1:4000/v1/whoami | head -1
curl -si -H "Authorization: Bearer $TOKEN" http://127.0.0.1:4000/v1/whoami | head -1

连接编码 Agent

Claude Code:使用 Claude Code 自带的命令添加一个用户范围的条目。在启动 Claude Code 的 shell 中运行;该条目只保存对变量的引用,不会保存令牌本身。此地址是新节点提供的地址;如果使用自己的 TLS 代理,请使用其 https 地址。

export SEMURG_API_TOKEN=<the API token your node printed at install>
claude mcp add-json --scope user semurg '{"type":"http","url":"http://127.0.0.1:4000/v1/mcp","headers":{"Authorization":"Bearer ${SEMURG_API_TOKEN}","X-Semurg-Scope":"default"}}'
# Claude Code starts 时会从 SEMURG_API_TOKEN 环境变量读取令牌

已在版本 r11.101.20261016.3097008 上连接:Claude Code 自带的客户端列出了该版本提供的所有记忆工具。

Claude Desktop:它在 macOS 和 Windows 上运行,而 Semurg 在 Linux x86_64 上运行,因此可通过以下两种方式之一在 127.0.0.1:4000 访问节点:在 Windows 机器上,在同一台机器的 WSL2(Ubuntu 24.04)下运行节点(目前正在测试 Windows 上的 Docker Desktop);否则,在 Linux 机器上运行节点,并使用 ssh -N -L 4000:127.0.0.1:4000 you@your-node 将其端口转发到桌面端,这样令牌就不会通过未加密的 HTTP 在网络中传输。目前尚未介绍通过 HTTPS 和登录(OAuth)访问远程节点的方式。Claude Desktop 只能启动本地(stdio)MCP 服务,因此由 npx(需要 Node.js)运行的 mcp-remote 桥接程序会将请求转发到节点的流式 HTTP 接口。将以下内容放入 claude_desktop_config.json(macOS:~/Library/Application Support/Claude/;Windows:%APPDATA%\Claude\),将 替换为你的令牌,然后重启 Claude Desktop。该文件会保存令牌:请妥善保密。

{
  "mcpServers": {
    "semurg": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://127.0.0.1:4000/v1/mcp",
               "--header", "Authorization:${SEMURG_AUTH}",
               "--header", "X-Semurg-Scope:default"],
      "env": { "SEMURG_AUTH": "Bearer <token>" }
    }
  }
}

结果待定。其他任何 MCP 客户端:通过节点上的 POST /v1/mcp 使用流式 HTTP,设置请求头 Authorization: Bearer ,并可选设置 X-Semurg-Scope 请求头。每个 Agent 的专属配置:https://one.semurg.io/agents

通过 MCP 使用 Agent 记忆

端点:节点上的 POST /v1/mcp。它使用流式 HTTP,并接受节点的 API 令牌作为 bearer token。可选的 X-Semurg-Scope 请求头可设置连接的默认范围。

除 comms_bind_address 外,每个工具都需要 scope:命名空间。在同一节点上使用相同范围的 Agent 会共享这些事实;其他范围则是私有的。如果连接设置了 X-Semurg-Scope 请求头,此参数可选。

memory_status(只读)

报告此节点是否启用了共享记忆,以及你的哪些范围中保存了事实。传入 scope 还可获取该范围的本体摘要:其中包含实体类型和关系类型的数量、最大的类别(最多 50 个)及其成员数量(members_bound 表示“精确”:实时成员数;每次遗忘都会减少 1,即使成员超过 64 个),这些类别的成员、该范围已使用的关系类型(请严格按照 spellings 中列出的拼写复用),以及名称合并模式。只读。其他记忆调用失败时,请先调用此工具。

参数:

  • user_id(string):可选,指定你密钥下的最终用户(一个应用、多个最终用户):此时你指定的每个范围都属于该最终用户,两个最终用户之间不会互通。此设置用于应用级隔离,类似于 mem0 的 user_id;每用户令牌仍是安全边界。如果连接设置了 X-Semurg-User 请求头,则该请求头所指定的用户就是最终用户,任何不同的 user_id 都会被拒绝。不得包含“:”,最多 256 个字节。
memory_remember(写入)

为 Agent 存储记忆。你是提取器:每当你存储文本(content 或 messages)时,都要在同一次调用中将从中发现的实体和关系作为 facts 发送。它们会立即存储;你的提取速度比此节点的本地模型更快、效果也更好。本地模型会在后台缓慢地使用 CPU 读取未附带 facts 的文本(如果没有安装模型,则不会读取)。content:原始文本(笔记、文档),立即存储:文本会在句末切分为约 100-200 个单词的段落;每个段落都会关联到其中提及的实体,这些实体必须已存储,或随 facts 一起发送;回复会说明 extraction(发送了 facts 时为 agent_facts,未发送时为 known_names_only)、没有关联到任何实体的段落数量 unlinked_passages,以及 meaning:如果此节点有嵌入模型,则为 queued(段落的向量会紧接回复写入;memory_status 会说明何时完成);如果没有,则为 not_armed(安装模型后会嵌入段落)。不提供 facts 时,节点已安装的提取模型会在回复之后读取已存储的文本,并添加从中提取的实体、类型和关系;每条关系都会引用其来源段落:model_extraction 会按名称说明状态,包括 pending(等待磁盘处理)、done(已提取)、failed(某个段落在尝试 3 次后仍失败)、other_model(由另一个模型提取)、not_installed、not_serving 或 could_not_judge;提供 facts 时不会运行模型。messages:对话 [{role, content}],作为一段文本存储,每轮占一行,绝不会将两轮对话切入同一段;除此之外,与 content 完全相同。facts:实体 [{name, type}] 和关系 [{source, target, type}],由你自行提取,例如类型 WORKS_AT;类型是类,匹配时不区分大小写。passages:供日后查找的文本,[{text, mentions, key?}],立即存储且不使用模型:mentions 列出文本所涉及的实体名称(每个实体都按提供的名称存储,且名称必须出现在文本中,大小写不敏感;否则会按名称拒绝该段),当 memory_context 命中其中一个实体时,会返回完整段落。content 和 passages 不能在同一次调用中使用。date(ISO 8601 格式,例如 2026-10-01)表示内容的说出时间:该日期会与调用的来源一同保存,并在返回其来源内容时一并返回。同一内容使用相同日期再次存储不会产生任何变化(会返回 already)。每次调用的上限:1000 个实体、5000 个关系、1048576 字节的 content、1000 个段落(文本总计 1048576 字节)以及 1000 个 mentions;每个段落最多 65536 字节;每个名称、提及和键最多 1024 字节。source 是可选的来源标签,回忆该事实时会一并返回。在创建类型或关系之前,请使用你的作用域调用 memory_status,并复用 ontology.top_classes 中的类和 ontology.relations 中的关系,拼写必须与其 spellings 列表中完全一致(拼写不同即为不同关系,同一事实存储两次)。在每次 remember 调用的 entities 中列出每个关系的两端,包括先前已存储的实体。 参数:

  • content (string):要记住的原始文本,现已存储,并按句子边界切分为段落。在同一次调用中,将你从文本中发现的实体及其关系作为 facts 发送。
  • date (string):所述内容发生或属实的时间,采用 ISO 8601 格式(2026-10-01 或 2026-10-01T09:30:00Z)。可选。
  • facts (object):你从要存储的内容中提取的实体及其关系:一次性存储,不运行模型。
  • messages (array):要作为一段文本记住的对话,每轮一行。不能与 content 或 passages 同时使用。
  • passages (array):以后要找回的文本,现已存储。每个段落都要注明其涉及的实体。
  • source (string):可选的来源标签(例如,文件名)。它会作为每条引用中的来源名称显示。之后在同一标签下发送的 facts(且不带 "date"),会附加到你在该标签下存储的文档中,因此其引用会摘引该文本;未存储任何内容的标签、带有 "date" 的调用、更改某个属性当前值的调用,或名称对应超过 8 个文档的标签(一个文件被存储为多个段落),都会保留为独立来源,并以该标签命名(回复中的 source_label_state 会说明具体状态:attached、new_source、dated_own_source、value_changed_own_source、many_documents_not_attached)。
  • user_id (string):在你的密钥中可选指定的终端用户(一个应用,多个终端用户):之后你命名的每个范围都属于该终端用户,不同终端用户之间互不相通。应用级隔离方式与 mem0 的 user_id 相同;每用户令牌仍是安全边界。当连接设置 X-Semurg-User 标头时,该标头即代表终端用户,并且会拒绝不同的 user_id。不能包含“:”,最多 256 字节。
memory_recall(只读)

回忆存储的某个实体的信息:按名称查找名为 subject 的实体,支持精确匹配、拼写或大小写相似匹配(“paris” 可找到 Paris,“Dan” 可找到 Dana),也支持匹配较长名称中的一个完整单词(“Priya” 可找到 Priya Raman;“the” 或 “of” 等常见英文小词不会单独匹配)。从该实体出发遍历图,并返回两个方向(direction 为 outbound 或 inbound)上相连的事实,每条都包含其 citation(citation.source:kind 为 document,或对于 Agent 未发送文本而直接断言的事实为 asserted;事实所读取文档的 doc_id;存储时使用的 name 标签;ingested_at。citation.span:从该文档引用的句子,以及该句在文档全文中的 Unicode 码点 start 和 end,在返回前会进行验证;如果无法提供,则为 null,并由 span_state 说明原因。citation.found_by:查找方式),如果存储过,还包含其 source_date,以及找到该实体的种子(seed:exact、name 或 type)。始终返回最新信息:刚刚存储的事实也可见。direction 为 derived(derived: true)的事实并未存储,而是根据事实关系的含义从已存储事实推导得出(对称关系:married_to、spouse_of、sibling_of;逆向关系:parent_of 和 child_of、owns 和 owned_by、employs 和 employed_by、manages 和 managed_by;传递关系,最多 6 条链接:part_of、located_in、contained_in);citation.found_by.reasoning 会指出推导规则及其所依据的已存储事实,每条事实都可单独检索。回复包含 state:answered、nothing_stored(名称未匹配到任何内容:明确返回空结果,绝不编造)或 could_not_judge(某个阶段无法运行,原因在 detail 中说明);seeding 说明各阶段执行的操作;在启用嵌入模型之前,meaning 为 not_armed(在此之前无法按含义搜索)。source_id 是生成该条目的节点 ID(段落:其分块;事实:另一端的实体;实体或类型:实体或类型本身),而不是其来源文档的 ID:文档 ID 位于 citation.source.doc_id。只读。ID(source_id、seed_id、citation.source.doc_id)是 64 位无符号整数的十进制字符串:请原样传回,切勿转换为数字(JavaScript Number 无法准确表示其中某些值)。

参数:

  • as_of(string):读取截至此时已知的记忆(ISO 8601 日期或日期时间;仅日期时表示该日 UTC 时间的结束):之后存储的事实不可见。若要读取当前信息,请省略此参数。
  • attribute(object):按属性的当前值查找实体,而不是按名称查找:{"key": "ndis_number", "value": "430000001"}(可选 "type")。仅搜索此范围;设置了 user_id 时,范围为最终用户自己的数据。使用此参数代替 subject。
  • compact(boolean):true:每条目只返回一次(text、kind、事实的 subject / relation / object、实体的属性,格式为 name: value、doc_id、source、date、score、seed),不包含检索诊断信息(chunks、seeds、seeding、traversal):响应字节数可减少至原来的几分之一。若要获取完整回复,请省略此参数。
  • k(integer,1 到 1000):最多返回的事实数。
  • subject(string):要回忆的实体名称:支持精确匹配,或拼写、大小写相似匹配。
  • user_id(string):可选,表示你密钥下的最终用户(一个应用,多个最终用户):之后指定的每个范围都属于该最终用户,不同最终用户之间完全隔离。应用级隔离方式与 mem0 的 user_id 一致;每位用户的令牌仍是安全边界。如果连接设置了 X-Semurg-User 标头,该标头即代表最终用户,并且会拒绝不同的 user_id。不得包含“:”,最多 256 字节。
  • valid_at(string):读取此时为真的信息(ISO 8601),无论其何时为已知信息。与 as_of 一起使用时,表示读取截至 as_of 已知、且在 valid_at 为真的信息。
memory_relate(写入)

在一个作用域内的两个实体之间添加一条带类型的边,例如添加一条从 Alice 指向 Bob、类型为 MENTORS 的边。新实体会被创建。返回该边是否实际存在。

参数:

  • from(string,必填)
  • to(string,必填)
  • type(string,必填):关系类型,例如 WORKS_AT。
  • attributes(object):此关系的类型化属性,存储在该关系上(role、frequency、ISO 日期格式的 valid_from / valid_to),规则与实体属性相同:{"role": "guardian_nominee", "valid_from": "2026-03-01"}。
  • replaces(boolean):true:此关系会替换主体已存储的其他同类型目标(works_at、owned_by、reports_to、lives_in):这些关系会在本次调用的日期(或当前日期)结束,并且在此日期之前使用 valid_at / as_of 查询时仍可读取;之后再次声明旧关系时,它会恢复。回复中的 replaces 会列出已结束的关系(ended)、已恢复的关系(restored)、早于已存储关系的关系(older_than_stored;该关系会保留在历史记录中,并在较新关系开始时结束),以及关联过多、无法完整读取的主体(unread,状态为 could_not_judge)。对于会与其他关系并存的关系(knows、visited),请省略此参数。
  • user_id(string):可选,表示你密钥下的最终用户(一个应用,多个最终用户):此时你命名的每个作用域都归该最终用户所有,两个最终用户之间不会互通。应用级隔离方式与 mem0 的 user_id 相同;每用户令牌仍是安全边界。当连接设置 X-Semurg-User 标头时,该标头即为最终用户,并且会拒绝不同的 user_id。不能包含「:」,最多 256 字节。
memory_forget(写入)

在某个作用域中忘记一项内容,每次调用只能处理一项(在 subject、fact、passage、source、all、attribute 中准确发送一个)。subject:按实体的确切名称指定实体;该实体、它在作用域中的位置、它所属的类型,以及以它为任一端的所有事实和所有提及它的已存储段落都会被删除,因此回忆、上下文、类型查询和段落搜索都不再返回它们;回复会统计 passages_hidden,并列出 documents_retained(其他文本仍保留的已存储文档)和 passages_retained(附带 passages_retained_why):仍包含名称中某个词、但从未与该实体关联的现存段落数量;这些段落会继续保留,直到通过段落形式或来源形式将其忘记。fact:{from, to, type}:仅删除这一条事实;两个实体都会保留。passage:remember 操作返回的 doc_id:删除整篇已存储文档(其分块、信封和目录条目);文档中提及的事实和实体会保留。source:文档存储时所用的标签(remember 操作中的 source):删除归在该标签下的每篇完整文档,与段落形式的处理方式相同;这些文档所断言的事实会保留(facts_kept: true),如果从未存储过该来源,则返回 404。all:发送 all: true 和 scope,一次调用即可忘记整个作用域:其中的每个实体、事实、文档和段落,以及作用域本身(回复会统计这些内容并说明哪些内容得以保留);如果该作用域从未存在过,则返回 404。实体名称必须完全一致:若无匹配项,则拒绝该调用并返回 404,同时最多提供三个相近名称供检查(“Did you mean”);相近匹配仅作建议,不会被忘记。忘记操作具有幂等性:再次忘记已忘记的内容,会返回相同的 200 响应,并带有 already_forgotten: true,且不会写入任何内容;从未存在过的内容则返回 404。之后的 remember 操作若再次提及该内容,就会将其恢复。通过此节点的任何入口都无法访问已忘记的数据,但目前数据并未从物理介质上擦除:清除磁盘上已忘记数据的步骤尚未发布,在此之前,任何能访问节点磁盘或备份的人仍可读取这些字节。接受 reason,但不会存储。

参数:

  • all (boolean):作用域形式:true 会忘记 scope 指定的整个作用域,包括其中的每个实体、事实、文档和段落,以及作用域本身。若作用域从未存在过,则返回 404;再次进行相同调用时会返回 already_forgotten。
  • attribute (object):属性形式:{"subject": "<exact entity name>", "key": "<attribute key>"}:忘记该属性(若键对应多个值,则忘记所有值);实体及其其他属性会保留。
  • fact (object):事实形式:要忘记的那条事实,格式与 memory_relate 接收的格式相同。两个实体都会保留。
  • passage (string):段落形式:remember 操作返回的已存储文档 doc_id,必须是其十进制字符串,并与回复中给出的内容完全一致(ID 是 64 位整数:作为大于 2^53 的 JSON 数字时,在大多数客户端中已经丢失精度)。
  • reason (string)
  • source (string):来源形式:文档存储时所用的标签;忘记归在该标签下的每篇完整文档,但如果同一文本也存储在另一个来源下,则该文档会保留在另一个来源下,仅从该文档中移除此标签(documents_kept)。这些文档所断言的事实会保留。
  • subject (string):实体形式:要忘记的实体的确切名称(若拼写接近但不完全一致,404 响应会提供建议,但不会忘记该实体)。
  • user_id (string):可选的、位于你的密钥中的最终用户标识(一款应用,多个最终用户):此后你指定的每个作用域都属于相应最终用户,两个最终用户彼此隔离。此隔离方式类似于 mem0 的 user_id,每个用户的令牌仍是安全边界。当连接设置了 X-Semurg-User 标头时,该标头即代表最终用户;若 user_id 不同,则会被拒绝。不得包含 :,最多 256 字节。
memory_context(只读)

按相关性排序,检索记忆中与问题或几个词相关的内容,并为每项附上 citation(在一个范围内进行 GraphRAG;引文会标明为该项提供来源的文档,以及引用的句子)。query 中每个指向已存储实体的词或短语(完全匹配、拼写相似或大小写不同的匹配、较长名称中的一个完整词,例如用“Priya”匹配 Priya Raman,或一个词的开头,例如“Pri”),以及每个已存储类型(例如“哪些公司”),都会成为种子;“the”“of”“is”“who”“tell”“me”或“about”这类常见英语小词不会单独匹配。图会从种子向外遍历 hops 步,然后返回排序后的事实,以及提及这些事实的段落,并附上其文本、citation(citation.source:对于文档为 kind,对于 Agent 未附文本发送的事实则为 asserted;读取来源文档的 doc_id;存储时使用的 name 标签;ingested_at。citation.span:从该文档中引用的句子,其在全文中的 Unicode 码点起止位置 start 和 end,并在提供前进行校验;若为 null,则由 span_state 说明原因。citation.found_by:找到该项的方式)、source_date,以及找到每项的种子。不会调用模型:由你根据返回内容撰写答案,并引用 citation.source.doc_id(引用 citation.span.text)。若没有匹配项,state 为 nothing_stored,且 items 为空(seeding 会说明每个阶段执行了什么);无法判断时,could_not_judge 会指出无法运行的阶段。direction 为 derived(derived: true)的事实并未存储:它是根据已存储事实及其关系含义推导得出的(对称关系:married_to、spouse_of、sibling_of;反向关系:parent_of 和 child_of、owns 和 owned_by、employs 和 employed_by、manages 和 managed_by;传递关系,最多 6 个链接:part_of、located_in、contained_in),且 citation.found_by.reasoning 会指出所依据的规则和已存储事实,每项事实都可单独检索。在嵌入模型启用前,meaning 会保持 not_armed 状态:与问题不共享任何名称的释义,在此之前无法检索。启用后,问题会被嵌入,并与此范围内的段落进行评分,同时结合名称和词语来源(seeding.meaning 会说明是否已运行;段落仍在等待向量时,coverage 为 incomplete)。有两项限制,按名称列出:实体名称(标签)和事实句子不会被嵌入,因此没有段落的已存储事实无法通过语义检索;语义检索在每个范围内最多精确处理 10,000 个段落,超过上限时会返回 could_not_judge 并指出数量,绝不会返回不完整列表,直到每个范围的索引上线。仅凭语义匹配的结果必须达到嵌入模型校准后的余弦相似度下限:若主题没有任何存储内容,则回答 nothing_stored,而不是返回最相近的段落。较长问题中的一个普通词若与已存储名称中的某个词相同,该名称就可能被返回,看起来像是在回答问题(例如,关于法国的问题中的“capital”会匹配已存储的“Capital One”):依赖结果前,请先查看结果中的 grounding:grounded 表示有一个带引文的条目涵盖了问题中的每个实义词(若只有多个条目合起来才涵盖这些词,则为 related,原因为 covered_only_across_items);grounded_by_meaning 表示有一个通过语义检索找到的带引文段落,回答了改写后的问题——该问题既没有准确写出任何已存储实体名称,也没有写出段落中未出现的任何名称(未共享的词会列在 uncovered 中;语义命中若只涉及问题所提及的对象,则为 related,因为提及该对象不等于陈述答案):请阅读段落,并在它确实回答问题时据此作答;related(附有 uncovered 词语,以及匹配为 related 的已存储名称)、uncited、nothing_stored 和 could_not_judge 都表示这些事实并未回答问题,因此应明确说明,而不要根据这些事实作答。source_id 是生成该条目的节点 ID(段落:其分块;事实:其另一端的实体;实体或类型:其自身),而不是提供来源的文档 ID:文档 ID 是 citation.source.doc_id。只读。ID(source_id、seed_ids、citation.source.doc_id)是 64 位无符号整数的十进制字符串:必须原样传回,绝不能转换为数字(JavaScript Number 无法精确存储这类值)。 参数:

  • query(字符串,必填):一个问题或几个词;其中的实体名称和类型词是匹配对象(完全匹配、拼写相近或大小写相近、较长名称中的一个完整单词,或单词的开头);“the”或“of”等短英语词不会单独匹配。
  • as_of(字符串):读取截至此时已知的记忆(ISO 8601 日期或日期时间;仅含日期时,表示该 UTC 日期的结束时刻):此后存储的事实不可见。当前可省略。
  • compact(布尔值):true:每项只返回一次(文本、类型、事实的主体/关系/客体、实体属性的名称:值、doc_id、来源、日期、分数、种子),不包含检索诊断信息(区块、种子、播种、遍历):字节数仅为原来的几分之一。若需完整回复,请省略。
  • hops(整数,0 到 3):从匹配到的实体开始遍历的距离(默认值为 2)。
  • k(整数,1 到 100):最多返回的事实数(默认值为 8)。
  • user_id(字符串):密钥中的可选最终用户(一个应用,多个最终用户):此后你指定的每个作用域都属于该最终用户,两个最终用户之间彼此隔离。应用级隔离方式与 mem0 的 user_id 一致;每个用户的令牌仍是安全边界。连接设置 X-Semurg-User 标头时,该标头即为最终用户,并且会拒绝不同的 user_id。不得包含“:”,最多 256 字节。
  • valid_at(字符串):读取截至此时为真的内容(ISO 8601),无论何时获知。与 as_of 搭配时,读取截至 as_of 已知、且在 valid_at 为真的内容。
memory_document(写入)

一次调用即可将文档(PDF、Word .docx、HTML 页面或 UTF-8 文本文件)存储为记忆:文件字节会写入此节点的 customs,解析文件文本(按顺序提取段落、标题和列表项;PDF 段落根据页面布局重建,而非每行一个段落),并按 remember 动词存储 content 的方式原样存储。按字节逐一读取回来后,才会从 customs 中删除文件。回复包含 doc_id(后续每次引用都要使用的来源 ID,十进制字符串)、解析后的 text(引用偏移量以此为索引),以及 blocks(每个区块在文本中的页面、段落和字节跨度);如果文本不超过 16384 字节,则返回以上内容,超过时则返回 text_bytes 和 block_count(文本仍会完整存储,并可通过 recall 和 context 查找),还会返回 customs.emptied。请以 content_base64 发送文件(标准 Base64),解码后不得超过 5000000 字节;name 是随文件存储的标签(可选)。文件类型根据文件开头的实际字节读取,绝不依据文件名判断。若文件不属于上述文档类型,则会在存储任何内容之前拒绝处理(415);若文档被截断或损坏,则会按名称拒绝处理(document_corrupt,422),且不会存储任何内容;加密或扫描版 PDF 会被判定为 document_not_readable(422)。

参数:

  • content_base64(字符串,必填):文档字节,采用标准 Base64 编码。
  • name(字符串):文档名称,作为来源标签存储(可选)。
  • user_id(字符串):密钥中的可选最终用户(一个应用,多个最终用户):此后你指定的每个作用域都属于该最终用户,两个最终用户之间彼此隔离。应用级隔离方式与 mem0 的 user_id 一致;每个用户的令牌仍是安全边界。连接设置 X-Semurg-User 标头时,该标头即为最终用户,并且会拒绝不同的 user_id。不得包含“:”,最多 256 字节。
memory_export(只读)

导出某个作用域中的所有内容,每次调用返回一页:将上一条回复中的 next 作为 cursor 发送,直到 next 为 null。每条记录都是一个 JSON 对象(写入 .jsonl 文件时每行一条):entity(名称、类型、当前属性及其 valid_from)、fact(主体、关系、客体、两端的类型、关系属性、带日期的来源,以及当前或已结束状态;若已结束,还包含 ended_at 和 replaced_by)、document(每段已存储文本仅导出一次,按顺序列出其中仍有效的段落,并包含日期和来源标签;已遗忘的段落绝不会导出),以及第一页上的 export 标头。memory_import 可将这些记录导入任意作用域。只读。limit = 每页遍历的目录条目数(默认 256,最多 1024)。

参数:

  • cursor(字符串):上一页的 next,保持不变;第一页时省略。
  • limit(整数,1 至 1024):本页遍历的目录条目数(默认 256)。
  • user_id(字符串):可选的密钥内 END USER(一个应用,多个最终用户):之后你指定的每个作用域都属于该最终用户,两个最终用户互不相通。与 mem0 的 user_id 一样,按应用隔离;每用户令牌仍是安全边界。连接设置了 X-Semurg-User 标头时,该标头就是最终用户,并且会拒绝不同的 user_id。不得包含“:”,最多 256 字节。
memory_import(写入)

将 memory_export 生成的记录(任意页面、任意顺序;同一页面发送两次也不会重复存储)通过与 remember 相同的写入方式存入某个作用域:文档按其文本、日期和来源标签存储;实体连同类型和属性存储;事实连同带日期的来源存储;已结束的事实会在其 ended_at 再次标记为结束,从而使历史记录保持原样。回复会统计导入内容,列出每条被跳过的记录(skipped:索引及原因),并列出导入无法还原的内容(not_reproduced)。每次调用最多 4096 条记录。

参数:

  • records(数组,必填):与 memory_export 返回内容完全相同的记录。
  • user_id(字符串):可选的密钥内 END USER(一个应用,多个最终用户):之后你指定的每个作用域都属于该最终用户,两个最终用户互不相通。与 mem0 的 user_id 一样,按应用隔离;每用户令牌仍是安全边界。连接设置了 X-Semurg-User 标头时,该标头就是最终用户,并且会拒绝不同的 user_id。不得包含“:”,最多 256 字节。
comms_bind_address(写入)

将 name@<cluster domain> 格式的地址绑定到你(即令牌对应的身份,或你通过 user_id 指定的最终用户),以便此集群上的人类和 Agent 能通过名称向你发送消息。人类和 Agent 使用相同的调用进行绑定;kind 用于说明绑定方的类型(user 为默认值,或 agent)。此操作具有幂等性:再次绑定相同地址时,返回 bound: "already"。以下情况会按名称拒绝:address_invalid(仅限 ASCII 字母、数字、.、-、_、+,且必须恰好包含一个 @)、domain_not_ours(集群的域名列在修复信息中)、address_taken(已绑定到其他人)、kind_invalid。此操作会写入数据,需要 API 令牌。

参数:

  • address(字符串,必填):要绑定的地址,格式为 name@<cluster domain>;大小写不敏感([email protected] = [email protected])。
  • kind(字符串):绑定主体的类型:user(人类,默认值)或 agent。
  • user_id(字符串):可选的密钥内 END USER(一个应用,多个最终用户):此时地址属于该最终用户。连接设置了 X-Semurg-User 标头时,该标头就是最终用户,并且会拒绝不同的 user_id。

通过 HTTP 调用相同的动词

每个路由都接受一个 JSON 请求体,其字段与同名工具的字段相同,并且需要携带请求头 Authorization: Bearer <token>。

GET /v1/memory/status
POST /v1/memory/remember
POST /v1/memory/recall
POST /v1/memory/relate
POST /v1/memory/forget
POST /v1/memory/context
POST /v1/memory/document
POST /v1/memory/delete_user
POST /v1/memory/export
POST /v1/memory/import
POST /v1/memory/audit

两个示例均在全新节点上运行,节点版本为 r11.83.20261013.c03a884,并且都读回了各自的回答;尚未在 r11.101 上重新运行。示例使用 http://127.0.0.1:4000,这是全新节点提供服务的地址;如果使用自己的 TLS 代理,请改用其 https 地址。将 SEMURG_API_TOKEN 设为节点的 API 令牌。

curl -sS http://127.0.0.1:4000/v1/memory/remember \
  -H "Authorization: Bearer $SEMURG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"scope":"demo","facts":{"entities":[{"name":"Acme","type":"Company"},{"name":"Dana","type":"Person"}],"relations":[{"source":"Dana","target":"Acme","type":"WORKS_AT"}]},"source":"curl example"}'

curl -sS http://127.0.0.1:4000/v1/memory/recall \
  -H "Authorization: Bearer $SEMURG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"scope":"demo","subject":"Dana"}'

客户端

一个归档包中包含 11 种语言的客户端,地址为 https://one.semurg.io/dl/clients.tar.gz,其中包含 CONNECTING.md,介绍如何让客户端连接到你的节点。客户端需要提供节点的基础 URL 和令牌。各客户端定义的记忆调用及其各自的命名方式如下:

  • Python (clients/python/semurg/client.py):memory_status、remember、recall、relate、forget、context
  • Go (clients/go/semurg/client.go):MemoryStatus、Remember、Recall、Relate、Forget、Context
  • Java (clients/java/src/main/java/io/semurg/client/SemurgClient.java):memoryStatus、remember、recall、relate、forget、context
  • C# (clients/csharp/Semurg.Client/SemurgClient.cs):MemoryStatus、Remember、Recall、Relate、Forget、Context
  • F# (clients/fsharp/Semurg.Client.FSharp/Client.fs):memoryStatus、remember、recall、relate、forget、context
  • Elixir (clients/elixir/lib/semurg/client.ex):memory_status、remember、recall、relate、forget、context
  • Erlang (clients/erlang/src/semurg_client.erl):memory_status、remember、recall、relate、forget、context
  • Rust (clients/rust/src/client.rs):memory_status、remember、recall、relate、forget、memory_context
  • Julia (clients/julia/src/client.jl):remember、recall、context
  • C++:此客户端目前尚未提供记忆调用;可通过 HTTP 调用(已在 clients/cpp/src/client.cpp 中确认)
  • OCaml (clients/ocaml/lib/client.ml):memory_status、remember、recall、relate、forget、context

下载后,请使用该版本自带的校验和进行验证:

curl -fsSLO https://one.semurg.io/dl/clients.tar.gz
curl -fsSLO https://one.semurg.io/dl/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS

软件包:现有内容

Semurg 通过 one.semurg.io 发布(安装程序 https://one.semurg.io/install、安装包 https://one.semurg.io/dl/semurg-r11-installer.tar.gz,经 https://one.semurg.io/dl/SHA256SUMS 校验,以及上文提到的客户端归档包),也会在下文列出的公共注册表上发布,除此之外不在其他地方发布。MCP 服务已内置于节点中(上文的 POST /v1/mcp):无需为它安装任何内容。

已在公共注册表发布:

PyPI:

pip install semurg==0.1.1

one.semurg.io(容器镜像):

docker pull one.semurg.io/semurg:latest

目前,Semurg 尚未在 npm、crates.io、NuGet、Hex、Maven Central、Go 模块代理、Julia General 注册表、opam 和 MCP 注册表上发布任何软件包。上述注册表中声称属于 Semurg 的软件包并非 Semurg 官方发布:请勿安装。

在节点上构建应用

应用分为两种。外部应用可以使用任何语言和任何 Web 框架,通过节点的公共 API(记忆路由、/v1/ingest、/v1/query 及其操作、MCP 工具或客户端)将数据保存在节点中:节点就是它的存储,以下内容都不适用于这类应用。今天就构建这种应用。节点内应用是 Elixir 扩展,运行在节点内部,使用节点自带的能力;Semurg 将这些能力称为 packs。只有通过组合检查后,它才会通过 Marketplace 发布(目前已有该检查;节点内应用的发布和安装流程仍在构建中)。以下每条规则都是该检查针对节点内应用强制执行的规则:

  • 应用不自带数据库:节点就是存储,应用只能通过节点的公共读写 API 访问它。
  • 应用只能基于 packs 构建:绝不能基于其他应用或节点自身的内部实现构建,而且应用和 packs 组成的链路绝不能形成循环。
  • 对于各个 pack,应用只能使用该 pack 声明开放的内容。
  • Web 界面必须使用 Phoenix LiveView。仅包含控制器或仅提供 JSON 的界面将不予通过。

页面

评论

支持 Markdown

第一次接触 MCP?

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

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