跳转至

第 7 章 记忆与会话系统

本章学习目标 - 深入理解 Agent 记忆模式的分类维度(短期/长期、语义/情景/程序、向量 vs 结构化) - 掌握 TTD 的四层记忆架构(Working / Profile / Episodic / Correction)与认知科学对应 - 深度理解 SQL 语义缓存与动态 Few-Shot 自学习的工程实现 - 对比 MemGPT/Letta 自治记忆与 TTD 触发式记忆的取舍 - 理解记忆形成、衰减、TTL 的生命周期理论 - 认清当前记忆系统的工程权衡与改进方向

前置知识第 4 章 Agent 编排第 5 章 RAG 检索 关联代码backend/app/memory/(facade/formation/long_term/short_term/sql_cache/dynamic_few_shot/term_mapping)


7.1 背景与动机

7.1.1 为什么 Agent 需要记忆

没有记忆的 Agent 是"金鱼"——每次对话从零开始,无法记住用户偏好、历史成功模式、被纠正的错误。在 NL2SQL 场景,记忆的价值尤其明显:

记忆类型 价值 例子
用户偏好 减少重复澄清 "我习惯看折线图"、"我常查华东区"
成功交互 复用经验 上次"GMV 同比"查得很好 → 类似问题复用
纠正记录 避免重蹈覆辙 用户上次纠正了"GMV 不含退款" → 以后别再错
SQL 复用 大幅降延迟 相同问题直接复用已验证 SQL

7.1.2 Agent 记忆模式分类

AI Agent 理论关联:Agent 记忆模式

Agent 记忆有多种分类维度,理解这些维度是设计记忆系统的基础:

按时间维度: - 短期记忆(Working Memory):当前上下文,容量有限(context window),随会话结束消失。对应人类的"工作记忆"。 - 长期记忆(Long-term Memory):跨会话持久化,容量大,需主动检索。对应人类的"长期记忆"。

按内容维度(认知科学经典分类): - 语义记忆(Semantic Memory):事实与知识——"用户偏好折线图"、"GMV 定义是 SUM(amount)"。 - 情景记忆(Episodic Memory):具体经历——"上次查 GMV 同比成功了"、"用户上周问过退货率"。 - 程序记忆(Procedural Memory):如何做事——"这种查询走这条路"、"术语消歧应该这样纠正"。

按实现维度: - 向量记忆:把记忆存为 embedding,用相似度检索。适合模糊召回。 - 结构化记忆:把记忆存为结构化记录(KV/关系表),用精确查询。适合事实查询。 - 混合记忆:两者结合。

代表性记忆架构: - MemGPT / Letta:分层记忆 + 自治记忆管理。LLM 通过 function call 自主决定何时读/写/遗忘记忆。类比操作系统的内存分级:main context(工作记忆,在 context window 内)、external context(归档记忆,在 context window 外,需检索调入)、recall memory(对话历史)。详见 arxiv.org/abs/2310.08560。 - Generative Agents(斯坦福小镇):情景记忆 + 反思(reflection)。定期从情景记忆中抽象出高层次的语义记忆("用户偏好折线图"是从多次选折线图的情景中反思出来的)。详见 arxiv.org/abs/2304.03442。 - LangGraph Store:基于 namespace 的 KV 存储 + 语义搜索,开发者手动调用 API 读写。

TTD 的四层记忆融合了这些思想:Working 是短期,Profile 是语义记忆,Episodic 是情景记忆,Correction 是程序记忆(纠正如何做对)。形成策略采用触发式而非 MemGPT 的自治式——这是安全敏感场景的取舍。


7.2 设计原理

