Context 模块设计¶
Context 模块负责记录一次 Agent 运行中的问题、工具调用、中间状态和数据对象之间的依赖关系。它主要服务于内部节点调度、轨迹复盘和调试,同时为跨轮次对话提供历史恢复能力。
1. 设计要点¶
1.1 实例隔离而非全局单例¶
Context 不是全局单例,而是按"用户 + 会话 + 运行轮次 + 子 Agent"四元组进行实例管理。同一四元组在进程内只存在一个实例,不同 Agent(主 Agent 与子 Agent)各自持有独立的轨迹记录。实例的创建和获取通过工厂模式实现,内部保证线程安全。
1.2 轨迹图模型¶
轨迹使用有向无环图表示:
- 节点:分为计算类节点和数据类节点两大类。计算类节点包括用户问题、Agent 推理结论、工具调用动作;数据类节点包括知识片段、工具定义、数据表、数据列、文件、脚本、技能包等各类中间产物。共支持十种节点类型。
- 边:表示节点间的关系。主要包括触发关系(问题或结论触发动作)、产出关系(动作产出结论或数据),以及跨轮次的延续关系。边的类型可由调用方显式指定,也可由系统根据前驱节点类型和当前节点类型自动推断。
- 活跃分支指针:维护当前轨迹的端点集合,用于标识后续规划和调试关注的位置。当新节点加入时可选择推进指针(向前移动)或仅追加分支。
1.3 跨轮次轨迹桥接¶
同一会话中的多次 Agent 运行可通过桥接边串联成完整轨迹:
- 从数据库或本地文件恢复历史轮次的轨迹图。
- 在相邻轮次之间,将上一轮的叶子节点(出度为零的节点)连接到下一轮的起始查询节点,边类型标记为"延续"。
- 当前轮次注册新查询时,自动桥接到最近一次历史轮次的尾部。
- 最终形成以会话首次查询为根、贯穿所有轮次的统一有向无环图。
1.4 中间表示与自动画像¶
每个轨迹节点都对应一份结构化的中间表示数据,包含标识、描述、归属信息、创建时间和历史版本记录。
数据类节点具备自动画像能力:系统可异步调用大模型,根据节点的前驱动作和结论上下文,自动推断并生成节点的自然语言描述。该过程不阻塞主流程,画像任务在后台执行,最终在流式输出结束前统一等待完成。
节点属性的修改会触发版本记录——每次修改前,当前值会存入历史版本字典,保证轨迹的回溯和审计能力。
1.5 工作流队列¶
模块内置三个队列用于管理 Agent 执行过程中的工作流节点:
- 前置队列:从 Agent 配置中加载,在运行启动时初始化,定义进入主循环前必须完成的步骤。
- 待办队列:运行过程中动态添加和消费的步骤,是主循环的核心驱动力。
- 后置队列:从 Agent 配置中加载,定义主循环结束后需要执行的收尾步骤。
每个队列有容量上限,防止无限增长。队列采用先进先出顺序消费。
1.6 消息存储与上下文格式化¶
- 支持标准对话消息类型(用户消息、助手消息、工具返回消息、系统消息)的持久化与恢复,采用统一的序列化格式。
- 提供消息清洗能力:自动过滤系统消息、移除孤儿的工具调用记录(助手声明了工具调用但缺少对应工具返回结果的配对),保证重放安全且不污染上下文窗口。
- 提供上下文格式化能力:将消息列表转换为紧凑可读的文本块,展示时跳过初始用户查询,对工具调用参数进行精简(仅保留名称和参数,丢弃内部标识等冗余字段),降低后续推理的上下文长度压力。
2. 持久化策略¶
模块支持双通道持久化:
- 本地文件:每个轮次生成两份文件——完整轨迹图(包含节点和边)和轻量元数据(包含当前轮次的起始节点标识和活跃分支端点集合),存储在会话根目录下。
- 关系型数据库:所有节点类型均有对应的数据库表,边关系也有独立存储表,支持按用户、会话、轮次、子 Agent 维度查询和恢复。首次使用时自动建库建表。适用于需要跨会话长期保留轨迹的场景。
写入时仅持久化当前轮次自身的节点和边。跨轮次桥接边和历史轮次节点不在持久化范围内——它们不属于当前轮次的数据,在下次加载时由恢复逻辑重新构建。
3. 与运行时关系¶
Agent 运行时会在状态中携带上下文标识信息,通过工厂接口获取对应的 Context 实例。普通用户通过 SDK 入口发起对话即可,无需手动管理上下文。
典型运行链路:
- 用户通过 SDK 入口发起对话。
- 运行时为本轮请求准备状态和上下文标识。
- 若属于同一会话的后续轮次,自动从持久化存储中恢复历史轨迹并桥接到当前查询。
- 规划、执行等内部节点在运行中写入消息、工具调用和轨迹信息。
- 运行结束时,当前轮次的轨迹和消息持久化到配置的存储后端。
- 最终状态返回给用户,包含消息和统计信息。
4. 使用边界¶
- 普通使用场景下,通过 SDK 提供的对话接口获取结果即可,无需直接操作 Context。
- 二次开发内部节点时,可通过 Context 记录可复盘轨迹:注册查询起点、注册中间节点(指定前驱和边类型)、修改节点属性、推进活跃分支指针。
- 可获取轨迹图进行可视化导出或裁剪(仅保留活跃分支路径)。
- 不建议外部代码直接修改轨迹图结构,除非明确知道节点类型和边关系的语义约束。
- Context 内部的异步任务会在流式输出结束时统一等待完成,调用方无需手动管理。