中断控制流消息误入steer队列问题修改 - #104
Open
openjiuwen-sync-bot[bot] wants to merge 2 commits into
Open
Conversation
|
guoyangsen seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
head_sha:
|
|
head_sha:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Paired: GitHub #104 ↔ GitCode !233
中断控制流消息误入 Steering 队列修复
一、问题描述
在
DeepAgent -> ReActAgent的嵌套调用场景中,当底层 ReActAgent 因工具调用需要用户补充输入而产生中断时,结构化中断信息会被额外转换成 steering 文本,并在下一轮 LLM 请求中作为用户消息注入模型上下文。develop 分支中的实际脏消息形态为:
正常情况下,
InteractionOutput应作为结构化交互状态向上传递,供客户端展示以及后续恢复使用,不应被转换成用户 steering 指令。实际现象是:
这条额外消息没有业务含义,可能污染模型上下文、干扰模型判断,并增加不必要的 token 消耗。
二、正确语义
当前
TASK_INTERACTION中可能包含两类内容:develop 当前存在两种结构化中断表示:
或者:
两类数据虽然都经过
handleTaskInteraction(),但不能执行相同的文本转换和入队逻辑。三、问题产生链路
内部流式中断的完整路径如下:
除内部流式
__interaction__外,ReActAgent 的最终中断结果还会通过以下结构生成TASK_INTERACTION:该结构同样会被
frameText()转成字符串并进入 steering 队列,因此需要同时覆盖两种中断标识。四、根因分析
根因位于
TaskLoopEventHandler.handleTaskInteraction():原实现默认把TASK_INTERACTION的第一个 frame 全部当作可注入模型的 steering 文本处理。原逻辑为:
frameText()对JsonDataFrame的处理是:该逻辑只判断 frame 是否可以转换为非空文本,没有判断它属于显式 steering 还是结构化 interrupt。因此,带有
type=__interaction__或result_type=interrupt的控制流数据也会被字符串化并入队。develop 中的
InteractionOutput已实现toString(),所以脏消息内容比早期版本更易读,但这并没有改变问题本质:内部中断状态仍被伪装成用户指令注入模型。五、修复原则
本次修复遵循以下原则:
结构化控制信息不进入 steering 队列
type=__interaction__或result_type=interrupt的 frame 不执行文本转换和 steering 入队。正常显式文本 interaction 保持原有行为
DeepAgent.steer()发送的TextDataFrame仍按原逻辑写入 steering 队列。在 interaction 业务边界进行过滤
判断放在
handleTaskInteraction()中,不修改通用frameText()。frameText()还被 follow-up 和 completion 路径使用,在其中加入中断语义会影响无关逻辑。依据协议字段判断,不依赖具体 payload 类型
使用
type和result_type识别结构化中断,避免只对InteractionOutput生效而遗漏其他中断载荷形式。保持修改范围最小
不修改事件结构、中断状态结构、恢复协议、steering 队列和通用 frame 文本转换规则。
六、具体代码修改
在
TaskLoopEventHandler.handleTaskInteraction()中,先判断第一个 frame 是否为结构化中断,再决定是否执行frameText():新增结构化中断识别函数:
处理结果如下:
type=__interaction__result_type=interruptTextDataFrameJsonDataFrame七、为什么不采用其他处理方式
1. 不修改 InteractionOutput.toString()
develop 中
InteractionOutput已经实现了可读的toString()。修改其输出形式只能改变脏消息的显示内容,不能阻止控制信息进入 steering 队列。2. 不删除 handleTaskInteraction() 的全部 steering 逻辑
当前
DeepAgent.steer()在 task-loop 运行期间会发送包含TextDataFrame的TaskInteractionEvent。完全禁止TASK_INTERACTION入 steering 会破坏正常的显式追加指令场景。3. 不修改通用 frameText()
frameText()同时用于:将 interrupt 判断加入通用转换函数会把 task interaction 的控制语义扩散到 follow-up 和 completion,扩大修改影响范围。
4. 不仅判断 payload 是否为 InteractionOutput
中断既可能以
type=__interaction__形式出现,也可能以result_type=interrupt的最终结果形式出现。依据协议字段判断可以覆盖两条实际链路。八、测试覆盖
在
TaskLoopEventHandlerTest中新增两个回归测试:1. structuredInteractionShouldNotEnterSteering
构造:
验证:
msg为空;2. interruptResultShouldNotEnterSteering
构造:
验证:
message字段,也不会被当作 steering;原有
handleTaskInteraction()测试继续验证:TextDataFrame("change plan")正常进入 steering 队列;执行命令:
mvn test \ -Dtest=TaskLoopEventHandlerTest,TaskLoopEventExecutorPythonParityTest,TaskLoopPackageTest验证结果:
测试完全使用 agent-core-java 内部对象,不依赖 yoskills、jiuwen-test、Redis、MCP 或其他外部服务。
九、影响范围与边界
本次修改涉及两个文件:
修改边界如下:
TASK_INTERACTION事件结构;InteractionOutput数据结构及序列化行为;修复后,结构化 interrupt 仍按原链路向上传递和恢复,但不会再生成多余的
[STEERING]用户消息。What type of PR is this?
/kind bug
Self-checklist:(请自检,在[ ]内打上x,我们将检视你的完成情况,否则会导致pr无法合入)