7.2.1 四层记忆架构

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#e8f0fe','primaryTextColor':'#202124','primaryBorderColor':'#1a73e8','lineColor':'#5f6368','secondaryColor':'#e0f2f1','tertiaryColor':'#f8f9fa'}}}%%
graph LR
    subgraph Personalized["Personalized Memory(per-user 隔离)"]
        direction LR
        W["Working Memory<br/>LangGraph Checkpointer<br/>会话作用域"]
        P["Profile Memory<br/>长期偏好<br/>365d TTL"]
        E["Episodic Memory<br/>成功交互摘要<br/>90d TTL"]
        C["Correction Memory<br/>已接受纠正<br/>180d TTL"]
        W -->|"跨轮传递"| P
        P -->|"情景积累"| E
        E -->|"纠正沉淀"| C
    end

    subgraph Shared["Shared Optimization(非用户记忆)"]
        direction LR
        SC["SQL Cache<br/>pgvector<br/>semlayer.sql_cache"]
        FS["Dynamic Few-Shot<br/>pgvector<br/>approved"]
        MC["Metadata Cache<br/>进程内<br/>TTL 24h"]
    end

    Q[用户问题] --> W
    W -->|"会话上下文"| Pipeline["Agent Pipeline<br/>Router → Retrieval → SQL Gen"]
    P -->|"用户偏好/默认值"| Pipeline
    E -->|"历史交互摘要"| Pipeline
    C -->|"已接受纠正"| Pipeline
    SC -->|"语义匹配 SQL<br/>sim ≥ 0.92"| Router["Router · 快速路径"]
    FS -->|"注入 Prompt"| Pipeline

    classDef bpData     fill:#e0f2f1,stroke:#0d7377,stroke-width:2px,color:#202124
    classDef bpInfo     fill:#f3e8fd,stroke:#9334e6,stroke-width:2px,color:#202124
    classDef bpProcess  fill:#e8f0fe,stroke:#1a73e8,stroke-width:2px,color:#202124
    classDef bpDecision fill:#fef7e0,stroke:#f9ab00,stroke-width:2px,color:#202124

    class W,P,E,C,SC,FS,MC bpData
    class Q,Pipeline,Router bpProcess
    class C bpInfo
存储 生命周期 用途 认知科学对应
Working LangGraph Checkpointer (PG) 请求/会话作用域 当前对话上下文,最近 N 轮 短期记忆
Profile ttd_memory_records (kind=profile) 长期 365 天 TTL(初始估算值) 稳定偏好:常用指标、偏好维度、图表风格 语义记忆
Episodic ttd_memory_records (kind=episodic) 中期 90 天 TTL(初始估算值)+ 衰减 成功交互摘要、已接受澄清 情景记忆
Correction ttd_memory_records (kind=correction) 中长期 180 天 TTL(初始估算值) 用户批准的纠正:术语消歧、SQL 修复模式 程序记忆

TTL 值为初始估算

上述 365/90/180 天 TTL 与衰减率(episodic 0.02/天、profile 0.005/天)均为初始估算值,项目尚未运行足够长时间以验证这些参数的合理性。改进方向:基于实际记忆访问模式与命中率数据校准 TTL(第 16 章)。

7.2.2 共享优化层(非用户记忆)

机制 存储 作用
SQL Cache semlayer.sql_cache (pgvector) 问题相似度 ≥ 0.92 命中,复用已验证 SQL
Dynamic Few-Shot semlayer.dynamic_few_shot_cache (pgvector) 从修复成功自学习,approved 后注入 RAG Engine D
Metadata Cache 进程内 TTL 24h,减少 PG 元数据查询

这些是跨用户的共享优化,不属于个人记忆——SQL Cache 对所有用户共享,Dynamic Few-Shot 是系统级学习成果。


7.3 实现详解

7.3.1 Working Memory(短期上下文)

