> ## Documentation Index
> Fetch the complete documentation index at: https://simplellmfunc.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# SelfRef 自引用

> 持久上下文管理：通过 SelfReference 系统实现经验记忆、上下文压缩与任务分叉

# SelfRef 自引用

SelfRef 是 SimpleLLMFunc 的**持久自修改上下文**系统——让 Agent 能够跨轮次记忆、压缩历史，并将工作委派给子 Agent。

## 两个组件，清晰分离

### SelfReference（持久后端）

有状态的存储层。跨调用持续存在。存储：

* **History**（按 memory key 分组）——完整的对话记录
* **Experiences** ——持久记忆的事实/教训
* **Summaries** ——压缩检查点
* **Fork state** ——子 Agent 句柄与结果

```python theme={null}
from SimpleLLMFunc.builtin import SelfReference

selfref = SelfReference()
selfref.bind_history("agent_main", initial_history)
```

### SelfRefSession（调用级插件）

单次调用的生命周期适配器。每次 `@llm_chat` 调用时重新创建。实现 ReAct hook：

* `collect_context_mutations()` ——在每次编译前提供来自 selfref 的内部对话记录补丁
* `finalize()` ——轮次结束后将最终状态持久化到 SelfReference 后端

Session 在无状态的 ReAct 循环和有状态的后端之间架起了桥梁。

## 连接方式

```
@llm_chat(self_reference_key="agent_main")
                    │
                    ▼
        ┌─ SelfRefSession（每次调用） ──────────────────┐
        │                                                │
        │  每次编译前：                                    │
        │    → collect_context_mutations()               │
        │    → 可能产出 Experience/Summary 补丁            │
        │                                                │
        │  轮次结束后：                                    │
        │    → finalize()                                │
        │    → 将更新后的历史持久化到后端                    │
        │                                                │
        └────────────────────────────────────────────────┘
                    │
                    ▼
        ┌─ SelfReference（持久后端）────────────────────┐
        │                                                │
        │  Memory["agent_main"]:                         │
        │    - history: [...]                            │
        │    - experiences: [{id, text}, ...]            │
        │    - summary: {...}                            │
        │                                                │
        └────────────────────────────────────────────────┘
```

## DataFromSelfRef：快照

当 SelfRef 处于活跃状态时，编译管道会收到一个 `DataFromSelfRef` 快照：

```python theme={null}
@dataclass(frozen=True)
class DataFromSelfRef:
    base_system_prompt: str          # System prompt (may include experience markers)
    experiences: List[Dict[str, str]]  # [{id: "...", text: "..."}, ...]
    summary: Optional[Dict[str, Any]]  # Compaction metadata
    summary_message: Optional[Dict[str, Any]]  # Summary as a message
    working_messages: NormalizedMessageList  # Post-compaction working transcript
```

该快照决定了：

* 系统提示词（基础提示词 + 渲染后的经验）
* 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]` |

## 经验生命周期

经验是存储在系统提示词中的持久事实：

```
System Prompt:
  You are a coding agent...

  <experiences>
    <exp id="exp_001">User prefers dark mode terminal output</exp>
    <exp id="exp_002">Always run tests before committing</exp>
  </experiences>
```

* `remember("...")` → 通过运行时补丁边界记录经验
* `forget("exp_001")` → 移除经验
* 经验在压缩中存活——它们存储在系统提示词中，而非工作对话记录中
* 在编译阶段 2 中由 `render_system_prompt_with_experiences()` 渲染

## 压缩生命周期

当上下文增长过大时，Agent 可以执行压缩：

```python theme={null}
# Inside execute_code:
payload = runtime.selfref.context.compact(
    goal="Build the authentication module",
    instruction="Continue implementing OAuth flow",
    discoveries=["API requires PKCE", "Token refresh interval is 1h"],
    completed=["Set up project structure", "Added OAuth dependency"],
    current_status="Implementing token exchange endpoint",
    likely_next_work="Add refresh token logic, then write tests",
    relevant_files_directories=["src/auth/", "tests/test_auth.py"],
    remember=["OAuth endpoint requires PKCE challenge"]
)
```

处理过程：

1. 压缩被**加入队列**（不会立即应用）
2. 当前工具批次完成后，运行时会应用摘要补丁
3. 系统提示词被保留
4. 工作对话记录被替换为摘要消息
5. `remember` 中的条目成为持久经验
6. SelfReference 后端存储新状态

## 分叉生命周期

分叉允许 Agent 将工作委派给继承上下文的子 Agent：

```python theme={null}
# Spawn (inside execute_code)
handle = runtime.selfref.fork.spawn(
    task="Review the auth module for security issues",
    instruction="Check for: SQL injection, XSS, auth bypass. Return findings as a list.",
)
print(handle["fork_id"])  # "fork_abc123"

# ... do other work ...

# Gather (when you need results)
results = runtime.selfref.fork.gather_all()
for fork_id, result in results.items():
    print(f"{fork_id}: {result['status']} - {result['response']}")
```

关键规则：

* 子 Agent 继承的是**分叉前**的上下文快照（不是父 Agent 的进行中状态）
* 子 Agent 无法修改父 Agent 的上下文
* `gather_all()` 会阻塞直到所有子 Agent 完成
* 结果包含 `status`、`response`，以及可选的 `history`

## 激活方式

通过 `@llm_chat` 的 `self_reference_key` 参数激活 SelfRef：

```python theme={null}
@llm_chat(
    llm_interface=llm,
    toolkit=[*repl.toolset, *file_tools],
    self_reference_key="agent_main",
)
async def agent(message: str, history: list):
    """Your agent prompt here."""
    pass
```

框架会自动：

1. 为该 key 创建/获取 `SelfReference` 后端
2. 将每次调用包装在 `SelfRefSession` 中
3. 将 selfref 原语注入 PyRepl 运行时
4. 在每轮结束后处理持久化（存储更新后的历史记录）

<CardGroup cols={2}>
  <Card title="构建指南：llm_chat" icon="comments" href="/zh/guide/llm-chat">
    如何在实践中使用 @llm\_chat 与 SelfRef。
  </Card>

  <Card title="进阶：SelfRef 工程化" icon="gear" href="/zh/advanced/selfref-engineering">
    进阶模式：多 key 记忆、压缩策略、分叉编排。
  </Card>
</CardGroup>
