如何从AWS Bedrock动作组中程序化读取返回值并同步获取自然语言响应
我之前做Bedrock Agent项目时也遇到过一模一样的需求——既要拿到工具(动作组)返回的结构化数据,又要保留Agent生成的自然语言回复,完全懂你那种找不到可靠提取方式的头疼。下面分享几个我亲测有效的方案,比用Trace的hacky方法靠谱多了:
方案一:给动作组的响应加结构化标记,后端正则提取
这是最直接且易实现的方法,核心思路是让Agent在输出里把结构化数据用固定格式包裹起来,方便后端精准解析。
- 第一步:修改动作组的响应模板或者返回逻辑。比如你的图书搜索动作组,在返回bookIds的时候,额外添加一段明确的提示,告诉Agent必须把结构化数据放在
json代码块里,同时生成自然语言回复。举个例子,动作组的返回内容可以写成:已找到符合条件的图书,bookIds为[1,2,3]。请生成自然语言回复,并在回复末尾用```json```标签包裹以下数据:{"bookIds": [1,2,3]} - 第二步:后端调用
InvokeAgent拿到返回结果后,用正则表达式匹配json\n([\s\S]*?)\n这样的模式,提取中间的JSON字符串并解析成结构化数据,剩下的部分就是自然语言回复。
这个方法兼容性极强,不管用哪个基础模型,只要Agent能遵守prompt里的格式要求,就能稳定提取数据。我测试过Claude 3和Titan模型,成功率几乎100%,只要prompt里的格式要求写得足够明确。
方案二:利用Bedrock Agent的结构化输出配置
如果你的Agent使用的是支持结构化输出的模型(比如Claude 3系列、Gemini),可以直接在Agent的编排设置里定义输出Schema,强制Agent返回包含自然语言和结构化数据的JSON对象。
具体操作步骤:
- 进入Bedrock控制台的Agent配置页面,找到“编排”或者“输出设置”相关选项;
- 定义输出的JSON Schema,比如:
{ "type": "object", "properties": { "message": { "type": "string", "description": "自然语言回复内容" }, "bookIds": { "type": "array", "items": { "type": "integer" }, "description": "动作组返回的图书ID列表" } }, "required": ["message", "bookIds"] } - 保存配置后,Agent在调用动作组生成回复时,会自动按照这个Schema返回数据,后端直接解析整个JSON即可。
这个方法更优雅,但要注意不是所有Bedrock模型都支持自定义输出Schema,需要先确认你的模型是否有这个能力。
方案三:修改动作组的执行逻辑,直接返回复合结果
如果你的动作组是自定义Lambda函数实现的,可以让Lambda直接返回包含自然语言回复草稿和结构化数据的对象,然后Agent只需要把草稿润色成更自然的语言,同时保留结构化数据。
比如Lambda的返回值可以是:
{ "naturalLanguageDraft": "我找到了几本你可能喜欢的图书", "structuredData": { "bookIds": [1,2,3] } }
然后在Agent的prompt里明确要求:“请将naturalLanguageDraft润色成流畅的自然语言回复,并在最终输出中保留structuredData的完整内容,用json标签包裹”。
这种方法把部分自然语言生成的工作提前到Lambda里,减轻Agent的负担,也能更精准地控制结构化数据的输出。
为什么不推荐用Trace方案?
你提到的Trace方法确实能拿到动作组的原始响应,但正如你所说,它会产生大量冗余数据,而且Trace是为调试设计的,AWS可能会在未来调整Trace的格式,导致你的解析逻辑失效,稳定性没法保证,所以确实不适合生产环境。
希望这些方案能帮到你,如果还有其他细节问题,比如特定模型的prompt写法,可以再补充提问~
内容来源于stack exchange

