![[Bug]: FunctionAgent.structured_output_fn is ignored when executed via AgentWorkflow](https://www.chat-gpts.plus/wp-content/uploads/2026/07/22159-28b261ee.jpg)
[Bug]: FunctionAgent.structured_output_fn is ignored when executed via AgentWorkflow
快速结论:该问题发生在将 FunctionAgent 放入 AgentWorkflow 中运行时——虽已在 FunctionAgent 上设置了 structured_output_fn 回调,但 AgentWorkflow 的完成处理中仅检查了自身(workflow 级别)的 structured_output_fn,忽略了 agent 级别的回调。优先排查是否在 workflow 运行代码中误用了 workflow.run(),且未手动将回调传递到 workflow。
问题场景
用户通过 FunctionAgent 设置 structured_output_fn 回调,并期望在 agent 执行完毕后自动触发。在直接调用 agent.run() 时行为正常;但当该 agent 被放入 AgentWorkflow 并用 workflow.run() 驱动时,回调从未被调用。如果回调附加到 workflow 实例上(即 AgentWorkflow 的 structured_output_fn 参数),则运行正常。这是一个 API 承诺与实际行为不一致的问题。
报错原文
# 无显式报错,但 structured_output_fn 回调未触发
# 在 AgentWorkflow 中 agent 完成后,回调函数 print("Structured output callback invoked") 未被打印
# 而在 agent.run() 下正常打印
原因分析
在 AgentWorkflow 的完成处理代码(multi_agent_workflow.py)中,当 agent 产生无工具调用(即 agent 已结束)时,流程仅检查 self.structured_output_fn(即 workflow 级别的回调),从未检查 agent.structured_output_fn。尽管 FunctionAgent 的 structured_output_fn 是 base_agent.py 中定义的模型字段(API 声称支持),但 workflow 路径直接忽略了它。
反观直接调用 agent.run() 时(base_agent.py 第 568 行附近),agent 自己的 structured_output_fn 会被正常调用,因此直接路径工作,但 workflow 路径不工作。
注意:以下解决方案在 Issue 中被认定为正确修复,但并未被最终合入(维护者通过关联线程处理了另一种修复方式)。请根据你的代码版本酌情参考。
环境排查
- 确认 LlamaIndex 版本是否为 0.14.22(Issue 报告的版本)
- 检查
FunctionAgent对象是否拥有structured_output_fn属性:hasattr(agent, 'structured_output_fn') - 确认
AgentWorkflow对象是否也设置了structured_output_fn——如果有,则 workflow 级别优先,是正常行为 - 确认
agent.run()单独调用时回调是否触发——用于区分是代码级 bug 还是环境配置问题
解决步骤
- 优先尝试:将
structured_output_fn直接传递给AgentWorkflow的构造函数:workflow = AgentWorkflow(agents=[agent], structured_output_fn=structured_output_fn)。这是 Issue 中的确认的 - 如果必须保持每个 agent 独立的回调,需要手动修改源码(或等待 LlamaIndex 更新)。在
multi_agent_workflow.py的完成处理(if not ev.tool_calls分支中)找到以下类似代码: - 将上述判断修改为“当 workflow 级别的
structured_output_fn未设置时,使用 agent 级别的作为回退”: - 注意:修改后需保留异常捕获和
AgentStreamStructuredOutput流事件写入(原代码中的ctx.write_event_to_stream)。 - 重新安装或手动替换修改后的文件,测试
workflow.run()逻辑。
# 在完成 agent 后,获取当前 agent 对象
agent = self.agents[ev.current_agent_name]
...
if self.structured_output_fn is not None:
output.structured_response = await self.structured_output_fn(messages)
effective_fn = self.structured_output_fn or agent.structured_output_fn
if effective_fn is not None:
if inspect.iscoroutinefunction(effective_fn):
output.structured_response = await effective_fn(messages)
else:
output.structured_response = cast(Dict[str, Any], effective_fn(messages))
验证方法
- 运行复现脚本:设置
print("Structured output callback invoked")在回调中,通过workflow.run()提交一条简单消息(如 “My name is Charlie”),确认控制台输出了该日志 - 同时确保当 workflow 级别也设置了
structured_output_fn时,workflow 级别回调仍然优先触发,且 agent 级别回调未被调用(回归测试) - 单独使用
agent.run()运行同一 agent,确认回调仍然正常触发

![[Bug]: HEadroom guardrail compress nothing](https://www.chat-gpts.plus/wp-content/uploads/2026/07/31969-93ddb3e2-768x403.jpg)
![[Bug]: guardrail_information is null on successful requests with headroom-compression guardrail (default_on=true)](https://www.chat-gpts.plus/wp-content/uploads/2026/07/32008-51ced23e-768x403.jpg)
![[OpenAI] 昨天服务器中了挖矿病毒, cpu100% 下不去,最后让 codex 远程 ssh 上去硬刚!](https://www.chat-gpts.plus/wp-content/uploads/2026/07/ai_cover_5-114-768x403.jpg)