For the complete documentation index, see llms.txt. This page is also available as Markdown.

动态上下文如何工作

了解状态与事件模型、标准上下文格式,以及在对话前和对话中更新如何排队和刷新。

Dynamic Context 让角色能够实时、结构化地了解场景中正在发生什么。它不再只依赖在 Convai 仪表板上配置的静态系统提示,而是可以引用受训者当前所在位置、已收集的设备,或刚刚触发的警报——因为这些信息是在事件发生时直接注入到会话中的。本页解释其底层模型:原语是什么,SDK 如何将它们组装成规范化的上下文字符串,以及为什么在对话开始前更新会安全排队。

状态和事件

Dynamic Context 建立在两种原语类型之上。

状态 是持久化的、带名称的键值对。每个状态都有名称和值。当你设置一个状态时,该名称之前的任何值都会被替换。状态适合表示会随时间变化、但在任一时刻只有一个当前值的事实:操作员当前所在工位、某区域的危险等级,或某个检查项是否已完成。

事件 是按时间顺序记录的一次性发生事项。与状态不同,事件会按顺序累积,且永远不会被替换或去重。每次调用 AddEvent 都会向角色的上下文追加一行新内容。事件适合表示会话中发生过、且角色应当能够按顺序引用的事情:"受训者绕过了手动锁定程序"、"7 号工位触发了化学警报"。

这两种原语会同时馈入角色的感知。状态提供当前条件的稳定、可查询快照;事件提供已发生事项的时间顺序记录。

规范化上下文格式

当 SDK 向 Convai 发送更新时,它会基于所有已跟踪的状态和事件组装出一个规范化上下文字符串:

{StateName} 是 {Value}
{AnotherState} 是 {Value}
事件文本第一行
事件文本第二行

状态最先出现,按它们被 首次设置 的顺序排列——更新某个状态的值不会改变它的位置。所有状态之后,事件按调用顺序排列。

状态之所以在更新后仍保留插入顺序,是为了给角色提供一个稳定、可预测的世界视图。如果 工位 是最先设置的内容,无论其值改变了多少次,它始终会在角色上下文中排在第一位。这让模型更容易始终如一地解释上下文。

示例:

context.SetState("Station", "Bay 3");       // 位置 1
context.SetState("HazardLevel", "High");    // 位置 2
context.AddEvent("Operator bypassed interlock");
context.SetState("Station", "Bay 7");       // 更新值;位置保持为 1

所有四次调用后的规范化上下文:

你只需提供名称、值和事件文本。SDK 会自动组装并传递规范化字符串。

两种入口

Dynamic Context 有两个入口,它们写入同一个底层跟踪器,并产生相同的网络行为。

检查器 — ConvaiDynamicContextCommand

添加此 MonoBehaviour 到 NPC 的 GameObject 上,并在检查器中配置命令类型、字段和响应模式。调用 Execute()UnityEvent、触发器碰撞体、时间线标记或 UI 按钮中调用。无需编写脚本。一个组件封装一个命令;对于每个 NPC 的多个命令,请将每个命令放在一个子 GameObject 上。

当以下情况时使用此入口:

  • 上下文变化与已触发的场景事件 UnityEvent 回调

  • 非程序员需要配置或修改上下文触发器

  • 你想在不编写胶水代码的情况下快速原型验证

脚本 — IConvaiDynamicContext

访问 character.DynamicContext 以获取 IConvaiDynamicContext 接口,并直接从 C# 调用方法。这使你能够完全控制时机、批量处理和响应模式。

当以下情况时使用此入口:

  • 上下文更新取决于运行时逻辑或无法用静态 Inspector 字段表示的数据

  • 多个状态必须以原子方式更改(使用 SetStates)

  • 你需要读回状态值(TryGetStateValue)

  • 更新源是外部系统,例如状态机或分析流水线

对话前排队

在会话开始前所做的更新,会由所有已跟踪的方法自动排队—— SetState, SetStates, AddEvent, RemoveState,和 Reset。当会话连接时,SDK 会发送一条 Replace 消息,其中包含当时的完整规范化上下文。

这意味着你可以自由地从 AwakeStart 中设置初始上下文,而无需担心时机。SDK 会负责传递。

之所以会折叠为一次 Replace,而不是逐条重放单独消息,是出于效率:角色接收到的是一个权威快照,而不是一串可能乱序到达、或造成冗余 LLM 回合的增量更新流。

何时使用哪种命令类型

目标
使用

跟踪一个当前条件

SetState

跟踪多个在同一时刻变化的条件

SetStates (一次规范化重建,一次网络往返)

记录某事已经发生

AddEvent

移除一个不再适用的条件

RemoveState

清除所有运行时上下文(用于新的场景阶段)

Reset

发送外部构造的上下文文本

Apply() ——高级用法;不会排队

下一步

动态上下文快速开始命令组件参考同步行为与时机

最后更新于

这有帮助吗?