ClouisleClouisle

记忆 API

管理当前用户的长期记忆实体与关系图谱

记忆 API 维护当前用户私有的长期记忆图谱:从 Agent 对话中提取的实体(节点),以及实体之间的有向关系(边)。所有端点都以调用者本人为边界——路径与查询参数里都不存在 team_id,一个用户永远无法读取或修改另一个用户的实体与关系。基础路径为 /api/v1/memories。

前置条件与认证

所有端点都需要已认证的 JWT 用户会话(Authorization: Bearer <token>)。这些端点不接受 API Key 认证,也不做任何权限码校验——数据隔离完全由 user_id 过滤实现。

对不属于自己的 ID,服务端统一按“不存在”处理,不会区分“不存在”与“无权访问”。注意本组端点的“资源不存在”返回的是 HTTP 400 + 业务码 4000(memory_entity_not_found / memory_relation_not_found),HTTP 状态不是 404——判断成败请以响应体 code 为准。

记忆通常在 Agent 对话过程中被自动提取;下面的手动增删改接口用于纠错和整理。自动提取的触发条件与开关见 Agent 记忆。

端点总览

方法路径用途
GET/api/v1/memories/entities列出当前用户的记忆实体
POST/api/v1/memories/entities手动创建记忆实体
GET/api/v1/memories/entities/{entity_id}获取实体详情及其出边与入边
PUT/api/v1/memories/entities/{entity_id}更新实体
DELETE/api/v1/memories/entities/{entity_id}删除实体及其全部关系
GET/api/v1/memories/relations列出当前用户的记忆关系
POST/api/v1/memories/relations手动创建记忆关系
DELETE/api/v1/memories/relations/{relation_id}删除关系
GET/api/v1/memories/graph获取用于可视化的记忆图谱

所有响应都使用统一信封 {"code": 0, "data": ..., "msg": "success"}。

认证与权限

项说明
认证方式JWT Bearer 令牌(get_current_user)
API Key不支持
权限码无(不经过 PermissionChecker)
作用域用户级:仅能操作 user_id 等于调用者的数据

数据结构

实体对象(Entity)

字段类型说明
idstring (UUID)实体 ID
user_idstring (UUID)归属用户
namestring实体名称,最长 255 字符
entity_typestring实体类型,见下方枚举
descriptionstring | null详细描述
propertiesobject自由结构属性,默认 {}
source_conversation_idstring | null自动提取时的来源会话 ID
source_message_idstring | null自动提取时的来源消息 ID
access_countinteger被召回次数,默认 0
last_accessed_atstring | null最近一次被召回的时间
created_atstring创建时间
updated_atstring最后更新时间

同一用户下 name + entity_type 组合唯一;重复创建不会新增记录(见创建记忆实体)。

关系对象(Relation)

字段类型说明
idstring (UUID)关系 ID
user_idstring (UUID)归属用户
source_entity_idstring (UUID)起点实体 ID
target_entity_idstring (UUID)终点实体 ID
relation_typestring关系类型,见下方枚举
descriptionstring | null关系描述
propertiesobject自由结构属性,默认 {}
source_conversation_idstring | null自动提取时的来源会话 ID
source_message_idstring | null自动提取时的来源消息 ID
created_atstring创建时间
updated_atstring最后更新时间

同一用户下 source_entity_id + target_entity_id + relation_type 组合唯一。

entity_type 枚举

取值含义
person用户本人或其提到的人
preference用户偏好
skill技能、技术栈
project项目、工作
goal目标、目的
fact一般事实
concept抽象概念
organization公司、团队
location地点
custom其它

relation_type 枚举

取值含义
prefers用户偏好 X
works_on用户正在做 X
knows用户认识 X
uses用户使用 X
works_at用户就职于 X
located_in用户/实体位于 X
has_goal用户的目标是 X
related_to通用关联
part_ofX 属于 Y

列出记忆实体

GET /api/v1/memories/entities

返回当前用户的实体,支持按类型筛选与分页。未显式排序,按数据库返回顺序;需要稳定顺序时请自行按 created_at / name 排序。

查询参数

参数类型必填默认值说明
entity_typestring否-按实体类型过滤
pageinteger否1页码,最小 1
page_sizeinteger否20每页条数,范围 1–100
curl -X GET "https://your-domain.com/api/v1/memories/entities?entity_type=preference&page=1&page_size=20" \
  -H "Authorization: Bearer YOUR_TOKEN"

成功响应(200 OK):