属性
存储 LangGraph Checkpointer (PostgreSQL)
窗口 最近 5 轮(TTD_SHORT_TERM_WINDOW=5
格式 list[dict],每轮含 user/assistant message
压缩 Context Compactor(token budget 3000,最近 3 轮原样保留)
# backend/app/memory/short_term.py
def trim_history(messages, *, window=5):
    """保留系统消息 + 最近 window 轮对话。"""

thread_id=session_id 实现 LangGraph Checkpointer 的多轮会话状态持久化——每一步的状态快照按 thread_id 隔离。stream.py 启动时从 SessionManager.get_turns() 加载历史注入 short_term_memory

Context Compactor 是 Advanced RAG 的 compress 模块——当历史超过 token 预算时,压缩早期对话为摘要,保留最近 3 轮原样。

7.3.2 Profile / Episodic / Correction Memory

通过统一的 MemoryFacade 访问,支持路由感知预算——不同路由对各类记忆设不同上限,避免记忆注入过多稀释当前查询的上下文:

# backend/app/memory/facade.py
class MemoryFacade:
    async def retrieve(self, *, user_id, query, route_decision, ...) -> MemoryContext
    async def write_candidate(self, *, user_id, kind, summary_text, ...) -> str | None
    async def upsert(self, *, memory_id, user_id, ...) -> bool
    async def suppress(self, *, memory_id, user_id, ...) -> bool
    async def delete_for_user(self, *, user_id, ...) -> int

路由预算(Route Budgets)——KPI 直查不需要太多记忆,深度分析需要更多历史经验:

Route Profile Episodic Correction
nl2sql_query 5 2 5
kpi_lookup 2 0 1
business_knowledge_qa 3 1 1
deep_analysis_workflow 8 8 4

7.3.3 记忆形成(Memory Formation)

记忆候选项从已持久化的 turn 中提取,而非内联于生成过程——这与 Generative Agents 的反思机制类似,但触发方式不同:

# backend/app/memory/formation.py
class MemoryFormationService:
    async def process_turn(self, *, user_id, turn_id, ...) -> list[str]
    async def process_feedback(self, *, user_id, rating, ...) -> list[str]

高信号写入策略:仅在有明确偏好信号、被接受的澄清、重复选择模式、或评估器确认的成功交互时写入。带衰减(episodic 0.02/天,profile 0.005/天)和 TTL。

AI Agent 理论关联:自治记忆 vs 触发式记忆

MemGPT/Letta 采用自治记忆——LLM 通过 function call 自主决定何时读/写/遗忘记忆。LLM 可以调用 core_memory_appendarchival_memory_insertarchival_memory_search 等函数管理自己的记忆。优势是灵活,LLM 能根据当前需要动态管理记忆;劣势是不可控(LLM 可能遗忘重要信息或记住噪声)。

TTD 采用触发式记忆——记忆形成由明确信号(成功交互、反馈、澄清)触发,而非 LLM 自主决定。优势是可审计、可预测(每条记忆的形成都有明确原因);劣势是可能遗漏隐式信号(如用户连续三次选折线图但未点"赞")。

取舍:安全敏感的 NL2SQL 场景需要可审计性,自治记忆不可控。但 TTD 可以向"受控自治"演进——LLM 在受限范围内提议记忆,经审批后写入。

与 Generative Agents 反思的关系:Generative Agents 定期从情景记忆中反思出语义记忆("用户偏好折线图"从多次行为中抽象)。TTD 的 formation service 是简化版——从成功 turn 提取 profile/episodic 候选,但缺少系统性的反思抽象。改进方向见 7.4。

7.3.4 记忆记录 Schema

所有长期记忆(Profile/Episodic/Correction)统一存储在 ttd_memory_records 表(backend/app/db/models.pyMemoryRecord ORM)。以下是完整字段:

# backend/app/db/models.py(MemoryRecord,表 ttd_memory_records)
class MemoryRecord:
    memory_id: str          # 主键,String(64)
    user_id: str            # 用户隔离,String(256)
    session_id: str | None  # 来源会话
    turn_id: str | None     # 来源轮次
    trace_id: str | None    # Langfuse 追踪 ID
    kind: MemoryKind         # working / profile / episodic / correction
    scope: str              # "global" 默认
    namespace: str          # "default" 默认
    summary_text: str       # 记忆摘要文本
    payload_json: dict      # 结构化载荷(如 correction_sql)
    source_route: str | None  # 来源路由
    source_agent: str | None  # 来源 Agent
    confidence: float       # 置信度,默认 0.5
    salience: float         # 显著性,默认 0.5
    status: MemoryStatus    # candidate / active / suppressed / expired / deleted
    embedding: list         # JSONB 向量(待迁移 pgvector)
    pii_level: MemoryPIILevel     # none / low / medium / high
    redaction_level: MemoryRedactionLevel  # full / summary / reference_only
    created_at: datetime
    last_seen_at: datetime
    last_accessed_at: datetime
    expires_at: datetime | None

四类记忆(MemoryKind)与生命周期状态(MemoryStatus)枚举:

MemoryKind 用途 典型 payload_json
working 短期上下文(实际由 Checkpointer 承载,此枚举预留)
profile 用户稳定偏好 {"preferred_chart": "line", "common_dimensions": ["time"]}
episodic 成功交互摘要 {"question": "GMV 同比", "route": "nl2sql_query", "success": true}
correction 用户纠正记录 {"correction_sql": "SELECT COUNT(*)...", "comment": "GMV 不含退款"}
MemoryStatus 含义
candidate 新写入候选,尚未激活
active 已激活,参与检索
suppressed 被抑制(如冲突消解时降级)
expired TTL 过期
deleted 软删除

记忆检索通过 MemoryFacade.retrieve() 返回 MemoryContext DTO,按路由预算填充三槽:

# backend/app/memory/facade.py
class MemoryContext:
    """注入 Agent 状态的记忆上下文。"""
    profile: list[MemoryResult]      # 用户偏好
    episodic: list[MemoryResult]     # 历史交互
    correction: list[MemoryResult]   # 纠正记录

MemoryContext 写入 LangGraph 状态的 state["memory_context"] 字段(backend/app/agents/state.py)。

7.3.5 Correction Memory 完整循环

Correction Memory 是"从用户纠正中学习"的机制。以下是完整的 before/after 循环:

形成阶段backend/app/memory/formation.pyprocess_feedback):

