Add User Model Service and Temporal Recall for MeMind V0.1.
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>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# Calendar Source Adapter v0.2(接口冻结)
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 状态 | **Draft(V0.2)** |
|
||||
| 实现 | `temporal-recall-service/adapters/calendar.mjs`(V0.1 stub) |
|
||||
|
||||
---
|
||||
|
||||
## 1. 职责
|
||||
|
||||
从 MeMind 日程系统(`scheduleService` / 未来 CalDAV)读取 **event_time 权威** 的 calendar events,归一化为 `TimelineItem`。
|
||||
|
||||
与 MeInput/Chat 的区别:
|
||||
|
||||
| Source | event_time 来源 |
|
||||
|--------|-----------------|
|
||||
| Calendar | 结构化字段(权威) |
|
||||
| MeInput/Chat | 文本抽取( hypothesis ) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Adapter 签名(Frozen)
|
||||
|
||||
```typescript
|
||||
interface CalendarSearchContext {
|
||||
userId: string;
|
||||
retrieval: ContextPlan['retrievals'][0];
|
||||
time: ContextPlan['time'];
|
||||
temporalMode: ContextPlan['temporal_mode'];
|
||||
}
|
||||
|
||||
searchCalendar(ctx: CalendarSearchContext): Promise<TimelineItem[]>;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据来源(计划)
|
||||
|
||||
| 优先级 | 来源 | 说明 |
|
||||
|--------|------|------|
|
||||
| P0 | `h5_schedules` / scheduleService API | MeMind 内置日程 |
|
||||
| P1 | CalDAV 订阅 | 只读 sync |
|
||||
| P2 | iOS EventKit export | 经 MeInput 伴侣 App |
|
||||
|
||||
---
|
||||
|
||||
## 4. 归一化规则
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "calendar",
|
||||
"type": "event",
|
||||
"event_time": "<schedule.start_at>",
|
||||
"observed_time": "<schedule.created_at>",
|
||||
"title": "<schedule.title>",
|
||||
"status": "planned",
|
||||
"confidence": 0.98,
|
||||
"source_ref": "calendar:schedule:<id>"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Context Planner 权重
|
||||
|
||||
当 query 含 `行程|会议|约会|日历|几点|安排` 时:
|
||||
|
||||
```json
|
||||
"sources": { "calendar": 0.85, ... }
|
||||
```
|
||||
|
||||
V0.2 启用 retrievals 中 `source: "calendar"`(V0.1 在 planner 中跳过未实现源)。
|
||||
|
||||
---
|
||||
|
||||
## 6. V0.2 验收
|
||||
|
||||
1. 「我今天有什么安排?」→ Calendar items 排在 MeInput 前
|
||||
2. Calendar event + MeInput 同事件 → Dedupe merge
|
||||
3. `PLANNED_IN` 模式仅按 `event_time` 过滤
|
||||
@@ -0,0 +1,151 @@
|
||||
# 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` 时启用。
|
||||
@@ -0,0 +1,373 @@
|
||||
# RFC: Temporal Recall & Context Planner v0.1
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 状态 | **Frozen(V0.1)** |
|
||||
| 日期 | 2026-09-03 |
|
||||
| 关联 Schema | `schemas/timeline-item.schema.json`, `schemas/context-plan.schema.json` |
|
||||
| 关联 API | `docs/api/temporal-recall-v1.md`, `docs/api/context-planner-v1.md` |
|
||||
| 前置 RFC | `docs/rfc/user-model-v0.1.md` |
|
||||
|
||||
---
|
||||
|
||||
## 1. 摘要
|
||||
|
||||
MeMind 需要一套独立于 User Model 与 Memory V2 的 **Temporal Recall** 能力,回答:
|
||||
|
||||
> **某个时间范围内,发生了什么?**
|
||||
|
||||
这与 User Model(「你是谁 / 你现在关注什么」)正交,是第四条一级能力域。
|
||||
|
||||
**V0.1 目标:** 跑通 `User Query → Context Planner → Multi-source Retrieval → Timeline → Rank → Answer`,数据源仅 **MeInput + Chat**;Calendar / Memory V2 作为可选低权重源或 v0.2 接入。
|
||||
|
||||
**核心架构转变(Frozen):**
|
||||
|
||||
```
|
||||
Intent Classification(单选 intent) → 不再是 Temporal 问题的核心
|
||||
Context Planning(多源 Query Plan) → 新核心
|
||||
Retrieval Robustness(宽召回 + Rank) → 优于 Intent Precision
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 四个能力域(Frozen)
|
||||
|
||||
| 域 | 回答 | 典型问题 |
|
||||
|----|------|----------|
|
||||
| **User Model** | 我是谁、我现在关注什么 | 「帮我写代码时用什么风格?」 |
|
||||
| **Memory V2** | 我过去明确发生过 / 决定过什么 | 「我们上次定的架构是什么?」 |
|
||||
| **Temporal Recall** | 某个时间范围内发生了什么 | 「我这周有什么重要的事?」 |
|
||||
| **Runtime Context** | 当前这一轮要用哪些上下文 | Session 内 tool / page / task 状态 |
|
||||
|
||||
```
|
||||
User Query
|
||||
│
|
||||
▼
|
||||
Context Planner
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
▼ ▼ ▼
|
||||
User Model Temporal Recall Memory V2
|
||||
「你是谁」 「发生了什么」 「曾经记住什么」
|
||||
│ │ │
|
||||
└─────────────┼─────────────┘
|
||||
▼
|
||||
Agent Runtime
|
||||
```
|
||||
|
||||
### 2.1 组合策略(Frozen)
|
||||
|
||||
| 问题类型 | User Model | Temporal Recall | Memory V2 |
|
||||
|----------|------------|-----------------|-----------|
|
||||
| 普通聊天 | REQUIRED | SKIP | SKIP |
|
||||
| 时间范围问题 | OPTIONAL | REQUIRED | OPTIONAL |
|
||||
| 历史决策 | OPTIONAL | OPTIONAL | REQUIRED |
|
||||
| 复杂综合 | OPTIONAL | REQUIRED | REQUIRED |
|
||||
|
||||
每项取值:`REQUIRED | OPTIONAL | SKIP`。
|
||||
|
||||
---
|
||||
|
||||
## 3. 架构铁律(Frozen)
|
||||
|
||||
1. **Temporal 问题不做单选 intent 分类。** 输出 Query Plan,允许多源并行检索。
|
||||
2. **时间词用确定性 parser,不交给 LLM 猜。**(今天 / 昨天 / 这周 / 最近三天 …)
|
||||
3. **强约束词给 source 加权,不硬路由。**(行程→Calendar 高权重;原话→MeInput 高权重)
|
||||
4. **模糊语义才走 LLM semantic expansion。**(「重要的事」「需要注意的」)
|
||||
5. **Timeline Item 必须区分 `event_time` 与 `observed_time`。**
|
||||
6. **宽召回优于窄 intent。** 误解 20% 仍应能召回正确证据。
|
||||
7. **Temporal Recall 不写入 User Model Graph。** 它是检索视图,不是画像。
|
||||
8. **Temporal Recall 不默认写入 Memory V2。** 长期记忆仍走 UMS → Candidate → Memory 链。
|
||||
9. **Answer 必须基于 ranked timeline items,禁止 LLM 无证据自由发挥。**
|
||||
10. **Dedupe 跨源合并同一事件**(Calendar + MeInput + Chat 三条 → 一条)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心组件
|
||||
|
||||
### 4.1 Context Planner(Personal Query Planner)
|
||||
|
||||
**职责:** 决定「这句话需要哪些上下文」,而非「这句话属于哪个 intent」。
|
||||
|
||||
**双通道解析(Frozen):**
|
||||
|
||||
```
|
||||
User Query
|
||||
│
|
||||
┌─────────┴──────────┐
|
||||
▼ ▼
|
||||
deterministic parser semantic parser
|
||||
(rule / small model) (LLM, 仅复杂 query)
|
||||
│ │
|
||||
time / keywords / targets / ambiguity /
|
||||
explicit entities implied meaning
|
||||
│ │
|
||||
└─────────┬──────────┘
|
||||
▼
|
||||
Context Plan Merge
|
||||
▼
|
||||
ContextPlan AST
|
||||
```
|
||||
|
||||
**Level 1 — Cheap Router(~80% 问题):** 无 LLM 或小模型;检测时间范围、明显 Calendar 词、明显原文请求、是否历史问题。
|
||||
|
||||
**Level 2 — Semantic Planner:** 仅复杂 query 启用 LLM(多时间引用、未完成承诺追踪、跨源条件过滤)。
|
||||
|
||||
### 4.2 Temporal Recall Service
|
||||
|
||||
**职责:** 按 Context Plan 并行检索各 Source Adapter,归一化为 Timeline Item,Dedupe + Rank,返回 Recall Bundle。
|
||||
|
||||
```
|
||||
Context Plan
|
||||
│
|
||||
┌────────────┼─────────────┐
|
||||
▼ ▼ ▼
|
||||
Calendar Chat MeInput
|
||||
(v0.2+) (v0.1) (v0.1)
|
||||
│ │ │
|
||||
└────────────┼─────────────┘
|
||||
▼
|
||||
Timeline Normalizer
|
||||
▼
|
||||
Dedupe
|
||||
▼
|
||||
Recall Ranker
|
||||
▼
|
||||
Recall Bundle
|
||||
```
|
||||
|
||||
### 4.3 Source Adapter 边界
|
||||
|
||||
每个 Source **只暴露 Timeline Item 或 Evidence Envelope**,Temporal Recall **不得** JOIN Source 内部表(与 UMS 铁律一致)。
|
||||
|
||||
| Source | V0.1 | Adapter 入口 |
|
||||
|--------|------|--------------|
|
||||
| MeInput | ✅ | `GET /v1/evidence/export`(expression_segment) |
|
||||
| Chat | ✅ | Portal session messages / agent runs |
|
||||
| Memory V2 | 低权重可选 | `memory-v2` time-bounded search |
|
||||
| Calendar | ❌ v0.2 | 待定 |
|
||||
|
||||
---
|
||||
|
||||
## 5. ContextPlan AST(Frozen)
|
||||
|
||||
见 `schemas/context-plan.schema.json`。核心字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"query_type": "personal_temporal_recall",
|
||||
"time": {
|
||||
"mention_range": { "start": "...", "end": "..." },
|
||||
"event_range": null
|
||||
},
|
||||
"temporal_mode": "OCCURRED_IN | MENTIONED_IN | PLANNED_IN | CREATED_IN | DUE_IN | AMBIGUOUS",
|
||||
"targets": [
|
||||
{ "type": "calendar_event", "weight": 0.8 },
|
||||
{ "type": "commitment", "weight": 1.0 },
|
||||
{ "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
|
||||
}
|
||||
],
|
||||
"filters": {
|
||||
"importance_min": 0.6,
|
||||
"status": "unresolved"
|
||||
},
|
||||
"output": {
|
||||
"group_by": "importance",
|
||||
"dedupe": true,
|
||||
"timeline": true,
|
||||
"wide_recall": true
|
||||
},
|
||||
"context_needs": {
|
||||
"user_snapshot": "OPTIONAL",
|
||||
"temporal_recall": "REQUIRED",
|
||||
"memory_retrieval": "OPTIONAL"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.1 六个解析槽位
|
||||
|
||||
| 槽位 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| `time_scope` | 绝对时间范围 | yesterday → `[start, end)` |
|
||||
| `target` | 要找什么类型 | event, schedule, todo, commitment |
|
||||
| `operation` | 检索后操作 | retrieve / retrieve_and_summarize |
|
||||
| `importance` | 重要性过滤 | important / any |
|
||||
| `sources` | 多源权重(非单选) | calendar:0.85, chat:0.80 |
|
||||
| `temporal_semantics` | 时间语义 | occurred_or_planned / ambiguous |
|
||||
|
||||
### 5.2 Temporal Mode(Frozen)
|
||||
|
||||
| Mode | 语义 | 示例问题 |
|
||||
|------|------|----------|
|
||||
| `OCCURRED_IN` | 事件发生在该范围 | 「我昨天做了什么?」 |
|
||||
| `MENTIONED_IN` | 在该范围内被提到 | 「我昨天说过要做什么?」 |
|
||||
| `PLANNED_IN` | 计划在该范围发生 | 「我今天有什么安排?」 |
|
||||
| `CREATED_IN` | 在该范围内创建/记录 | 「我上周定了哪些事?」 |
|
||||
| `DUE_IN` | 截止 / 应完成在该范围 | 「这周五之前要交什么?」 |
|
||||
| `AMBIGUOUS` | 宽召回两种语义 | 「我昨天有什么重要的事?」 |
|
||||
|
||||
`AMBIGUOUS` 时 **禁止追问为默认行为**;并行查 occurred + mentioned,分组回答。
|
||||
|
||||
---
|
||||
|
||||
## 6. Timeline Item 统一模型(Frozen)
|
||||
|
||||
见 `schemas/timeline-item.schema.json`。
|
||||
|
||||
```json
|
||||
{
|
||||
"timeline_item_id": "uuid",
|
||||
"user_id": "uuid",
|
||||
"source": "calendar | chat | meinput | memory_v2",
|
||||
"type": "event | todo | decision | mention | commitment",
|
||||
"event_time": "2026-09-03T15:00:00+08:00",
|
||||
"observed_time": "2026-09-02T20:30:00+08:00",
|
||||
"title": "与张总签合同",
|
||||
"content": "明天下午三点去签合同",
|
||||
"importance": 0.82,
|
||||
"confidence": 0.91,
|
||||
"recall_score": 0.76,
|
||||
"source_ref": "meinput:segment:...",
|
||||
"participants": ["张总"],
|
||||
"status": "planned | completed | mentioned | unknown",
|
||||
"merged_from": ["calendar:...", "chat:...", "meinput:..."]
|
||||
}
|
||||
```
|
||||
|
||||
**关键区分:**
|
||||
|
||||
- `event_time` — 事情何时发生 / 计划发生
|
||||
- `observed_time` — 何时被记录 / 输入 / 提到
|
||||
|
||||
例:9 月 2 日输入「明天下午三点签合同」→ `observed_time=9/2`, `event_time=9/3 15:00`。
|
||||
|
||||
---
|
||||
|
||||
## 7. Recall Score(Frozen)
|
||||
|
||||
```
|
||||
recall_score =
|
||||
source_quality
|
||||
× temporal_match
|
||||
× semantic_match
|
||||
× importance
|
||||
× extraction_confidence
|
||||
```
|
||||
|
||||
| 分数区间 | 展示策略 |
|
||||
|----------|----------|
|
||||
| ≥ 0.75 | 主答案直接展示 |
|
||||
| 0.50 ~ 0.75 | 次要信息 / 「可能相关」 |
|
||||
| < 0.50 | 默认不展示 |
|
||||
|
||||
---
|
||||
|
||||
## 8. Query Expansion(Frozen)
|
||||
|
||||
**禁止**用用户原句单一 embedding 搜所有库。
|
||||
|
||||
Planner 为每个 source 生成 **expanded_queries**:
|
||||
|
||||
| Source | 扩展策略 |
|
||||
|--------|----------|
|
||||
| Calendar | 时间 filter 为主,keyword 为辅 |
|
||||
| Chat | 约 / 安排 / 明天 / 会议 / 确认 / 跟进 / 截止 |
|
||||
| MeInput | 任务词 / 时间表达 / action verbs |
|
||||
| Memory V2 | commitment / task / decision |
|
||||
|
||||
---
|
||||
|
||||
## 9. Dedupe 规则(V0.1 简化)
|
||||
|
||||
同一 `event_time` ±15min + 语义相似(title/content embedding 或 keyword overlap > 0.7)→ merge。
|
||||
|
||||
Merge 后保留最高 `source_quality`,`merged_from` 记录各源。
|
||||
|
||||
---
|
||||
|
||||
## 10. 与 User Model 的关系
|
||||
|
||||
| | User Model | Temporal Recall |
|
||||
|--|------------|-----------------|
|
||||
| 时间性 | 慢变 / 半静态 | 强时间索引 |
|
||||
| 问题 | 「我是谁」 | 「那时发生了什么」 |
|
||||
| 存储 | Graph + Snapshot | 检索视图(不持久化画像) |
|
||||
| 写入 | Evidence → Signal → Candidate | 只读各 Source |
|
||||
| Session 加载 | 默认 REQUIRED | 按 Planner 按需 |
|
||||
|
||||
Planner 可将 User Snapshot 作为 **ranking prior**(例如已知 active_projects 加权相关 timeline items),但 Temporal Recall 不反向写 Graph。
|
||||
|
||||
---
|
||||
|
||||
## 11. V0.1 范围
|
||||
|
||||
### 做
|
||||
|
||||
- [ ] ContextPlan JSON Schema + Timeline Item Schema
|
||||
- [ ] Deterministic time parser(zh-CN 相对时间)
|
||||
- [ ] Rule-based source weight(强约束词表)
|
||||
- [ ] Cheap Router(Level 1)
|
||||
- [ ] MeInput Source Adapter(evidence export)
|
||||
- [ ] Chat Source Adapter(session messages)
|
||||
- [ ] Timeline Normalizer + Dedupe + Rank
|
||||
- [ ] `POST /v1/temporal-recall/query` API
|
||||
- [ ] Agent Runtime hook:`context_needs.temporal_recall = REQUIRED` 时注入 Recall Bundle
|
||||
|
||||
### 不做(V0.1)
|
||||
|
||||
- Calendar / Email / Browser / Git / Location
|
||||
- LLM Semantic Planner(Level 2)— 仅预留接口
|
||||
- Memory V2 深度集成(可选低权重 stub)
|
||||
- 用户追问 clarification UI(默认宽召回 + 分组)
|
||||
- Timeline 持久化索引库(V0.1 实时检索;V0.2 考虑 `memind_timeline` 物化)
|
||||
|
||||
---
|
||||
|
||||
## 12. 开发顺序(建议)
|
||||
|
||||
1. Schema + API 契约冻结(本文档)
|
||||
2. Deterministic time parser + rule keyword weights
|
||||
3. MeInput adapter(复用 evidence export)
|
||||
4. Chat adapter
|
||||
5. Normalizer + Ranker + Dedupe
|
||||
6. Cheap Router → ContextPlan
|
||||
7. Temporal Recall API
|
||||
8. Runtime Context Planner hook
|
||||
9. v0.2:Calendar adapter + Semantic Planner + 物化 timeline index
|
||||
|
||||
---
|
||||
|
||||
## 13. 命名约定(Frozen)
|
||||
|
||||
| 避免 | 使用 |
|
||||
|------|------|
|
||||
| Intent Layer(用于 Temporal) | **Context Planner** |
|
||||
| `intent: query_schedule` | `ContextPlan.sources` 多源权重 |
|
||||
| 「猜测用户唯一意图」 | 「宽召回 + Rank」 |
|
||||
| Personal Intent Classification | **Personal Temporal Recall** |
|
||||
|
||||
Task Execution Intent(聊天→Agent 升级)仍走现有 `chat-intent-router`;**不与 Context Planner 混用**。
|
||||
|
||||
---
|
||||
|
||||
## 14. 验收标准(V0.1)
|
||||
|
||||
1. 「我昨天有什么重要的事?」→ 返回 grouped timeline(occurred + mentioned),不全为空
|
||||
2. 「我这周输入过什么关于 MeInput 的?」→ MeInput source 高权重命中
|
||||
3. 同一事件在 Chat + MeInput 重复出现 → Dedupe 为一条
|
||||
4. `event_time` / `observed_time` 过滤行为符合 Temporal Mode
|
||||
5. 无 ContextPlan 时 Agent 不调用 Temporal Recall(不误触发)
|
||||
@@ -0,0 +1,190 @@
|
||||
# Temporal Recall API v1
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 状态 | **Frozen(V0.1)** |
|
||||
| 建议 Base URL | MeMind Portal 同域 `/api/v1/temporal-recall/*` |
|
||||
| 输入 | `ContextPlan` 或简化 query |
|
||||
| 输出 | `TimelineItem[]` + 分组元数据 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 职责
|
||||
|
||||
按 Context Plan **并行检索**多源,归一化、Dedupe、Rank,返回 Personal Timeline Recall Bundle。
|
||||
|
||||
**回答:** 「某个时间范围内发生了什么?」
|
||||
|
||||
---
|
||||
|
||||
## 2. `POST /v1/temporal-recall/query`
|
||||
|
||||
### 方式 A — 传入完整 Plan(推荐)
|
||||
|
||||
```json
|
||||
{
|
||||
"plan": { "...ContextPlan..." },
|
||||
"limit": 50
|
||||
}
|
||||
```
|
||||
|
||||
### 方式 B — 快捷 query(内部先调 Planner)
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "我这周有什么重要的事?",
|
||||
"user_id": "a70ff537-8908-486e-9b6c-042e07cc25db",
|
||||
"now": "2026-09-03T22:00:00+08:00",
|
||||
"limit": 50
|
||||
}
|
||||
```
|
||||
|
||||
### 响应
|
||||
|
||||
```json
|
||||
{
|
||||
"query_type": "personal_temporal_recall",
|
||||
"temporal_mode": "AMBIGUOUS",
|
||||
"time_range": {
|
||||
"start": "2026-09-01T00:00:00+08:00",
|
||||
"end": "2026-09-08T00:00:00+08:00"
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"label": "occurred_in_range",
|
||||
"items": [
|
||||
{
|
||||
"timeline_item_id": "...",
|
||||
"source": "meinput",
|
||||
"type": "mention",
|
||||
"event_time": null,
|
||||
"observed_time": "2026-09-02T14:30:00+08:00",
|
||||
"title": "MeInput 验证上屏",
|
||||
"content": "MeInput验证上屏",
|
||||
"importance": 0.71,
|
||||
"confidence": 0.95,
|
||||
"recall_score": 0.78,
|
||||
"source_ref": "meinput:segment:...",
|
||||
"status": "mentioned"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "mentioned_or_planned",
|
||||
"items": []
|
||||
}
|
||||
],
|
||||
"items": [],
|
||||
"stats": {
|
||||
"sources_queried": ["meinput", "chat"],
|
||||
"raw_count": 42,
|
||||
"deduped_count": 38,
|
||||
"returned_count": 25,
|
||||
"elapsed_ms": 320
|
||||
},
|
||||
"plan": { "...echo ContextPlan..." }
|
||||
}
|
||||
```
|
||||
|
||||
`groups` 在 `temporal_mode=AMBIGUOUS` 时区分「实际发生」与「提到/安排」;否则 `items` 为 flat ranked list。
|
||||
|
||||
---
|
||||
|
||||
## 3. `GET /v1/temporal-recall/info`
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": 1,
|
||||
"supported_sources": ["meinput", "chat"],
|
||||
"planned_sources": ["calendar", "memory_v2", "email", "browser", "tasks"],
|
||||
"temporal_modes": ["OCCURRED_IN", "MENTIONED_IN", "PLANNED_IN", "CREATED_IN", "DUE_IN", "AMBIGUOUS"],
|
||||
"default_limit": 50,
|
||||
"max_limit": 200
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Source Adapter 契约
|
||||
|
||||
每个 adapter 实现:
|
||||
|
||||
```typescript
|
||||
interface TemporalSourceAdapter {
|
||||
source: 'meinput' | 'chat' | 'calendar' | 'memory_v2';
|
||||
search(ctx: {
|
||||
userId: string;
|
||||
retrieval: ContextPlan['retrievals'][0];
|
||||
time: ContextPlan['time'];
|
||||
temporalMode: ContextPlan['temporal_mode'];
|
||||
}): Promise<TimelineItem[]>;
|
||||
}
|
||||
```
|
||||
|
||||
### MeInput Adapter(V0.1)
|
||||
|
||||
- 调用 `GET /v1/evidence/export`(MeInput Cloud)
|
||||
- 过滤 `expression_segment`,按 `occurred_at` 映射 `observed_time`
|
||||
- 规则抽取 `event_time`(「明天下午三点」→ 解析为绝对时间)
|
||||
- `source_ref = meinput:segment:{evidence_id}`
|
||||
|
||||
### Chat Adapter(V0.1)
|
||||
|
||||
- 查 `h5_agent_runs` + session messages(用户可见范围)
|
||||
- `observed_time = message.created_at`
|
||||
- commitment/todo 规则抽取
|
||||
|
||||
---
|
||||
|
||||
## 5. Rank 公式
|
||||
|
||||
```
|
||||
recall_score =
|
||||
source_quality(source)
|
||||
× temporal_match(item, plan.time, plan.temporal_mode)
|
||||
× semantic_match(item, expanded_queries)
|
||||
× importance(item)
|
||||
× confidence(item)
|
||||
```
|
||||
|
||||
| 阈值 | 展示 |
|
||||
|------|------|
|
||||
| ≥ 0.75 | 主答案 |
|
||||
| 0.50 ~ 0.75 | 次要 |
|
||||
| < 0.50 | 丢弃 |
|
||||
|
||||
---
|
||||
|
||||
## 6. Dedupe
|
||||
|
||||
- 时间:`|event_time_a - event_time_b| < 15min` 或同日 + 同类
|
||||
- 语义:title/content keyword overlap > 0.7 或 embedding cosine > 0.85(v0.2)
|
||||
- Merge → 保留最高 `source_quality`,填充 `merged_from`
|
||||
|
||||
---
|
||||
|
||||
## 7. 认证
|
||||
|
||||
| 调用方 | 认证 |
|
||||
|--------|------|
|
||||
| Agent Runtime | 用户 sessionToken |
|
||||
| 内部 Worker | `TEMPORAL_RECALL_TOKEN`(可选) |
|
||||
|
||||
---
|
||||
|
||||
## 8. V0.1 不做
|
||||
|
||||
- Calendar / Email / Browser adapter
|
||||
- 持久化 timeline 索引表
|
||||
- LLM 答案生成(只返回 structured timeline;Answer 层在 Agent)
|
||||
|
||||
---
|
||||
|
||||
## 9. 错误码
|
||||
|
||||
| HTTP | code | 说明 |
|
||||
|------|------|------|
|
||||
| 400 | `invalid_plan` | Plan schema 校验失败 |
|
||||
| 401 | `unauthenticated` | 未登录 |
|
||||
| 503 | `source_unavailable` | MeInput export 不可用 |
|
||||
| 504 | `recall_timeout` | 并行检索超时(默认 5s) |
|
||||
Reference in New Issue
Block a user