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

同步行为与时序

了解动态上下文负载如何在防抖后刷新、离线排队如何工作,以及何时立即刷新会绕过批处理。

动态上下文更新不会在每次 Blueprint 调用时都发送到 Convai。默认情况下,插件会短暂等待,使快速变化合并为一次发送。本页说明何时会刷新、每次刷新包含什么,以及何时绕过防抖计时器。

何时发送更新

情况
发生什么

连接时的默认防抖调用

更新会先在本地暂存;一次 替换 context-update 会在 ContextDebounceWindow (默认 0.5 秒)内没有新更新时发送

快速突发的更新

突发中的所有更改会合并为一次刷新;计时器会在每次调用时重置,但不会超过 ContextMaxDebounceWindow (默认 3.0 秒)自首次更新起

bFlushImmediately = true 在连接后

FlushDynamicContext() 会在当前帧运行,绕过防抖

会话连接前的更新

更改会累积到 PendingContextBatch;首次刷新会在连接后和防抖截止时间到达时发生

重置动态上下文

先清空暂存内容,然后发送一个 Reset context-update,随后清除本地跟踪器

传输消息形式

UConvaiSubsystem::UpdateContext 会发送一条 context-update 带有 JSON 数据负载的消息:

JSON 字段
值(线上格式)
何时出现

mode

append, replace, reset

每条消息都会出现

run_llm

"auto", "true", "false"

每条消息都会出现 — 映射自 EC_RunLLMOption (Auto, 始终, 从不)

文本

上下文字符串

Reset 文本为空时省略

current_attention_object

对象名称字符串

当注意对象被折叠进同一条消息时

Blueprint 枚举显示名称(Append, 替换, Reset, Auto, 始终, 从不)与上面的线上字符串不同。

刷新负载结构

每次包含暂存状态或事件的刷新都会构建一个文本负载:

{StateName} 是 {Value}
{AnotherState} 是 {Value}
事件文本第一行
{Key} 从 {OldValue} 更改为 {NewValue}
{NewKey} 是 {NewValue}

第一块是 规范上下文 —— 按插入顺序排列的状态("{Key} is {Value}" 每行一个),随后按时间顺序排列的事件。它由 FConvaiDynamicContextTracker::BuildCanonicalContext().

当批次的聚合 ShouldRespond 不是 从不 且存在状态增量行时,插件会将它们追加到 下一行 规范上下文之后(一个 \n 分隔符,而不是空白行)。增量行会在提示词末尾展示状态变化。

对于新值包含超过三个以空格分隔单词的状态更新,增量行会使用 "{Key} changed from {OldValue}" 而不重复较长的新值。

活动会话期间的场景

新状态 — 聚合 ShouldRespond从不

触发调用: 设置上下文状态设置上下文状态 使用一个之前从未设置过的键,并且批次中的每个暂存项都保持聚合 ShouldRespond从不.

新键会立即进入规范上下文。不会添加增量行。

新状态 — 聚合 ShouldRespondAuto始终

触发调用: 设置上下文状态设置上下文状态 使用一个新键,并且至少有一个暂存项会提升聚合 ShouldRespond 设为 Auto始终.

在这次刷新中,新键会 被排除 在规范上下文之外。会在规范块之后追加一条类似 Health 是 50 的增量行。

下一次刷新时,该键会正常进入规范上下文。

更新现有状态 — 聚合 ShouldRespond从不

触发调用: 设置上下文状态 使用一个已有的键,并且批次保持聚合 ShouldRespond从不.

更新后的值会进入规范上下文。不会添加增量行。

更新现有状态 — 聚合 ShouldRespondAuto始终

触发调用: 设置上下文状态 使用一个已有的键,并且至少有一个暂存项会提升聚合 ShouldRespond 设为 Auto始终.

更新后的值会进入规范上下文。会追加一条描述该变化的增量行。

一次更新多个状态

触发调用: 设置上下文状态 使用一个键值对映射,可能混合新键和已有键。

所有值都会写入跟踪器。当聚合不是 从不时,首次出现的延迟会按每个新键分别应用。所有更改共享一次刷新 — 一条 替换 context-update.

添加上下文事件

触发调用: 添加上下文事件.

事件文本会提交到跟踪器的事件列表,并出现在规范上下文中。常规上下文事件不会重复到单独的增量行中。

在同一个防抖窗口内多次暂存相同的事件字符串会被去重——这次刷新只保留第一次出现。

移除上下文状态

触发调用: 移除上下文状态.

该键会从跟踪器中移除。 bForceReplace 被设为开启,因此刷新会发送不包含已移除键的规范上下文。移除不会添加增量行。

动态上下文重置

触发调用: 重置动态上下文.

插件会先清空任何已暂存的上下文批次,然后发送一个 Reset context-update (模式:重置, run_llm: "false")且没有 文本Reset 负载字段。该本地跟踪器会在 Reset 消息之后被清除。

重置动态上下文 被调用时,已存在的排队触发器会立即清除。排队在一个待处理离线 Reset 之后的触发器仍可能在 Reset 期间 FlushDynamicContext().

当已连接时, 重置动态上下文 会立即走刷新路径。当离线时,重置标志会等待首次连接后的刷新。

会话前排队

默认的防抖变更调用 — 设置上下文状态, 设置上下文状态, 添加上下文事件, 移除上下文状态,和 重置动态上下文 — 会累积在 PendingContextBatch 中,同时 IsChatbotConnected()false.

TickDynamicContext() 会持续累积,直到会话连接。连接后,当到达防抖截止时间时, FlushDynamicContext() 会发送待处理批次。

离线更新会折叠为上文所述的刷新行为——不会作为一系列单独消息重放。连接后,在首次到达防抖截止时间的 tick 中,聚合 ShouldRespond 保持 从不 的批次会从跟踪器发送当前规范快照;聚合 Auto始终 的批次则遵循上文所述的规范加增量行为。任何待处理 Reset 会最后清除上下文。

如果 重置动态上下文 并且后续更新都处于离线待处理状态,则刷新会先发送暂存内容,然后 Reset 最后发送。

bFlushImmediately

每个变更函数 — 设置上下文状态, 设置上下文状态, 添加上下文事件, 移除上下文状态 — 都提供一个 高级 参数 bFlushImmediately。当 true, FlushDynamicContext() 在当前帧运行。

使用 bFlushImmediately 适用于时间敏感的更新,因为默认防抖延迟会造成可感知的滞后。每次立即调用都会在 FlushDynamicContext() 当前帧中运行并发送一个 context-update 当聊天机器人已连接且有可发送的暂存工作时。避免对持续变化的值在每个 tick 都调用它。

重置动态上下文 在连接时会立即走刷新路径。它没有 bFlushImmediately 参数。

下一步

排查动态上下文问题动态上下文 Blueprint 参考

最后更新于

这有帮助吗?