# 用户对一条 SQL 结果给出"踩"并附纠正 SQL
await formation.process_feedback(
    user_id="u_123",
    rating="dislike",
    correction_sql="SELECT SUM(price) FROM gold_hm.fact_transaction WHERE price > 0",
    comment="GMV 不含退款,要过滤 price > 0",
)
# → 写入 MemoryRecord(kind=correction, payload_json={"correction_sql": ..., "comment": ...},
#                     confidence=0.8, status="candidate")

检索阶段MemoryFacade.retrieve):

# 下次该用户提问类似问题时
ctx = await facade.retrieve(user_id="u_123", query="本月 GMV", route_decision="nl2sql_query")
# ctx.correction = [MemoryResult(summary="GMV 不含退款,过滤 price > 0", confidence=0.8)]

诚实声明:Correction Memory 尚未接入 SQL 生成

基于当前代码事实,Correction Memory 已持久化但尚未端到端接入 SQL 生成。具体状态:

  • 已实现process_feedback 写入 correction 记录;MemoryFacade.retrieve 能检索 correction 层;MemoryContext.correction DTO 与 state["memory_context"] 状态槽已预留。
  • 未连通:SQL 生成节点(sql_generation.py)当前仅消费 long_term_context(Profile 偏好,通过 LongTermMemory.get_preferences() 注入 assemble_sql_promptuser_preferences 参数)。MemoryFacade.retrieve() 在请求路径中未被调用——state["memory_context"] 的 correction 槽虽存在但无数据填充。

这意味着:用户纠正的 SQL 当前会被记录,但不会自动影响后续 SQL 生成。Correction Memory 的端到端连通是明确的改进项(第 16 章)。此处的循环描述为目标设计,非当前运行行为。

7.3.6 SQL 语义缓存

