- Updated API authentication headers to use `X-API-Key` for both admin and user APIs. - Modified the account creation process to directly create user-specific accounts without requiring an admin workspace. - Enhanced user creation to return account-specific details, including `admin_user_id`. - Introduced new endpoints for retrieving task status and user profiles, allowing for more flexible user data management. - Updated search functionality to include additional parameters such as `level` and `score_threshold`. - Improved the handling of user keys in the storage layer to associate them with specific accounts. - Added tests to validate the new user account creation process and search functionalities, ensuring proper integration with the OpenViking service. - Included new documentation to reflect changes in API usage and expected request/response formats.
391 lines
9.4 KiB
Markdown
391 lines
9.4 KiB
Markdown
# OpenViking Memory API 流程说明
|
||
|
||
> 本文档整理 OpenViking 中「创建账号/用户 → 创建 session → 写入消息 → commit 抽取长期 memory → 查询 task 状态 → 检索 user memory/session memory」的完整 API 流程。
|
||
>
|
||
> 出于安全原因,示例中不写入真实 `root_api_key` 或 `user_key`,统一使用环境变量占位。
|
||
|
||
## 0. 前置变量
|
||
|
||
```bash
|
||
# 在config.yaml里设置的 openviking url 和 api_key
|
||
export OV_HOST="http://localhost:1933"
|
||
export ROOT_KEY="your-secret-root-key"
|
||
|
||
# 创建用户后填入返回的 user_key
|
||
export USER_A_KEY="<userA-user-key>"
|
||
export USER_B_KEY="<userB-user-key>"
|
||
```
|
||
|
||
OpenViking 的常见鉴权方式:
|
||
|
||
| 场景 | Header |
|
||
|---|---|
|
||
| Admin API,例如创建 account | `X-API-Key: $ROOT_KEY` |
|
||
| 普通用户 API,例如 session/message/search | `X-API-Key: $USER_A_KEY` |
|
||
|
||
---
|
||
|
||
## 1. 创建用户隔离工作区 / account
|
||
|
||
Admin API 用于多租户管理。Memory Gateway 为每个业务用户直接创建一个 admin account,不再调用 `/api/v1/admin/accounts/admin/users`。
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/admin/accounts" \
|
||
-H "X-API-Key: $ROOT_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"account_id": "userA_account",
|
||
"admin_user_id": "userA"
|
||
}'
|
||
```
|
||
|
||
典型返回:
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": {
|
||
"account_id": "userA_account",
|
||
"admin_user_id": "userA",
|
||
"user_key": "<userA-user-key>"
|
||
},
|
||
"error": null,
|
||
"telemetry": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 创建更多用户
|
||
|
||
### 2.1 创建 userA
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/admin/accounts" \
|
||
-H "X-API-Key: $ROOT_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"account_id": "userA_account",
|
||
"admin_user_id": "userA"
|
||
}'
|
||
```
|
||
|
||
返回后保存:
|
||
|
||
```bash
|
||
export USER_A_KEY="<userA-user-key>"
|
||
```
|
||
|
||
### 2.2 创建 userB
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/admin/accounts" \
|
||
-H "X-API-Key: $ROOT_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"account_id": "userB_account",
|
||
"admin_user_id": "userB"
|
||
}'
|
||
```
|
||
|
||
返回后保存:
|
||
|
||
```bash
|
||
export USER_B_KEY="<userB-user-key>"
|
||
```
|
||
|
||
> 注意:不同用户必须使用各自的 `user_key`。用 userA 的 key 只能访问 userA 的用户空间,用 userB 的 key 只能访问 userB 的用户空间。
|
||
|
||
---
|
||
|
||
## 3. 创建 session
|
||
|
||
Session 是会话容器,用于保存消息、跟踪上下文使用、commit 后抽取长期 memories。
|
||
|
||
### 3.1 创建 userA 的 sessionA1
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions" \
|
||
-H "X-API-Key: $USER_A_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"session_id": "sessionA1"
|
||
}'
|
||
```
|
||
|
||
典型返回:
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": {
|
||
"session_id": "sessionA1",
|
||
"user": {
|
||
"account_id": "userA_account",
|
||
"user_id": "userA",
|
||
"agent_id": "default"
|
||
}
|
||
},
|
||
"error": null,
|
||
"telemetry": null
|
||
}
|
||
```
|
||
|
||
### 3.2 创建 userB 的 sessionB1
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions" \
|
||
-H "X-API-Key: $USER_B_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"session_id": "sessionB1"
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 写入 session 消息
|
||
|
||
HTTP API 支持简单文本模式:`role + content`。`role` 通常为 `user` 或 `assistant`。
|
||
|
||
### 4.1 写入 userA / sessionA1 消息
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions/sessionA1/messages" \
|
||
-H "X-API-Key: $USER_A_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"role": "user",
|
||
"content": "我喜欢用 Python 写数据分析脚本。"
|
||
}'
|
||
```
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions/sessionA1/messages" \
|
||
-H "X-API-Key: $USER_A_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"role": "assistant",
|
||
"content": "好的,我会记住你偏好 Python 数据分析。"
|
||
}'
|
||
```
|
||
|
||
### 4.2 写入 userB / sessionB1 消息
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions/sessionB1/messages" \
|
||
-H "X-API-Key: $USER_B_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"role": "user",
|
||
"content": "我喜欢用 vibe coding 写项目。"
|
||
}'
|
||
```
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions/sessionB1/messages" \
|
||
-H "X-API-Key: $USER_B_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"role": "assistant",
|
||
"content": "好的,我会记住你偏好 vibe coding 项目。"
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Commit session,触发长期 memory 抽取
|
||
|
||
`commit` 是两阶段流程:
|
||
|
||
1. **Phase 1,同步完成**:把当前 live messages 快照归档,创建 archive 目录,清空 live session。
|
||
2. **Phase 2,异步完成**:生成 session 摘要,抽取长期 memories,更新关系和 active count。
|
||
|
||
因此 `commit` 请求会很快返回 `task_id`,后续要轮询 task 状态。
|
||
|
||
### 5.1 Commit userA / sessionA1
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions/sessionA1/commit" \
|
||
-H "X-API-Key: $USER_A_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"keep_recent_count": 0
|
||
}'
|
||
```
|
||
|
||
典型返回:
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": {
|
||
"session_id": "sessionA1",
|
||
"status": "accepted",
|
||
"task_id": "fe6510e1-fdee-4f2d-9f87-5e48b519c2a2",
|
||
"archive_uri": "viking://session/userA/sessionA1/history/archive_001",
|
||
"archived": true
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.2 Commit userB / sessionB1
|
||
|
||
```bash
|
||
curl -X POST "$OV_HOST/api/v1/sessions/sessionB1/commit" \
|
||
-H "X-API-Key: $USER_B_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"keep_recent_count": 0
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 查询 commit task 状态
|
||
|
||
```bash
|
||
curl -s "$OV_HOST/api/v1/tasks/<task_id>" \
|
||
-H "X-API-Key: $USER_A_KEY" | jq .
|
||
```
|
||
|
||
成功完成后类似:
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": {
|
||
"task_id": "fe6510e1-fdee-4f2d-9f87-5e48b519c2a2",
|
||
"task_type": "session_commit",
|
||
"status": "completed",
|
||
"resource_id": "sessionA1",
|
||
"result": {
|
||
"session_id": "sessionA1",
|
||
"archive_uri": "viking://session/userA/sessionA1/history/archive_001",
|
||
"memories_extracted": {
|
||
"preferences": 1
|
||
},
|
||
"active_count_updated": 0
|
||
},
|
||
"error": null
|
||
},
|
||
"error": null,
|
||
"telemetry": null
|
||
}
|
||
```
|
||
|
||
关键字段说明:
|
||
|
||
| 字段 | 含义 |
|
||
|---|---|
|
||
| `status: completed` | Phase 2 已完成,memory 抽取结束 |
|
||
| `result.archive_uri` | 本次归档目录 URI |
|
||
| `result.memories_extracted` | 本次 commit 提取到的 memory 分类计数,不是 memory 内容 |
|
||
| `active_count_updated` | 本次基于 `sessions/{id}/used` 使用记录更新的活跃计数数量 |
|
||
|
||
如果返回:
|
||
|
||
```json
|
||
"status": "running"
|
||
```
|
||
|
||
说明后台任务还没完成。此时可以稍后继续查询同一个 task。
|
||
|
||
---
|
||
|
||
## 7. 用 `search/find` 向量搜索 user 长期 memory
|
||
|
||
`find` 是纯向量检索,不使用 session 上下文,也不做意图分析。适合直接按语义检索用户长期 memory。
|
||
|
||
使用显式用户路径:
|
||
|
||
```bash
|
||
curl -s -X POST "$OV_HOST/api/v1/search/find" \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: $USER_A_KEY" \
|
||
-d '{
|
||
"query": "我之前说了什么",
|
||
"target_uri": "viking://user/userA/memories/",
|
||
"limit": 3
|
||
}' | jq .
|
||
```
|
||
|
||
典型返回:
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": {
|
||
"memories": [
|
||
{
|
||
"context_type": "memory",
|
||
"uri": "viking://user/userA/memories/preferences/mem_xxx.md",
|
||
"level": 2,
|
||
"score": 0.7411,
|
||
"abstract": "Python 数据分析:偏好使用 Python 编写数据分析脚本"
|
||
}
|
||
],
|
||
"resources": [],
|
||
"skills": [],
|
||
"total": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 用 `search/search` 做带 session 上下文的 LLM 搜索
|
||
|
||
`search` 是智能检索:在 `find` 的基础上增加 session context、意图分析和 query expansion。它适合「用户当前对话里有上下文,查询语义不完整」的场景。
|
||
|
||
```bash
|
||
curl -s -X POST "$OV_HOST/api/v1/search/search" \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: $USER_A_KEY" \
|
||
-d '{
|
||
"query": "我正在做什么",
|
||
"target_uri": "viking://user/userA/sessionA1", #
|
||
"session_id": "sessionA1",
|
||
"limit": 10,
|
||
}
|
||
```
|
||
|
||
典型返回:
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": {
|
||
"memories": [],
|
||
"resources": [],
|
||
"skills": [],
|
||
"total": 0,
|
||
"query_plan": {
|
||
"reasoning": "1. Conversational task (user asking '我正在做什么' - 'What am I doing?'); 2. This is a simple conversational query about current state/activity; 3. The session context contains the user's previous interactions about Python preferences and EverOS API questions; 4. No specific context gaps need to be filled for this conversational task, but a memory query about the user's current activity context could help provide a more personalized response",
|
||
"queries": [
|
||
{
|
||
"query": "User's current activity and task context",
|
||
"context_type": "memory",
|
||
"intent": "Understand what the user is currently working on to provide relevant context",
|
||
"priority": 3
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. `find` 与 `search` 的选择
|
||
|
||
| 接口 | 是否使用 session 上下文 | 是否做意图分析 | 适合场景 |
|
||
|---|---:|---:|---|
|
||
| `/api/v1/search/find` | 否 | 否 | 直接按 query 做向量检索,稳定查 user memory |
|
||
| `/api/v1/search/search` | 是,可传 `session_id` | 是 | 对话式检索,需要结合 session 语境、自动扩展 query |
|
||
|
||
推荐实践:
|
||
|
||
1. **验证 memory 是否已经写入**:先用 `tasks/{task_id}` 确认 `completed`。
|
||
2. **确认 user 长期 memory 是否可召回**:用 `/api/v1/search/find`,query 写得贴近 memory 内容。
|
||
3. **需要结合当前会话上下文**:再用 `/api/v1/search/search` 加 `session_id`。
|