Skip to main content

概述

在 kira-cms 中新增 Memory Admin 自定义视图,让运营人员可以按用户查看、搜索、新增、编辑和删除记忆。实现方式参考现有的 Delete Account 视图(Server Component + Client Form),通过调用 kira-memory 的 Admin API 完成所有操作。

核心能力

功能说明
用户搜索按 userId / email / nickname 搜索用户,展示其记忆概览
Profile 查看展示用户的 Compact Memory 画像(style / workflow / instructions / context)
Profile 编辑运营人员可手动修正用户画像内容
记忆列表分页展示用户所有 Vector Memory(情景记忆),支持按类型筛选
记忆详情查看单条记忆的完整内容、元数据、权重信息
新增记忆手动为用户添加记忆(自动生成 embedding)
编辑记忆修改记忆内容(自动重新 embedding)
删除记忆硬删除单条记忆
批量删除勾选多条记忆批量删除
清空记忆一键清空用户所有记忆 + 重置 profile(高危操作,需二次确认)

架构

CMS 不直接访问 LanceDB 或 Supabase memory schema,所有操作通过 kira-memory 的 Admin API 进行,保持职责单一。

kira-memory Admin API

所有 Admin API 路由前缀为 /admin,通过内网调用,需要 CMS 层面的管理员鉴权(CMS 登录态 → 请求携带 admin token)。

GET /admin/users

搜索有记忆数据的用户列表。
// Request
GET /admin/users?q=john&page=1&limit=20

// Response
{
  users: Array<{
    entity_id: string,
    entity_type: 'user' | 'group',
    memory_count: number,          // 记忆总数
    profile_updated_at: string,    // 画像最后更新时间
    has_profile: boolean,
  }>,
  total: number,
  page: number,
  limit: number,
}
实现:查询 Supabase memory.profiles 表,联合 LanceDB 统计 memory_count。q 参数先去 Supabase auth.users / user_profiles 做模糊匹配拿到 userId 列表,再关联 memory 数据。

GET /admin/users/:entity_id/profile

获取用户 Compact Memory 画像。
// Response
{
  entity_id: string,
  entity_type: 'user' | 'group',
  style: string | null,
  workflow: string | null,
  instructions: string | null,
  context: string | null,
  stats: object,
  updated_at: string,
}

PUT /admin/users/:entity_id/profile

手动编辑用户画像。
// Request
{
  style?: string,
  workflow?: string,
  instructions?: string,
  context?: string,
}

// Response
{ success: true, updated_at: string }
编辑后同步刷新 Dragonfly 缓存。

GET /admin/users/:entity_id/memories

分页获取用户的所有情景记忆。
// Request
GET /admin/users/:entity_id/memories?page=1&limit=20&type=preference&sort=created_at&order=desc

// Query Params
{
  page?: number,           // 默认 1
  limit?: number,          // 默认 20,最大 100
  type?: string,           // 可选过滤:preference | workflow | instruction | episodic
  sort?: string,           // 排序字段:created_at | importance | decay_weight | access_count
  order?: 'asc' | 'desc',  // 默认 desc
}

// Response
{
  memories: Array<{
    id: string,
    content: string,
    type: 'preference' | 'workflow' | 'instruction' | 'episodic',
    source: 'behavior' | 'conversation' | 'explicit',
    importance: number,
    access_count: number,
    decay_weight: number,
    metadata: {
      thread_id?: string,
      tool_name?: string,
      model?: string,
      prompt?: string,
      satisfaction?: string,
    },
    created_at: string,
    last_accessed_at: string | null,
    consolidated_at: string | null,
  }>,
  total: number,
  page: number,
  limit: number,
}
返回结果不包含 embedding 向量(512 维 Float32Array 太大),仅在详情接口中按需返回。

GET /admin/memories/:id

获取单条记忆详情(含 embedding 元信息)。
// Response
{
  id: string,
  entity_id: string,
  entity_type: 'user' | 'group',
  content: string,
  embedding_preview: number[],     // 前 8 维,用于调试展示
  embedding_norm: number,          // 向量范数
  type: string,
  source: string,
  importance: number,
  access_count: number,
  decay_weight: number,
  metadata: object,
  created_at: string,
  last_accessed_at: string | null,
  consolidated_at: string | null,
}

POST /admin/users/:entity_id/memories

运营手动为用户新增记忆。
// Request
{
  content: string,                 // 记忆内容(自然语言)
  type: 'preference' | 'workflow' | 'instruction' | 'episodic',
  importance?: number,             // 0-1,默认 0.8
  metadata?: {
    note?: string,                 // 运营备注(标记为人工添加)
  },
}

// Response
{ id: string, deduplicated: boolean }
自动生成 embedding,写入前执行去重检查(与 /memory/add 逻辑一致)。source 自动标记为 explicitmetadata 中附加 { admin: true, operator: "cms_user_id" } 以区分运营手动添加和 Agent 添加。

PUT /admin/memories/:id

编辑记忆内容。
// Request
{
  content?: string,                // 修改后内容(触发重新 embedding)
  type?: string,                   // 修改分类
  importance?: number,             // 修改重要性
}

// Response
{ success: true }

DELETE /admin/memories/:id

硬删除单条记忆。
// Response
{ success: true }

POST /admin/users/:entity_id/memories/batch-delete

批量删除记忆。
// Request
{ ids: string[] }

// Response
{ deleted: number }

DELETE /admin/users/:entity_id/memories

清空用户所有记忆并重置 profile。高危操作,需要请求头携带确认标记。
// Request Header
X-Confirm-Dangerous: "RESET_ALL_MEMORIES"