属性
存储 semlayer.sql_cache 表 (pgvector)
匹配 cosine similarity > 0.92(TTD_SQL_CACHE_SIMILARITY
TTL 15 分钟(TTD_SQL_CACHE_TTL_MINUTES
缓存内容 仅 SQL 文本,不缓存执行结果

数据新鲜度

SQL Cache 只缓存生成的 SQL 语句。执行结果始终从数据面实时获取,确保返回最新数据。这是 ADR-10 的核心决策——宁愿命中缓存仍执行 SQL,也不要返回脏数据。

命中流程:Router 检测 question_embedding 与缓存 SQL 的 embedding 相似度 ≥ 0.92 → 直接跳转 guardrails_agent,跳过检索与生成。

SQL 缓存 vs 结果缓存 vs 通用语义缓存

  • SQL-Only Cache(TTD):只缓存 SQL 文本,每次仍执行。数据新鲜,但对"慢查询"加速有限(省的是生成时间,不是执行时间)。
  • 结果缓存:缓存查询结果,命中即返回。加速最大,但有脏数据风险,不适合实时数据。
  • 通用语义缓存(如 GPTCache):缓存任意 LLM 响应(不只 SQL),用语义相似度匹配。通用但不可控。
  • TTD 选 SQL-Only 是数据敏感场景的正确取舍——对历史报表等低新鲜度场景,可演进为分级缓存(ADR-10 改进)。

7.3.7 动态 Few-Shot 缓存

从 SQL 修复成功案例自动学习 {question, final_sql} 对,作为实时 few-shot 补充手工策划的 semantic-plane/few_shots/。这是 Engine D 的数据源,实现了"系统从自己的成功中学习"的闭环。

三步审批工作流(质量控制):

record_success()           →  review_status = 'pending_review'
                               (新条目不参与 RAG,等待审核)
Admin 审批 (/admin/few-shots)  →  approve / reject
search_similar()           →  仅返回 approved + sim ≥ 0.95 + confidence ≥ 0.9 + fail_count ≤ 3
属性
存储 semlayer.dynamic_few_shot_cache (pgvector + review 状态)
RAG 注入条件 approved AND sim ≥ 0.95 AND confidence ≥ 0.9 AND fail_count ≤ 3
自动过期 30 天,或 fail_count > 3
YAML 导出 approved 条目可导出为 semantic-plane/few_shots/ 一致的 YAML,晋升为正式资产
class DynamicFewShotCache:
    async def record_success(question, final_sql, *, intent_type, grounded_tables,
                             question_embedding, confidence) -> None
    async def search_similar(question_embedding, *, top_k=3,
                             min_confidence=0.9, min_similarity=0.95) -> list[dict]
    async def approve(entry_id, reviewer) -> bool
    async def reject(entry_id, reviewer) -> bool

7.3.8 会话管理

配置 默认值 说明
TTD_SESSION_TTL_HOURS 24 会话过期时间
TTD_SESSION_MAX_TURNS 20 单会话最大轮次
TTD_CLEANUP_INTERVAL_MINUTES 60 清理循环间隔

新对话标题自动取自第一条用户消息(LATERAL JOIN 查询)。后台 asyncio.Task 定期执行过期会话清理。

7.3.9 Correction Memory 连通方案

7.3.5 已说明 Correction Memory 当前已持久化但未接入 SQL 生成。本节给出一个可执行的连通方案设计(非"改进方向"),供贡献者直接落地。

目标

让用户的纠正 SQL 在下次类似查询时自动影响 SQL 生成——通过 Prompt 注入 correction 记录,引导 LLM 避免重复错误。

实现步骤

# backend/app/agents/sub_agents/sql_generation.py(修改点)

async def sql_generation(state: AgenticBIState) -> dict:
    # ... 现有逻辑 ...

    # 新增:从 state["memory_context"] 提取 correction 记录
    memory_ctx = state.get("memory_context") or {}
    corrections = memory_ctx.get("correction", [])

    # 新增:将 correction 摘要拼接为 repair_hint 风格的提示
    correction_hints = _format_correction_hints(corrections, user_question)

    # 现有:user_preferences 来自 long_term_context
    user_preferences = _format_preferences(state.get("long_term_context"))

    # 修改:将 correction_hints 追加到 user message(与 repair_hint 同级)
    user_msg = f"{user_question}\n{repair_hint}\n{semantic_hint}\n{correction_hints}"
    messages = assemble_sql_prompt(retrieval_results, graph_context, user_msg,
                                   user_preferences=user_preferences)
    # ...
def _format_correction_hints(corrections: list, question: str) -> str:
    """将相关 correction 记录格式化为 Prompt 提示。"""
    if not corrections:
        return ""
    lines = ["[历史纠正提示] 该用户曾对类似查询做过纠正,请参考:"]
    for c in corrections[:3]:  # 最多注入 3 条
        payload = c.payload_ref or {}
        comment = payload.get("comment", "")
        lines.append(f"- {comment}")
    return "\n".join(lines)

前置改动

上述方案的前提是在请求路径中调用 MemoryFacade.retrieve() 填充 state["memory_context"]。当前 chats.py 未调用它,需增加:

# backend/app/api/chats.py(修改点,send_message 内)
memory_ctx = await MemoryFacade(store).retrieve(
    user_id=user_id, query=user_message, route_decision=route_decision
)
initial_state["memory_context"] = memory_ctx.to_dict()

预期效果(假设)

指标 连通前 连通后(预期) 说明
重复错误率 基线 降低 30-50% 用户纠正过的错误不再重复
SQL 首次正确率 基线 提升 5-10% correction hint 引导 LLM 避坑
Prompt token 增量 +100-300 token 最多 3 条 correction 摘要

预期效果为假设值

上表数字为基于经验的假设,未经实测验证。连通后应通过 第 15 章 的 A/B 评估量化真实效果——对比"有 correction 注入"与"无 correction 注入"两组的 SQL 正确率。

7.3.10 记忆冲突消解

当新记忆与旧记忆冲突时(如用户改了偏好:"我喜欢折线图" → "我喜欢柱状图"),当前无自动消解,可能导致矛盾记忆共存。本节给出具体的冲突检测算法与合并策略。

冲突检测算法

# backend/app/memory/formation.py(新增)

def detect_conflict(new_memory: MemoryRecord, existing: list[MemoryRecord]) -> ConflictResult:
    """检测新记忆是否与已有同类记忆冲突。"""
    # 1. 同类筛选:相同 kind + 相同 namespace + 相同 scope
    candidates = [m for m in existing
                  if m.kind == new_memory.kind
                  and m.namespace == new_memory.namespace
                  and m.scope == new_memory.scope]

    # 2. 语义相似度检测:embedding cosine > 0.85 视为"同一主题"
    for m in candidates:
        sim = cosine(new_memory.embedding, m.embedding)
        if sim > 0.85:
            # 3. 内容冲突检测:payload 的同名字段值不同
            if _payload_conflicts(new_memory.payload_json, m.payload_json):
                return ConflictResult(conflict_with=m, similarity=sim)

    return ConflictResult(no_conflict=True)

合并策略

冲突类型 策略 示例
偏好覆盖(profile) 新覆盖旧,旧记忆 status → suppressed "折线图" → "柱状图":旧的 suppressed
纠正迭代(correction) 保留两者,按时间排序,Reranker 取最新 用户先纠正 A,后又纠正 B → 两条都保留,检索时 latest 优先
情景并存(episodic) 不视为冲突,共存 不同时间的成功交互互不冲突
矛盾且无法自动消解 触发 HITL,让用户选择 两条 profile 都说"偏好图表"但值完全相反

7.3.11 记忆可视化

下图展示某用户经过 20 轮对话后,四层记忆的状态及它们如何影响当前查询:

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#e8f0fe','primaryTextColor':'#202124','primaryBorderColor':'#1a73e8','lineColor':'#5f6368','secondaryColor':'#e0f2f1','tertiaryColor':'#f8f9fa'}}}%%
flowchart TB
    subgraph Q["当前查询"]
        Q1["用户问题<br/>「本月线上 GMV 趋势」"]
    end
    subgraph M["四层记忆状态(20 轮会话后)"]
        direction LR
        W["Working Memory<br/>最近 5 轮上下文<br/>含上轮 GMV 查询"]
        P["Profile(3 条 active)<br/>· 偏好图表:折线图<br/>· 常用维度:时间、渠道<br/>· 常用指标:GMV"]
        E["Episodic(2 条 active)<br/>· GMV 同比查询成功<br/>· 退货率查询成功"]
        C["Correction(1 条 candidate<br/>尚未接入生成)<br/>· GMV 不含退款"]
    end
    Q1 -->|"问题 + embedding"| Prompt["SQL Prompt<br/>组装注入"]
    W -->|"注入最近上下文"| Prompt
    P -->|"注入 user_preferences"| Prompt
    C -.->|"连通后注入<br/>(见 7.3.9)"| Prompt
    E -.->|"提升路由置信度<br/>GMV 问题走 nl2sql_query"| Router["Router"]

    Prompt --> SG["SQL Generator"]

    classDef bpData     fill:#e0f2f1,stroke:#0d7377,stroke-width:2px,color:#202124
    classDef bpInfo     fill:#f3e8fd,stroke:#9334e6,stroke-width:2px,color:#202124
    classDef bpProcess  fill:#e8f0fe,stroke:#1a73e8,stroke-width:2px,color:#202124
    classDef bpDecision fill:#fef7e0,stroke:#f9ab00,stroke-width:2px,color:#202124

    class W,P,E,C bpData
    class Q1 bpProcess
    class Prompt,Router,SG bpProcess
    class C bpInfo
记忆层 影响当前查询的方式 状态
Working 最近上下文注入 Prompt("上轮查了 GMV 同比,本轮可能延续") 已生效
Profile user_preferences 注入 Prompt(偏好折线图 → 可视化推荐直接选折线) 已生效
Episodic 历史成功交互提升路由置信度(GMV 类问题走 nl2sql_query) 已生效
Correction 预期注入 Prompt("GMV 不含退款") 未连通(见 7.3.9)

7.4 方案选型对比

7.4.1 记忆架构对比

维度 TTD 触发式四层 MemGPT/Letta 自治 LangGraph Store
记忆管理 触发式(明确信号写入) 自治(LLM 决定读写遗忘) 手动 API
可控性
灵活性
可审计
实现复杂度
TTD 选择理由 安全敏感场景需可审计,自治记忆不可控

7.4.2 记忆形成策略对比

策略 代表 优势 劣势 TTD 状态
明确信号触发 TTD 可控、可审计 遗漏隐式信号
行为反思抽象 Generative Agents 能发现隐式偏好 反思质量依赖 LLM
自治 function call MemGPT 灵活 不可控

性能与质量指标(设计目标)

以下为记忆系统的设计目标值,TTD 尚未进行系统化实测

指标 设计目标 说明
Profile/Episodic 检索延迟 < 20ms 按置信度+显著性排序,路由预算截断
SQL Cache 命中延迟 < 5ms pgvector cosine 相似度 + TTL 检查
SQL Cache 命中率 ≥ 0.3 相似问题复用比例(未实测)
Dynamic Few-Shot 注入率 ≥ 0.1 approved 条目参与 RAG 的比例(未实测)
记忆形成延迟 < 500ms 后台异步,不阻塞主路径

评估基础设施见 第 15 章,改进路线见 第 16 章

当前实现可改进之处

  1. 记忆形成策略单一:只在明确信号(成功/反馈/澄清)时写入,会遗漏隐式偏好。例如用户连续三次选择折线图但未点"赞",系统不会形成"偏好折线图"的记忆。改进:引入行为信号挖掘——从交互模式(连续选择、停留时长)提取隐式偏好,参考 Generative Agents 的反思机制。
  2. 缺记忆冲突消解:当新记忆与旧记忆冲突时(如用户改了偏好),无自动消解机制,可能导致矛盾记忆共存。改进:写入时检查同类记忆,新记忆覆盖或合并旧记忆。
  3. 动态 Few-Shot 审批瓶颈:所有自学习条目需人工审批,规模化后审批成为瓶颈。改进:引入置信度自动晋升——高置信度(sim ≥ 0.98 + 多次成功)的条目自动 approved,仅边缘案例人工审核。
  4. SQL Cache 阈值固定:0.92 是全局固定阈值,对不同业务域的语义粒度不敏感。改进:按域或按表组动态调整阈值。

改进方向

记忆系统的演进方向是更自治、更智能的形成与遗忘。短期:补隐式信号挖掘与冲突消解。长期:向 MemGPT 式自治记忆靠拢——让 LLM 在可控范围内自主决定记忆读写,配合审批门控保证质量。动态 Few-Shot 应建立"置信度自动晋升 + 边缘人工审核"的分级机制,打破审批瓶颈。


7.5 小结与延伸阅读

本章要点

  1. 四层记忆:Working(短期)/ Profile(语义)/ Episodic(情景)/ Correction(程序),对应认知科学分类。
  2. 共享优化层:SQL 语义缓存(仅缓存 SQL 不缓存结果)、动态 Few-Shot(自学习 + 三步审批)、元数据缓存。
  3. 记忆形成是触发式(非 MemGPT 自治),路由感知预算控制各类记忆注入量。
  4. 动态 Few-Shot 实现"从成功中学习"的闭环,经审批后注入 RAG Engine D。
  5. SQL-Only Cache 是数据敏感场景的正确取舍——新鲜度优先于速度。

延伸阅读

下一章第 8 章 工具调用与代码解释器——ML 工具集、代码沙箱、GraphRAG、可视化推荐引擎如何作为 Agent 的"手脚"。