SelfRef 自引用
SelfRef 是 SimpleLLMFunc 的持久自修改上下文系统——让 Agent 能够跨轮次记忆、压缩历史,并将工作委派给子 Agent。两个组件,清晰分离
SelfReference(持久后端)
有状态的存储层。跨调用持续存在。存储:- History(按 memory key 分组)——完整的对话记录
- Experiences ——持久记忆的事实/教训
- Summaries ——压缩检查点
- Fork state ——子 Agent 句柄与结果
SelfRefSession(调用级插件)
单次调用的生命周期适配器。每次@llm_chat 调用时重新创建。实现 ReAct hook:
collect_context_mutations()——在每次编译前提供来自 selfref 的内部对话记录补丁finalize()——轮次结束后将最终状态持久化到 SelfReference 后端
连接方式
DataFromSelfRef:快照
当 SelfRef 处于活跃状态时,编译管道会收到一个DataFromSelfRef 快照:
- 系统提示词(基础提示词 + 渲染后的经验)
- LLM 看到的消息(压缩后的 working_messages)
- 哪些经验处于活跃状态
6 个运行时原语
当@llm_chat Agent 启用了 SelfRef 并使用 PyRepl 时,以下原语可在 execute_code 中使用:
上下文原语
| 原语 | 功能说明 |
|---|---|
runtime.selfref.context.inspect() | 返回只读快照:活跃 key、经验、摘要、消息、是否有待处理的压缩 |
runtime.selfref.context.remember(text) | 通过内部经验补丁存储持久经验 |
runtime.selfref.context.forget(experience_id) | 通过内部经验补丁移除经验 |
runtime.selfref.context.compact(goal, instruction, discoveries, completed, current_status, likely_next_work, relevant_files_directories, remember=[]) | 将上下文压缩加入队列 → 稍后应用内部摘要补丁 |
分叉原语
| 原语 | 功能说明 |
|---|---|
runtime.selfref.fork.spawn(task, instruction, ...) | 以分叉前的上下文快照生成子 Agent。返回 {fork_id, status} |
runtime.selfref.fork.gather_all(include_history=False) | 等待所有已创建的子 Agent 完成。返回 dict[fork_id → ForkResult] |
经验生命周期
经验是存储在系统提示词中的持久事实:remember("...")→ 通过运行时补丁边界记录经验forget("exp_001")→ 移除经验- 经验在压缩中存活——它们存储在系统提示词中,而非工作对话记录中
- 在编译阶段 2 中由
render_system_prompt_with_experiences()渲染
压缩生命周期
当上下文增长过大时,Agent 可以执行压缩:- 压缩被加入队列(不会立即应用)
- 当前工具批次完成后,运行时会应用摘要补丁
- 系统提示词被保留
- 工作对话记录被替换为摘要消息
remember中的条目成为持久经验- SelfReference 后端存储新状态
分叉生命周期
分叉允许 Agent 将工作委派给继承上下文的子 Agent:- 子 Agent 继承的是分叉前的上下文快照(不是父 Agent 的进行中状态)
- 子 Agent 无法修改父 Agent 的上下文
gather_all()会阻塞直到所有子 Agent 完成- 结果包含
status、response,以及可选的history
激活方式
通过@llm_chat 的 self_reference_key 参数激活 SelfRef:
- 为该 key 创建/获取
SelfReference后端 - 将每次调用包装在
SelfRefSession中 - 将 selfref 原语注入 PyRepl 运行时
- 在每轮结束后处理持久化(存储更新后的历史记录)
构建指南:llm_chat
如何在实践中使用 @llm_chat 与 SelfRef。
进阶:SelfRef 工程化
进阶模式:多 key 记忆、压缩策略、分叉编排。