ContextualUserFragment 是 Runtime 注入上下文的统一协议:每个实现声明角色、正文、起止标记,以及是否必须独立成一条消息。它解决的不是排版问题,而是“这段模型可见文本以后还能否被准确识别、替换和迁移”。
片段的五个契约
| 方法 | 含义 |
|---|---|
role() | 生成 developer 还是 user 消息 |
markers() | 当前实例的起止边界 |
type_markers() | 类型级识别边界 |
body() | 标记内部正文 |
requires_separate_message() | 禁止与相邻同角色片段合并 |
class ContextFragment(Protocol):
role: Literal["developer", "user"]
start_marker: str
end_marker: str
separate: bool
def render(self) -> str:
if not self.start_marker and not self.end_marker:
return self.body()
return self.start_marker + self.body() + self.end_marker
matches_marked_text 对标记大小写不敏感,但要求两端同时存在。空标记片段永远不会用“任意文本匹配”冒充某种上下文。这个保守策略可避免用户恰好输入类似内容时被迁移代码误删。
合并发生在渲染之后
初始构造先按角色和隔离要求分桶,普通片段在桶内渲染,再由 build_*_item 合成 ResponseItem。后续 World State 差异则由 merge_contextual_fragments 只合并相邻、同角色且均允许合并的片段。
def merge_fragments(fragments):
groups = []
for fragment in fragments:
if (not groups or fragment.separate
or groups[-1].separate
or groups[-1].role != fragment.role):
groups.append(MessageGroup.from_fragment(fragment))
else:
groups[-1].append(fragment.render())
return [group.to_response_item() for group in groups]
失败边界
若只用开标签识别,截断历史可能留下半个片段并被误判;若合并跨角色,指令权限会改变;若先拼正文后丢掉每段标记,World State 无法确认保留历史里究竟还有哪个分区。要求独立消息的策略片段则用于审计和上游协议边界,不能为了节省一个 item 强制合并。
源码与测试锚点
codex-rs/context-fragments/src/fragment.rs:trait、渲染和双端识别。codex-rs/core/src/context_manager/updates.rs:相邻片段合并。codex-rs/core/src/session/mod.rs:初始上下文分桶与隔离。codex-rs/core/src/context/world_state/*_tests.rs:旧片段识别与保留匹配。
评论
登录后即可评论