{
  "code": 0,
  "data": {
    "items": [
      {
        "id": "8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f",
        "user_id": "3d1f7a92-5b6c-4f8e-9a01-2c3d4e5f6a7b",
        "name": "Python",
        "entity_type": "preference",
        "description": "Prefers concise Python snippets using async/await syntax.",
        "properties": {"level": "expert"},
        "source_conversation_id": "0b2c3d4e-5f60-4a71-8b92-c3d4e5f60718",
        "source_message_id": null,
        "access_count": 4,
        "last_accessed_at": "2026-09-20T10:15:00Z",
        "created_at": "2026-03-02T08:30:00Z",
        "updated_at": "2026-09-20T10:15:00Z"
      }
    ],
    "total": 1,
    "page": 1,
    "page_size": 20
  },
  "msg": "success"
}

分页信封固定为 data.items / data.total / data.page / data.page_size。


创建记忆实体

POST /api/v1/memories/entities

请求体

字段类型必填说明
namestring是实体名称,最长 255 字符
entity_typestring是实体类型枚举值
descriptionstring | null否实体描述
propertiesobject否附加属性,默认 {}
curl -X POST "https://your-domain.com/api/v1/memories/entities" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Python",
    "entity_type": "preference",
    "description": "Prefers concise Python snippets using async/await syntax.",
    "properties": {"level": "expert"}
  }'

成功响应(200 OK): data 为创建(或更新,见下)后的实体对象。

同名同类型写入是幂等的

name + entity_type 已存在时不会新建记录,而是合并到已有实体:description 追加到原描述之后,properties 逐键合并(同名键覆盖),并刷新向量嵌入。响应 code 仍为 0,但 data.id 是既有实体 ID。

无法创建(如服务端内部错误)时返回 400 + 1003。


获取实体详情

GET /api/v1/memories/entities/{entity_id}

返回实体本身,以及它以起点身份出现在其中的全部关系(outgoing_relations)和以终点身份出现的全部关系(incoming_relations)。两组关系都不分页。

路径参数

参数类型必填说明
entity_idstring (UUID)是实体 ID

成功响应(200 OK):

{
  "code": 0,
  "data": {
    "entity": {
      "id": "8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f",
      "user_id": "3d1f7a92-5b6c-4f8e-9a01-2c3d4e5f6a7b",
      "name": "Python",
      "entity_type": "preference",
      "description": "Prefers concise Python snippets using async/await syntax.",
      "properties": {"level": "expert"},
      "source_conversation_id": null,
      "source_message_id": null,
      "access_count": 4,
      "last_accessed_at": "2026-09-20T10:15:00Z",
      "created_at": "2026-03-02T08:30:00Z",
      "updated_at": "2026-09-20T10:15:00Z"
    },
    "outgoing_relations": [
      {
        "id": "c6d5e4f3-a2b1-4c0d-9e8f-7a6b5c4d3e2f",
        "user_id": "3d1f7a92-5b6c-4f8e-9a01-2c3d4e5f6a7b",
        "source_entity_id": "8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f",
        "target_entity_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "relation_type": "uses",
        "description": null,
        "properties": {},
        "source_conversation_id": null,
        "source_message_id": null,
        "created_at": "2026-03-02T08:31:00Z",
        "updated_at": "2026-03-02T08:31:00Z"
      }
    ],
    "incoming_relations": []
  },
  "msg": "success"
}

错误:

HTTP错误码说明
4004000memory_entity_not_found:ID 不存在或不属于当前用户

更新实体

PUT /api/v1/memories/entities/{entity_id}

请求体

所有字段可选。省略或传 null 的字段保持不变;因此无法通过本端点把 description 清空。

字段类型说明
namestring | null新名称,最长 255 字符
descriptionstring | null新描述(直接覆盖,不追加)
propertiesobject | null与既有 properties 逐键合并,同名键覆盖
curl -X PUT "https://your-domain.com/api/v1/memories/entities/8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Python 3.13",
    "description": "Prefers concise Python snippets using async/await syntax.",
    "properties": {"level": "expert", "years": 5}
  }'

成功响应(200 OK): data 为更新后的实体对象。修改 name 或 description 会同步刷新实体的向量嵌入。

错误:

HTTP错误码说明
4004000memory_entity_not_found
4001003memory_entity_update_failed

删除实体

DELETE /api/v1/memories/entities/{entity_id}

删除实体,并级联删除所有以它为起点或终点的关系,同时清理 Qdrant 中的向量。

成功响应(200 OK):

{
  "code": 0,
  "data": {"message": "Memory entity deleted successfully"},
  "msg": "Memory entity deleted successfully"
}

错误:

HTTP错误码说明
4004000memory_entity_not_found
4001003memory_entity_delete_failed

列出记忆关系

GET /api/v1/memories/relations

查询参数

参数类型必填默认值说明
entity_idstring (UUID)否-按实体过滤;匹配该实体作为起点或终点的关系
relation_typestring否-按关系类型过滤
pageinteger否1页码,最小 1
page_sizeinteger否20每页条数,范围 1–100

成功响应(200 OK):

