fix(adk): improve instruction formatting error handling#688
fix(adk): improve instruction formatting error handling#688shentongmartin merged 1 commit intomainfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #688 +/- ##
==========================================
+ Coverage 81.71% 81.98% +0.27%
==========================================
Files 129 132 +3
Lines 12423 12952 +529
==========================================
+ Hits 10151 10619 +468
- Misses 1516 1562 +46
- Partials 756 771 +15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
这里是否只是 adk 模块的配置, 如果我使用 adk 和 compose 或者 手写 template , 等多种组合; 有没有办法一处配置多处默认使用全局设置. |
@timandy “默认使用全局设置”,是指全局的一个 instruction,还是指全局的一个 DisableDefaultTemplateFormatting 配置。 |
ec65a64 to
65fc1cf
Compare
@shentongmartin 我指的全局的 FormatType , 例如 全局使用 schema.Jinja2 或 FString; 因为当前业务开发, 输入输出大概率包含 json, 而 FString 对 json 不太友好, 建议默认设置为 Jinja2, 包括 cozeLoop 网站的 prompt 都使用 Jinja2 进行格式化
总结起来就是有两个级别, 一个是 实例级别的FormatType 设置, 这个优先级最高; 第二个是 全局的 FormatType, 这个优先级低; |
|
我现在为了使用 Jinja2 格式化方式, 非常的繁琐: //1. 先定义一个函数 copy 自 defaultGenModelInput
func GenModelInput(ctx context.Context, instruction string, input *adk.AgentInput) ([]adk.Message, error) {
msgs := make([]adk.Message, 0, len(input.Messages)+1)
if instruction != "" {
sp := schema.SystemMessage(instruction)
vs := adk.GetSessionValues(ctx)
if len(vs) > 0 {
ct := prompt.FromMessages(schema.Jinja2, sp) //只改了这里
ms, err := ct.Format(ctx, vs)
if err != nil {
return nil, err
}
sp = ms[0]
}
msgs = append(msgs, sp)
}
msgs = append(msgs, input.Messages...)
return msgs, nil
}
//2. 指定 GenModelInput, 而且每个 Agent 都要指定一次 GenModelInput, 漏了就容易炸;
// 希望不指定 GenModelInput 的请款下, 默认的 defaultGenModelInput 优先使用 Agent 自身的 FormatType(待增加),
// 如果FormatType也未指定, 则使用全局的 FormatType
agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "courseware_extractor",
Description: "从教学课件提取内容, 并匹配数据库中的字典信息",
Instruction: utils.GetPrompt("teach_element.extract.system"),
Model: chatModel,
GenModelInput: GenModelInput, //每次都要指定
})
//构建消息的时候每次都要带 这个格式参数 FormatType
//希望能增加一个FromMessages 的重载函数, 减少这个参数, 默认使用全局的FormatType .
template := prompt.FromMessages( schema.Jinja2, //每次都要指定
&schema.Message{
Role: schema.User,
Content: "请根据以上规则,对我提供的文档内容进行分析,并返回符合要求的 JSON 结果。",
UserInputMultiContent: []schema.MessageInputPart{
utils.CreateMessagePartText("请根据以上规则,对我提供的文档内容进行分析,并返回符合要求的 JSON 结果。"),
utils.CreateMessagePartFileAuto(path),
},
}) |
|
是的 默认jinjia2 会比较好?prompt里面带 {} 代码示例就不work |
|
我怎么感觉这个被拒绝的方案使用起来更简单呢: 与自定义 GenModelInput 功能重叠 (一个是简单api, 一个是深层定制) |
dfcd2d9 to
8171279
Compare
de783bf to
18b8c00
Compare
1b81064 to
0b9d7cb
Compare
Change-Id: I31a1f38c02378ac46624b39d90749a2630409472
0b9d7cb to
2a3d177
Compare
Instruction 格式化问题修复
问题
defaultGenModelInput在 SessionValues 存在时会静默应用 FString 格式化,导致包含 JSON 的 Instruction 解析失败。具体场景:
期望:Instruction 原样传递给模型
实际:FString 尝试解析
{name}和{value}作为变量,失败并报错问题根源:
这个设计假设 SessionValues 的唯一用途是 Instruction 格式化,但实际上用户可能:
DeepAgent 的额外问题:
DeepAgent 封装了
ChatModelAgent,但没有暴露GenModelInput配置,导致用户无法绕过默认行为。同样,Handlers配置也未暴露,用户无法通过BeforeAgent自定义格式化逻辑。解决方案
1. 改进错误信息
在 defaultGenModelInput 中,将原本的通用错误信息改为详细说明:
关键洞察:错误信息应该解释"为什么会发生"和"如何解决",而不仅仅是"发生了什么"。
2. DeepAgent 新增 DisableDefaultInstructionFormatting 配置
在 Config 中新增配置项:
实现方式:提供一个不做格式化的 genModelInputWithoutFormatting:
3. DeepAgent 新增 Handlers 配置
在 Config 中暴露 Handlers:
这允许用户通过
BeforeAgent实现自定义格式化逻辑。决策记录
考虑过的方案:添加 InstructionFormatType 配置
拒绝原因:
GenModelInput功能重叠InstructionFormatType和GenModelInput,行为不明确最终选择:
DisableDefaultInstructionFormatting是一个简单的开关,语义明确:false(默认):使用默认的 FString 格式化true:禁用默认格式化,Instruction 原样传递为什么同时暴露 Handlers
DisableDefaultInstructionFormatting只能禁用格式化,但用户可能需要自定义格式化逻辑(如使用 Go template 或其他模板引擎)。通过暴露Handlers,用户可以在BeforeAgent中实现任意格式化:总结
DisableDefaultInstructionFormatting配置Handlers配置,支持BeforeAgent自定义逻辑solves: #685
solves: #677