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

在运行时更新角色动作

在会话中发送动作配置补丁,跟踪其更新 ID,并在确认后端已确认之前,不要假定更改已生效。

使用 ConvaiActionConfigPatch ,参数为 ConvaiCharacter.DynamicContext.Apply 用于替换已连接角色的动作、对象、角色或注意力目标,而无需断开会话。当连接后场景状态发生变化——出现新对象、目标变得不可用——且角色的可交互能力需要及时跟上时使用。只有在 Convai 对其更新 ID 返回成功确认后,此补丁才会生效。

前提条件

  • A ConvaiCharacter 已连接(IsInConversation 返回 true).

  • 本地 ConvaiActionDefinition 补丁添加的任何动作名称都已存在本地注册条目——被补丁化的动作名称必须与可在本地执行的定义匹配,否则整个更新会在发送前被拒绝。

  • 熟悉 配置角色动作.

发送运行时动作补丁

1

构建补丁

只设置你想更改的字段。 ConvaiActionConfigPatch 使用省略与空值语义:一个 null 字段会保留已确认的值,空列表或空字符串会清空它,而非空值会替换它。

using System.Collections.Generic;
using Convai.Shared.Actions;

var patch = new ConvaiActionConfigPatch
{
    Objects = new List<ConvaiActionObjectDefinition>
    {
        new()
        {
            Name = "Lever",
            Description = "Metal wall lever.",
            GameObjectReference = leverGameObject
        }
    }
};

字段

null (已省略)

空列表或字符串

非空值

动作

保留已确认的动作列表

清除请求级动作

替换已确认的动作列表

对象

保留已确认的对象

清除已确认的对象

替换已确认的对象。同名替换会继承现有的本地 GameObjectReference 当新条目未设置时

角色

保留已确认的角色

清除已确认的角色

替换已确认的角色

当前注意对象

保留注意力目标

清除注意力目标

设置注意力目标。必须与中的名称匹配 对象 在替换应用后

替换 对象 如果该目标不再存在,会自动清除失效的注意力目标。

2

发送补丁

将补丁传递给 DynamicContext.Apply 使用显式的 updateId ,以便你可以将其与后端确认对应起来:

using Convai.Runtime;
using Convai.Runtime.DynamicContext;

character.DynamicContext.Apply(new ConvaiDynamicContextUpdate(
    text: null,
    reaction: ConvaiRespondMode.Silent,
    currentAttentionObject: "Lever",
    updateId: "lever-unlock-01",
    actionConfig: patch));

跟踪更新 ID

提供你自己的 updateIdConvaiDynamicContextUpdate 而不是依赖 SDK 自动生成的 ID。当 updateId 被省略时,SDK 会生成一个内部 ID 用于跟踪,但不会返回给调用方,因此你无法将其与之后的确认对应起来。

一个 updateId 一次只能有一个待处理的运行时动作变更。发送第二个带有一个 updateId 仍在等待确认的补丁会在本地被拒绝并给出控制台警告;请等待第一个更新完成,或使用不同的 updateId.

读取后端确认

订阅 ConvaiManager.ActiveManager.Events.OnDynamicContextUpdateResultReceived 并按以下内容筛选 updateId 你发送的:

using Convai.Domain.DomainEvents.Runtime;
using Convai.Runtime.Components;

ConvaiManager.ActiveManager.Events.OnDynamicContextUpdateResultReceived += result =>
{
    if (result.UpdateId != "lever-unlock-01")
        return;

    if (result.Status == "success")
    {
        Debug.Log($"已确认动作:objects={result.ObjectsCount}, attention={result.CurrentAttentionObject}");
    }
    else
    {
        Debug.LogWarning($"动作补丁失败:{result.Status}");
    }
};

DynamicContextUpdateResultReceived 除了通用的动态上下文字段之外,还携带该动作更新的类型化元数据:

属性
类型
含义

UpdateId

string

你在 ConvaiDynamicContextUpdate.

状态

string

"success" 当补丁被应用时;任何其他值都表示它被拒绝。

ActionConfigUpdated

bool?

此确认是否包含动作配置更改。

ActionConfigCreated

bool?

后端是否为该会话创建了新的动作配置。

ActionsCount, ObjectsCount, CharactersCount

int?

补丁后,已确认配置中的最终数量。

当前注意对象

string

补丁后的最终注意力对象。

CurrentAttentionObjectCleared

bool?

此更新是否清除了注意力目标。

ActionGenerationStrategyChanged

bool?

后端的动作生成策略是否发生了变化。

ActionGenerationStrategyStatus

string

策略变更的状态字符串,包括 "requires_reconnect".

原始 Extras

JObject

尚未以类型化属性暴露的字段的后端原始负载。

ActionGenerationStrategyStatus"requires_reconnect",SDK 会显示该状态,但不会自动重新连接——如果新策略需要重新连接,请你自行重新连接会话。

若要在代码中发送之前预览补丁的预测结果,请使用 Action Debug 窗口中描述的运行时补丁编辑器,详见 排查角色动作问题.

故障排除

补丁在发送前被拒绝

症状: 控制台警告会指出该字段,例如 action_config 动作 '...' 没有本地可执行定义重复的动作目标名称 '...'.

原因: 该补丁已在本地验证但失败——某个动作名称没有匹配的本地 ConvaiActionDefinition,某个目标名称为空或重复,或者当前注意力对象无法与补丁中的对象对应。

修复: 更正警告中指出的字段,并使用新的 updateId.

验证: 控制台没有显示任何拒绝警告,而且 OnDynamicContextUpdateResultReceived 随后会为同一个 updateId.

从未收到任何确认

症状: OnDynamicContextUpdateResultReceived 从未为 updateId 你发送的内容触发,并且 ConvaiCharacter.ActionConfig 从不反映该补丁。

原因: 该更新在 30 秒确认超时、ACK 错误或格式错误/不匹配的确认元数据后被丢弃——控制台会记录 Runtime action mutation discarded update_id=<id> reason=<reasonCode> 在这些情况下。若在 Convai 响应之前会话断开,也会丢弃该更新,但不会有任何控制台消息。被丢弃的更新不会自动重试。

修复: 使用新的 ID 重新发送补丁 updateId 一旦角色确认已连接(IsInConversationtrue).

验证: OnDynamicContextUpdateResultReceived 触发时带有 Status == "success" 用于新的 updateId.

下一步

注意力与引用锚定排查角色动作问题

最后更新于

这有帮助吗?