最近在试着用LangChain做一个能查天气、设提醒、发邮件的个人助理Agent,但工具调用老是出幺蛾子。比如用户说“明天下午提醒我带伞”,它有时会莫名其妙去调天气API(明明没问天气),有时又把提醒设成“带伞”这种无效内容。我试过调高temperature、加few-shot示例,还是偶尔抽风。是不是我tool的描述写太简单了?还是需要加个中间校验步骤?求有经验的大佬指点下通用的调参或Prompt设计思路,感谢!
用LangChain搭Agent时,工具调用总是“幻觉”乱选,怎么调教?
全部回复
共 144 条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。