// Response
{
  memories_deleted: number,
  profile_reset: true,
}
清空后同步刷新 Dragonfly 缓存。操作记录写入 Supabase 审计日志。

CMS 视图设计

文件结构

参考 Delete Account 视图的实现模式:
kira-cms/src/
  components/
    NavLinks.tsx              # 新增 "User Memory" 导航链接
    views/
      MemoryAdmin.tsx         # Server Component:页面入口
      MemoryAdminPanel.tsx    # Client Component:主面板
      MemoryUserSearch.tsx    # Client Component:用户搜索
      MemoryProfileCard.tsx   # Client Component:画像卡片(可编辑)
      MemoryTable.tsx         # Client Component:记忆列表表格
      MemoryDetailModal.tsx   # Client Component:记忆详情/编辑弹窗

页面布局

┌────────────────────────────────────────────────────────────┐
│  User Memory Management                                    │
├────────────────────────────────────────────────────────────┤
│  🔍 搜索用户: [userId / email / nickname        ] [Search] │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  ┌─ User Profile (Compact Memory) ──────────────────────┐  │
│  │ Style:        偏好复古暖色调,vintage 使用率 80%...    │  │
│  │ Workflow:     典型流程:滤镜→微调→裁剪→导出...        │  │
│  │ Instructions: 导出时保持原始分辨率...                  │  │
│  │ Context:      常拍人像                                │  │
│  │ Stats:        sessions: 142 | edits/session: 3.2      │  │
│  │                                     [Edit Profile]    │  │
│  └───────────────────────────────────────────────────────┘  │
│                                                            │
│  ┌─ Vector Memories ─────────────────────────────────────┐  │
│  │ Filter: [All Types ▼]  Sort: [Created ▼]  [+ Add]    │  │
│  │ ┌─────────────────────────────────────────────────────│  │
│  │ │ ☐ │ Type       │ Content          │ Imp. │ Decay │  │  │
│  │ ├───┼────────────┼──────────────────┼──────┼───────│  │  │
│  │ │ ☐ │ preference │ 喜欢暖色调滤镜... │ 0.9  │ 0.82  │  │  │
│  │ │ ☐ │ workflow   │ 先裁剪再调色...   │ 0.7  │ 0.65  │  │  │
│  │ │ ☐ │ instruction│ 所有图加水印...   │ 1.0  │ 0.91  │  │  │
│  │ │ ☐ │ episodic   │ 2月15日日落照...  │ 0.6  │ 0.33  │  │  │
│  │ └─────────────────────────────────────────────────────│  │
│  │ [Delete Selected]           Page 1/5  [< Prev] [Next >]│  │
│  │                                                       │  │
│  │ ⚠️ [Clear All Memories] (需二次确认)                   │  │
│  └───────────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────┘

交互细节

操作行为
搜索用户输入后 debounce 300ms,调用 GET /admin/users?q=xxx,下拉展示匹配结果
选择用户并行加载 profile 和 memories 列表
Edit Profile点击后 profile 区域切换为可编辑文本框,保存调用 PUT /admin/users/:id/profile
+ Add打开弹窗,填写 content / type / importance,提交调用 POST /admin/users/:id/memories
点击行打开详情弹窗,展示完整记忆信息,可编辑 content / type / importance
Delete Selected调用 POST /admin/users/:id/memories/batch-delete,需确认
Clear All二次确认弹窗(输入 “RESET” 确认),调用 DELETE /admin/users/:id/memories

Lark 通知

高危操作触发 Lark webhook 通知(复用现有 lib/lark.ts):
  • 清空用户所有记忆
  • 批量删除超过 10 条记忆
通知内容包含操作人、目标用户、删除数量、时间戳。

鉴权

  • CMS 层面:复用 Payload CMS 的管理员登录态,只有登录的管理员才能访问 Memory Admin 视图
  • kira-memory 层面:Admin API 通过 X-Admin-Token 头部鉴权(共享密钥,环境变量 MEMORY_ADMIN_TOKEN),拒绝非授权请求
  • 审计:所有写操作(增 / 改 / 删)记录操作人 ID、目标用户、操作类型、时间戳到 Supabase 审计表

审计日志

所有 Admin API 的写操作记录到 memory.admin_audit_log 表:
CREATE TABLE memory.admin_audit_log (
  id            UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  operator_id   TEXT NOT NULL,         -- CMS 管理员 ID
  action        TEXT NOT NULL,         -- create_memory | update_memory | delete_memory | batch_delete | reset_all | update_profile
  target_entity TEXT NOT NULL,         -- 目标用户/群 entity_id
  detail        JSONB DEFAULT '{}',   -- 操作详情(如删除的 memory_id 列表、修改前后内容)
  created_at    TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_admin_audit_entity ON memory.admin_audit_log (target_entity, created_at DESC);
CREATE INDEX idx_admin_audit_operator ON memory.admin_audit_log (operator_id, created_at DESC);

与现有 API 的关系

接口调用方说明
POST /injectkira-be Agent每轮对话前注入记忆上下文
POST /memory/addkira-be AgentAgent 显式存储记忆
POST /memory/searchkira-be AgentAgent 主动查询
PUT /memory/:idkira-be AgentAgent 更新记忆
DELETE /memory/:idkira-be AgentAgent 删除记忆
/admin/*kira-cms运营后台管理记忆(本文档)
Agent API 和 Admin API 职责分离:
  • Agent API 面向 AI,鉴权走 Supabase JWT,操作范围限于当前用户
  • Admin API 面向运营,鉴权走 Admin Token,可操作任意用户