212ff3ff80
Introduce UMS ingest/snapshot pipeline, Context Planner with multi-source recall, runtime context injection, canonical user mapping, and session snapshot loading on auth/me. Co-authored-by: Cursor <cursoragent@cursor.com>
152 lines
3.9 KiB
Markdown
152 lines
3.9 KiB
Markdown
# Context Planner API v1
|
||
|
||
| 字段 | 值 |
|
||
|------|-----|
|
||
| 状态 | **Frozen(V0.1)** |
|
||
| 建议 Base URL | MeMind Portal 同域 `/api/v1/context/*` |
|
||
| 输出契约 | `schemas/context-plan.schema.json` |
|
||
|
||
---
|
||
|
||
## 1. 职责
|
||
|
||
将用户自然语言解析为 **ContextPlan AST**,决定:
|
||
|
||
- 需要哪些上下文域(User Model / Temporal Recall / Memory V2)
|
||
- 多源检索权重与 expanded queries
|
||
- 时间范围与 Temporal Mode
|
||
|
||
**不做**单选 intent 分类。
|
||
|
||
---
|
||
|
||
## 2. `POST /v1/context/plan`
|
||
|
||
### 请求
|
||
|
||
```json
|
||
{
|
||
"query": "我昨天有什么重要的事情安排吗?",
|
||
"user_id": "a70ff537-8908-486e-9b6c-042e07cc25db",
|
||
"now": "2026-09-03T22:00:00+08:00",
|
||
"session_id": "optional-session-uuid",
|
||
"locale": "zh-CN",
|
||
"planner_level": "auto"
|
||
}
|
||
```
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `query` | 是 | 用户原句 |
|
||
| `user_id` | 是 | 当前用户 |
|
||
| `now` | 否 | 解析相对时间的锚点,默认服务端当前时间 |
|
||
| `session_id` | 否 | 用于 Chat 上下文 |
|
||
| `planner_level` | 否 | `auto` / `cheap_only` / `semantic` |
|
||
|
||
### 响应
|
||
|
||
```json
|
||
{
|
||
"plan": {
|
||
"query_type": "personal_temporal_recall",
|
||
"temporal_mode": "AMBIGUOUS",
|
||
"time": {
|
||
"mention_range": {
|
||
"start": "2026-09-02T00:00:00+08:00",
|
||
"end": "2026-09-03T00:00:00+08:00"
|
||
},
|
||
"event_range": {
|
||
"start": "2026-09-02T00:00:00+08:00",
|
||
"end": "2026-09-03T00:00:00+08:00"
|
||
},
|
||
"relative_label": "yesterday"
|
||
},
|
||
"targets": [
|
||
{ "type": "commitment", "weight": 1.0 },
|
||
{ "type": "calendar_event", "weight": 0.85 },
|
||
{ "type": "todo", "weight": 0.9 }
|
||
],
|
||
"sources": {
|
||
"calendar": 0.85,
|
||
"chat": 0.80,
|
||
"meinput": 0.75,
|
||
"memory_v2": 0.45
|
||
},
|
||
"retrievals": [
|
||
{
|
||
"source": "meinput",
|
||
"query_type": "important_mentions",
|
||
"expanded_queries": ["重要", "安排", "会议", "明天", "截止"],
|
||
"weight": 0.75
|
||
},
|
||
{
|
||
"source": "chat",
|
||
"query_type": "commitments_and_decisions",
|
||
"expanded_queries": ["安排", "确认", "跟进", "记得"],
|
||
"weight": 0.80
|
||
}
|
||
],
|
||
"filters": { "importance_min": 0.6, "status": "any" },
|
||
"output": { "group_by": "importance", "dedupe": true, "timeline": true, "wide_recall": true },
|
||
"context_needs": {
|
||
"user_snapshot": "OPTIONAL",
|
||
"temporal_recall": "REQUIRED",
|
||
"memory_retrieval": "OPTIONAL"
|
||
},
|
||
"planner_meta": {
|
||
"level": "cheap_router",
|
||
"rule_hits": ["time:yesterday", "keyword:重要", "keyword:安排"],
|
||
"confidence": 0.82
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 错误
|
||
|
||
| HTTP | code | 说明 |
|
||
|------|------|------|
|
||
| 400 | `invalid_query` | 空 query |
|
||
| 401 | `unauthenticated` | 未登录 |
|
||
| 422 | `time_unparseable` | 时间词无法解析且无 fallback |
|
||
|
||
---
|
||
|
||
## 3. 解析管线(实现约束)
|
||
|
||
```
|
||
1. deterministic time parser → mention_range / event_range / relative_label
|
||
2. keyword rule matcher → sources 权重 + rule_hits
|
||
3. target inference (rules) → targets[]
|
||
4. merge → ContextPlan
|
||
5. [v0.2] semantic planner patch → 仅 cheap_router confidence < 0.6 时
|
||
```
|
||
|
||
V0.1 **默认 `cheap_only`**;`semantic` 返回 `501 not_implemented`。
|
||
|
||
---
|
||
|
||
## 4. 与 Task Intent Router 边界
|
||
|
||
| 组件 | 用途 |
|
||
|------|------|
|
||
| `chat-intent-router` | 聊天 → Agent 升级、tool 路由 |
|
||
| **Context Planner** | 回答需要哪些**检索上下文** |
|
||
|
||
Context Planner **不决定**是否启动 Agent Run。
|
||
|
||
---
|
||
|
||
## 5. Runtime 集成
|
||
|
||
Agent 每轮开始前:
|
||
|
||
```
|
||
plan = POST /v1/context/plan { query: user_message }
|
||
if plan.context_needs.user_snapshot != SKIP → load snapshot
|
||
if plan.context_needs.temporal_recall != SKIP → POST /v1/temporal-recall/query { plan }
|
||
if plan.context_needs.memory_retrieval != SKIP → memory-v2 retrieve
|
||
```
|
||
|
||
V0.1 Runtime hook 可仅在 `temporal_recall = REQUIRED` 时启用。
|