最近在试着用LangChain做一个能查天气、设提醒、发邮件的个人助理Agent,但工具调用老是出幺蛾子。比如用户说“明天下午提醒我带伞”,它有时会莫名其妙去调天气API(明明没问天气),有时又把提醒设成“带伞”这种无效内容。我试过调高temperature、加few-shot示例,还是偶尔抽风。是不是我tool的描述写太简单了?还是需要加个中间校验步骤?求有经验的大佬指点下通用的调参或Prompt设计思路,感谢!
用LangChain搭Agent时,工具调用总是“幻觉”乱选,怎么调教?
全部回复
共 154 条tool描述确实很关键,别只写“查天气”,要写清楚什么时候该用、什么时候不该用,比如“仅当用户明确询问天气状况时调用”。另外提醒带伞这种其实算条件触发,可以考虑拆成两步:先解析意图,再决定调哪个工具。temperature调高反而容易乱选,建议降到0附近试试。
工具描述得写清楚输入输出,光靠few-shot不够。我一般加个路由层先判断意图再分发,能少很多乱调。
工具描述真的太关键了,别只写“查天气”这种模糊的,要把参数格式、触发条件、返回啥都写清楚,模型才能分辨该不该调。temperature调高反而更容易乱选,建议降到0或者0.1试试。另外提醒场景可以在prompt里加个判断步骤,先让模型输出“需要调用哪个工具、参数是什么”,再执行,能拦掉不少幻觉。
工具描述这块确实值得好好抠一抠,我之前也踩过类似的坑。LangChain在选工具的时候其实很依赖你给的name和description做语义匹配,“查天气”和“提醒带伞”在语义空间里离得太近了,模型很容易把带伞这个动作关联到天气上去。我的做法是把tool的description写得更“排他”一点,比如天气工具明确写“仅当用户询问温度、降水、风力等气象信息时调用”,提醒工具就写“用于创建定时通知,不涉及任何信息查询”,边界划清楚会好很多。另外提醒内容变成“带伞”这种无效值,大概率是参数抽取那步没约束好,你可以在tool的args_schema里把content字段描述成“需要包含完整动作和时间信息的自然语言”,再配合Pydantic做校验,不合格就让它重新生成。few-shot我建议别只给正例,故意放一两个“用户说提醒但错误调用了天气”的反例,模型对负样本其实挺敏感的。还有个思路是别让Agent一步到位,先让它输出一个intent判断,再走对应的工具链,多一次LLM调用但稳定性提升很明显。temperature调高反而会让工具选择更随机,这个场景我一般压到0.1以下甚至0。
有没有更详细的教程推荐?
工具选择幻觉这事儿我也踩过不少坑,感觉根子还是在tool的描述和命名上。你试试把每个tool的description写成一段小说明书,不光说它能干嘛,还要明确说清什么时候不该用它,比如天气API就加一句“仅当用户明确询问天气状况时调用”。另外提醒类的tool可以把参数schema卡死,比如content字段加个正则或者枚举约束,别让它自由发挥成“带伞”这种半截话。temperature调高其实反而容易让它乱选,我一般会降到0.1到0.3之间,再配合结构化输出强制它先输出thought再输出action。few-shot示例确实有用,但例子要覆盖那些容易混淆的边界case,比如“提醒我带伞”和“明天天气怎么样”放一起对比。还有个歪招是在prompt里加个自检环节,让它选完tool之后自己复述一遍“我选这个是因为用户说了X”,不对就重来。不过最稳的还是加一层轻量规则校验,比如提醒类必须包含时间+动作,不满足就直接打回去让它重新生成。
工具描述真的太关键了,别只写“查天气”,得写清楚什么时候该用、什么时候不该用,比如“仅当用户明确询问天气状况时调用”。temperature调高反而更容易乱选,这步我觉得你方向反了,应该往低调甚至设成0。幻觉选错工具往往是模型没搞清楚意图边界,加个轻量级的意图分类前置步骤会稳很多。另外提醒内容这种参数抽取,可以在tool里加个格式校验,把无效输入直接打回去让它重试。
tool描述真的很关键,别写“查天气”这种模糊的,要写清楚什么时候该用、什么时候不该用。我上次把参数说明写细之后,误调用少了一大半。另外“明天下午”这种相对时间最好在prompt里先让模型转成具体时间再传工具,不然它容易自己脑补。温度调高反而更容易乱选,我一般调到0到0.2之间。
tool描述真的别写太笼统,像“查天气”这种得把触发条件写清楚,比如“仅当用户明确询问温度、降雨、风力时调用”,不然模型看到“带伞”就容易联想过去。另外提醒类工具最好加个参数校验,把时间和内容拆成两个字段,让它没法把“带伞”塞进时间槽里。我之前也遇到过类似情况,后来在prompt里加了一句“先判断意图再选工具,不确定就反问用户”,幻觉少了很多。
工具描述确实得写细点,光写“查天气”太笼统了,得把参数格式、触发场景都塞进去,比如“仅当用户明确问温度或天气时调用”。另外建议在Agent外面套个校验层,拿模型输出的意图跟用户原话做下匹配,对不上就重试或者反问确认,比硬调temperature管用。temperature调高反而更容易乱选,我一般调到0.1左右做工具调用。还有个坑是few-shot例子别放太多,容易让模型死记硬背反而忽略当前上下文。
有没有更详细的教程推荐?
工具描述写清楚输入输出格式很关键,再加个参数校验层能挡掉不少乱调。
tool描述确实得写细点,把参数格式和适用场景都塞进去,比调temperature管用多了。
tool描述得写清楚适用场景和边界,再加个前置意图分类小模型过滤一下,基本就不乱调了。