|
| 1 | +# Advanced Memory |
| 2 | + |
| 3 | +## Advanced Memory 简介 |
| 4 | + |
| 5 | +`Advanced Memory` 是一套面向 Agent 的本地化记忆与上下文管理机制,重点增强 |
| 6 | +Agent 在长期信息沉淀和超长对话处理方面的能力: |
| 7 | + |
| 8 | +- **本地化持久存储**:记忆和上下文数据以本地文件形式持久化,存储位置、数据边界 |
| 9 | + 和组织方式清晰可控,适合本地开发、调试、迁移和审计。 |
| 10 | +- **更强的长期记忆能力**:支持将对话中的稳定事实、用户偏好和重要经验主动沉淀为 |
| 11 | + 可组织、可更新、可跨 Session 使用的长期记忆,而不是简单堆积历史消息。 |
| 12 | +- **分层记忆管理**:分别管理原始对话、Session 级记忆和跨 Session 长期记忆,让不同 |
| 13 | + 类型的信息以合适的粒度参与后续推理。 |
| 14 | +- **上下文管理**:根据上下文规模、信息类型和使用情况,对历史消息、工具结果及记忆 |
| 15 | + 内容进行统一治理,在保留关键信息的同时控制模型输入规模。 |
| 16 | +- **上下文压缩**:支持对历史上下文和工具结果进行渐进式裁剪、压缩和摘要,降低长 |
| 17 | + 对话导致的上下文膨胀以及超出模型窗口限制的风险。 |
| 18 | +- **结构化记忆提取**:从持续增长的对话中提取结构化信息,形成更稳定、更易维护的 |
| 19 | + Session Memory,提升后续对话对历史信息的利用效率。 |
| 20 | + |
| 21 | +本示例演示如何使用 `AdvancedMemorySessionService`。它把 Session 持久化和 |
| 22 | +Advanced Memory 上下文管理整合到一个 SessionService 中,用户不需要显式调用 |
| 23 | +`setup_advanced_memory()`,也不需要再创建 `InMemorySessionService`。 |
| 24 | + |
| 25 | +## 示例流程 |
| 26 | + |
| 27 | +脚本使用同一个 Runner 执行多个 Session: |
| 28 | + |
| 29 | +1. `session-1` 连续输入多轮 Python 开发偏好。 |
| 30 | +2. 低阈值配置会触发 session memory 提取,并写入 `session_memory.md`。 |
| 31 | +3. `session-1` 请求总结已经学习到的开发偏好。 |
| 32 | +4. `session-2` 查询长期记忆,验证不同 Session 共享同一个 `MEMORY/`。 |
| 33 | + |
| 34 | +## 使用方式 |
| 35 | + |
| 36 | +```python |
| 37 | +from pathlib import Path |
| 38 | + |
| 39 | +from trpc_agent_sdk.memory import AdvancedMemoryConfig |
| 40 | +from trpc_agent_sdk.sessions import AdvancedMemorySessionService |
| 41 | +from trpc_agent_sdk.runners import Runner |
| 42 | + |
| 43 | +session_service = AdvancedMemorySessionService( |
| 44 | + config=AdvancedMemoryConfig( |
| 45 | + root_dir=Path(__file__).resolve().parent, |
| 46 | + ) |
| 47 | +) |
| 48 | + |
| 49 | +runner = Runner( |
| 50 | + app_name="advanced_memory_demo", |
| 51 | + agent=agent, |
| 52 | + session_service=session_service, |
| 53 | +) |
| 54 | +``` |
| 55 | + |
| 56 | +`Runner` 检测到 `AdvancedMemorySessionService` 后会自动完成 Advanced Memory |
| 57 | +绑定,包括: |
| 58 | + |
| 59 | +- transcript 持久化 |
| 60 | +- session memory 提取 |
| 61 | +- 长期记忆 tools:`save_memory`、`read_memory`、`list_memory_index` |
| 62 | +- `HistorySnip` |
| 63 | +- `Microcompact` |
| 64 | +- `AutoCompact` |
| 65 | +- `ToolResultBudget` |
| 66 | + |
| 67 | +`AdvancedMemoryConfig` 默认已经启用这些能力。示例中额外降低了 |
| 68 | +session-memory 的阈值,只是为了用较少的对话轮数演示提取流程;生产环境可以 |
| 69 | +删除这些阈值配置,使用默认值。 |
| 70 | + |
| 71 | +## 数据目录 |
| 72 | + |
| 73 | +运行后,数据默认写入当前示例目录: |
| 74 | + |
| 75 | +```text |
| 76 | +MEMORY/ |
| 77 | +├── MEMORY.md |
| 78 | +└── *.md # 长期记忆详情 |
| 79 | +
|
| 80 | +SESSION/ |
| 81 | +├── _state.json # app/user 级 state |
| 82 | +├── session-1/ |
| 83 | +│ ├── session.json # Session 元数据和 session state |
| 84 | +│ ├── transcript.jsonl # 原始 Events 和 checkpoint |
| 85 | +│ ├── session_memory.md # 结构化 Session 记忆 |
| 86 | +│ └── tool-results/ # 超大工具结果 |
| 87 | +└── session-2/ |
| 88 | + ├── session.json |
| 89 | + ├── transcript.jsonl |
| 90 | + └── session_memory.md |
| 91 | +``` |
| 92 | + |
| 93 | +其中: |
| 94 | + |
| 95 | +- `session.json` 保存 Session 元数据和状态,不保存完整 Events。 |
| 96 | +- `transcript.jsonl` 是追加写入的原始事件日志,可用于恢复 Session。 |
| 97 | +- `session_memory.md` 是根据 transcript 提取的结构化摘要。 |
| 98 | +- `MEMORY/` 保存跨 Session 使用的长期记忆。 |
| 99 | + |
| 100 | +## 运行 |
| 101 | + |
| 102 | +先在本目录创建 `.env`,然后填写模型配置: |
| 103 | + |
| 104 | +```bash |
| 105 | +cd examples/memory_service_with_advanced_memory |
| 106 | +python3 run_agent.py |
| 107 | +``` |
| 108 | + |
| 109 | +需要的环境变量: |
| 110 | + |
| 111 | +- `TRPC_AGENT_API_KEY` |
| 112 | +- `TRPC_AGENT_BASE_URL` |
| 113 | +- `TRPC_AGENT_MODEL_NAME` |
| 114 | +- `TRPC_AGENT_MODEL_CONTEXT_WINDOW_TOKENS`(可选,模型总上下文窗口大小,单位为 token) |
| 115 | +- `TRPC_AGENT_MAX_OUTPUT_TOKENS`(可选,模型最大输出窗口大小,单位为 token) |
| 116 | + |
| 117 | +`.env` 中留空的变量不会覆盖默认值;如果同时在 Python 中传入 |
| 118 | +`model_context_window_tokens` 或 `max_output_tokens`,Python 显式配置优先。 |
| 119 | + |
| 120 | +如果配置了模型上下文窗口,Advanced Memory 会用 |
| 121 | +`TRPC_AGENT_MODEL_CONTEXT_WINDOW_TOKENS - TRPC_AGENT_MAX_OUTPUT_TOKENS` |
| 122 | +作为可用于输入内容的窗口;两个变量都留空时使用字符数阈值。 |
| 123 | + |
| 124 | +## `AdvancedMemoryConfig` 配置项 |
| 125 | + |
| 126 | +下面列出当前所有可直接传入 `AdvancedMemoryConfig` 的配置项。**没有特殊需求时, |
| 127 | +只设置 `root_dir` 即可**;示例中的值均为默认值。 |
| 128 | + |
| 129 | +```python |
| 130 | +session_service = AdvancedMemorySessionService( |
| 131 | + config=AdvancedMemoryConfig( |
| 132 | + root_dir=Path(__file__).resolve().parent, # 当前示例目录 |
| 133 | + # root_dir=Path( |
| 134 | + # "/data/workspace/trpc-agent-python/examples/memory_service_with_advanced_memory" |
| 135 | + # ), |
| 136 | + # Optional |
| 137 | + enabled=True, # 总开关和存储路径 |
| 138 | + memory_dir_name="MEMORY", # 长期记忆目录 |
| 139 | + session_dir_name="SESSION", # Session 数据目录 |
| 140 | + memory_index_name="MEMORY.md", # 长期记忆索引文件 |
| 141 | + transcript_name="transcript.jsonl", # transcript 文件 |
| 142 | + session_memory_name="session_memory.md", # Session 摘要文件 |
| 143 | + encoding="utf-8", # 文件编码 |
| 144 | + transcript_fsync=False, # transcript 写入后是否 fsync |
| 145 | + |
| 146 | + # 长期记忆 |
| 147 | + memory_index_max_lines=200, # 注入 prompt 的索引最大行数 |
| 148 | + memory_index_max_bytes=25_000, # 注入 prompt 的索引最大字节数 |
| 149 | + long_term_memory_injection_enabled=True, # 是否注入 MEMORY.md |
| 150 | + |
| 151 | + # 工具结果 |
| 152 | + tool_result_max_chars=50_000, # 单个工具结果最大字符数 |
| 153 | + tool_results_per_message_max_chars=200_000, # 单条消息工具结果总上限 |
| 154 | + tool_result_preview_chars=2_000, # 超限结果的预览字符数 |
| 155 | + |
| 156 | + # HistorySnip |
| 157 | + history_snip_enabled=True, # 是否压缩过长历史 |
| 158 | + history_snip_trigger_chars=600_000, # 触发阈值 |
| 159 | + history_snip_target_chars=400_000, # 压缩目标 |
| 160 | + history_snip_keep_recent=5, # 保留最近的完整消息数 |
| 161 | + history_snip_tool_names=( # 可处理的工具名称 |
| 162 | + "Read", "Bash", "Grep", "Glob", |
| 163 | + "WebSearch", "WebFetch", "Edit", "Write", |
| 164 | + ), |
| 165 | + |
| 166 | + # Token 上下文预算 |
| 167 | + # 这两个值也可以通过 .env 配置;显式传参优先于环境变量。 |
| 168 | + # model_context_window_tokens=131072, # 显式设置后覆盖环境变量 |
| 169 | + # max_output_tokens=8192, # 显式设置后覆盖环境变量 |
| 170 | + # 如果省略这两行,则分别读取 .env;未配置时默认 None 和 0。 |
| 171 | + token_warning_ratio=0.85, # 告警比例 |
| 172 | + token_autocompact_ratio=0.90, # 自动压缩比例 |
| 173 | + token_blocking_ratio=0.95, # 阻止继续增加上下文的比例 |
| 174 | + token_estimator=None, # 可选:自定义 token 估算器 |
| 175 | + context_window_resolver=None, # 可选:自定义窗口解析器 |
| 176 | + |
| 177 | + # Session Memory |
| 178 | + session_memory_enabled=True, # 是否启用 Session 摘要 |
| 179 | + session_memory_initial_chars=40_000, # 首次提取字符阈值 |
| 180 | + session_memory_update_chars=20_000, # 后续更新字符阈值 |
| 181 | + session_memory_initial_tokens=10_000, # 首次提取 token 阈值 |
| 182 | + session_memory_update_tokens=5_000, # 后续更新 token 阈值 |
| 183 | + session_memory_tool_calls_between_updates=3, # 两次更新间的工具调用数 |
| 184 | + session_memory_prompt_max_chars=200_000, # 摘要请求最大字符数 |
| 185 | + session_memory_request_overhead_tokens=2_048, # 请求预留 token |
| 186 | + session_memory_section_max_chars=8_000, # 单个摘要 section 最大字符数 |
| 187 | + session_memory_total_max_chars=54_000, # 摘要总最大字符数 |
| 188 | + session_memory_wait_timeout_seconds=15.0, # 等待摘要 Agent 的超时时间 |
| 189 | + |
| 190 | + # AutoCompact |
| 191 | + autocompact_enabled=True, # 是否启用自动压缩 |
| 192 | + autocompact_trigger_chars=700_000, # 触发阈值 |
| 193 | + autocompact_target_chars=350_000, # 压缩目标 |
| 194 | + autocompact_blocking_chars=780_000, # 阻止继续增加上下文的阈值 |
| 195 | + autocompact_keep_recent_contents=8, # 保留最近内容数 |
| 196 | + autocompact_max_failures=3, # 最大连续失败次数 |
| 197 | + autocompact_summary_input_max_chars=600_000, # 摘要 Agent 输入上限 |
| 198 | + autocompact_summary_retries=3, # 摘要 Agent 重试次数 |
| 199 | + |
| 200 | + # Microcompact |
| 201 | + microcompact_enabled=True, # 是否启用工具结果微压缩 |
| 202 | + microcompact_gap_seconds=3_600.0, # 工具结果时间间隔阈值 |
| 203 | + microcompact_trigger_count=20, # 触发工具结果数量 |
| 204 | + microcompact_keep_recent=5, # 保留最近工具结果数 |
| 205 | + microcompact_tool_names=( # 可处理的工具名称 |
| 206 | + "Read", "Bash", "Grep", "Glob", |
| 207 | + "WebSearch", "WebFetch", "Edit", "Write", |
| 208 | + ), |
| 209 | + |
| 210 | + # Advanced Memory preload |
| 211 | + preload_memory_enabled=False, # 是否自动预加载相关 topic |
| 212 | + preload_memory_max_topics=5, # 一次最多加载的 topic 数 |
| 213 | + preload_memory_max_chars=50_000, # 预加载内容总字符上限 |
| 214 | + preload_memory_candidate_limit=200, # 筛选模型的候选 topic 数 |
| 215 | + ), |
| 216 | +) |
| 217 | +``` |
| 218 | + |
| 219 | +`preload_memory_model` 不是 `AdvancedMemoryConfig` 字段,而是 |
| 220 | +`AdvancedMemorySessionService` 的可选参数,用于指定轻量筛选模型: |
| 221 | + |
| 222 | +```python |
| 223 | +session_service = AdvancedMemorySessionService( |
| 224 | + config=AdvancedMemoryConfig(preload_memory_enabled=True), |
| 225 | + preload_memory_model=small_model, # 不传时复用主 Agent 的模型 |
| 226 | +) |
| 227 | +``` |
0 commit comments