本文给出 Context0 数据面与管理面全部 REST API 的详细说明,包括端点路径、请求参数、请求示例和响应示例。
概览
项目 | 说明 |
Base URL |
|
认证方式 | 请求头 |
响应格式 |
|
错误格式 |
|
Key 类型 | Admin Key(平台级引导凭证,仅管理面)/ Owner Key(租户管理员,管理端全权限)/ User Key(终端用户,隔离到自身数据) |
部分 Mem0 兼容端点(
/v1/memories、/v1/memories/search等)返回裸 JSON(无 Box 包装),以保持与 Mem0 SDK 的线协议兼容。时间字段约定:所有
*_at字段都是 ISO-8601 瞬间,UTC,以Z结尾(如2026-09-17T18:03:43.226352Z),客户端负责按本地时区渲染。2026-09-16新版本修正了一组违反该约定的字段:本体目录/版本(created_at、generated_at)、本体任务(created_at)、文档修订历史与修订产物(created_at)、评审通知投递(created_at、delivered_at)此前返回的是数据库墙上时间2026-09-17 18:03:43.226352(无T、无时区),无法被new Date()可靠解析。若您的客户端对这些字段做过“补 T 补 Z”的兼容处理,可以移除。
更新日志
2026-09-16:知识库权限重构:四处行为变化
本次重构把知识库鉴权从“漏了就放行”改成默认拒绝,角色为 viewer < editor < owner。以下四点会改变既有调用方的可观测行为,升级前请确认(其中 1、4 是放宽,2、3 是收紧或改码):
公开库默认档提升为可写。
visibility=workspace(别名public)的库,workspace 内任意成员的默认角色是editor。不仅能搜、能读,还能上传与删除库内文档(含别人上传的)。若不希望如此,把库改成private后按需授权,或给具体成员写一条viewer显式行(见知识库章节的「知识库权限(ACL)」)。ACL 行到期是硬失效。
expires_at过期的授权行等同于不存在:调用方直接回落到库默认档(公开库editor/ 私有库无权限),不会保留任何“曾经授权过”的残留权限。过期行仍会出现在 ACL 列表里,便于清理。图谱数据面的跨 workspace 响应由 403 改为 404。
GET /v1/knowledge-bases/{kbId}/graph/nodes|edges在知识库ID(kbId)跨 workspace 或不存在时,此前返回403,现在返回404(不泄漏知识库ID存在性)。按 403 分支做兜底的客户端需同时接受 404。User Key 删库不再只认创建者。
DELETE /v1/knowledge/bases/{id}此前对 User Key 走独立的“创建者”判定,被显式授予owner的成员拿到my_role=owner却删不掉库;现已统一到 ACL 判定链,owner即可删。
权限不足统一返回 403 + code=40303(ACL_FORBIDDEN)。知识库ID跨 workspace 或不存在统一返回 404。知识库详情与列表响应新增 my_role / role_source / can_manage_acl,调用方据此渲染入口,不必再靠“先试一次看是不是 403”探测权限。
API目录
上下文(Context)
POST /v1/context/ingest
将一批对话消息写入指定 session,触发后续记忆抽取与去重。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
session_id | string | 是 | 会话 ID(外部 session_id),1~128 字符 |
user_id | string | 否 | 终端用户 ID(mem0 user_id),缺省回退到 |
messages | array | 是 | 消息列表,每批最多 100 条 |
messages[].role | string | 是 |
|
messages[].content | string | 是 | 消息文本,小于等于65535 字符 |
messages[].tool_name | string | 条件 | 仅 |
messages[].metadata | object | 否 | 消息级元数据 |
messages[].resource_ids | string[] | 否 | 绑定的多模态资源 ID,至多 10 个 |
messages[].timestamp | long | 否 | 消息发生时间(epoch 秒) |
metadata | object | 否 |
|
agent_id | string | 否 | Agent 标识,持久化到 session.agent_id |
extract_mode | string | 否 | 缺省回退全局配置。
|
custom_instructions | string | 否 | 请求级蒸馏指令(仅 |
timestamp | long | 否 | 记忆发生时间( |
请求示例
curl -X POST http://<host>:4040/v1/context/ingest \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"session_id": "sess-2026-08-19-001",
"user_id": "alice",
"messages": [
{"role": "user", "content": "我最近在学习 Rust"},
{"role": "assistant", "content": "Rust 是一门关注安全性和性能的系统编程语言。"}
],
"extract_mode": "eager"
}'响应
响应参数
字段 | 类型 | 说明 |
session_id | string | 外部会话 ID(即请求传入的 |
session_internal_id | long | 内部数据库自增 ID(可能为 |
message_ids | array | 写入的消息引用列表 |
message_ids[].id | long | 消息内部 ID |
message_ids[].seq | int | 消息序列号 |
event_id | long | 记忆抽取事件 ID( |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"session_id": "sess-2026-08-19-001",
"session_internal_id": 42,
"message_ids": [
{"id": 1, "seq": 1},
{"id": 2, "seq": 2}
],
"event_id": 789
},
"trace_id": "trace-001"
}POST /v1/context/assemble
按查询装配面向 LLM 的上下文 PromptBlock,返回召回记忆与原文引用。核心端点,Agent 每次对话时调用。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
session_id | string | 条件 | 与 |
user_id | string | 条件 | 与 |
query | string | 否 | 查询文本,空值触发 |
token_budget | integer | 否 | Token 预算,取值范围:[1, 32000] |
strategy_id | long | 否 | 覆盖 ws 默认策略 |
recall.top_k | integer | 否 | 记忆召回 top_k,取值范围:[1, 50] |
recall.filters | object | 否 | ES filter 键值对 |
recall.cosine_threshold | double | 否 | 余弦相关性下限,取值范围:[0, 1] |
include | string[] | 否 | 强制包含的 PromptBlock 类型 |
exclude | string[] | 否 | 强制排除的 PromptBlock 类型 |
recent_messages_fetch_limit | integer | 否 | 近期消息抓取上限,取值范围:[1, 1000] |
bootstrap_top_l0 | integer | 否 | 冷启动 L0 实体卡 top-N,取值范围:[0, 100] |
bootstrap_top_l1 | integer | 否 | 冷启动 L1 事实 top-N,取值范围:[0, 100] |
budget_allocator | object | 否 | Token 预算分配比例覆盖 |
budget_allocator.memory_ratio | double | 否 | 记忆占比 |
budget_allocator.knowledge_ratio | double | 否 | 知识库占比 |
budget_allocator.history_ratio | double | 否 | 历史占比 |
budget_allocator.system_ratio | double | 否 | 系统占比 |
knowledge_base_ids | long[] | 否 | 限定知识库检索的知识库 ID 列表;去重后上限 100 个,含 |
knowledge_top_k | integer | 否 | 知识库检索 top_k,取值范围:[1, 50] |
include_multimodal | boolean | 否 | 是否注入多模态 PromptBlock,默认 |
multimodal_max_images | integer | 否 | 每次最多注入的多模态块数,取值范围:[0, 50] |
context_scope | string | 否 |
|
include_memories | boolean | 否 | 细粒度覆盖:强制开/关记忆维度 |
include_knowledge | boolean | 否 | 细粒度覆盖:强制开/关知识库维度 |
include_wiki | boolean | 否 | 是否注入 Wiki 页面 lane(tag |
inherit_summary | boolean | 否 | 是否继承上次的 |
inherit_from_session_id | string | 否 | 显式指定继承哪个 |
请求示例
curl -X POST http://<host>:4040/v1/context/assemble \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"session_id": "sess-2026-08-19-001",
"query": "Rust 的所有权机制是什么?",
"token_budget": 4096,
"recall": {"top_k": 10, "cosine_threshold": 0.3}
}'响应
响应参数
字段 | 类型 | 说明 |
prompt_blocks | array | PromptBlock 列表,Agent 应按序拼入 LLM prompt |
prompt_blocks[].role | string |
|
prompt_blocks[].tag | string | 类型标签( |
prompt_blocks[].content | string | 正文 |
prompt_blocks[].tokens | int | 该 block 消耗的 token 数 |
prompt_blocks[].sources | string[] | 来源引用列表(如 |
token_used | int | 实际消耗的总 token 数 |
token_budget | int | 请求传入的 token 预算 |
trace_id | string | 链路追踪 ID |
stats | object | 装配统计信息 |
stats.recall_total | int | 总召回记忆数 |
stats.recall_kept | int | 经裁剪后保留的记忆数 |
stats.messages_total | int | 总消息数 |
stats.messages_kept | int | 经裁剪后保留的消息数 |
stats.took_ms | long | 装配耗时(毫秒) |
stats.multimodal_kept | int | 多模态 block 数量 |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"prompt_blocks": [
{"role": "system", "tag": "user_profile", "content": "用户正在学习 Rust...", "tokens": 42, "sources": ["memory:mem_1_2_abc"]},
{"role": "system", "tag": "memory_recall", "content": "- 用户喜欢系统编程\n- ...", "tokens": 128, "sources": ["memory:mem_1_2_def"]},
{"role": "system", "tag": "recent_history", "content": "...", "tokens": 256, "sources": []}
],
"token_used": 426,
"token_budget": 4096,
"trace_id": "trace-001",
"stats": {
"recall_total": 5,
"recall_kept": 3,
"messages_total": 20,
"messages_kept": 10,
"took_ms": 142,
"multimodal_kept": 0
}
}
}POST /v1/context/compact
增量压缩会话上下文,按 chunk_size 折叠最早的活跃消息为叶子摘要。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
session_id | string | 是 | 会话 ID |
keep_recent_n | integer | 否 | 保留最近活跃消息条数,默认 50,范围 [1, 500] |
chunk_size | integer | 否 | 单次折叠消息条数,默认 20,范围 [5, 200] |
model_hint | string | 否 | 覆盖默认 LLM 模型 |
请求示例
curl -X POST http://<host>:4040/v1/context/compact \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"session_id": "sess-2026-08-19-001", "keep_recent_n": 30}'响应
响应参数
字段 | 类型 | 说明 |
session_id | string | 外部会话 ID |
session_internal_id | long | 内部数据库自增 ID |
summary_message_id | long | 生成的摘要消息 ID |
compacted_message_count | int | 被压缩的消息数 |
summary_token_count | int | 摘要 token 数 |
active_message_count | int | 压缩后仍活跃的消息数 |
depth | integer | 压缩深度(叶子摘要为 0) |
source_seq_range | int[] | 被压缩的消息序列范围 [firstSeq, lastSeq] |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"session_id": "sess-2026-08-19-001",
"session_internal_id": 42,
"summary_message_id": 101,
"compacted_message_count": 20,
"summary_token_count": 180,
"active_message_count": 50,
"depth": 0,
"source_seq_range": [1, 20]
}
}POST /v1/context/flush
将短期上下文落盘为长期记忆与事件。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
session_id | string | 是 | 会话 ID |
compact_first | boolean | 否 | 落盘前是否先 compact,默认 true |
keep_recent_n | integer | 否 | compact 时保留的近 N 条消息,默认 20,范围 [1, 500] |
请求示例
curl -X POST http://<host>:4040/v1/context/flush \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"session_id": "sess-2026-08-19-001", "compact_first": true}'响应
响应参数
字段 | 类型 | 说明 |
session_id | string | 外部会话 ID |
session_internal_id | long | 内部数据库自增 ID |
status | string | 会话状态( |
flushed_at | string | 落盘时间(ISO-8601) |
compact_summary | object | 落盘前 compact 的摘要(compact_first=true 时有值),结构同 compact 响应 |
evolve_event_id | long | 记忆蒸馏事件 ID |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"session_id": "sess-2026-08-19-001",
"session_internal_id": 42,
"status": "flushed",
"flushed_at": "2026-08-19T10:30:00Z",
"compact_summary": {
"session_id": "sess-2026-08-19-001",
"compacted_message_count": 20,
"summary_token_count": 180,
"active_message_count": 30
},
"evolve_event_id": 1001
}
}POST /v1/context/lifecycle
上报上下文生命周期事件,按 action 分发驱动 session 状态机。action=start 会创建/打开会话并返回首屏装配的 PromptBlock;action=end 会关闭会话并返回收尾统计。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
action | string | 是 | start / end |
session | object | 是(start) | action=start 时必填,描述新会话的元信息 |
session.external_id | string | 是(start) | 外部 session ID,action=start 时必填。取值范围: |
session.user_id | string | 否 | 终端用户 ID(mem0 user_id),落库到 session.user_id。省略 / null 表示未指定,非空时必须匹配 |
session.agent_id | string | 否 | Agent 标识,≤128 字符 |
session.title | string | 否 | 会话标题,≤256 字符 |
session.metadata | object | 否 | 自定义元数据 |
session_id | string | 条件 | action=end 时必填,会话 ID |
user_id | string | 否 | action=end 可选。
|
query | string | 否 | action=start 可选,配合 token_budget 决定首条 prompt 装配 |
token_budget | integer | 否 | action=start 可选,Token 预算 [1, 32000] |
请求示例
start
curl -X POST http://<host>:4040/v1/context/lifecycle \ -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \ -d '{ "action": "start", "session": {"external_id": "sess-2026-08-19-001", "user_id": "alice", "agent_id": "my-agent"}, "query": "继续上次的 Rust 讨论", "token_budget": 4096 }'end
curl -X POST http://<host>:4040/v1/context/lifecycle \ -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \ -d '{"action": "end", "session_id": "sess-2026-08-19-001", "user_id": "alice"}'
Owner Key 代表 workspace,不能仅凭 Key 推断某个终端用户。
若 start 时使用了
session.user_id,end 时应传相同的顶层user_id,使关闭与 flush 落在同一终端用户/member 身份上。只有
start/end都省略该值时,两个动作才都回退到 Key 绑定的 member。User Key 仍受 own-user 校验约束;空串不作为“缺失”接受。
响应
响应参数
字段 | 类型 | 说明 |
session_id | string | 外部会话 ID |
session_internal_id | long | 内部数据库自增 ID |
prompt_blocks | array | 仅 action=start 返回,结构同 /v1/context/assemble |
token_used / token_budget / trace_id / stats | - | 仅 action=start 返回,语义同 assemble |
message_count | int | 仅 action=end 返回,会话累计消息数 |
total_tokens | long | 仅 action=end 返回,会话累计 Token |
event_id | long | 仅 action=end 返回,收尾生成的事件 ID |
空值字段(NON_NULL)不输出:start 只返回装配相关字段,end 只返回收尾相关字段。
响应示例
start,含装配结果:
{ "code": 0, "msg": "ok", "data": { "session_id": "sess-2026-08-19-001", "session_internal_id": 42, "prompt_blocks": [ {"role": "system", "tag": "user_profile", "content": "用户正在学习 Rust...", "tokens": 42, "sources": ["memory:mem_1_2_abc"]} ], "token_used": 42, "token_budget": 4096, "trace_id": "trace-001", "stats": {"recall_total": 3, "recall_kept": 1, "messages_total": 0, "messages_kept": 0, "took_ms": 88} } }end,含收尾统计:
{ "code": 0, "msg": "ok", "data": {"session_id": "sess-2026-08-19-001", "message_count": 45, "total_tokens": 12800, "event_id": 789} }
POST /v1/context/dialectic
在上下文召回结果上进行辩证分析,输出多视角证据与判断。需提供 session_id 或 user_id 至少一项(禁止 workspace 全域召回)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
query | string | 是 | 查询文本 |
session_id | string | 条件 | 会话 ID(可选,绑定召回作用域);与 user_id 至少一项必填 |
user_id | string | 条件 | 用户 ID(可选,限定召回的用户隔离);与 session_id 至少一项必填 |
depth | string | 否 | 分析深度: |
top_k | integer | 否 | 返回 top-k [1, 20],默认 5 |
scope | string | 否 | 保留字段(未来用于 |
请求示例
curl -X POST http://<host>:4040/v1/context/dialectic \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"query": "Rust 的所有权模型有什么优缺点?",
"user_id": "alice",
"depth": "standard",
"top_k": 5
}'响应
响应参数
字段 | 类型 | 说明 |
depth | string | 实际使用的分析深度 |
hits_count | int | 召回命中数 |
latency_ms | long | 分析耗时(毫秒) |
prompt_blocks | array | PromptBlock 列表,结构同 |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"depth": "standard",
"hits_count": 5,
"latency_ms": 230,
"prompt_blocks": [
{"role": "system", "tag": "dialectic_analysis", "content": "## 多视角分析\n\n**正面证据**:...\n**反面证据**:...", "tokens": 320, "sources": ["memory:mem_1_2_abc"]}
]
}
}会话(Session)
POST /v1/sessions
创建或获取现有会话(幂等)。若 externalId 已存在则返回已有会话。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
external_id | string | 是 | 外部会话 ID,取值范围:1~128 字符 |
agent_id | string | 否 | Agent 标识,小于等于128 字符 |
title | string | 否 | 会话标题,小于等于256 字符 |
metadata | string | 否 | JSON 格式元数据字符串 |
user_id | string | 否 | 终端用户 ID,小于等于128 字符 |
session_key | string | 否 | 线程 key,用于跨会话继承链,小于等于64 字符 |
parent_session_id | string | 否 | 显式父会话的 external_id,小于等于128 字符 |
请求示例
curl -X POST http://<host>:4040/v1/sessions \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"external_id": "sess-2026-08-19-001", "agent_id": "my-agent", "user_id": "alice"}'响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"session": {
"id": 1,
"external_id": "sess-2026-08-19-001",
"agent_id": "my-agent",
"user_id": "alice",
"status": "open",
"title": null,
"message_count": 0,
"total_tokens": 0,
"session_key": null,
"parent_session_id": null,
"created_at": "2026-08-19T10:00:00Z",
"updated_at": "2026-08-19T10:00:00Z",
"closed_at": null
},
"created": true
}
}session.id 是内部数据库自增主键(Long 类型),session.external_id 是调用方传入的外部会话标识。
GET /v1/sessions
分页列出当前租户会话。User Key 只看自己的,Owner Key看全 workspace。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
agent_id | string | 否 | 按 agent 过滤 |
status | string | 否 | 按状态过滤( |
page | integer | 否 | 页码(从0开始),默认 0 |
page_size | integer | 否 | 每页大小,默认 20,上限 200 |
请求示例
curl "http://<host>:4040/v1/sessions?status=open&page_size=10" \
-H "X-API-Key: $API_KEY"响应说明:返回 Box<List<SessionDto>>,分页信息通过响应头 X-Total-Count、X-Page、X-Page-Size、X-Has-More 暴露。
GET /v1/sessions/{id}
获取指定会话详情。{id} 为 externalId 或内部 ID。
请求
请求示例
curl "http://<host>:4040/v1/sessions/sess-2026-08-19-001" \
-H "X-API-Key: $API_KEY"PATCH /v1/sessions/{id}
部分更新会话属性(如 title / metadata)。
请求
请求示例
curl -X PATCH http://<host>:4040/v1/sessions/sess-2026-08-19-001 \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"title": "Rust 学习会话"}'POST /v1/sessions/{id}/messages
向会话追加一批消息。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
messages | array | 是 | 消息列表,每条含 |
messages[].role | string | 是 |
|
messages[].content | string | 是 | 消息文本 |
messages[].toolName | string | 条件 |
|
请求示例
curl -X POST http://<host>:4040/v1/sessions/sess-2026-08-19-001/messages \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "什么是 borrow checker?"}]}'GET /v1/sessions/{id}/messages
按 since_seq 增量拉取或按 before_seq 倒序拉取会话消息。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
since_seq | integer | 否 | 从该序列号之后开始拉取,默认 0 |
before_seq | integer | 否 | 拉取该序列号之前的消息 |
order | string | 否 | asc(默认)/ desc |
limit | integer | 否 | 返回条数,默认 50,上限 200 |
page_size | integer | 否 | limit 的兼容别名,范围 [1, 200] |
size | integer | 否 | limit 的兼容别名,范围 [1, 200] |
limit、page_size、size 只能提供一个;同时提供多个时返回 400。
请求示例
curl "http://<host>:4040/v1/sessions/sess-2026-08-19-001/messages?since_seq=0&limit=50" \
-H "X-API-Key: $API_KEY"响应
返回 Box<MessagePage>,MessagePage 含 items(消息数组)和 total(总数)。响应头包含 X-Total-Count。
PUT /v1/sessions/{id}/close
关闭会话,可选生成交接摘要(handoff)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
generate_summary | boolean | 否 | 是否生成 handoff 摘要,默认 |
请求示例
curl -X PUT http://<host>:4040/v1/sessions/sess-2026-08-19-001/close \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"generate_summary": true}'DELETE /v1/sessions/{id}
物理删除指定会话及其消息。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/sessions/sess-2026-08-19-001 \
-H "X-API-Key: $API_KEY"GET /v1/sessions/{id}/inheritance
返回会话的继承链,展示跨会话上下文传递关系。
请求
请求示例
curl "http://<host>:4040/v1/sessions/sess-2026-08-19-001/inheritance" \
-H "X-API-Key: $API_KEY"GET /v1/sessions/stats
返回会话聚合统计(总数/活跃/关闭/继承/累计 Token)。
请求
请求示例
curl "http://<host>:4040/v1/sessions/stats" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"total": 5,
"open": 4,
"closed": 1,
"inherited": 0,
"total_tokens": 32
}
}GET /v1/sessions/{id}/token-stats
返回指定会话的 Token 用量统计,包含按角色拆分的 Token 计数和所用 tokenizer。
请求
请求示例
curl "http://<host>:4040/v1/sessions/3/token-stats" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"total_tokens": 26,
"message_count": 4,
"by_role": {
"user": 23,
"assistant": 3
},
"token_estimator": "cl100k_base"
}
}记忆(Memory)
POST /v1/memories
Mem0 兼容的记忆创建接口。自动触发去重与蒸馏。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
messages | array | 是 | 对话消息列表( |
user_id | string | 否 | 终端用户 ID,省略时由 API key 身份推导 |
agent_id | string | 否 | Agent 标识 |
run_id | string | 否 | 运行实例标识 |
metadata | object | 否 | 自定义元数据键值对 |
custom_instructions | string | 否 | 请求级蒸馏指令,小于等于8192 字符 |
timestamp | long | 否 | 发生时间(epoch 秒) |
请求示例
curl -X POST http://<host>:4040/v1/memories \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "我喜欢用 Vim 编辑器"},
{"role": "assistant", "content": "好的,我记住了你偏好 Vim。"}
],
"user_id": "alice"
}'响应
响应示例
{"results": [{"id": "mem_1_2_abc123", "memory": "用户偏好使用 Vim 编辑器", "event": "ADD"}]}POST /v3/memories/add
V3 记忆写入,返回包含 memory_id / event_id / created 的 Box 响应。 请求参数:与 POST /v1/memories 相同。
请求
请求示例
curl -X POST http://<host>:4040/v3/memories/add \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "我的技术栈是 Java + Spring Boot"}],
"user_id": "alice"
}'响应
响应示例
{"code": 0, "msg": "ok", "data": {"memory_id": "mem_1_2_def456", "event_id": "evt_789", "created": true}}POST /v3/memories
Mem0 v1.1 SDK 兼容的记忆列表接口。实体过滤参数(user_id / agent_id / run_id)既可放在请求体顶层,也可放在 filters map 中,分页通过 query 参数控制。返回 Mem0 云端同款分页信封(裸 JSON,无 Box 包装)。
请求
请求参数
参数 | 位置 | 类型 | 必填 | 说明 |
user_id / userId | body | string | 否 | 顶层用户过滤;服务端解析为租户内 |
agent_id / agentId | body | string | 否 | 顶层 Agent 过滤 |
run_id / runId | body | string | 否 | 顶层 Run 过滤 |
filters | body | object | 否 | 实体过滤 map,接受上述 |
page | query | integer | 否 | 页码(从1开始),默认 1 |
page_size | query | integer | 否 | 每页大小,默认 100,范围 [1, 200] |
请求示例
curl -X POST "http://<host>:4040/v3/memories?page=1&page_size=50" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"user_id": "alice"}'响应
响应参数
字段 | 类型 | 说明 |
count | long | 匹配的记忆总数 |
next | string | 下一页 URL;无更多时为 null |
previous | string | 上一页 URL;首页为 null |
results | array | 本页记忆列表(Mem0 记忆结构) |
响应示例
{
"count": 156,
"next": "/v3/memories/?page=2&page_size=50",
"previous": null,
"results": [
{"id": "mem_1_2_abc123", "memory": "用户偏好使用 Vim 编辑器", "metadata": {}}
]
}POST /v3/entity_cards/{id}/edit
对 L0 实体卡的 role / preferences / attributes 进行部分更新(partial update)。仅传入的字段被覆写,未传(null)字段保持不变。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
role | string | 否 | 实体角色(如 |
preferences | string[] | 否 | 偏好列表 |
attributes | object | 否 | 开放属性 map,键随卡类型而定( |
请求示例
curl -X POST http://<host>:4040/v3/entity_cards/card_1_2_alice/edit \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"role": "资深后端工程师", "preferences": ["Java", "Spring Boot"]}'响应
响应参数
字段 | 类型 | 说明 |
card_id | string | 实体卡 ID |
metadata | object | 合并后的完整实体卡 metadata(含 |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"card_id": "card_1_2_alice",
"metadata": {"role": "资深后端工程师", "preferences": ["Java", "Spring Boot"], "attributes": {}}
}
}GET /v1/memories
按 user_id / agent_id / run_id 过滤分页列出记忆。Mem0 兼容裸 JSON 数组响应。
分页窗口约束:offset + limit 不得超过 10000,超出返回 400。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
user_id | string | 否 | 终端用户过滤 |
agent_id | string | 否 | Agent 过滤 |
run_id | string | 否 | 运行实例过滤 |
doc_type | string | 否 | 按类型过滤( |
limit | integer | 否 | 返回条数,默认 100,上限 200(与 page_size 互斥) |
offset | integer | 否 | 偏移量,默认 0(与 page 互斥) |
page | integer | 否 | 页码(从0开始),兼容老调用 |
page_size | integer | 否 | 每页大小,兼容老调用 |
start_date | string | 否 | 更新时间下界(ISO-8601) |
end_date | string | 否 | 更新时间上界(ISO-8601) |
请求示例
curl "http://<host>:4040/v1/memories?user_id=alice&limit=20" \
-H "X-API-Key: $API_KEY"GET /v1/memories/{id}
根据 memory_id 获取单条记忆详情。
请求
请求示例
curl "http://<host>:4040/v1/memories/mem_1_2_abc123" -H "X-API-Key: $API_KEY"PUT /v1/memories/{id}
更新指定记忆的内容或元数据。
请求
请求示例
curl -X PUT http://<host>:4040/v1/memories/mem_1_2_abc123 \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"text": "用户偏好使用 Neovim 编辑器"}'DELETE /v1/memories/{id}
删除单条记忆。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/memories/mem_1_2_abc123 -H "X-API-Key: $API_KEY"响应
响应示例
{"message": "memory deleted", "id": "mem_1_2_abc123"}DELETE /v1/memories/clear
批量清理记忆,按 scope 范围删除。不可逆操作,需 confirm=true。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
confirm | boolean | 是 | 必须为 |
scope | string | 否 |
|
before_date | string | 条件 |
|
session_ids | string[] | 条件 |
|
请求示例
curl -X DELETE http://<host>:4040/v1/memories/clear \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"confirm": true, "scope": "all"}'响应
响应示例
{"message": "memories cleared", "deleted": 42, "scope": "all"}POST /v1/memories/search
V1 记忆语义检索,仅 L1-only(不执行 L2 原文 BM25 召回),作为 Mem0 基线路径。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
query | string | 是 | 查询语句 |
user_id | string | 否 | 终端用户过滤 |
agent_id | string | 否 | Agent 过滤 |
run_id | string | 否 | 运行实例过滤 |
filters | object | 否 | 附加 ES filter |
limit | integer | 否 | 返回条数 [1, 200],默认 10(兼容 top_k) |
vector_only | boolean | 否 | true 关闭 BM25 词法通道,纯向量 kNN |
cosine_threshold | float | 否 | 余弦相关性下限 [0, 1](兼容 threshold);缺省时由服务端注入默认阈值 0.2 |
exclude_l2 | boolean | 否 | true 排除 L2 占位符 |
Owner Key 调用 search 端点必须显式传入 user_id,否则返回 400 VALIDATION_FAILED。
请求示例
curl -X POST http://<host>:4040/v1/memories/search \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"query": "用户喜欢什么编辑器?", "user_id": "alice", "limit": 5}'响应
响应示例
[
{"id": "mem_1_2_abc123", "memory": "用户偏好使用 Vim 编辑器", "score": 0.92, "metadata": {}},
{"id": "mem_1_2_def456", "memory": "用户使用 Neovim 插件", "score": 0.85, "metadata": {}}
]POST /v2/memories/search
V2 记忆检索,L1 + L2 原文 BM25 召回。相比 V1 额外执行 L2 源文本的 BM25 检索,适合需要原文溯源的场景。
请求
请求参数
请求参数与 V1 相同,额外支持:
参数 | 类型 | 必填 | 说明 |
include_l2 | boolean | 否 | 显式控制 L2 开关(未传时服务端默认开启) |
V2 是推荐的搜索端点。include_l2 未传时由服务端 include-l2-default 配置决定(默认 true)。cosine_threshold 缺省时由服务端注入默认阈值 0.2;Owner Key 调用必须显式传入 user_id,否则返回 400 VALIDATION_FAILED。
请求示例
curl -X POST "$HOST/v2/memories/search"POST /v3/memories/search
V3 搜索,Mem0 v1.1 SDK 兼容格式。user_id 等实体参数放在 filters map 中。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
query | string | 是 | 查询语句 |
filters | object | 否 | 含 |
limit | integer | 否 | 返回条数 |
vector_only | boolean | 否 | 纯向量模式 |
include_l2 | boolean | 否 | L2 开关 |
cosine_threshold | float | 否 | 余弦下限;缺省时由服务端注入默认阈值 0.1 |
Owner Key 调用 search 端点必须显式传入 user_id,否则返回 400 VALIDATION_FAILED。V3 的 user_id 承载在 filters map 内(filters.user_id,也接受 filters.userId 与顶层 user_id);顶层与 filters 内取值冲突时同样返回 400 VALIDATION_FAILED。
请求示例
curl -X POST http://<host>:4040/v3/memories/search \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"query": "用户的技术栈", "filters": {"user_id": "alice"}, "limit": 10}'响应
响应示例
{"results": [{"id": "mem_1_2_def456", "memory": "用户技术栈是 Java + Spring Boot", "score": 0.88}]}POST /v1/memories/{id}/pin
置顶记忆,提升召回优先级。
请求
请求示例
curl -X POST http://<host>:4040/v1/memories/mem_1_2_abc123/pin -H "X-API-Key: $API_KEY"POST /v1/memories/{id}/unpin
取消置顶。
请求
请求示例
curl -X POST http://<host>:4040/v1/memories/mem_1_2_abc123/unpin -H "X-API-Key: $API_KEY"POST /v3/memories/{id}/invalidate
标记记忆失效(invalid_at=now()),使其不再被检索召回。
请求
请求示例
curl -X POST http://<host>:4040/v3/memories/mem_1_2_abc123/invalidate -H "X-API-Key: $API_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"id": "mem_1_2_abc123", "invalid_at": "2026-08-19T10:30:00Z"}}POST /v3/memories/{id}/promote
将 session 作用域的记忆提升为 user 作用域,使其跨会话保留。
请求
请求示例
curl -X POST http://<host>:4040/v3/memories/mem_1_2_abc123/promote -H "X-API-Key: $API_KEY"GET /v1/memories/{id}/history
返回指定记忆的所有版本变更记录。Mem0 兼容裸 JSON 数组。
请求
请求示例
curl "http://<host>:4040/v1/memories/mem_1_2_abc123/history" -H "X-API-Key: $API_KEY"响应
响应示例
[
{"id": 1, "version": 1, "event_type": "ADD", "content_after": "用户偏好 Vim", "created_at": "2026-08-19T10:00:00Z"},
{"id": 2, "version": 2, "event_type": "UPDATE", "content_before": "用户偏好 Vim", "content_after": "用户偏好 Neovim", "created_at": "2026-08-19T11:00:00Z"}
]GET /v1/memories/{id}/source-texts
查看产生该 L1 记忆的 L2 原始对话消息(溯源)。
请求
请求示例
curl "http://<host>:4040/v1/memories/mem_1_2_abc123/source-texts" -H "X-API-Key: $API_KEY"GET /v1/memories/distill-prompt
查询当前成员的蒸馏规则配置及生效状态。无需 OWNER 权限,每个认证成员可管理自己的蒸馏规则。
请求
请求参数
参数 | 类型 | 说明 |
configured | boolean | 是否存在配置行 |
custom_prompt | string | 已配置的自定义蒸馏提示词;未配置为 |
enabled | boolean | 配置行业务开关 |
rollout_enabled | boolean | 特性开关是否对本 Workspace 放量 |
effective | boolean | 是否实际生效( |
effective_source | string | 生效来源: |
updated_at | string | 最后更新时间(ISO-8601) |
member_id | long | 所属 member ID(workspace 默认行为 |
请求示例
curl "http://<host>:4040/v1/memories/distill-prompt" -H "X-API-Key: $API_KEY"响应
响应参数
字段 | 类型 | 说明 |
configured | boolean | 是否存在配置行 |
custom_prompt | string | 已配置的自定义蒸馏提示词;未配置为 null |
enabled | boolean | 配置行业务开关 |
rollout_enabled | boolean | 特性开关是否对本 Workspace 放量 |
effective | boolean | 是否实际生效( |
effective_source | string | 生效来源: |
updated_at | string | 最后更新时间(ISO-8601) |
member_id | long | 所属 member ID(workspace 默认行为 null) |
PUT /v1/memories/distill-prompt
创建或更新当前成员的蒸馏规则;返回更新后的完整状态。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
custom_prompt | string | 是 | 自定义蒸馏提示词,小于等于 8192 字符 |
enabled | boolean | 否 | 业务开关,缺省 |
请求示例
curl -X PUT http://<host>:4040/v1/memories/distill-prompt \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"custom_prompt": "请重点提取用户的技术栈偏好和工作流习惯", "enabled": true}'响应
同GET /v1/memories/distill-prompt。
DELETE /v1/memories/distill-prompt
删除当前成员的蒸馏规则(幂等);删除后回退到 workspace 默认或内置 prompt。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/memories/distill-prompt -H "X-API-Key: $API_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": null}POST /v3/memories/{id}/feedback
提交记忆反馈信号(thumbs up/down / 显式/隐式反馈)。负反馈触发 Dream 反证流水线。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
signal_type | string | 是 | 反馈类型(四种):
|
channel | string | 否 | 反馈渠道标识 |
session_id | string | 否 | 关联的会话 ID |
recall_path | string | 否 | 召回路径: |
corrected_content | string | 否 | 用户提供的修正内容 |
信号类型说明
类型 | 效果 |
| 用户/Agent 显式点赞。hotness +0.2 |
| 用户/Agent 显式踩踏。hotness -0.2 + 触发 Dream 反证流水线 |
| 隐式正向信号(复用、停留)。hotness +0.1 |
| 隐式负向信号(跳过、拒绝)。hotness -0.1 |
请求示例
curl -X POST http://<host>:4040/v3/memories/mem_1_2_abc123/feedback \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"signal_type": "negative_explicit", "recall_path": "vector", "corrected_content": "用户已从 Vim 切换到 Neovim"}'GET /v3/memories/{id}/feedback
分页查询指定记忆的反馈历史。
请求
page(从0开始,默认 0)、size(默认 20,上限 100)。
请求示例
curl -X GET "$HOST/v3/memories/{id}/feedback"GET /v1/memories/stats
返回记忆聚合统计(总数/事实/实体/源文本)。Box 包装响应。
请求
请求参数
Query 参数:user_id、agent_id、run_id(均可选)。
请求示例
curl "http://<host>:4040/v1/memories/stats?user_id=alice" -H "X-API-Key: $API_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"total": 156, "facts": 120, "entities": 12, "sources": 24}}GET /v1/memories/relations
查询指定实体的记忆关系图谱(节点 + 边),用于可视化记忆之间的关联关系。返回以 entity_id 为中心、指定深度内的关系网络。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
entity_id | string | 是 | 起始实体 ID |
depth | integer | 否 | 遍历深度,默认 1 |
include_all_members | boolean | 否 | 是否包含 workspace 全部成员的关系(默认 false,仅 Owner Key可开启;User Key 传 true 返回 403) |
请求示例
curl "http://<host>:4040/v1/memories/relations?entity_id=alice&depth=2" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"nodes": [
{"id": "alice", "label": "alice"},
{"id": "rust-project", "label": "rust-project"}
],
"edges": [
{"from": "alice", "to": "rust-project", "label": "works_on"}
]
}
}GET /v1/memory_promotions
分页列出当前成员的记忆晋升记录(含手动发起和定时产生的晋升)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
page | integer | 否 | 页码(从0开始),默认 0 |
pageSize | integer | 否 | 每页大小,默认 20 |
status | string | 否 | 按状态过滤: |
memberId | long | 否 | 按成员过滤(Owner Key可用;User Key 自动限定为自己) |
请求示例
curl "http://<host>:4040/v1/memory_promotions?page=0&pageSize=10" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"content": [
{
"id": 1,
"topic": "总结本周架构决策",
"title": null,
"status": "generating",
"source_type": "scheduled",
"target_member_id": 4,
"memory_count": 0,
"verification_degraded": false,
"created_at": "2026-09-16T01:03:20Z",
"updated_at": "2026-09-16T01:03:20Z"
}
],
"total_elements": 1,
"total_pages": 1
}
}status 说明:
generating(生成中)、pending_review(待审批)、approved(已通过)、rejected(已驳回)。source_type 说明:
manual(手动发起)、scheduled(定时任务触发)。
POST /v1/memory_promotions/generate
手动发起一次记忆晋升生成,将当前成员的记忆根据 topic 提炼为知识文档候选。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
topic | string | 是 | 晋升主题 / 提示词 |
target_kb_id | long | 否 | 自动审批的目标知识库 ID |
请求示例
curl -X POST "http://<host>:4040/v1/memory_promotions/generate" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"topic": "总结本周架构决策", "target_kb_id": 3}'GET /v1/memory_promotions/{promotionId}
获取指定晋升记录详情。
请求
请求示例
curl "http://<host>:4040/v1/memory_promotions/1" -H "X-API-Key: $API_KEY"附录:V1/V2/V3 搜索版本差异
版本 | 路径 | L2 原文召回 | 响应格式 | 适用场景 |
V1 |
| 关闭(L1-only) | 裸数组 | Mem0 基线兼容 |
V2 |
| 默认开启 | 裸数组 | 推荐,支持原文溯源 |
V3 |
| 默认开启 |
| Mem0 v1.1 SDK 兼容 |
知识库(Knowledge)
知识库权限(ACL)
四个端点全部要求该知识库的 owner 权限:Owner Key 全局放行;知识库创建者与被授予 owner 角色的成员是委派管理员;其他成员 403(40303),kbId 跨 workspace 或不存在 404。
方法 | 路径 | 说明 |
|
| 授予一条显式权限行(同一主体重复授予 409,不是改写) |
|
| 列出该库全部显式权限行(含已过期行) |
|
| 授权候选人:本 workspace 成员 + 各自已有的显式行角色 |
|
| 撤销一条权限行 |
三条必须先理解的语义:
显式行是终局裁决,不是下限。写一条
viewer到公开库上,该成员就从默认的editor降为只读,而不是“至少 viewer”。denied是动作而不是一档权限。它用于在公开库上彻底关掉某个成员的默认档;它不出现在my_role里(无权访问时my_role为null、role_source为denied)。到期是硬失效。过期行等同于没有这一行 → 回落到库默认档(公开库
editor/ 私有库无权限)。过期行仍在GET .../acl结果中列出,便于清理;判断是否已失效请比较expires_at与当前时间。
POST /v1/knowledge/bases/{kbId}/acl
请求
请求参数
参数 | 类型 | 必填 | 说明 |
subject_type | string | 是 | 固定 |
subject_id | string | 是 | 授权主体 ID,即 |
role | string | 是 |
|
expires_at | string | 否 | 到期时间(ISO-8601)。 |
granted_by | string | 否 | 授权人标识;缺省取调用方 |
请求体里的
kb_id会被忽略,一律以 path 上的kbId为准。(kb_id, subject_type, subject_id)唯一:同一主体重复 POST 返回 409(40901,msg为ACL already exists for (kb_id, subject_type, subject_id)),不是改写。改角色请先DELETE .../acl/{aclId}再 POST。参数校验失败统一 400
40001(VALIDATION_FAILED)。
请求示例
# 给 member 42 授予编辑权,7 天后到期
curl -X POST http://<host>:4040/v1/knowledge/bases/1/acl \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"subject_type": "member", "subject_id": "42", "role": "editor", "expires_at": "2026-09-23T00:00:00Z"}'
# 把公开库上的 member 43 降为只读(显式行终局裁决,不是"至少 viewer")
curl -X POST http://<host>:4040/v1/knowledge/bases/1/acl \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"subject_type": "member", "subject_id": "43", "role": "viewer"}'
# 彻底关掉公开库上 member 44 的默认档
curl -X POST http://<host>:4040/v1/knowledge/bases/1/acl \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"subject_type": "member", "subject_id": "44", "role": "denied"}'响应
响应参数
字段 | 类型 | 说明 |
id | long | 授权行 ID,撤销时用( |
kb_id / workspace_id | long | 所属知识库 / workspace |
subject_type | string | 固定 |
subject_id | string |
|
role | string |
|
granted_by | string | 授权人标识 |
granted_at | string | 授权时间(ISO-8601) |
expires_at | string | 到期时间; |
subject_name | string | 主体成员名(只读展示字段;member 已被删除时为 |
subject_user_id | string | 主体成员的外部 |
subject_name / subject_user_id 是本次追加的只读展示字段,老字段的类型与语义未变。member 被删除后授权行仍在(此时两者为 null),需要显式 DELETE 清理。
响应示例
GET 返回同结构的数组:
{"code": 0, "msg": "ok", "data": {"id": 7, "kb_id": 1, "workspace_id": 1, "subject_type": "member", "subject_id": "42", "role": "editor", "granted_by": "2", "granted_at": "2026-09-16T10:00:00Z", "expires_at": "2026-09-23T00:00:00Z", "subject_name": "alice", "subject_user_id": "u-alice"}}GET /v1/knowledge/bases/{kbId}/acl/candidates
请求
请求示例
curl "http://<host>:4040/v1/knowledge/bases/1/acl/candidates" -H "X-API-Key: $API_KEY"响应
响应参数
字段 | 类型 | 说明 |
member_id | long | 成员 ID,即写 ACL 时提交的 |
user_id | string | 成员的外部 |
name | string | 成员名 |
current_role | string | 该成员在本知识库上已有显式行的角色; |
2026-09-16 修复:current_role 此前把已过期的行(expires_at <= now)也算作当前角色,与鉴权侧「过期行等同于没有这一行」的硬失效语义相反 —— 同一个成员在知识库详情里是 role_source: kb_default,在这里却还挂着上个月就到期的 denied。现在过期行不再出现在 current_role 里(字段类型与取值范围未变,仅口径与鉴权对齐)。要看到并清理过期行请用 GET /v1/knowledge/bases/{kbId}/acl,它按设计含过期行。
响应示例
{"code": 0, "msg": "ok", "data": [
{"member_id": 42, "user_id": "u-alice", "name": "alice", "current_role": "editor"},
{"member_id": 43, "user_id": "u-bob", "name": "bob", "current_role": null}
]}DELETE /v1/knowledge/bases/{kbId}/acl/{aclId}
请求
请求示例
curl -X DELETE http://<host>:4040/v1/knowledge/bases/1/acl/7 -H "X-API-Key: $API_KEY"撤销后该成员回落到库默认档(公开库 editor / 私有库无权限)—— 撤销 denied 行会把公开库的默认可写权限还给他。返回 Box<Void>(data 为 null)。
aclId 必须属于 URL 里的 kbId,否则 404(与“该行不存在”同码,不泄漏“这个 id 存在但属于别的库”)。2026-09-17 修复:此前只按 (aclId, workspaceId) 定位行,而鉴权看的是 kbId —— 于是任何在某一个库上是 owner 的成员(哪怕只是自己刚建的库)都能拿那个 kbId 当门票,删掉同 workspace 内任意其它库的授权行,包括别人的 owner 行和正锁着自己的 denied 行。这是收紧:以前能成功的跨库删除现在返回 404,配对正确的 kbId 行为不变。
POST /v1/knowledge/bases
创建一个新知识库。visibility 不传时按 Key 类型取默认值:User Key → private,Owner Key → workspace;显式传入则以传入值为准(User Key 也可以建公开库)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
name | string | 是 | 知识库名称 |
description | string | 否 | 描述 |
visibility | string | 否 |
|
graph_enabled | boolean | 否 | 是否启用知识图谱 |
wiki_enabled | boolean | 否 | 是否开启 Wiki 蒸馏,默认 false |
tuning | object | 否 | 可选初始化 tuning 参数 |
tuning.top_k | integer | 否 | 检索 top_k |
tuning.rerank_enabled | boolean | 否 | 是否启用重排序 |
tuning.hybrid_weight | double | 否 | BM25 vs 向量权重 |
tuning.chunk_size | integer | 否 | 分块大小 |
tuning.chunk_overlap | integer | 否 | 分块重叠 |
请求示例
curl -X POST http://<host>:4040/v1/knowledge/bases \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"name": "项目文档库", "description": "存放项目技术文档"}'响应
响应示例
{"code": 0, "msg": "ok", "data": {"id": 1, "name": "项目文档库", "description": "存放项目技术文档", "visibility": "workspace", "wiki_enabled": false, "created_at": "2026-08-19T10:00:00Z", "my_role": "owner", "role_source": "owner_member", "can_manage_acl": true}}GET /v1/knowledge/bases
分页模式下每一行都带 my_role / role_source / can_manage_acl(字段含义见下方知识库详情的字段表),调用方可直接据此渲染“上传/删除/权限管理”入口的可用状态。compact=true 的精简 catalog 只含 name / description / doc_count / updated_at(同样只列有权访问的库),不带角色字段。
分页列出当前调用方有访问权的知识库(无权访问的库不出现在结果里,而不是出现后调用报 403)。支持
compact=true精简 catalog + ETag 增量同步。判定“有访问权”的口径与鉴权侧完全一致:本人创建的库 ∪ 有未过期且非
denied显式行的库 ∪ 公开库中自己没有任何显式行的(有显式行时以显式行为准,见下方知识库权限(ACL))。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
page | integer | 否 | 页码(从0开始),默认 0 |
page_size | integer | 否 | 每页大小,默认 20,[1, 100] |
compact | boolean | 否 | true 时返回精简 catalog(不分页),支持 ETag |
请求示例
curl "http://<host>:4040/v1/knowledge/bases?page_size=10" -H "X-API-Key: $API_KEY"GET /v1/knowledge/bases/{id}
获取指定知识库详情。需 viewer 及以上权限;权限不足返回 403(40303),kbId 跨 workspace 或不存在返回 404。
请求
请求示例
curl "http://<host>:4040/v1/knowledge/bases/1" -H "X-API-Key: $API_KEY"响应
响应参数
字段 | 类型 | 说明 |
id | long | 知识库 ID |
workspace_id | long | 所属 workspace ID |
name | string | 知识库名称 |
description | string | 描述 |
visibility | string |
|
owner_member_id | long | 创建者 member_id |
doc_count | int | 文档总数(缓存值,由摄入路径维护) |
graph_enabled | boolean | 是否启用知识图谱 |
wiki_enabled | boolean | 是否开启 Wiki 蒸馏,默认 false |
created_at / updated_at | string | 创建 / 更新时间(ISO-8601) |
my_role | string | 调用方在该库上的生效角色: |
role_source | string | 生效角色的来源: |
can_manage_acl | boolean | 是否可管理该库的 ACL(等价于 |
角色能力对照:
角色 | 可以做 |
| 搜索、读文档、读 Wiki、读图谱节点/边 |
|
|
|
|
响应示例
{"code": 0, "msg": "ok", "data": {"id": 1, "workspace_id": 1, "name": "项目文档库", "description": "存放项目技术文档", "visibility": "workspace", "owner_member_id": 2, "doc_count": 42, "graph_enabled": false, "wiki_enabled": false, "created_at": "2026-08-19T10:00:00Z", "updated_at": "2026-08-19T10:00:00Z", "my_role": "editor", "role_source": "kb_default", "can_manage_acl": false}}DELETE /v1/knowledge/bases/{id}
删除知识库。需该知识库的 owner 权限,判定与 my_role 完全同源:Owner Key 全局放行、知识库创建者恒为 owner、被显式授予 owner 的成员同样可删。权限不足 403(40303),跨 workspace 或不存在 404(重复删除第二次即 404)。
2026-09-16 起,User Key 删库不再只认“创建者”。此前这里走的是独立的 ownerMemberId 判定,导致被授予 owner 的成员拿到 my_role=owner 却删不掉库;现已统一到 ACL 判定链。这是一处权限放宽,只影响被显式授予 owner 的成员。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/knowledge/bases/1 -H "X-API-Key: $API_KEY"POST /v1/knowledge/bases/{kbId}/documents/upload
上传文档到指定知识库。支持多模态(文本/PDF/图片/音频)。相同内容幂等。需 editor 及以上权限(公开库的成员默认就是 editor);权限不足 403(40303),kbId 跨 workspace 或不存在 404。
请求
Form参数(multipart/form-data)
参数 | 类型 | 必填 | 说明 |
file | file | 是 | 上传的文件 |
title | string | 否 | 文档标题 |
external_id | string | 否 | 外部唯一标识(幂等 key) |
source_url | string | 否 | 来源 URL |
file_path | string | 否 | 同步来源路径 |
source_updated_at | string | 否 | 源文件更新时间(ISO-8601) |
folder_path | string | 否 | 批量上传的文件夹路径 |
images | file[] | 否 | Markdown 的 sidecar 图片附件 |
metadata | string | 否 | JSON 格式用户元数据 |
请求示例
curl -X POST http://<host>:4040/v1/knowledge/bases/1/documents/upload \
-H "X-API-Key: $API_KEY" \
-F "file=@./docs/architecture.md" \
-F "title=架构设计文档"POST /v1/knowledge/documents
通过 URL 或文本内容创建文档(flat API,body 中指定 knowledge_base_id)。需目标库的 editor 及以上权限;权限不足 403(40303),知识库跨 workspace 或不存在 404。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
knowledge_base_id | long | 是 | 目标知识库 ID |
title | string | 文档标题 | |
content | string | 条件 | 文本内容(与 source_url 二选一) |
source_url | string | 条件 | 来源 URL |
external_id | string | 否 | 外部唯一标识 |
请求示例
curl -X POST http://<host>:4040/v1/knowledge/documents \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"knowledge_base_id": 1, "title": "API 设计规范", "content": "RESTful API 应该..."}'GET /v1/knowledge/bases/{kbId}/documents
分页列出指定知识库下的文档。需 viewer 及以上权限;权限不足 403(40303),kbId 跨 workspace 或不存在 404。
请求
请求参数
Query 参数:page(默认 0)、size(默认 20,上限 100)、q(可选,最长 200 字符,标题或 external_id 的字面子串,非 SQL 通配符)、ingest_status(可选:pending / processing / indexed / done / failed)。过滤、分页和总数均由服务端计算,不限于浏览器已加载的前 100 条。原有响应字段和无过滤请求保持兼容。扁平文档列表入口也支持相同过滤。
请求示例
curl "http://<host>:4040/v1/knowledge/bases/1/documents?size=10" -H "X-API-Key: $API_KEY"POST /v1/knowledge/documents/reindex
把一篇已有文档按正常 knowledge.ingest 流程重新入队,用于 embedding fingerprint / 模型、chunking 或索引配置发布后的存量重建。需 editor 及以上权限。
安全与并发契约:
workspace/member 只从
X-API-Key推导,请求体不提供workspace_id。knowledge_base_id必须属于当前 workspace,且document_id必须属于该 KB;跨 workspace 返回 404,ACL 不足返回 403。expected_ingest_revision必须使用文档列表刚读取的值。成功后 revision 加一并返回新的event_id;旧 revision 重放返回 409,避免重复重建。每次只重建一个文档。文档状态更新与 outbox 入队在一个短事务内完成,embedding / OSS / OpenSearch 在事务提交后异步执行。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
knowledge_base_id | long | 是 | 目标知识库 ID |
document_id | long | 是 | 目标文档 ID |
expected_ingest_revision | long | 是 | 列表/详情中读到的当前 revision,必须 ≥ 0 |
请求示例
curl -X POST http://<host>:4040/v1/knowledge/documents/reindex \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"knowledge_base_id":1,"document_id":42,"expected_ingest_revision":3}'响应
响应说明
成功响应的 data.ingest_status 为 pending、data.ingest_revision 为 4,data.event_id 可用于事件追踪。全知识库/ 全 workspace 的分页重建请使用 scripts/reindex-knowledge.sh,发布步骤见 docs/operations/runbooks/embedding-dimension-change.md。
GET /v1/knowledge/documents/{id}
获取文档详情。需该文档所属库的 viewer 及以上权限;权限不足 403(40303),文档跨 workspace 或不存在 404。
请求
请求示例
curl "http://<host>:4040/v1/knowledge/documents/42" -H "X-API-Key: $API_KEY"DELETE /v1/knowledge/documents/{id}
删除文档,需该文档所属库的 editor 及以上权限(不要求是上传者本人 —— 公开库里任意成员默认可删他人上传的文档,见概览「2026-09-16 知识库权限重构」行为变化 1)。权限不足 403(40303),文档跨 workspace 或不存在 404。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/knowledge/documents/42 -H "X-API-Key: $API_KEY"POST /v1/knowledge/search
在租户可访问的知识库上进行混合检索(BM25 + 向量 + RRF 融合)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
query | string | 是 | 查询语句,小于等于4096 字符 |
kb_ids | long[] | 条件 | User Key 必须指定;Owner Key 可省略(全 ws 搜索)。去重后上限 100 |
top_k | integer | 否 | 返回条数 [1, 100],默认 5 |
filters | object | 否 | 白名单 filter( |
rrf_k | integer | 否 | RRF 融合常数 K,取值范围:[1, 1000] |
recall_multiplier | integer | 否 | 召回扩展倍数,取值范围:[1, 20] |
hybrid_weight | double | 否 | BM25 vs 向量权重,取值范围:[0.0, 1.0] |
rewrite | boolean | 否 | 是否启用 LLM 查询改写 |
type | string | 否 | 文档类型过滤 |
tags | string[] | 否 | 标签过滤 |
block_type | string | 否 | 块类型过滤( |
metadata_condition | object | 否 | 结构化元数据条件 |
decompose | boolean | 否 | 是否启用多跳查询分解;缺省由部署开关 |
cross_languages | string[] | 否 | 查询改写生成的跨语言变体(BCP-47 风格语言标签),最多 5 个;原查询始终保留 |
请求示例
curl -X POST http://<host>:4040/v1/knowledge/search \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"query": "如何配置 OpenSearch?", "kb_ids": [1, 2], "top_k": 5}'响应
响应参数
字段 | 类型 | 说明 |
chunk_id | string | 文本块 ID |
document_id | string | 文档 ID |
knowledge_base_id | string | 知识库 ID |
title | string | 文档标题 |
snippet | string | 内容片段(前 ~4096 字符预览) |
score | double | RRF 融合分数(非归一化) |
position | int | 结果排序位置(从0开始) |
rerank_score | double | 重排序分数(启用 |
modality | string | 模态类型( |
block_type | string | 块类型( |
section_path | string | 章节路径(多模态时有值) |
page_number | integer | 页码(PDF 文档有值) |
oss_url | string | Context0 短时签名下载 URL(有效期由业务配置决定) |
graph_hit | boolean | 是否由知识图谱召回 |
graph_path | string | 图谱实体链路径 |
空值(null)字段不输出。未知请求字段会被严格拒绝(防止
kb_id单数 typo 被静默忽略导致全 ws 搜索)。ACL 语义:
kb_ids是逐个校验viewer权限的 —— 列表里只要有一个库无权访问,整个请求返回 403(40303),不会“跳过无权的库、返回其余结果”。请先用GET /v1/knowledge/bases拿到可访问列表(该接口只返回有权访问的库)再检索。Owner Key 省略kb_ids时搜全 workspace;User Key 省略kb_ids直接 403(不再回退到“搜全 workspace”)。
响应示例
{
"code": 0, "msg": "ok",
"data": [
{
"chunk_id": "chunk_001",
"document_id": "42",
"knowledge_base_id": "1",
"title": "OpenSearch 配置指南",
"snippet": "OpenSearch 需要配置 cluster.name、node.name...",
"score": 0.91,
"position": 0,
"rerank_score": 0.95,
"modality": "text",
"block_type": "text"
}
]
}GET /v1/knowledge/bases/{kbId}/tuning
读取指定知识库的检索调优参数(需 viewer 及以上权限)。任一字段为 null 表示“使用全局默认”(top_k=5 / rerank=true / hybrid_weight=0.7 / graph_weight=0.3 / chunk_size=800 / chunk_overlap=100)。
请求
请求示例
curl "http://<host>:4040/v1/knowledge/bases/1/tuning" -H "X-API-Key: $API_KEY"响应
响应参数
字段 | 类型 | 说明 |
top_k | integer | 检索返回条数 |
rerank_enabled | boolean | 是否启用重排序 |
hybrid_weight | double | BM25 vs 向量权重 [0.0, 1.0] |
chunk_size | integer | 分块大小 |
chunk_overlap | integer | 分块重叠 |
rrf_k | integer | RRF 融合常数 K |
recall_multiplier | integer | 召回扩展倍数 |
query_rewrite_enabled | boolean | 是否启用 LLM 查询改写 |
enable_contextual_retrieval | boolean | 是否启用上下文增强检索 |
graph_weight | double | 知识图谱召回权重(GraphRAG) |
graph_skip_extensions | string[] | 图抽取跳过扩展名;null 继承全局,空数组关闭该知识库过滤,非空数组完全替换全局值 |
enable_parent_child | boolean | 父子分块与命中后父上下文补全;null 继承全局配置(默认 false) |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"top_k": 8,
"rerank_enabled": true,
"hybrid_weight": 0.5,
"chunk_size": 800,
"chunk_overlap": 100,
"rrf_k": 60,
"recall_multiplier": 3,
"query_rewrite_enabled": false,
"enable_contextual_retrieval": false,
"graph_weight": null,
"graph_skip_extensions": null,
"enable_parent_child": null
}
}PUT /v1/knowledge/bases/{kbId}/tuning
局部更新知识库调优参数(patch 语义,仅覆写传入的键),需 editor 及以上权限。请求体为调优字段的任意子集,字段名与GET /v1/knowledge/bases/{kbId}/tuning响应一致。
请求
请求示例
curl -X PUT http://<host>:4040/v1/knowledge/bases/1/tuning \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"top_k": 8, "rerank_enabled": true}'响应
响应说明
同 GET 响应结构(返回合并后的完整 tuning)。
PUT /v1/knowledge/bases/{kbId}/settings
更新知识库设置——质量评审开关、知识图谱开关与可见性,三个字段至少传一项(需该知识库的 owner 权限)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
review_enabled | boolean | 条件 | 是否开启质量评审。开启需部署级 worker 与 workspace Feature Flag 均已打开,否则返回 |
graph_enabled | boolean | 条件 | 是否开启知识图谱构建(GraphRAG),无额外门控 |
visibility | string | 条件 |
|
review_enabled / graph_enabled / visibility 至少传一项。改 visibility 不会动任何显式 ACL 行 —— 显式行是终局裁决,切换可见性只改变“没有显式行的人”落到哪个默认档。
请求示例
curl -X PUT http://<host>:4040/v1/knowledge/bases/1/settings \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"review_enabled": true, "graph_enabled": false, "visibility": "private"}'响应
响应示例
{"code": 0, "msg": "ok", "data": {"kb_id": 1, "review_enabled": true, "graph_enabled": false, "visibility": "private"}}GET /v1/knowledge/bases/{kbId}/index-stats
查看该库的索引统计——文档数、分块数、索引体积、摄入队列深度与最后一次摄入时间。需 viewer 及以上权限;权限不足 403(40303),kbId 跨 workspace 或不存在 404。
请求
请求示例
curl "http://<host>:4040/v1/knowledge/bases/1/index-stats" -H "X-API-Key: $API_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"kb_id": 1, "kb_name": "项目文档库", "doc_count": 42, "chunks_count": 1380, "index_size_bytes": 10485760, "ingest_queue_depth": 0, "last_ingest_at": "2026-09-16T09:31:00Z"}}这些计数会泄漏库内容的规模特征,因此与“读知识库内容”同档。2026-09-16 起新增 viewer 门槛:此前只有 workspace 围栏,同 workspace 的任意 User Key 都能读到私有库的文档数/分块数/索引体积/最后摄入时间。
GET /v1/knowledge-bases/{kbId}/graph/nodes
分页查看该库的图谱实体节点(pagerank 降序)。需 viewer 及以上权限。
路径注意:图谱数据面挂在 /v1/knowledge-bases/...(连字符),与本章其余 /v1/knowledge/bases/... 的写法不同。
请求
请求参数
Query 参数:page(默认 0)、size(默认 50,上限 1000,超限静默夹到上限)。
请求示例
curl "http://<host>:4040/v1/knowledge-bases/1/graph/nodes?page=0&size=50" -H "X-API-Key: $API_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"page": 0, "size": 50, "nodes": [{"id": "…", "label": "PolarDB-X", "type": "product", "pagerank": 0.42}]}}GET /v1/knowledge-bases/{kbId}/graph/edges
查看某个实体的 1 跳邻接子图(nodes + edges)。需 viewer 及以上权限。depth 参数目前仅支持 1 跳,保留做 API 兼容。
请求
请求示例
curl "http://<host>:4040/v1/knowledge-bases/1/graph/edges?node=PolarDB-X&depth=1" -H "X-API-Key: $API_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"nodes": [{"id": "…", "label": "PolarDB-X", "type": "product", "pagerank": 0.42}], "edges": [{"from": "PolarDB-X", "to": "CN", "predicate": "part_of", "weight": 0.8}]}}权限与行为变化:图谱实体/关系是从 chunk 抽出来的内容摘要,因此这两个端点与“读知识库内容”同档 —— 需
viewer及以上,权限不足 403(40303)。2026-09-16 起,kbId跨 workspace 或不存在时返回 404(此前为 403),以免自增 kbId 被枚举探测出存在性。图谱新增下述知识库数据面管理接口;原管理面
/ops/knowledge-bases/{kbId}/graph仍要求 Owner Key + OPS 端口 8080。知识库owner 的 User Key 不因此获得全局 OPS 权限。
Graph 数据面清空与补建
方法 / 路径 | 权限与返回 |
DELETE | 当前知识库owner(管理权限); |
POST | 当前知识库owner(管理权限); |
无需请求体,均返回 Box;路径使用 knowledge-bases 连字符。User Key 具有该知识库owner 权限即可调用,viewer / editor 不可执行。资源按 workspace/KB 校验,复用原图谱 guard / barrier;补建计数表示已入队数量,不是同步构建完成,不绕过既有审核。
Graph 冲突检测与人工评审(2026-09-16新增)
多文档合并(consolidate)时的两类静默裁决信号——同实体跨文档类型分歧(type_conflict)与同别名被多实体声明(alias_conflict)——可按需扫描入队,由 editor+ 人工裁决。检测是同步只读扫描(零 LLM、不写图谱);type / alias 裁决与图谱更新事件在同一事务提交,后台合并后生效。功能由 context.knowledge.graph.conflict-detection.enabled(默认 true)门控,关闭时端点返回 404。
方法 / 路径 | 权限 | 说明 |
POST | editor+ | 同步扫描存活子图:新冲突入队、已存在冲突刷新 detected_at、本轮未复现的 open 行转 stale;幂等,重复点击无害 |
GET | viewer+ | 评审队列分页; |
GET | viewer+ | 单条详情(payload 已解析为候选值 + 来源文档/chunk 证据链,与列表项同构) |
POST | editor+ | 人工裁决;仅 open 状态可裁决 |
示例:
# 触发检测(editor+)
curl -X POST "http://<host>:4040/v1/knowledge-bases/1/graph/conflicts/detect" -H "X-API-Key: $API_KEY"{"code": 0, "msg": "ok", "data": {"scanned_documents": 12, "conflicts": 3, "opened": 2, "refreshed": 1, "staled": 0}}# type 冲突裁决:选定正确类型(chosen_type 必须在候选集内,否则 400)
curl -X POST "http://<host>:4040/v1/knowledge-bases/1/graph/conflicts/11/decision" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"action":"resolve","chosen_type":"project"}'
# alias 冲突裁决:选定别名归属 / 忽略不再提醒
curl -X POST "http://<host>:4040/v1/knowledge-bases/1/graph/conflicts/12/decision" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"action":"resolve","chosen_owner":"阿里云"}'
curl -X POST "http://<host>:4040/v1/knowledge-bases/1/graph/conflicts/12/decision" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" -d '{"action":"dismiss"}'裁决语义:
resolved表示裁决和更新事件已提交,不表示图谱已完成更新。type / alias 均由 graph-consolidate worker 异步更新;失败按既有事件策略重试,事件入队失败则裁决一起回滚。人工别名裁决优先于旧映射;类型裁决在别名归并后应用到最终实体,后续合并继续重放。dismiss后同指纹(payload_hash)冲突不再重开;信号消失的 open 行转stale,复现时复活为 open;已 resolved/dismissed 的冲突不因重复检测重开。冲突列表对 viewer 只读知情,检测与裁决是写权限操作(403)。删除知识库或工作空间时同步清理冲突记录。实体自动确认保留
context.knowledge.graph.consolidate.auto-confirm.containment-enabled配置名,但仅允许既有归一规则下名称相同的候选直接确认;单纯子串包含(如PolarDB/PolarDB-X)仍须经过消歧。Jaccard 自动确认仍需显式开启,默认关闭。
Graph 管理面路由收敛(2026-09-16更新)
管理面(OPS 端口 8080、Owner Key)图谱路由改用 query param 传 kb_id,与 /ops/knowledge/wiki/** 同形。旧的路径参数版本仍然可用,进入 deprecation 周期后再摘除。
新路径(推荐) | 旧路径(deprecated,行为不变) |
GET | GET |
GET | GET |
DELETE | DELETE |
POST | POST |
两组路由共用同一实现,请求/响应 JSON、鉴权(Owner Key)与 workspace fence(跨 workspace 403)逐字相同;size 上限仍为 1000。改动原因是后端红线「/ops/** 路由禁止 @PathVariable,标识符走 query param 或 body」。
同一批收敛还包括晋升删除接口:新增 DELETE /ops/promotion/delete?promotionId=,旧的 DELETE /ops/promotion/{promotionId} 同样在 deprecation 周期内保持可用。
Wiki 数据面门控:Search-Read-Expand controller 的搜索、按 ID / slug 阅读、目录读取、原文追溯及 issues 方法仅在服务端
context.wiki.enabled=true(环境变量WIKI_ENABLED,默认 true,显式 false 仍有效)时注册;关闭时对应方法不可用(404,或同路径有其他 HTTP 方法时为 405)。这不等于整个/v1/knowledge/wiki前缀关闭:页面列表 / 更新、单页重新生成、死信 / 日志和 config / backfill 数据面管理接口不受此读侧开关门控;生成仍受 worker 与知识库配置限制。原 OPS 权限与蒸馏管线门控保持不变。ACL:User Key 必须显式列出知识库 ID(search 请求体字段为
knowledge_base_ids,read 类端点为查询参数kb_id;误写为kb_ids等其他字段名会因未识别而按未授权处理返回 403),否则返回 403(workspace 级 Wiki 检索为 Owner Key 专属);请求中的 kb_id 列表去重后不得超过 100 个(超限 400),并逐知识库校验读权限。GET /v1/knowledge/wiki/read结果默认走服务端读缓存(context.wiki.read-cache.*,默认开启、TTL 300s,缓存 key 含 workspaceId 隔离)。
GET /v1/knowledge/wiki/config?kb_id=<id>
查看单个知识库的生成开关与部署能力,需要知识库读权限,返回 Box<SettingsDto>:
响应
响应示例
{"code":0,"msg":"ok","data":{"kb_id":1,"wiki_enabled":false,"build_available":true,"search_available":true,"wiki_config":{"wiki_language":"Chinese","extraction_granularity":"standard","content_instructions":""}}}build_available 表示 distill/finalize worker 已启用,search_available 表示读侧服务开关;均不代表已有页面。
PUT /v1/knowledge/wiki/config?kb_id=<id>
设置单个知识库的持续生成开关与生成配置,需要知识库owner(管理权限),User Key 有相应角色即可。wiki_enabled 与 wiki_config 至少提供一个;旧的仅开关请求保持有效。DATA 的 wiki_config 是 JSON 对象:
请求
请求示例
{"wiki_enabled":true,"wiki_config":{"wiki_language":"Chinese","extraction_granularity":"focused","content_instructions":"侧重架构决策"}}响应
响应说明
返回上述设置结构。开启时要求生成 worker 可用;开启不补建已有文档,关闭不删除已有页面,配置修改不立即重建历史页。
wiki_config按字段合并而非整对象替换:省略的字段保留,字段值 null 清除对应覆盖并恢复读取默认值。规范字段为:
wiki_language(Chinese / English / Japanese / Korean / French / German / Spanish)extraction_granularity(standard / focused / exhaustive)content_instructions(最多 8000 字符)。
读取默认值依次为 Chinese、standard、空字符串。
兼容
granularity→extraction_granularity、custom_instructions→content_instructions。同请求冲突别名拒绝。新传入未知字段拒绝,存量未知配置字段仍保留;历史非法 JSON 不阻断开关读取,但写配置时拒绝静默覆盖。
POST /v1/knowledge/wiki/backfill?kb_id=<id>
为已开启 Wiki 的知识库补建现有 indexed 文档,需要知识库owner(管理权限)。无需请求体,返回:
响应
响应示例
{"code":0,"msg":"ok","data":{"kb_id":1,"status":"accepted","enqueued":3}}enqueued 是入队文档操作数,不是已生成页数;可以为 0。任务异步处理且不绕过审核,无请求级去重保证,超时后先查状态再决定是否重试。该接口不代开知识库生成开关。
PUT /ops/knowledge/wiki/config?kb_id=<id>(高级生成配置)
使用管理面地址和工作区 Owner Key,可设置 wiki_config JSON 字符串。此旧 OPS 契约保留,不改成 DATA 的对象格式;知识库页面配置优先使用上述数据面接口,知识库owner 身份不等于工作区 Owner Key。
请求
请求示例
curl -X PUT "http://<host>:8080/ops/knowledge/wiki/config?kb_id=1" \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"wiki_config":"{\"extraction_granularity\":\"focused\",\"wiki_language\":\"Chinese\",\"content_instructions\":\"侧重架构决策\"}"}'配置修改不表示历史页面立即重建。完整上手步骤见构建 RAG + Wiki 企业知识库。
Wiki 数据面页面管理与任务摘要
前缀 /v1/knowledge/wiki,全部返回 Box。viewer 只读;editor 可编辑 / 发布 / 归档 / 恢复页面、单页重新生成及重试本知识库失败任务;配置、ACL 与全库补建仍需知识库owner。ES 全局维修仍仅在 OPS,未对普通知识库角色开放。
方法 / 相对路径 | 请求与返回 |
GET | 知识库隔离分页页面列表;可选 status / type / folder_id |
POST | editor;手工建页, |
GET | 本知识库统计,任务计数不混入其他 KB |
PUT | editor;部分更新 title / content_markdown / summary / category / folder_id / status,返回页面 DTO |
POST | editor;无需请求体,返回 |
GET | viewer;分页脱敏死信摘要 |
GET | viewer;分页脱敏任务日志摘要 |
POST | editor;无需请求体,返回 |
页面、死信、日志分页要求 page 非负、size 为 1–200,非法值拒绝。分页 data 包含 content / total_elements 等分页字段,不是裸数组。页面、目标目录、死信及其关联来源文档必须属于已授权 workspace/KB,跨范围资源不能借合法 kb_id 访问。创建 / 更新目录的 parent_id 也必须同知识库。
status与page_type是封闭取值域,写入面按白名单校验,域外值一律 40040001:status∈draft/published/archived。搜索与召回只索引published,反向链接图只认published与可解析draft,/stats只统计published_pages/draft_pages,控制台的发布 / 归档 / 恢复按钮也只在draft/archived下渲染 —— 写入域外值会让页面同时从这四处消失。page_type∈entity/concept/summary/index(生成侧实际产出的四种)。不传时默认entity。标题解析与去重候选只看entity/concept。GET /pages?type=的过滤值同样限于这四种。
slug与title必填且不可为空白,两端空格按 wikilink 目标的同一规则 trim;slug≤ 256 字符、title≤ 512 字符,超长返回 400 并在 message 里给出列预算。漏传或空白slug是校验错误(40001),不再落到存储层约束上(历史行为是40009 missing or invalid required column: slug)。页面更新的分类请求字段是
category,响应仍为category_path;不修改 slug。设置status=published可发布草稿或恢复归档页;设置status=archived是 UI“删除”的归档语义,不是物理删除。正文编辑应先请求/pages/{pageId}?for_edit=true取得完整正文,不能把普通预算读取的截断内容保存回去。重新生成先检查全部来源归属,再对仍有效的同知识库来源入队;没有有效来源的手工页或来源已全部删除时返回 409,不假装已入队。重试死信必须同时验证死信及关联文档归属,成功入队并移除该死信记录;accepted / retried 都不表示模型处理已完成。
死信摘要字段:
id、knowledge_id、fail_count、created_at、error_code=WIKI_DISTILL_FAILED、last_error(固定为“蒸馏失败,请重试或联系管理员”)。日志摘要字段:id、action、summary、created_at;action 仅 distill_batch / distill_coverage / link_validation / other,summary 为固定脱敏提示。两类接口均不回传原始模型结果或供应商错误。
POST /v1/knowledge/wiki/search
对 Wiki 蒸馏页面进行 BM25 全文检索,返回命中列表(不含全文正文)。区别于 /v1/knowledge/search(chunk 级混合检索),Wiki 搜索面向蒸馏后的结构化知识页面。仅 status=published 的页面可被检索(服务端强制过滤);draft 页可由 editor 经数据面页面更新发布,也可沿用原管理面发布,索引同步后才会出现在搜索结果中。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
query | string | 条件必填 | 单个查询;与非空 queries 至少提供一个 |
queries | string[] | 否 | 最多 10 个查询;非空时优先于 query |
knowledge_base_ids | long[] | 否 | 限定检索的知识库 ID 列表(接受 |
top_k | integer | 否 | 返回条数,范围 1–100(接受 |
mode | string | 否 | keyword(默认,BM25)或 regex(字面匹配) |
未知字段严格拒绝:请求体中出现上表以外的字段(如把 kb_ids 误写成单数 kb_id)会直接返回 400 40001 unknown field '<name>',与 /v1/knowledge/search 一致。此前这类 typo 会被静默丢弃,使请求从“检索指定 KB”降级为“检索整个 workspace”。
请求示例
curl -X POST http://<host>:4040/v1/knowledge/wiki/search \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"query": "部署流程", "knowledge_base_ids": [1], "top_k": 5}'响应
响应示例
正文需再调 GET /v1/knowledge/wiki/pages/{pageId} 获取。
{
"code": 0, "msg": "ok",
"data": [
{
"id": "101",
"title": "部署指南",
"slug": "deploy-guide",
"page_type": "concept",
"category": "运维",
"summary": "介绍 Docker Compose 与镜像部署流程",
"snippet": "...部署前需准备 .env 中的 DASHSCOPE_API_KEY...",
"score": 8.42
}
]
}GET /v1/knowledge/wiki/pages/{pageId}
按页面 ID 从 MySQL 读取 Wiki 页面(含 markdown 正文)。普通读取按页面实际知识库校验读权限,并遵循输出预算;for_edit=true 按页面实际知识库要求 editor 写权限,返回完整正文,忽略普通读取预算。不接受由客户端换一个 kb_id 绕过页面归属。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
max_output_chars | int | 否 | 普通读取正文输出预算(按 Unicode code point 计数),范围 1000–200000;超预算时保留头 70% + 尾 30% 并插入截断标记行。缺省使用 |
for_edit | boolean | 否 | 默认 false;true 要求该页面实际知识库的写权限并返回完整正文,不应用 max_output_chars 或部署默认预算 |
预算生效时(参数或配置 > 0),响应 data 额外回显 content_truncated(boolean,是否发生截断)与 content_total_chars(int,截断前正文总字符数);预算关闭时这两个字段不出现。
请求示例
curl "http://<host>:4040/v1/knowledge/wiki/pages/101" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"id": 101,
"knowledge_base_id": 1,
"slug": "deploy-guide",
"title": "部署指南",
"page_type": "concept",
"category_path": "运维/部署",
"summary": "介绍 Docker Compose 与镜像部署流程",
"content_markdown": "# 部署指南\n...",
"source_refs": "[\"doc:42\"]",
"aliases": "部署,deploy",
"status": "published",
"view_count": 12,
"created_at": "2026-08-19T10:00:00Z",
"updated_at": "2026-08-19T11:00:00Z"
}
}GET /v1/knowledge/wiki/pages/by-slug
按知识库 ID + slug 读取 Wiki 页面(响应结构同上)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
kb_id | long | 是 | 知识库 ID |
slug | string | 是 | 页面 slug |
max_output_chars | int | 否 | 正文输出预算,语义同 |
请求示例
curl "http://<host>:4040/v1/knowledge/wiki/pages/by-slug?kb_id=1&slug=deploy-guide" \
-H "X-API-Key: $API_KEY"GET /v1/knowledge/wiki/folders
列出指定知识库的 Wiki 目录(文件夹)结构,可按父目录过滤。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
kb_id | long | 是 | 知识库 ID |
parent_id | long | 否 | 父目录 ID。缺省返回顶层目录 |
请求示例
curl "http://<host>:4040/v1/knowledge/wiki/folders?kb_id=1" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": [
{"id": 10, "knowledge_base_id": 1, "name": "运维", "path": "/运维", "parent_id": null, "sort_order": 0}
]
}排序:返回顺序按 sort_order 升序,sort_order 相同时按 id 升序兜底(跨 DB 稳定)。
目录写入规则(POST /ops/knowledge/wiki/folders、PUT /ops/knowledge/wiki/folders/update)
目录的写入面在管理面(/ops/knowledge/wiki/folders*,均要求 Owner Key)。约束如下:
字段 | 规则 |
| 必填;两端空格会被 trim,trim 后不得为空;最长 256 字符;不得包含 |
| 只读,由服务端按 |
| 可选,必须是整数(可为负)。传字符串 / |
| 创建时可选;更新时不支持改 parent,传入与当前不同的值返回 |
同父同名唯一:同一
kb_id+ 同一parent_id下不允许重名,冲突返回409/40901a folder named 'X' already exists under the same parent。不同父目录下同名是合法的;把目录改成它自己当前的名字也是合法的(空操作)。改名会级联重算 path:重命名一个目录后,其整棵子树的
path前缀会被同步重写(子目录自身的name不变)。前缀相同但不属于该子树的目录(如/Alpha与/AlphaOther)不受影响。删除语义(
DELETE /ops/knowledge/wiki/folders/delete):目录下还有子目录时返回
409/40901folder still has N subfolder(s); delete or empty them first—— 因为不支持改 parent,被删父目录的子目录会成为无法列出也无法修复的孤儿。目录下只有页面时仍返回
200,这些页面的folder_id被就地置空(回到未归档状态),不会留下悬垂引用。kb_id参与校验:目录不属于该kb_id时返回404,与/folders/update、/pages/move行为一致。
GET /v1/knowledge/wiki/read
Read 步骤核心端点。按 kb_id + slug 读取 Wiki 页面全文,并返回 out_links / in_links slug 列表与邻居页面摘要卡(neighbors),供 Agent 沿链接图导航展开(Expand)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
kb_id | long | 是 | 知识库 ID |
slug | string | 是 | 页面 slug |
max_output_chars | int | 否 |
|
请求示例
curl "http://<host>:4040/v1/knowledge/wiki/read?kb_id=1&slug=deploy-guide" \
-H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"page": {
"id": 101,
"knowledge_base_id": 1,
"slug": "deploy-guide",
"title": "部署指南",
"page_type": "concept",
"content_markdown": "# 部署指南\n...",
"status": "published"
},
"out_links": ["env-config", "docker-compose"],
"in_links": ["getting-started"],
"neighbors": [
{
"id": 102,
"slug": "env-config",
"title": "环境变量配置",
"page_type": "entity",
"summary": "介绍 .env 关键变量(截断至 150 字)",
"direction": "out"
},
{
"id": 99,
"slug": "getting-started",
"title": "快速开始",
"page_type": "concept",
"summary": "5 分钟上手指南",
"direction": "in"
}
]
}
}neighbors 中 direction 为 out(当前页指向邻居)或 in(邻居指向当前页),summary 截断至 150 字。结果默认命中服务端读缓存(TTL 300s)。
GET /v1/knowledge/wiki/pages/{pageId}/sources
原文追溯端点。列出 Wiki 页面的来源文档(含 OSS 短时签名下载链接,TTL 1800s)及每文档默认 10 个代表性 chunk 片段(可配 context.wiki.source-query.preview-chunks),用于核对蒸馏内容与原文。
请求
请求参数(检索模式)
参数 | 类型 | 必填 | 说明 |
query | string | 否 | 检索词,≤256 字符;命中 chunk 并附加相邻上下文 |
mode | string | 否 |
|
max_chunks | int | 否 | 每文档返回 chunk 上限,默认 20,范围 1–20 |
context_window | int | 否 | 上下文窗口,默认 1,范围 0–2 |
检索模式与区间读取互斥:query 与 start_chunk 同时传返回 400。query 与区间参数都不传时,返回默认概览(每文档代表性 chunk 片段)。
请求参数(区间读取模式)
参数 | 类型 | 必填 | 说明 |
start_chunk | int | 否 | 区间起始 chunk position(>= 0)。与 |
end_chunk | int | 否 | 区间结束 position(含端点)。只传 |
响应中每个源文档回显 total_chunks(该文档 chunk 总数),供 Agent 规划下一个读取区间。
请求示例
curl "http://<host>:4040/v1/knowledge/wiki/pages/101/sources" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": [
{
"document_id": 42,
"title": "部署手册.pdf",
"source_url": null,
"file_path": "docs/deploy.pdf",
"mime_type": "application/pdf",
"oss_presigned_url": "/v1/files/download?key=...&expires=...&signature=...",
"total_chunks": 128,
"chunks": [
{"chunk_id": "42_3", "position": 3, "content": "...部署前需准备 .env..."}
]
}
]
}POST /v1/knowledge/wiki/issues
对 Wiki 页面内容标记质量问题(过时/不准确/缺失/断链),供后台评审与重新蒸馏参考。按页面真实知识库要求 editor 写权限;viewer 不可提交,这是只读角色的授权修复。成功返回 200(Box 包裹)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
page_id | long | 是 | 页面 ID |
issue_type | string | 是 |
|
description | string | 否 | 问题描述,≤2048 字符 |
请求示例
curl -X POST http://<host>:4040/v1/knowledge/wiki/issues \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"page_id": 101, "issue_type": "outdated", "description": "部署端口已从 8080 改为 4040"}'响应
响应示例
{"code": 0, "msg": "ok", "data": {"id": 7, "status": "open"}}GET /v1/knowledge/documents/{id}/images
列出文档抽取出的图片(OSS 原图 + 短时签名下载链接 + Vision 描述/OCR 文本),需 reader 及以上权限。跨 workspace / 不存在返回 404。
请求
请求参数
参数 | 类型 | 说明 |
oss_key | string | OSS 对象 key |
signed_url | string | 短时预签名 GET URL。OSS 未接入时为 |
page_number | integer | 页码(PDF 有值) |
block_type | string | 块类型(通常为 image) |
section_path | string | 章节路径 |
caption | string | Vision 生成的描述 + OCR 文本(已嵌入向量库用于检索) |
请求示例
curl "http://<host>:4040/v1/knowledge/documents/42/images" -H "X-API-Key: $API_KEY"响应
响应参数
字段 | 类型 | 说明 |
oss_key | string | OSS 对象 key |
signed_url | string | 短时预签名 GET URL;OSS 未接入时为 null(仍返回 oss_key) |
page_number | integer | 页码(PDF 有值) |
block_type | string | 块类型(通常为 image) |
section_path | string | 章节路径 |
caption | string | Vision 生成的描述 + OCR 文本(已嵌入向量库用于检索) |
响应示例
{
"code": 0, "msg": "ok",
"data": [
{
"oss_key": "ws1/doc42/img_001.png",
"signed_url": "https://oss.example.com/...&Signature=...",
"page_number": 3,
"block_type": "image",
"section_path": "架构/存储层",
"caption": "存储三件套架构图:PolarDB-X + PolarDB-X Search + OSS"
}
]
}文档不可变来源修订(2026-09-16新增)
前缀:/v1/knowledge/bases/{kbId}/documents/{docId}/revisions。所有响应沿用 Box<T>(业务数据在 data),每次调用重新检查当前知识库viewer 权限,跨 workspace /知识库/ document 的 revision ID 返回 404;历史 ID 不是授权凭据。原文存储读取 / PDF 渲染结束后再次查询当前权限状态;期间已提交的 ACL 降权或公开库改私有不会沿用请求内缓存的旧权限返回正文。
方法 / 相对路径 | 行为 |
GET | 倒序列表; |
GET | 固定来源快照 |
GET | 原件正文;不签发 OSS bearer URL,不回退到当前文档 |
GET | PDF 第 page 页(从 1 开始),服务端 PDFBox 渲染 PNG;不执行浏览器 PDF 动作 |
GET | 读取该来源修订最新一次留存的解析文本、块和覆盖范围;不存在返回 404,不回退到当前文章 |
POST | editor 显式恢复固定来源;请求 |
Revision 字段:
id(业务 UUID)、number、snapshot_hash、source、created_at、author_member_id(旧记录可空)。source包含来源、原件哈希 / OSS key、标题、metadata 与文档元数据快照;解析 coverage 通过独立/parsed接口提供;不保存整库发布 manifest。恢复产生的新修订在source.restored_from_revision_id中记录来源;该审计注记不参与来源内容的snapshot_hash。技术ingest_revision、projection_generation不是业务修订 ID。相同快照不重复创建;metadata 变化或 A→B→A 产生新业务修订。restore 保留 document ID / external_id,先在事务外校验原件,短事务内 CAS 并生成新来源修订与原有 ingest outbox;不恢复旧权限、旧审核决定或 Wiki / 图谱派生,也不等于整库 release 回滚。此接口不表示内容已审核或已发布。新增捕获及 restore 默认关闭:
context.knowledge.revisions.capture-enabled=false。只有确认所有 reader / writer / worker / GC 已升级兼容版本后才设置 true;旧程序不认识历史引用,单纯 epoch 或开关不能隔离旧 GC。关闭捕获不会关闭既有历史对象的保护或读取。旧原件缺少可核实 content_hash 时不伪造历史基线。Source 字段:
revision_id、source_hash、mime_type、encoding(utf-8或base64)、content。原件 SHA-256 校验失败、对象丢失或超过 16 MiB 在线预览预算时显式失败;上传含附件时主文件校验使用固定metadata_json.content_sha256。PDF 返回page、total_pages、mime_type=image/png、base64content;每份最多 1,000 页、每页最多 1,200×1,600,服务器同时最多渲染 2 页。二进制原件与解析证据分别提供。Parsed 字段:
revision_id、source_hash、artifact_hash、text、blocks、coverage、created_at。blocks仅保留page_number、block_type、section_path、text,不持久化签名 URL。成功摄入提交时,按(revision_id, ingest_revision)留存不可变解析;同一次摄入重试不覆盖证据,重新摄入可以新增解析,使初次部分解析可以修复。读取校验内容摘要,Ontology 任务固定artifact_hash,后续重解析不会改变旧任务的证据。覆盖状态为 complete / partial / unknown,unknown 不能当作完整。单个解析产物上限 12,000,000 字节,workspace 默认最多 1 GiB(context.knowledge.revisions.max-parsed-bytes-per-workspace),并计入 workspace 逻辑存储配额。保留策略分为两层。自动裁剪:每次新增修订时,按
context.knowledge.revisions.max-kept-per-document(默认 5)保留最新 N 个修订,超出部分连同解析产物一并物理删除。硬上限:默认单文档最多 1,000 个修订(max-per-document)、workspace 历史源文件包最多 50 GiB(max-retained-bytes-per-workspace),超限拒绝新写入而不是静默删除历史。存在历史引用的原件 / sidecar 不随当前文档更新而删除,删除知识库/ workspace 才删除该范围历史。逻辑历史字节计入 workspace 存储配额。当前按 document/source_hash 包去重并取记录中的最大字节数,不是逐 OSS 对象台账;相同 source_hash 下后生成的派生附件不能据此精确计量。这不是最终的按 release 引用计数 / 保留窗口 / 物理账单实现。ctxdb0 读取接线:
knowledge documents versions <document-id> --source <name-or-id> --page 0 --limit 20 --json与knowledge documents source <document-id> --source <name-or-id> --revision <business-revision-uuid> --json。后者原样保留源响应 JSON 与编码,权限 / 丢失 / 损坏错误直接失败,不调用当前 document detail 作为替代;未增加 release pin 或语义 verify 能力。单篇恢复命令为knowledge documents restore <document-id> --source <name-or-id> --revision <business-revision-uuid> --expected-revision <current-head-uuid> --json,使用同一 editor 权限与并发检查。
本体知识库(管理目录、候选版本与校验)
前缀:/v1/knowledge/bases/{kbId}/ontology;全部采用 Box 包装(code、msg、data、trace_id),以下字段均指 data。本体属于单个 KB;读需 viewer,保存、结构校验、发现、引用、停用、删除需 editor。viewer 只读。所有资源受当前 workspace/member/KB 权限限制。保存得到候选定义,不自动改变现有 Wiki / 图谱;显式应用后,新的图谱与 Wiki 任务固定所选定义,文章仍遵循现有审核。
管理目录与候选追加
方法 / 相对路径 | 请求与返回 |
GET |
|
POST |
|
DELETE | 返回 |
目录行字段为 id、kind、status、schema_version_id、version_number、source_kind、created_at、generated_at、author_member_id、type_count、relation_count、is_active、task_id、error_code。kind=version 的状态为 candidate / active;kind=discovery 的状态为 pending / processing / dead / expired。来源为 legacy / json_import / manual_edit / sample_discovery。目录不返回 schema 全文、样本文本或原始模型请求。服务端合并版本与未隐藏任务后,按 created_at DESC,id DESC 统一分页;成功发现只显示生成的版本,不重复显示任务行。目录读取错误不是空目录,404 应检查实际请求地址与部署版本,不能降级成成功空列表。
候选保存契约:
request_id必填、非空、最长 128 字符;同 ID 且完整请求内容一致返回原版本,不同内容返回 409。新请求校验后强制追加版本,即使 schema / 指令内容相同也不复用旧版本。source_kind只接受 manual_edit / json_import。schema、instructions必填;instructions的ontology_discovery_instructions与graph_extraction_instructions分别最多 8000 字符,随新版本固定保存。expected_head_version_id必须取目录返回的真实历史 head(空历史为 null),不是当前 active 或选中的编辑来源;管理墓碑也属于历史 head。parent_version_id仅标识编辑来源,可为 null;非空时必须属于同知识库且仍可选择,不承担 CAS。编辑旧版本时仍用最新 head 作 CAS。head 冲突返回 409。客户端保留草稿,由用户显式刷新 head 后再次保存;不得自动重试覆盖。保存不等于引用或发布。
schema 字段名为 camelCase 且严格校验:
schema这一族(types[]、types[].attributes[]、relations[])的字段名是 camelCase(valueType/allowedUnits/typeId),与本文档其余 snake_case 请求体不同。出现未声明的字段(例如把aliases写成alias、把allowedUnits写成allowed_units)会返回 40040001 unknown field '<name>' on OntologySchema…,POST /ontology/validate同样如此。此前这类 typo 会被静默丢弃,保存成功但aliases/allowedUnits落库为 null,导致别名解析与单位校验静默失效。注意validate-facts的 facts 结构(instances/links)仍保持宽松,因为同一批类型也承载模型抽取输出。删除只隐藏管理目录与新选择,保留 schema、指令、历史 facts / 任务及按 ID 的历史读取;不回退 head / 版本号、不释放历史版本配额。重复删除幂等,删除不增加 active generation。唯一引用仍通过下述
/active的 generation CAS 切换。
直接上传样本发现
这是独立样本协议,不是下文 /tasks 的 revision 发现 / 抽取协议。
方法 / 相对路径 | 请求与返回 |
POST | multipart:重复 |
GET |
|
POST | 请求必须是空 JSON 对象 |
DELETE | 返回 |
options为{request_id,ontology_discovery_instructions?,graph_extraction_instructions?,base_schema_version_id?,competency_questions?}。request_id 必填、最长 128 字符,同 ID 同有效输入返回原任务,不同输入 409。
两条指令分别最多 8000 字符:省略时继承固定基准版本的对应值,无基准则为空;显式空字符串表示清空该指令,不是继承。基准必须属于同知识库且可选择。实例抽取指令仅随任务与候选版本固定保存,供后续图谱抽取使用;样本模型提示词不包含抽取指令,不能由样本模型代写。
competency_questions(V103,选填):能力问题验收用例,字符串数组最多 10 条、每条 1..200 字符;提供时随发现调用一并评估,schema 无法回答的问题在任务quality_report中产生competency_unsupportedwarning(不拦截发布),留空表示本次不评估。
示例:
curl -X POST "http://<host>:4040/v1/knowledge/bases/1/ontology/discoveries" \
-H "X-API-Key: $API_KEY" \
-F 'files=@sample-a.pdf' -F 'files=@sample-b.txt' \
-F 'options={"request_id":"sample-request-001","ontology_discovery_instructions":"仅关注产品与条款","graph_extraction_instructions":"抽取时保留原文证据"};type=application/json'状态为 pending / processing / done / dead / expired。前两种在 UI 显示“运行中”,不能查看候选、编辑、引用或删除;刷新后从服务端目录恢复。done 原子生成一个未应用的版本,
authority=unreviewed_candidate,不自动引用。样本模型只输出 schema / explanation,经结构校验,不伪造 revision 原文锚点,也不表示旧逐项证据协议已通过。样本限制(配置前缀
context.knowledge.ontology-samples):默认每批 1–4 文件、单文件 10 MiB、总计 20 MiB,仅 PDF / DOCX / TXT / MD;解析文本总计最多 32000 UTF-16 字符。超限整批失败,不截断、不只取部分文件。不进行 OCR、图片 / 嵌入附件处理或外链抓取;扫描无文本、加密、损坏、空文件或不支持格式明确失败。默认实际解析线程 2、单文件 30 秒、批次解析预算 120 秒;模型仍用现有 provider 超时,不承诺线程中断等于硬 CPU 隔离。零正式摄入副作用:样本使用独立私有存储,仅解析并发现;不调用正式文档上传、不创建 document / revision、不投递 INGEST、不执行 chunk / embedding / ES / Graph / Wiki / review 写入。原件按原始字节 SHA-256 固定,artifact hash 包含 parser version、source hash 与文本;任务固定基准、双指令、parser/template 版本及模型配置。重试复用已成功解析的固定输入,输入或运行配置失效时拒绝重试,需重新上传。
临时故障默认首次加最多 3 次自动重试(5 / 10 / 20 秒),429 同样有界;结构、权限、无文本错误不作为临时成功。新旧任务合计默认每知识库最多 8 个活跃任务、1000 个保留任务;版本默认最多 1000,管理删除不释放配额。
files摘要字段为id、filename、mime、bytes、source_hash、artifact_hash、parser_version、retain_until、source_available,不返回原件 URL 或全文。样本原件和文本至少保留 7 天;运行任务不能回收。保留期到达不等于已经回收,source_available依据实际回收标记与对象定位信息,而不是仅比较时间。已成功版本在样本回收后仍可使用;dead 任务失去样本或事件后为 expired,不可重试。未提交孤儿对象满 24 小时才可回收,数据库 / 对象年龄不确定时不删,删除失败保留定位以便重试。
兼容版本、事实校验与应用协议
方法 / 相对路径 | 请求与返回 |
GET | 每页 20 个固定版本,倒序数组 |
GET |
|
PUT | editor; |
GET | viewer;最近 20 次固定 schema 抽取记录,含源修订、schema 版本、摄入次数、facts、模型/证据 provenance 与 published 标记 |
GET | 当前权限下读取固定版本 |
POST |
|
POST | 请求为 schema;返回 |
POST | 请求为 facts;依固定 schema 校验并验证原文锚点;返回相同 Validation |
GET | 名称 / 别名忽略大小写匹配的稳定类型 ID 数组;歧义返回所有候选,不自动合并 |
schema / facts 内字段为 camelCase;外层版本、指令、任务字段为 snake_case。类型最多 100,关系最多 300,每类型属性最多 50,名称 / ID 非空且最长 128。示例定义:
{
"expected_version_id": null,
"schema": {
"types": [{"id":"indicator","name":"Indicator","aliases":["指标"],"attributes":[{"id":"value","name":"Value","valueType":"number","required":true,"allowedUnits":["u_test"]}]}],
"relations": []
},
"instructions": {"ontology_discovery_instructions":"仅输出候选及原文依据", "graph_extraction_instructions":"严格遵守固定类型和单位"}
}关系字段
{id,name,domain,range,min,max};max 为 null 表示无上限。facts 字段{instances,links,complete},实例为{id,typeId,properties,units,evidence},边为{id,typeId,from,to,evidence};锚点为{revisionId,sourceHash,quote,page,start,end}。定位必须提供page或同时提供start/end;只有 quote 而无定位时返回anchor问题。文本偏移采用 UTF-16、左闭右开,给出偏移时必须精确匹配 quote;纯文本页码只支持page=1;已留存的 PDF / Office 解析使用固定块页码,若同时提供页码和偏移则两者须一致。最多 5,000 个实例 / 20,000 条边;完整集合必须满足 required、数值 / 字符串 / 布尔类型、单位、domain/range、方向与基数。数值属性声明非空allowedUnits时,缺少或不匹配的单位返回结构化unit问题。原文验证最多 200 锚点 / 16 原件,未知或缺少历史解析的二进制来源显式不可核验;只有字面定位,不等于五态语义支持性验证或事实权威。complete=false保留 partial 问题,不声称完整通过。应用不等于全库重建:已存在的文章需要显式重新处理,沿用当前文章摄入接口。Graph / Wiki 开关仍各自生效;不配置 schema 时保留原处理方式。运行中任务固定应用代数与定义版本;切换后旧任务不能发布覆盖新结果。图谱使用类型 ID、属性、单位、关系约束和原文锚点校验,再接入原图谱发布/聚合流程;完整解析及完整模型输出才允许替换该文章的图谱贡献。当前自动图谱抽取每篇上限 64,000 字符,超限、部分/未知解析或模型截断会明确失败并保留旧图谱。
facts.published表示该次结果曾通过图谱发布,当前应用版本以/active为准。Wiki 在候选页面发现、文章摘要、页面合并三处使用同一固定 schema,保留既有 slug 和引用;正文与 schema 发布前分别检查文档代数和应用代数。现有 Wiki 日志
distill_coverage记录ontology_version和ingest_revision,可追溯处理配置。这保证定义进入真实模型请求,不承诺模型生成内容的业务准确率。ctxdb0 提供
knowledge ontology versions|active|apply|save|discover|extract|tasks。各命令均指定--source <name-or-id>;apply 使用--version <uuid|none> --expected-generation <n>,save 从--stdin读取上述保存请求,discover 使用--revision <uuid>(可选--schema-version),extract 必须同时指定这两个固定版本参数。tasks列出最近任务及其结果状态,单任务详情和重试可使用上述 API。
审核通过通知(2026-09-16新增,默认关闭)
前缀:/v1/knowledge/bases/{kbId}/review-notifications。全部返回 Box<T>,配置、投递记录和重试均要求当前知识库owner。
方法 / 相对路径 | 请求与返回 |
GET |
|
PUT |
|
GET | 每页 20 条数组; |
POST | 仅 pending 且 outbox 为 dead 的失败投递可重试;配置已变化或通知已发送/取消返回 409 |
通知在原审核最终
accepted提交事务内写入 outbox,自动审核和人工审核共用该入口。accepted_pending、拒绝或激活失败不发送“审核通过”;事务回滚不留通知。通知异步发送,失败使用已有事件重试机制,不回退文章审核状态。只对开启后的新审核通过生成通知,不补发历史审批。Webhook 是 JSON POST,包含
event_id(稳定通知 UUID)、type=knowledge.document.review_approved、knowledge_base_id、document_id、review_id、revision_id(未捕获历史时为 null)、content_hash、approved_at。不包含文档全文。请求头Idempotency-Key和X-Context0-Event-Id均为该 UUID;接收器应以它去重。发送成功但本地确认失败时可能重复投递,不承诺 exactly-once。2xx 为成功,其他状态为失败。status为 pending / delivered / cancelled;pending 配合event_status=dead表示自动重试耗尽,可由 owner 手动重试。关闭或更改订阅后,尚未开始发送的旧配置通知会取消,不会投递到新地址;已经在途的 HTTP 请求可能完成。重试保留同一事件编号。地址限制在保存时和实际 DNS 连接时均校验:禁止重定向、URL 用户名密码、fragment、云元数据地址、链路本地和保留地址。默认拒绝私网/回环;内部接收器由管理员在
context.knowledge.review-notifications.allowed-internal-hosts中逐个配置精确主机名,不能由 API 绕过。连接超时 5 秒、响应超时 10 秒;不读取响应正文,不把含接收器令牌的 URL 写入失败日志。定时发送默认开启(context.knowledge.review-notifications.scheduled-enabled=true),没有启用订阅不会发送。
固定 revision 本体发现 / 抽取异步任务(兼容协议)
前缀:/v1/knowledge/bases/{kbId}/ontology。服务端 context.knowledge.ontology-tasks.enabled 当前缺省为 true,显式 false 时旧任务创建 / 重试返回校验错误且不注册 worker。context.knowledge.ontology-tasks.scheduled-enabled 缺省为 true,控制轮询;两项配置应以实际部署覆盖值为准。新样本发现共用该 worker 与开关,显式关闭时样本创建 / 重试返回功能关闭错误。复用既有事件 outbox / lease / 重试队列,不新增 Agent runtime。
方法 / 相对路径 | 请求与返回 |
POST |
|
GET | 每页 20 条任务;需 viewer |
GET | 固定任务、输入指纹、候选结果与运行状态;需 viewer |
POST | 原作者 editor 显式重试仍保留的 dead 事件;固定输入不变,非 dead / 已清理 409;运行配置漂移仍会拒绝 |
extract 必须指定固定本体版本;discover 可选已有版本,指令随该版本固定。每次 1–4 个同知识库修订,支持保留的文本原件和已有历史解析的 PDF / Office,总长不超过 32,000 字符;每知识库最多 8 个排队 / 处理中任务。源修订 / 原件哈希 / 解析产物哈希与覆盖范围、schema / 指令、系统 templateVersion / hash、模型配置摘要及采样预算形成输入 fingerprint,重复输入返回同一任务。失败任务不会借重复创建悄悄重试;原作者可显式 retry,输入依赖变化则需创建新任务。默认每知识库最多保留 1,000 个任务与 1,000 个本体版本(
context.knowledge.ontology-tasks.max-retained-per-kb/context.knowledge.ontology.max-versions-per-kb);到限拒绝,不自动删除历史。状态使用既有事件状态(pending / processing / done / dead)。模型结果截断、运行配置变化或失去权限会失败;失租 worker 不得写回。结果含
candidate、issues、valid、authority=unreviewed_candidate、coverage.scope=selected_originals_only、coverage.corpus_complete=false。done 只是任务结束,valid 只是结构与字面证据通过,二者都不是正式发布。接受 schema 需显式保存候选,随后通过/active应用;兼容任务面板允许编辑候选 JSON,原始模型结果保持留存。新版本体目录使用独立样本发现与版本处置,不展示已移除的 revision 试跑 / 画布面板,也不将版本引用、编辑、删除等同于旧逐项候选接受 / 合并 / 拒绝。文章审核继续采用既有审核机制;整库发布、整库版本回滚与专家双审不在本次简化范围内。discover 输出为
{schema,candidates}。每个类型、属性、关系都必须有对应的 provenance candidate,path分别采用types.TYPE_ID、types.TYPE_ID.attributes.ATTRIBUTE_ID、relations.RELATION_ID;每项包含独立id、0–1 有限数confidence及非空evidence。最多 100 项,缺项 / 重复路径 / 未声明路径都会返回阻断问题;高置信度不豁免锚点校验。extract 输出为上文 facts 格式。任务引用只能来自请求已选修订,不能引入同知识库的其他未选原文。事件被保留策略清理后,有结果的任务仍为 done,无结果的任务显示 expired,不能借 retry 重新创建已失去的事件。
检索质量 Benchmark(金标准 + 跑分)
方法 | 路径 | 说明 |
|
| 提交一条金标准样本,请求体 |
|
| 列出本 workspace 的样本 |
|
| 跑一次 benchmark,请求体 |
|
| 列出历史跑分 |
|
| 单次跑分详情(含 metrics JSON) |
ACL 语义(2026-09-16 起):benchmark 本质是受控检索探针 —— 一条“expect chunk X 出现在库 N 的结果里”的样本,天然能当作“库 N 里有没有 chunk X”的存在性判定器。因此种探针与跑探针都要过 ACL:
POST .../gold-standards:kb_ids里的每个库都需viewer及以上权限,无权即 403(40303),跨 workspace / 不存在 404。POST .../runs:先对入参kb_ids逐个requireRead(403 不会在benchmark_runs里留下 failed 记录 —— 校验在建 run 记录之前);随后逐条样本判定调用方对样本自己存的kb_ids有没有读权,无权的样本整条跳过(而不是缩到可读子集,否则回报的召回率与样本口径不一致)。kb_ids现在必须是数字数组,非数字元素返回 400(而非静默丢弃)。注意:此前kb_ids过滤因类型问题实际从未生效(请求体里的小整数被解析成Integer,与样本里的Long比较恒不相等),跑分总是覆盖全 workspace 样本。修复后kb_ids真正生效,历史跑分数值与修复后的不可直接横比。
多模态资源(Multimodal)
多模态资源由 /v1/context/ingest(messages[].resource_ids)与上传接口写入。User Key 仅能访问自己的资源,Owner Key可访问全 workspace。跨租户查询统一返回 404。
POST /v1/multimodal/upload
上传多模态资源(图片/音频/文档),返回 queued 状态,后续由异步调度器抽取 OCR/ASR/转写。
上传路径是 /v1/multimodal/upload(非 /v1/multimodal);POST /v1/multimodal 返回 405。
请求
Form参数(multipart/form-data)
参数 | 类型 | 必填 | 说明 |
file | file | 是 | 要上传的文件 |
modality | string | 是 | 模态类型: |
session_id | string | 否 | 关联会话 ID |
metadata | string | 否 | JSON 格式元数据字符串 |
请求示例
curl -X POST "http://<host>:4040/v1/multimodal/upload" \
-H "X-API-Key: $API_KEY" \
-F "file=@/path/to/image.png" \
-F "modality=image"响应
响应示例
{"code": 0, "msg": "ok", "data": {"resource_id": "res_abc123", "ingest_status": "queued"}}GET /v1/multimodal
分页列出当前租户的多模态资源,按created_at 倒序。轻量投影,不含OCR/ASR/转写等重字段。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
page | integer | 否 | 页码(从0开始),默认 0 |
size | integer | 否 | 每页大小,默认 50,上限 200 |
请求示例
curl "http://<host>:4040/v1/multimodal?page=0&size=20" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"content": [
{
"resource_id": "res_abc123",
"modality": "image",
"mime": "image/png",
"oss_url": "http://context0.example.com/v1/files/download?key=...&expires=...&signature=...",
"thumbnail_url": null,
"size_bytes": 20480,
"ingest_status": "done",
"memory_id": "mem_1_2_abc",
"session_id": "sess-2026-08-19-001",
"member_id": 2,
"created_at": "2026-08-19T10:00:00Z",
"updated_at": "2026-08-19T10:00:05Z"
}
],
"total_elements": 1,
"total_pages": 1,
"number": 0,
"size": 20
}
}data 为 Spring Data Page 结构:条目在 content,分页元信息在 total_elements / total_pages / number / size(全局 SNAKE_CASE 命名策略生效)。
GET /v1/multimodal/{resourceId}
获取多模态资源详情,含 OCR / ASR / 转写文本与元数据。跨租户返回 404。
请求
请求示例
curl "http://<host>:4040/v1/multimodal/res_abc123" -H "X-API-Key: $API_KEY"响应
响应参数
字段 | 类型 | 说明 |
resource_id | string | 资源 ID |
modality | string | 模态( |
mime | string | MIME 类型 |
oss_url | string | Context0 短时签名下载 URL |
thumbnail_url | string | 缩略图 URL |
size_bytes | long | 文件大小(字节) |
transcribed_text | string | 转写文本(音视频) |
ocr | object | OCR 结果(图片/PDF) |
asr | object | ASR 结果(音频) |
metadata | object | 用户元数据 |
memory_id | string | 关联记忆 ID |
session_id | string | 关联会话 ID |
member_id | long | 所属成员 ID |
ingest_status | string | 摄取状态 |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"resource_id": "res_abc123",
"modality": "image",
"mime": "image/png",
"oss_url": "http://context0.example.com/v1/files/download?key=...&expires=...&signature=...",
"thumbnail_url": null,
"size_bytes": 20480,
"transcribed_text": null,
"ocr": {"text": "架构图标注文本"},
"asr": null,
"metadata": {},
"memory_id": "mem_1_2_abc",
"session_id": "sess-2026-08-19-001",
"member_id": 2,
"ingest_status": "done",
"created_at": "2026-08-19T10:00:00Z",
"updated_at": "2026-08-19T10:00:05Z"
}
}GET /v1/multimodal/{resourceId}/url
为资源生成临时预签名下载 URL(每次调用铸造新链接,不落库长期链接)。跨租户返回 404。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
ttl | integer | 否 | 预签名有效期(秒);非正数回退配置默认值,上限 86400(24h),超限返回 400 |
请求示例
curl "http://<host>:4040/v1/multimodal/res_abc123/url?ttl=3600" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"signed_url": "https://oss.example.com/...&Expires=...&Signature=...",
"expires_at": "2026-08-19T11:00:00Z",
"oss_key": "ws1/res_abc123.png"
}
}技能(Skill)
GET /v1/skills
分页列出当前 workspace 下的 Skill,按 updated_at 倒序。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
page | integer | 否 | 页码(从0开始),默认 0 |
page_size | integer | 否 | 每页大小,默认 20,取值范围:[1, 100] |
请求示例
curl "http://<host>:4040/v1/skills?page=0&page_size=10" -H "X-API-Key: $API_KEY"POST /v1/skills/search
Skill 语义检索专用端点,返回按相关度排序的 Skill 列表(L0/L1 层信息,用于触发判断)。
请求
请求参数
字段 | 类型 | 必填 | 说明 |
query | string | 是 | 检索文本 |
top_k | int | 否 | 返回条数上限 |
tags | string[] | 否 | 按标签过滤 |
请求示例
curl -X POST http://<host>:4040/v1/skills/search \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"query": "代码审查", "top_k": 5, "tags": ["review"]}'响应
响应示例
响应(Box<List<SkillSearchResult>>):
{
"code": 0,
"msg": "ok",
"data": [
{"id": 1, "name": "code-review", "description": "...", "abstract": "...", "score": 0.87, "tags": ["review"]}
]
}枚举已上传的 Skill 用 GET /v1/skills(支持分页,按 updated_at 倒序)。
GET /v1/skills/{id}
获取 Skill 元信息(L0 层,最轻量)。
请求
请求示例
curl "http://<host>:4040/v1/skills/1" -H "X-API-Key: $API_KEY"GET /v1/skills/{id}/overview
获取 Skill 摘要/abstract(L1 层),用于触发判断后再决定是否加载完整正文。
请求
请求示例
curl "http://<host>:4040/v1/skills/1/overview" -H "X-API-Key: $API_KEY"GET /v1/skills/{id}/content
获取 Skill 完整 markdown/脚本正文(L2 层)。
请求
请求示例
curl "http://<host>:4040/v1/skills/1/content" -H "X-API-Key: $API_KEY"GET /v1/skills/{id}/package
一次性返回 Skill 正文 + 资源清单(含预签名下载 URL 与 SHA-256),供客户端校验后安装。
请求
请求参数
Query 参数:ttl(预签名有效期秒数,默认 3600)。
请求示例
curl "http://<host>:4040/v1/skills/1/package?ttl=7200" -H "X-API-Key: $API_KEY"响应
客户端必须在落盘前分别校验正文和每个资源的摘要;摘要缺失或不匹配时应拒绝安装。download_url 是数据而不是信任授权:客户端还应限定允许的 scheme/origin、禁止凭据随重定向泄漏,并在完整性校验通过后再原子落盘。
响应参数
字段 | 类型 | 说明 |
id | integer | Skill ID |
name | string | Skill 包名 |
version | integer | Skill 版本 |
visibility | string | 可见性 |
content | string | 将安装为 |
content_sha256 | string |
|
resources[].rel_path | string | Skill 包内的相对路径 |
resources[].mime_type | string | 资源 MIME 类型 |
resources[].size_bytes | integer | 资源原始字节数 |
resources[].sha256 | string | 对应资源原始字节的 SHA-256(64 位十六进制) |
resources[].download_url | string | Context0 短时签名下载 URL;后端流式读取 OSS,客户端无需访问 OSS |
响应示例
{
"code": 0,
"msg": "ok",
"data": {
"id": 1,
"name": "incident-response",
"version": 3,
"visibility": "workspace",
"content": "---\nname: incident-response\n---\n# Incident response\n",
"content_sha256": "<64-hex-sha256>",
"resources": [
{
"rel_path": "references/runbook.md",
"mime_type": "text/markdown",
"size_bytes": 1024,
"sha256": "<64-hex-sha256>",
"download_url": "http://context0.example.com/v1/files/download?key=redacted&expires=redacted&signature=redacted"
}
]
}
}POST /v1/skills
创建一个 Skill,上传元信息与正文(可选附带 base64 二进制资源),需 OWNER 权限。有三种创建模式(按优先级排序:input_schema > content > body):
input_schema 模式:传
input_schema(JSON Schema)+name,自动生成 MCP Tool 格式的 Skill。body 模式:传
body(结构化正文,无需 frontmatter)+name(一般搭配description/tags等元信息字段)。content 模式:传
content(完整 Skill Markdown,必须以---YAML frontmatter 开头,name / description 等从 frontmatter 解析)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
content | string | 条件 | 完整 Skill Markdown,必须以 |
name | string | 条件 | Skill 名称。body 模式下必填( |
body | string | 条件 | 配合 name / description 的结构化正文(无需 frontmatter),与 content 二选一 |
description | string | 否 | Skill 描述 |
allowed_tools | string[] | 否 | 允许调用的工具白名单 |
tags | string[] | 否 | 标签,用于检索筛选 |
input_schema | object | 否 | Skill 参数 JSON Schema |
visibility | string | 否 | 可见性,如 workspace / member |
metadata | object | 否 | 自定义元数据 |
resources | array | 否 | 随 Skill 上传的资源(base64) |
resources[].rel_path | string | 是 | 资源相对路径 |
resources[].content_base64 | string | 是 | Base64 编码的资源内容 |
resources[].mime | string | 否 | MIME 类型(如 image/png) |
请求示例
body 模式
curl -X POST http://<host>:4040/v1/skills \ -H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \ -d '{"name": "代码审查", "description": "PR 代码审查流程", "body": "# 代码审查流程\n...", "tags": ["review"]}'content 模式,以 frontmatter 开头
curl -X POST http://<host>:4040/v1/skills \ -H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \ -d '{"content": "---\nname: 代码审查\ndescription: PR 代码审查流程\n---\n# 代码审查流程\n...", "tags": ["review"]}'
响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"id": 1,
"name": "代码审查",
"description": null,
"version": 1,
"source_format": "markdown",
"abstract": null,
"allowed_tools": [],
"tags": ["review"],
"visibility": "workspace",
"owner_member_id": 2,
"resource_count": 0,
"ingest_status": "pending",
"created_at": "2026-08-19T10:00:00Z",
"updated_at": "2026-08-19T10:00:00Z"
}
}GET /v1/skills/{id}/resources
列出 Skill 关联的二进制 / 文本资源(如示例脚本、说明截图)。
请求
请求参数
参数 | 类型 | 说明 |
rel_path | string | 资源相对路径 |
mime_type | string | MIME 类型 |
size_bytes | long | 资源字节数 |
请求示例
curl "http://<host>:4040/v1/skills/1/resources" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": [
{"rel_path": "scripts/run.sh", "mime_type": "text/x-shellscript", "size_bytes": 512}
]
}GET /v1/skills/{id}/resources/{relPath}
为指定 Skill 资源生成 OSS 预签名下载 URL,可在 ttl 秒内匿名下载。{relPath} 为资源相对路径(可含 /)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
ttl | integer | 否 | 预签名 URL 有效期(秒),默认 3600 |
请求示例
curl "http://<host>:4040/v1/skills/1/resources/scripts/run.sh?ttl=3600" -H "X-API-Key: $API_KEY"响应
响应示例
data 为预签名 URL 字符串。
{"code": 0, "msg": "ok", "data": "https://oss.example.com/...&Signature=..."}DELETE /v1/skills/{id}
按 ID 删除 Skill 及其资源,需OWNER权限。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/skills/1 -H "X-API-Key: $OWNER_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": null}策略(Strategy)
策略管理需Owner Key。
GET /v1/strategies/presets
返回内置可用的策略预设列表。
请求
请求示例
curl "http://<host>:4040/v1/strategies/presets" -H "X-API-Key: $OWNER_KEY"GET /v1/strategies
列出当前租户策略。支持按 preset / active 过滤。
请求
请求参数
Query 参数:preset(string)、active(boolean)。
请求示例
curl "http://<host>:4040/v1/strategies?active=true" -H "X-API-Key: $OWNER_KEY"POST /v1/strategies
创建一条自定义策略。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
name | string | 是 | 策略名称,1–128 字符,仅 |
config_json | object | 是 | 策略配置(JSON 对象) |
preset | string | 否 | 预设类型: |
description | string | 否 | 描述,最长 512 字符 |
创建后 active 默认为 true。
请求示例
curl -X POST http://<host>:4040/v1/strategies \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"preset": "coding", "name": "编码助手策略", "config_json": {"recall_top_k": 15}}'GET /v1/strategies/{id}
获取指定策略详情。
请求
请求示例
curl "http://<host>:4040/v1/strategies/1" -H "X-API-Key: $OWNER_KEY"PUT /v1/strategies/{id}
更新策略字段或参数。所有字段均可选,仅更新传入的字段(name 不可更新,需删除后重建)。
请求
请求示例
curl -X PUT http://<host>:4040/v1/strategies/1 \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"config_json": {"recall_top_k": 20}}'DELETE /v1/strategies/{id}
删除指定策略。
请求
请求示例
curl -X DELETE http://<host>:4040/v1/strategies/1 -H "X-API-Key: $OWNER_KEY"POST /v1/strategies/{id}/apply
将策略应用为当前租户的生效配置。
请求
请求示例
curl -X POST http://<host>:4040/v1/strategies/1/apply -H "X-API-Key: $OWNER_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"strategy_id": 1, "applied_at": "2026-08-19T10:00:00Z"}}POST /v1/strategies/{id}/deactivate
将策略设为 inactive。
请求
请求示例
curl -X POST http://<host>:4040/v1/strategies/1/deactivate -H "X-API-Key: $OWNER_KEY"策略钩子(Strategy Hooks)
策略钩子允许在策略执行的特定生命周期节点(hook_point)触发自定义行为。钩子按 priority 升序执行。策略管理需 Owner Key。
POST /v1/strategies/{strategyId}/hooks
为指定策略创建一个钩子。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
hook_point | string | 是 | 触发点标识,有效值: |
hook_type | string | 是 | 钩子类型,有效值: |
config_json | object | 否 | 钩子配置(JSON 对象,如 webhook URL、超时等) |
enabled | boolean | 否 | 是否启用,默认 true |
priority | integer | 否 | 执行优先级(升序),默认 0 |
请求示例
curl -X POST "http://<host>:4040/v1/strategies/1/hooks" \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"hook_point": "recall_pre", "hook_type": "script", "config_json": {"expr": "ctx.topK = 20"}, "enabled": true, "priority": 10}'GET /v1/strategies/{strategyId}/hooks
列出指定策略的所有钩子。
请求
请求示例
curl "http://<host>:4040/v1/strategies/1/hooks" -H "X-API-Key: $OWNER_KEY"GET /v1/strategies/{strategyId}/hooks/{hookId}
获取指定钩子详情。
请求
请求示例
curl "http://<host>:4040/v1/strategies/1/hooks/1" -H "X-API-Key: $OWNER_KEY"PUT /v1/strategies/{strategyId}/hooks/{hookId}
更新钩子配置。所有字段均可选,仅更新传入的字段。
请求
请求示例
curl -X PUT "http://<host>:4040/v1/strategies/1/hooks/1" \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"enabled": false}'DELETE /v1/strategies/{strategyId}/hooks/{hookId}
删除指定钩子。
请求
请求示例
curl -X DELETE "http://<host>:4040/v1/strategies/1/hooks/1" -H "X-API-Key: $OWNER_KEY"认证(Auth)
GET /v1/auth/whoami
返回当前 API Key 解析出的身份信息,用于验证 key 有效性和查看当前身份。无 ACL 校验。
请求
请求示例
curl "http://<host>:4040/v1/auth/whoami" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"authenticated": true,
"workspace_id": 1,
"member_id": 2,
"key_type": "USER",
"bound_user_id": "alice"
}
}未认证时:
{"code": 0, "msg": "ok", "data": {"authenticated": false}}API Key 管理(管理面)
管理面端点,需 Owner Key认证。前缀:/ops/workspaces/members/keys。
方法 | 路径 | 说明 |
|
| 创建 API Key,返回一次性明文密钥 |
|
| 分页列出 API Key;V56 版本后创建的 Key 在响应中包含 |
|
| 撤销指定 API Key |
创建请求参数:
参数
类型
必填
说明
workspace_id
long
是
工作空间 ID
member_id
long
否
成员 ID;省略时由服务端根据 Key 绑定的 member 推断
key_type
string
是
OWNER/USER创建响应(一次性明文):
{"code": 0, "msg": "ok", "data": {"id": 5, "key_prefix": "ctx0_", "key_type": "USER", "plain_key": "ctx0_abc123..."}}列表响应(
plain_key仅 V56+ Key 非空):{"code": 0, "msg": "ok", "data": {"items": [{"id": 5, "workspace_id": 1, "member_id": 2, "key_prefix": "ctx0_", "plain_key": "ctx0_abc123...", "key_type": "USER", "status": "active", "created_at": "2026-08-19T10:00:00Z", "last_used_at": "2026-09-16T08:00:00Z"}], "total_elements": 1}}撤销请求:
{"id": 5}
成员管理(管理面)
管理面端点,需 Owner Key认证。前缀:/ops/workspaces/members。
方法 | 路径 | 说明 |
|
| 创建成员 |
|
| 分页列出成员(上限 200 条/页) |
|
| 更新成员信息 |
|
| 删除成员,请求体 |
列表请求示例:
curl "http://<host>:8080/ops/workspaces/members?workspaceId=3&page=0&pageSize=20" -H "X-API-Key: $OWNER_KEY"列表响应示例:
{ "code": 0, "msg": "ok", "data": { "content": [ {"id": 1, "workspace_id": 3, "user_id": "admin", "name": "Admin", "status": "active", "created_at": "2026-09-16T01:00:00Z", "updated_at": "2026-09-16T01:00:00Z"} ], "total_elements": 1, "total_pages": 1 } }说明workspaceId必须等于调用方自身的工作空间,不允许跨租户查询。
托管文件下载
GET /v1/files/download
统一从 OSS / MinIO 流式中转文件给客户端。Skill 包资源、Skill 单资源 URL、知识库检索命中的原文/图片、文档图片列表、Wiki 来源原文及多模态上传结果、列表、详情、资源 URL 和上下文中的下载链接均通过此接口交付。后台模型调用使用的存储预签名地址保留原用途。
业务接口先执行原有租户、成员和资源可见性检查,再签发具体对象的短时下载链接。原有 download_url、oss_url、signed_url 字段名称及字符串类型不变,客户端直接使用返回值,不应自行解析 OSS 域名或拼接对象路径。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
key | string | 是 | 服务端生成的对象键编码 |
expires | integer | 是 | 服务端生成的 Unix 过期时间(秒) |
signature | string | 是 | 服务端生成的 HMAC-SHA256 签名 |
响应
成功响应
HTTP 200 原始文件字节(不是 Box JSON),Content-Disposition: attachment、Cache-Control: no-store、X-Content-Type-Options: nosniff。服务端流式传输并关闭存储流,不将整个文件缓存在内存中;不重定向到 OSS。
生效条件:此端点仅在配置了 OSS 存储(
context.oss.access-key)时生效。无 OSS 配置的部署不注册该路由。认证:完整签名 URL 即临时下载凭证,仅数据面端口(默认 4040)支持免 Key 访问,管理面端口仍需
X-API-Key。签名限定存储命名空间、对象键和有效期;篡改或过期返回 403,不能凭任意 OSS key 下载。签名链接和原 OSS 预签名链接一样,在有效期内持有者可读取该对象,应避免公开分享。有效期沿用签发业务接口的 TTL 规则(多模态资源 URL 接口上限仍为 86400 秒)。对象删除后链接无法读取原对象;权限变更不会提前撤销已签发、尚未过期的链接。部署:默认使用当前 API 请求的 origin,并随请求上下文传递到异步检索。如果通过反向代理访问且后端看到的是内部 origin,配置
OSS_DOWNLOAD_ENDPOINT=https://<Context0 对外域名>;该值是 Context0 服务 origin,不是 OSS origin。多个副本须使用一致的 OSS 配置和签名凭据。CLI:
ctxdb0 skills fetch继续校验正文/资源 SHA-256、大小和路径并原子落盘,不执行下载内容。已配置的 Context0 origin 可按原连接协议下载(含已授权的 HTTP 托管实例);额外跨域 origin 仍须显式 HTTPS 白名单,禁止重定向,不向下载地址发送 API Key。
模型调用用量(管理面)
以下端点运行在管理面端口(默认 8080),需Owner Key认证,使用标准 Box 响应,只查询认证工作空间;可选 memberId 限定成员。
方法 | 路径 | 说明 |
|
| 日聚合汇总,返回 |
|
| 按日、调用类型、模型的趋势 |
|
| 按小时和调用类型的趋势; |
call_type包含llm、embedding、vision、ocr、rerank、dedup。新增四类分别覆盖 DashScope Vision、独立 OCR、DashScope/HTTP Rerank 和自定义 HTTP 去重裁决(单条及批量);默认LlmProviderDedupAdjudicator已归入llm,不会再次归入dedup。用量取自成功 HTTP 响应的
usage.prompt_tokens/completion_tokens或input_tokens/output_tokens,总量优先采用total_tokens,没有总量时累加已知输入输出。Rerank 只返回总量时按输入 Token 记录;生成式调用只返回总量时不推测输入输出拆分。每个响应计一次,不按批量裁决对数重复乘算;业务解析失败后发生新的请求,分别统计各次成功响应。403、429、超时等没有成功响应的请求不凭输入长度推算消耗。自定义裁决服务须在响应顶层透传上述
usage,批量响应应给出整次请求的累计用量。缺失、非法 usage 或仅返回非 Token 计费单位(如search_units)时,仅增加成功调用次数,Token 按 0 个已知值累计并记录model token usage unavailable告警;0 不代表实际免费。数据异步累加至共享数据库的
token_usage_daily/hourly,允许跨节点汇总;沿用现有尽力记录机制。后台调用可能只有工作空间、没有成员,按成员筛选时不包含这些用量。新增类别会进入现有总览及已启用的月 Token 配额判断;已有接口字段、表结构和配置不变。此处不涵盖流式回答及其他尚未接入的模型路径,也不能追补升级前漏记的数据。
定时记忆晋升(Scheduled Promotion)
定时任务按 schedule_mode 调度配置(daily / weekly / monthly / interval / cron 五种触发时机,另有 legacy 兼容模式,见下文)周期性触发一次记忆晋升生成,auto_approve=true(默认)时生成完成后自动审批入库到 target_kb_id 指定的知识库(此时 target_kb_id 必填)。整体能力由配置 context.promotion.scheduled.enabled(默认 false)与 workspace 级 feature flag scheduled_promotion_enabled 控制;自动审批另受 scheduled_promotion_auto_approve_enabled flag 控制(kill-switch,默认放行)。每 workspace 活跃任务上限 10 个,每日定时执行上限 24 次;手动触发有 5 分钟 cooldown。
任务对象字段(snake_case wire 格式):{id, member_id, name, prompt, schedule_type, schedule_mode, schedule_hour, schedule_minute, schedule_day_of_week, schedule_day_of_month, schedule_interval_hours, schedule_cron, trigger_summary, auto_approve, target_kb_id, enabled, last_run_at, next_run_at, fire_count, created_at, updated_at}。
调度配置(schedule_mode)
字段 | 适用模式 | 取值与说明 |
| — |
|
| daily / weekly / monthly | 0–23,触发小时 |
| daily / weekly / monthly | 0–59,触发分钟 |
| weekly | 1–7,周一=1 |
| monthly | 1–31;超过当月最后一天时截断到月末执行(如配 31 号,2 月按月末触发) |
| interval | ≥1,间隔小时数 |
| cron | Spring 6 位 cron 表达式(秒 分 时 日 月 周) |
所有调度均按固定时区 Asia/Shanghai 触发,不可配置。
cron 限制:服务端除校验表达式合法性外,还会采样后续 3 次触发时刻,要求相邻触发间隔 ≥1 小时,否则拒绝;无任何未来触发时刻的 cron 同样拒绝。
trigger_summary:响应新增只读字段
trigger_summary,为服务端生成的中文调度摘要(如「每天 09:00」「每周 周一 10:00」),可直接展示给用户。legacy 兼容:旧字段
schedule_type(hourly/every_other_day/weekly)继续接受——只传schedule_type的旧客户端按legacy模式处理,三档分别映射为 1h / 48h / 168h 间隔(响应中schedule_mode返回legacy);使用新模式创建的任务,schedule_type字段写入与 mode 同名的值。本次变更为纯 additive,旧schedule_type客户端不受影响,无 breaking change。
数据面(User / Agent Key)
User Key 只能看到并操作本人创建的任务;创建要求携带成员上下文。
方法与路径 | 说明 |
| 分页列出任务,返回 |
| 创建任务,请求体 |
| 更新任务,请求体各字段可选,另支持 |
| 删除任务(幂等:任务不存在也返回成功,重复 DELETE 均成功) |
| 手动立即触发一次(5 分钟 cooldown;上一轮晋升仍在 |
target_kb_id 的权限校验(2026-09-16 起):创建与更新时,
target_kb_id必须是任务归属成员(不是当次请求者)有editor及以上权限的知识库——无权返回 403(40303),跨 workspace / 不存在返回 404。此前只校验"这个知识库在不在本 workspace",任何成员都能把定时任务的落库目标指向同 workspace 的任意库(含私有库),此后每次调度都在无人值守的情况下往里写文档。判定主体用任务归属的
member_id而不是当次请求身份:任务是长期存在的,执行时点上唯一有意义的主体就是它的归属人。已存在的任务不会被追溯校验;但执行时同样会过这道闸——如果归属人后来失去了目标库的写权限,该轮晋升会失败并把原因记录在任务的最近错误里,而不是照写。
更新时只在请求体真的带了 auto_approve 或 target_kb_id 时才校验(2026-09-17 修正)。此前是无条件校验,于是一个纯改名请求
PUT {"name": "新名字"}会把早已存在的target_kb_id重判一次;目标库的 ACL 后来收紧之后,改名会莫名 403 / 404,而任务本身根本没碰过那个库。判定对象是"这次请求要建立的新状态",不是历史遗留状态。
请求
请求示例:
curl -X POST "http://<host>:4040/v1/scheduled_promotions" -H "X-API-Key: $USER_KEY" \
-H 'Content-Type: application/json' \
-d '{"name": "每周架构沉淀", "prompt": "总结本周的架构决策", "schedule_mode": "weekly", "schedule_day_of_week": 1, "schedule_hour": 10, "schedule_minute": 0, "auto_approve": true, "target_kb_id": 3}'五种模式请求体示例(均为
POST /v1/scheduled_promotions,auto_approve/target_kb_id等公共字段同上,此处省略):daily——每天 09:00:
{"name": "每日沉淀", "prompt": "总结当日关键决策", "schedule_mode": "daily", "schedule_hour": 9, "schedule_minute": 0}weekly——每周一 10:00:
{"name": "周报沉淀", "prompt": "总结本周的架构决策", "schedule_mode": "weekly", "schedule_day_of_week": 1, "schedule_hour": 10, "schedule_minute": 0}monthly——每月 15 号 09:00:
{"name": "月度沉淀", "prompt": "总结本月里程碑", "schedule_mode": "monthly", "schedule_day_of_month": 15, "schedule_hour": 9, "schedule_minute": 0}interval——每隔 6 小时:
{"name": "高频沉淀", "prompt": "提炼近期讨论要点", "schedule_mode": "interval", "schedule_interval_hours": 6}cron——工作日 09:00:
{"name": "工作日沉淀", "prompt": "总结工作日进展", "schedule_mode": "cron", "schedule_cron": "0 0 9 * * 1-5"}
响应
响应示例:
{
"code": 0, "msg": "ok",
"data": {
"id": 12, "member_id": 7, "name": "每周架构沉淀", "prompt": "总结本周的架构决策",
"schedule_type": "weekly", "schedule_mode": "weekly",
"schedule_hour": 10, "schedule_minute": 0, "schedule_day_of_week": 1,
"schedule_day_of_month": null, "schedule_interval_hours": null, "schedule_cron": null,
"trigger_summary": "每周 周一 10:00",
"auto_approve": true, "target_kb_id": 3, "enabled": true,
"last_run_at": null, "next_run_at": "2026-09-14T02:00:00Z", "fire_count": 0,
"created_at": "2026-09-10T00:00:00Z", "updated_at": "2026-09-10T00:00:00Z"
}
}管理面
管理面端点需Owner Key认证,遵循 /ops/** 全 query param 约定(不使用路径参数);不带 memberId 时操作 workspace 全量任务。
方法与路径 | 说明 |
| 分页列出(可按成员过滤) |
| 任务详情 |
| 创建(请求体同数据面) |
| 更新(请求体同数据面) |
| 删除(幂等,语义同数据面) |
| 手动触发 |
定时产生的晋升在既有列表(数据面 GET /v1/memory_promotions、管理面 GET /ops/promotion/list)中以 source_type=scheduled 呈现,人工审批 / 驳回流程不变;自动审批完成的晋升在审计历史 metadata 中记录来源 scheduledTaskId。
晋升审批与产物可见性(2026-09-16新增)
审批时判定的是发起人,不是审批人。approve 一条晋升时,校验的是该晋升的
requested_by成员对目标库有没有editor及以上权限——否则 403(40303),且晋升状态原样留在pending_review(校验在状态 CAS 之前,不会卡在approving)。这条规则挡住的是“我没有写权,但找个有权的人替我点确认”这条绕行路径。晋升产物就是一篇普通的知识库文档。落库后它继承目标知识库的 ACL,不自带任何额外可见性:目标库的
viewer能搜到、能读它、能在 Wiki/图谱里看到;对目标库无权的成员在所有读路径上都拿不到它(403),包括原始记忆的归属人。审批前的草稿不在知识库路径上存在。
pending_review状态的晋升只出现在晋升列表里,GET /v1/knowledge/bases/{kbId}/documents等知识库路径上查不到——目标库的成员不会提前看到还没批的内容。
Provider 管理与部署规则边界
模型请求高级 Header/顶层字段删除仅由部署文件在启动时加载(见「配置参考」文档的「模型请求高级配置独立 JSON」章节)。现有 Provider 管理接口仍使用 Box<T>,config_json 保持字符串;没有新增规则读写接口或响应字段。
既有接口 | 权限与行为 |
| 全局仅平台 ADMIN;租户仅本工作区 OWNER;响应不合并部署规则 |
| 沿用既有 active 解析与权限,历史 metadata 可读 |
| 沿用既有 chain 排序、权限及 DTO,历史 metadata 不激活为部署规则 |
| 主 |
| 平台 ADMIN;managed kind 的非空 DB chain 返回 409。空 chain 沿用进程内 disable,锁仍保留,重新启用须部署重启 |
所有 Provider PUT 均拒绝保留命名空间 requestOverrides / request-overrides(外层 DTO 未知字段丢弃前以及 config_json 内检查;空值也拒绝)。这不扩大为对历史 extraHeaders / removeBodyFields 等 metadata 的封禁,不自动迁移数据库或改变合法 GET。
兼容性影响:不改变 endpoint、响应结构、已有字段类型或 Embedding fingerprint。未配置规则时保留原管理/请求/fallback 行为;明确的安全变化为上述新 PUT 命名空间拒绝、全部 Provider PUT 审计正文抑制(动作/身份/结果/trace 保留),以及 ASR 结果下载鉴权隔离与 taskId 路径校验。Provider PUT 的畸形 body/config JSON 错误使用固定提示,不回显提交值或底层解析片段。租户 Provider 配置仍是暂存状态,不会改写全局 live Provider。
Agent 用量上报
供 Agent 运行时上报模型调用用量,便于按 session/agent 维度统计 Token 消耗。
POST /v1/agent-usage
上报一条 Agent 用量记录。
请求
请求参数(扁平结构,不嵌套)
参数 | 类型 | 必填 | 说明 |
session_id | string | 否 | 关联的会话 ID |
agent_type | string | 否 | Agent 类型标识 |
model | string | 否 | 模型名称 |
input_tokens | long | 否 | 输入 Token 数(≥0) |
output_tokens | long | 否 | 输出 Token 数(≥0) |
turns | integer | 否 | 对话轮次(≥0) |
duration_sec | integer | 否 | 持续时长(秒,≥0) |
请求示例
curl -X POST "http://<host>:4040/v1/agent-usage" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"session_id": "sess-001", "agent_type": "chat", "model": "qwen-plus", "input_tokens": 1000, "output_tokens": 500, "turns": 3, "duration_sec": 120}'响应
响应示例
{"code": 0, "msg": "ok", "data": null}POST /v1/agent-usage/batch
批量上报多条 Agent 用量记录(上限 100 条)。
请求
请求体
JSON 数组,每项结构同单条上报。
请求示例
curl -X POST "http://<host>:4040/v1/agent-usage/batch" \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '[{"session_id": "sess-001", "agent_type": "chat", "model": "qwen-plus", "input_tokens": 500, "output_tokens": 200, "turns": 1, "duration_sec": 30}, {"session_id": "sess-002", "agent_type": "rag", "model": "qwen-max", "input_tokens": 800, "output_tokens": 300, "turns": 2, "duration_sec": 60}]'Agent 用量统计(管理面)
以下端点运行在管理面端口(默认 8080),需Owner Key。
GET /ops/agent-usage/summary
查询指定时间范围内的 Agent 用量汇总,按 agent_type + model 分组。
请求
Query 参数
参数 | 类型 | 必填 | 说明 |
from | date | 是 | 起始日期(ISO 格式 |
to | date | 是 | 截止日期(ISO 格式 |
memberId | string | 否 | 按成员过滤 |
请求示例
curl "http://<host>:8080/ops/agent-usage/summary?from=2026-09-01&to=2026-09-19" -H "X-API-Key: $OWNER_KEY"响应
响应示例
{"code": 0, "msg": "ok", "data": {"total_tokens": 15000, "total_sessions": 5, "items": [{"agent_type": "chat", "model": "qwen-plus", "input_tokens": 8000, "output_tokens": 4000, "sessions": 3}]}}GET /ops/agent-usage/trend
查询指定时间范围内的 Agent 用量趋势,按日期分组。
请求
Query 参数
同 summary。
请求示例
curl "http://<host>:8080/ops/agent-usage/trend?from=2026-09-01&to=2026-09-19" -H "X-API-Key: $OWNER_KEY"审计与合规
审计日志(Audit Logs)
审计日志自动记录 API 操作,Owner Key和User Key均可读取。User Key只能查看自己的操作记录。
GET /v1/audit/logs
分页列出审计日志,支持按操作类型、结果、时间范围过滤。
请求
Query 参数
参数 | 类型 | 必填 | 说明 |
action | string | 否 | 按操作类型过滤(如 |
result | string | 否 | 按结果过滤: |
from | string | 否 | 起始时间(ISO-8601,含) |
to | string | 否 | 截止时间(ISO-8601,含) |
page | integer | 否 | 页码(0-indexed),默认 0 |
size | integer | 否 | 每页大小,默认 50,上限 200 |
请求示例
curl "http://<host>:4040/v1/audit/logs?action=context.ingest&result=success&page=0&size=20" \
-H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"content": [
{
"id": 42,
"workspace_id": 1,
"action": "context.ingest",
"subject_type": "user",
"subject_id": "4",
"result": "success",
"path": "/v1/context/ingest",
"created_at": "2026-09-16T01:00:00Z",
"last_error_short": null
}
],
"total_elements": 1,
"total_pages": 1
}
}GET /v1/audit/logs/{id}
获取单条审计日志详情,含完整请求/响应信息。
请求
请求示例
curl "http://<host>:4040/v1/audit/logs/42" -H "X-API-Key: $API_KEY"GET /v1/audit/stats
按指定维度聚合审计统计(操作类型分布、成功率等)。
请求
Query 参数
参数 | 类型 | 必填 | 说明 |
group_by | string | 是 | 聚合维度: |
action | string | 否 | 按操作类型过滤 |
from | string | 否 | 起始时间(ISO-8601) |
to | string | 否 | 截止时间(ISO-8601) |
请求示例
curl "http://<host>:4040/v1/audit/stats?group_by=action" -H "X-API-Key: $API_KEY"响应
响应示例
{
"code": 0, "msg": "ok",
"data": {
"groups": [
{"key": {"action": "context.ingest"}, "count": 10, "success_rate": 0.9},
{"key": {"action": "session.create"}, "count": 25, "success_rate": 0.8}
]
}
}审计策略(Audit Policies)
审计策略管理需Owner Key(高影响操作,可控制审计链路开关)。
GET /v1/audit/policies
列出当前 workspace 的审计策略。
请求
请求示例
curl "http://<host>:4040/v1/audit/policies" -H "X-API-Key: $OWNER_KEY"POST /v1/audit/policies
创建一条审计策略。
请求
请求示例
curl -X POST "http://<host>:4040/v1/audit/policies" \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"name": "记录所有写操作", "action_pattern": "*.create|*.update|*.delete", "enabled": true}'GET /v1/audit/policies/{id}
获取指定审计策略详情。
请求
请求示例
curl "http://<host>:4040/v1/audit/policies/1" -H "X-API-Key: $OWNER_KEY"PUT /v1/audit/policies/{id}
更新审计策略。
请求
请求示例
curl -X PUT "http://<host>:4040/v1/audit/policies/1" \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"enabled": false}'DELETE /v1/audit/policies/{id}
删除指定审计策略。
请求
请求示例
curl -X DELETE "http://<host>:4040/v1/audit/policies/1" -H "X-API-Key: $OWNER_KEY"数据擦除
数据擦除端点均需Owner Key(高影响、不可逆级联删除,不向User Key 开放)。User Key调用返回端口/权限错误。
POST /v1/audit/gdpr/erasure
发起一个 GDPR “被遗忘权”数据擦除作业(异步排队,由后台 worker 全链路级联删除主体数据)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
subjectType | string | 是 | 主体类型: |
subjectId | string | 是 | 主体标识( |
workspaceId | string | 否 | 目标 workspace;缺省用当前(OWNER 可通过 |
reason | string | 否 | 擦除原因(审计留存) |
scope | string[] | 否 | 限定擦除目标,缺省全链路级联 |
主体解析失败不会静默成功:subject_id 在该 workspace 内解析不到对应 member(user 无同名 user_id、member 非数字)时,作业终态为 failed 且 last_error 说明 subject unresolved,deleted_counts 为 {};不会回报 done + 全 0 计数。
请求示例
curl -X POST http://<host>:4040/v1/audit/gdpr/erasure \
-H "X-API-Key: $OWNER_KEY" -H "Content-Type: application/json" \
-d '{"subjectType": "user", "subjectId": "alice", "reason": "user request"}'响应
响应示例
{"code": 0, "msg": "ok", "data": {"jobId": 1001, "status": "queued"}}GET /v1/audit/gdpr/jobs
分页列出当前 workspace 的擦除作业(仅限调用方 workspace)。
请求
请求参数
参数 | 类型 | 必填 | 说明 |
status | string | 否 | 按状态过滤(如 |
page | integer | 否 | 页码(从0开始),默认 0 |
size | integer | 否 | 每页大小,默认 50,上限 200 |
请求示例
curl "http://<host>:4040/v1/audit/gdpr/jobs?status=done&size=20" -H "X-API-Key: $OWNER_KEY"响应
返回 Box<Page<DetailResponse>>,条目在 content。
响应示例
{
"code": 0, "msg": "ok",
"data": {
"content": [
{"id": 1001, "workspace_id": "1", "subject_type": "user", "subject_id": "alice", "status": "done", "attempt_count": 1, "submitted_at": "2026-08-19T10:00:00Z", "completed_at": "2026-08-19T10:00:30Z"}
],
"total_elements": 1,
"total_pages": 1,
"number": 0,
"size": 20
}
}GET /v1/audit/gdpr/jobs/{id}
获取单个擦除作业详情,含各目标删除计数与失败时的错误信息。跨 workspace 访问返回错误。
请求
请求示例
curl "http://<host>:4040/v1/audit/gdpr/jobs/1001" -H "X-API-Key: $OWNER_KEY"响应
响应参数
参数 | 类型 | 说明 |
id | long | 作业 ID |
workspaceId | string | 所属 workspace |
subjectType / subjectId | string | 擦除主体类型与标识 |
reason | string | 擦除原因 |
scope | string[] | 限定目标;全链路时为 |
status | string | 作业状态 |
attemptCount | int | 已尝试次数 |
lastError | string | 最后一次失败的错误信息 |
deletedCounts | string | 各目标删除计数(JSON 字符串) |
submittedBy | string | 提交方标识 |
submittedAt / completedAt | string | 提交 / 完成时间(ISO-8601) |
响应示例
{
"code": 0, "msg": "ok",
"data": {
"id": 1001,
"workspace_id": "1",
"subject_type": "user",
"subject_id": "alice",
"reason": "user request",
"scope": null,
"status": "done",
"attempt_count": 1,
"last_error": null,
"deleted_counts": "{\"memories\":42,\"sessions\":3}",
"submitted_by": "owner-key-2",
"submitted_at": "2026-08-19T10:00:00Z",
"completed_at": "2026-08-19T10:00:30Z"
}
}附录:通用错误码
错误码 | 名称 | HTTP Status | 说明 |
0 | OK | 200 | 成功 |
40001 | VALIDATION_FAILED | 400 | 参数校验失败 |
40002 | FILTER_SYNTAX_INVALID | 400 | filter 语法非法 |
40009 | DATA_INTEGRITY_VIOLATION | 400 | 数据完整性冲突(NOT NULL / FK / UK) |
40010 | SOURCE_CHUNK_READ_ONLY | 400 |
|
40011 | QUOTA_EXCEEDED | 429 | 配额超限(OSS 存储 / 月度 token) |
40012 | UNSUPPORTED_CHARACTER | 400 | 文本含存储层字符集无法承载的字符 |
40101 | AUTH_INVALID_KEY | 401 | 认证失败(API Key 无效或缺失) |
40301 | AUTH_PORT_MISMATCH | 403 | Key 类型与端口不匹配(如 USER key 调管理面) |
40302 | AUTH_REVOKED | 403 | API Key 已吊销 |
40303 | ACL_FORBIDDEN | 403 | Knowledge ACL 校验失败(知识库权限不足)。注意:kbId 跨 workspace 或不存在返回 |
40304 | FEATURE_DISABLED | 403 | 能力被配置开关关闭 |
40401 | RESOURCE_NOT_FOUND | 404 | 资源不存在 |
40901 | CONFLICT | 409 | 资源冲突 |
40902 | SESSION_CLOSED | 409 | 会话已关闭 |
42901 | RATE_LIMITED | 429 | 请求频率超限 |
50001 | INTERNAL_ERROR | 500 | 服务内部错误 |
50301 | EMBEDDING_UNAVAILABLE | 503 | Embedding 服务不可用 |
50302 | LLM_UNAVAILABLE | 503 | LLM 服务不可用 |
50303 | OSS_UNAVAILABLE | 503 | OSS 服务不可用 |
50304 | SERVICE_UNAVAILABLE | 503 | 依赖的可选运行时组件在当前部署模式不可用 |
旧版文档错误码迁移对照:早前公开文档的错误码表与服务端实际枚举不符。按旧码编写的错误处理或告警规则请对照替换:
旧
40001(认证失败)→40101 AUTH_INVALID_KEY;当前40001已表示 VALIDATION_FAILED(参数校验失败)旧
40003(权限不足)→40301 AUTH_PORT_MISMATCH(Key 类型与端口不匹配)/40302 AUTH_REVOKED(Key 已吊销)/40303 ACL_FORBIDDEN(ACL 校验失败)旧
40004(资源不存在)→40401 RESOURCE_NOT_FOUND旧
40010(参数校验失败)→40001 VALIDATION_FAILED;当前40010已表示 SOURCE_CHUNK_READ_ONLY旧
42900(请求频率超限)→42901 RATE_LIMITED;配额超限另用40011 QUOTA_EXCEEDED(HTTP 429)旧
50000(服务内部错误)→50001 INTERNAL_ERROR
旧码 40003 / 40004 / 42900 / 50000 以及旧表中 40010 的「参数校验失败」语义,服务端从未返回过;40009(数据完整性冲突)码值与语义均未变。
附录:参数别名约定
API 同时接受 snake_case和 camelCase:
session_id↔sessionIduser_id↔userIdagent_id↔agentIdtop_k↔topKkb_ids↔kbIdstoken_budget↔tokenBudgetkeep_recent_n↔keepRecentNinclude_l2↔includeL2vector_only↔vectorOnlycosine_threshold↔cosineThreshold↔threshold