{
  "code": 0,
  "data": {
    "items": [
      {
        "id": "c6d5e4f3-a2b1-4c0d-9e8f-7a6b5c4d3e2f",
        "user_id": "3d1f7a92-5b6c-4f8e-9a01-2c3d4e5f6a7b",
        "source_entity_id": "8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f",
        "target_entity_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "relation_type": "uses",
        "description": null,
        "properties": {},
        "source_conversation_id": null,
        "source_message_id": null,
        "created_at": "2026-03-02T08:31:00Z",
        "updated_at": "2026-03-02T08:31:00Z"
      }
    ],
    "total": 1,
    "page": 1,
    "page_size": 20
  },
  "msg": "success"
}

创建记忆关系

POST /api/v1/memories/relations

请求体

字段类型必填说明
source_entity_idstring (UUID)是起点实体,必须属于当前用户
target_entity_idstring (UUID)是终点实体,必须属于当前用户
relation_typestring是关系类型枚举值
descriptionstring | null否关系描述
propertiesobject否附加属性,默认 {}

成功响应(200 OK): data 为关系对象。

重复关系是幂等的

相同 source_entity_id + target_entity_id + relation_type 已存在时,直接返回既有关系(code: 0),不会重复写入,也不会用新请求的 description / properties 覆盖它。

错误:

HTTP错误码说明
4001002memory_source_entity_not_found / memory_target_entity_not_found(实体不存在或不属于当前用户)
4001002memory_relation_create_failed(其它创建失败)
4001003服务端内部错误

删除关系

DELETE /api/v1/memories/relations/{relation_id}

路径参数

参数类型必填说明
relation_idstring (UUID)是关系 ID

成功响应(200 OK):

{
  "code": 0,
  "data": {"message": "Memory relation deleted successfully"},
  "msg": "Memory relation deleted successfully"
}

错误:

HTTP错误码说明
4004000memory_relation_not_found
4001003memory_relation_delete_failed

获取记忆图谱

GET /api/v1/memories/graph

返回用于可视化的实体与关系集合。响应只包含 entities 与 relations 两个数组,不含分页字段。

查询参数

参数类型必填默认值说明
entity_idsarray of UUID否-重复该参数可指定种子实体,只返回其周围子图
max_depthinteger否1子图遍历深度,范围 1–3(超范围返回 422)

省略 entity_ids 时返回当前用户的全量图谱(全部实体 + 全部关系,不分页)。传入 entity_ids 时返回的是一张有界子图:服务端会限制节点数与关系数上限,超出部分静默截断——需要完整数据请改用 GET /entities 与 GET /relations 分页拉取。

curl -X GET "https://your-domain.com/api/v1/memories/graph?entity_ids=8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f&max_depth=2" \
  -H "Authorization: Bearer YOUR_TOKEN"

成功响应(200 OK):

{
  "code": 0,
  "data": {
    "entities": [
      {
        "id": "8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f",
        "user_id": "3d1f7a92-5b6c-4f8e-9a01-2c3d4e5f6a7b",
        "name": "Python",
        "entity_type": "preference",
        "description": "Prefers concise Python snippets using async/await syntax.",
        "properties": {"level": "expert"},
        "source_conversation_id": null,
        "source_message_id": null,
        "access_count": 4,
        "last_accessed_at": "2026-09-20T10:15:00Z",
        "created_at": "2026-03-02T08:30:00Z",
        "updated_at": "2026-09-20T10:15:00Z"
      }
    ],
    "relations": [
      {
        "id": "c6d5e4f3-a2b1-4c0d-9e8f-7a6b5c4d3e2f",
        "user_id": "3d1f7a92-5b6c-4f8e-9a01-2c3d4e5f6a7b",
        "source_entity_id": "8f14e45f-ceea-467a-9c1c-1b0c1a2d3e4f",
        "target_entity_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "relation_type": "uses",
        "description": null,
        "properties": {},
        "source_conversation_id": null,
        "source_message_id": null,
        "created_at": "2026-03-02T08:31:00Z",
        "updated_at": "2026-03-02T08:31:00Z"
      }
    ]
  },
  "msg": "success"
}

错误处理

HTTP错误码触发场景
4012000 / 2001 / 2002缺少令牌、令牌无效或已过期
4004000实体/关系不存在或不属于当前用户
4001002关系端点引用了不存在的实体,或关系创建失败
4001003实体创建/更新/删除的内部错误
4221001请求校验失败:UUID 格式错误、未知枚举值、page < 1、page_size 超出 1–100、max_depth 超出 1–3

本组端点未实现单独限流,无专属速率限制中间件;通用错误处理约定见 错误处理。

相关文档

  • Agent 记忆 — 记忆的自动提取、召回与开关
  • 会话 API — source_conversation_id 指向的会话
  • Agent API — 承载记忆提取的对话入口
  • 错误处理 — 按 HTTP 状态与业务错误码恢复

这篇文章对你有帮助吗?

本页目录