Skip to content
Dormon's Hideaway
Go back

AGI-Saber:记忆上下文的组织与应用

来源:抖音 @永泽

AGI-Saber项目旨在使用promptctcx包构建System Prompt。其核心在于每次LLM推理之前,根据当前Mode编排出System Prompt前缀,拒绝简单的字符串拼接。

1. 拼接流程

Agi-Saber的拼接流程始于用户输入。用户输入后,agent会触发ContextAssembler.Assemble(Query(Mode))方法,其主要步骤如下:

  1. 选择Schema:根据输入的Mode(如chat, tool, rag, react),匹配适合的上下文Schema。
  2. 并发请求:并发调用所有ContextSource(槽位数据提供者),获取对应的上下文数据。ContextSource是独立、可探测的源,支持多种SlotKind。
  3. SlotFilter过滤:根据每个槽位的特定过滤器(SlotFilter)进行数据筛选。SlotFilter定义了过滤规则,包括:
    • Categories:分类,其中之一即可,空表示不限。
    • RequireTags:必须全部包含的标签。
    • MinScore:返回的综合分数阈值。
    • TopK:单槽位最多返回项数,0表示不截断。
    • MaxAgeHours:最大年龄(小时),0表示不限。
    • TokenBudget:单槽位字符预算(粗略以字符数近似token)。
  4. Token Budget裁剪:对每个槽位的数据进行独立的Token Budget裁剪。
  5. 全局预算与优先级裁减:填充完所有槽位数据后,系统会进行全局预算控制,默认2400字符。通过双层预算机制,即单槽位预算和全局预算,结合优先级(SlotPriority)进行裁减,保证重要信息不会丢失。例如,安全约束的优先级最高,确保在提示词中不丢失。
  6. System Prompt前缀生成:将处理后的上下文数据渲染成System Prompt前缀,喂给LLM。

2. 核心概念

2.1. SlotKind六种槽位

AGI-Saber定义了六种SlotKind(槽位类型),用于存储不同类型的记忆上下文,包括:

2.2. SlotFilter含义

SlotFilter结构体用于描述Source在填充槽位时的过滤约束。它允许对召回数据进行细粒度控制,确保只有相关且符合预算的数据被填充进上下文,前文已详细介绍其字段含义。

2.3. RuntimeContextSchema: Mode与槽位编排表

AGI-Saber支持多种Mode,每个Mode都有特定的槽位编排需求。这些Mode包括:

当遇到未知Mode时,系统会自动回退到chat模式。

2.4. ContextSource: 槽位数据提供者

ContextSource接口定义了数据提供者如何支持多种SlotKind,并独立探测和填充数据。例如,GraphMemory同时提供了Profile和Recall数据。新的ContextSource可以注册,以便在运行时动态获取数据。

3. 装配核心流程

核心装配流程从根据Mode选择Schema开始。然后,系统会并发地填充各个槽位的数据,并对数据进行内部Token Budget裁剪。最后,通过全局预算控制,根据优先级从低到高进行裁减,确保提示词的长度适中且关键信息得以保留。

4. 渲染

裁剪后的槽位数据最终被渲染成中文System Prompt前缀。这个前缀包含了Agent的各项状态和信息,如硬性约束、任务规划、工具调用结果、用户画像和相关记忆。例如,一个渲染后的System Prompt前缀可能包含:

【硬性约束】
- [禁止] 不允许执行 rm -rf
- [告警] 网络访问需要审批
【任务规划】
- 任务 t-001 状态=running 阶段=executing
- 进度:第 2/5 步
- 下一步:调用 weather_api (工具 = http_get)
【可用工具】
- get_time - 获取当前时间
- weather_api - 查询天气 (必填 city)
- 近期调用 weather_api [成功]: {"temp":22}
【用户画像】
- 城市:北京
- 语言:中文
- 用户叫张三
【相关回忆】
-上次访问天气API (重要性 = 0.70, 综合分 = 0.82)

空白或被跳过的项不会被渲染。

5. 与“普通字符串拼接”的差异

AGI-Saber的promptctcx方法在多方面优于普通字符串拼接:

维度普通做法promptctcx
组织方式按数据类型按SlotKind(profile/planner/…)
Mode区分一套prompt走天下Schema驱动,4 Mode各取所需
召回策略Top-K全量SlotFilter声明式过滤
预算控制仅个总长度裁断双层budget + 优先级裁剪
安全约束可能被裁断丢失Constraints优先级0,永不丢
数据获取串行goroutine并发
可测试性拼好的字符串每个source独立单测

6. 主流程的使用

6.1. 装配阶段 (agent启动时一次)

Agent在启动时会进行一次性初始化,注册各种ContextSource,例如ProfileSource、ConstraintsSource、RecallSource等。

6.2. 开始前注入

在每次ReAct模式开始前,会装配一次memPrefix,并冻结复用。Promptctcx内部缓冲区会在循环中实时更新任务步骤和工具调用结果。但这些更新会“延迟一轮”才出现在prompt里,这相当于跨轮次的短期工作记忆。这样可以避免上下文污染,同时确保Token的高利用率和长任务能力。

7. 总结

采用“槽位拼接”的方式组织记忆上下文,具有以下几大优势:

  1. 避免上下文污染:带来最大的收益,确保提示词的纯净和相关性。
  2. 恢复Agent状态:不仅仅是恢复聊天记录,更能准确恢复Agent的工具调用状态和任务当前所处状态。
  3. Token利用率更高:通过精细的预算控制和优先级裁减,优化Token的使用效率。
  4. 长任务能力更强:精确的上下文管理支持Agent在复杂长任务中保持一致性和连贯性。
  5. 让不同记忆有不同生命周期:不同类型的槽位记忆可以根据其性质设置不同的生命周期和更新频率,提升系统的灵活性和准确性。

通过以上机制,AGI-Saber能够高效、精准地管理和组织记忆上下文,从而提升Agent的整体性能和可靠性。

图例

整个系统通过ContextBuilder将各种状态和信息整合,经过LLM的处理,最终响应用户输入。


Share this post:

Previous Post
Stanford STORM 方法:五分钟深度研究指南
Next Post
循环工程师:智能体时代的新机遇