作者:京东物流 赵勇萍
前言
最近随着manus的火爆, 其实大家更关注AI-Agent的开发技术了.毕竟大模型是大脑, 而Ai-Agent才是给最强大脑重塑真身的那个莲藕. 而我也这多半年的时间里, 研究了很多AI-Agent框架. 而在AI-Agent开发中, 其实也发现了一些技巧,思路和架构思考. 比如, 我们如何更好的跟LLM进行交流? 如何可以更好的优化我们的prompt和token数量? 如何能让LLM更快的返回我们想要的思考结果? 基于这些问题,我们一点点的展开讨论。
一. 不要让“大块头”吓倒你:拆分才是王道
还记得我们第一次写代码的情景吗?那时候,我们可能会写出一个上百行的main
方法,恨不得把所有逻辑都塞进去。结果调试起来头昏脑涨,连自己都看不懂写的是什么。从那时起,我们就明白了一个道理:复杂的逻辑需要拆分成更小的部分。将代码分成多个方法、类和模块,不仅让代码更易读、易维护,也更容易调试和测试。
其实,在AI-Agent的开发中,这个原则同样适用,甚至更加重要。因为大模型的能力虽然强大,但如果我们不加以限制和合理利用,反而会适得其反。
很多人觉得,既然LLM(大型语言模型) 这么智能,那我就把所有可能的指令都塞进系统提示词里(System Prompt),让它自己处理所有情况。结果呢?模型懵了,该执行的不执行,不该执行的到处乱跑,输出的结果让人哭笑不得.
为什么会这样?
当我们在系统提示词中堆砌太多内容时,会出现以下问题:
1.信息过载:模型需要处理的信息量过大,可能会忽略其中一些指令。
2.指令冲突:不同指令之间可能存在矛盾,导致模型无法判断优先级。
3.上下文混乱:提示词过长,模型可能会混淆指令之间的关系,理解出现偏差。
4.令牌限制:过长的提示词会占用大量的令牌(Tokens),增加成本和响应时间。
想象一下,你在超市里拿着一长串购物清单,上面还有各种删改和备注,例如:
•牛奶(脱脂,如果没有就买全脂)
•鸡蛋(有机的,12个装,如果有促销买24个)
•面包(全麦,不要买白面包,除非打折)
是不是觉得头晕眼花?一不小心就可能买错。
模型也是一样的,当提示词过于繁杂时,它可能会:
•忽略重要指令:只关注最显眼或最前面的指令,忽略后面的。
•误解指令:因为信息量太大,导致对指令的理解出现偏差。
•产生冲突行为:不知道该遵循哪个指令,导致输出混乱。
举个栗子
下面我可能举个实际例子会更好理解一下:
场景
一位开发者希望构建一个智能客服机器人,能够处理各种用户需求。他在系统提示词中加入了大量的指令"
你是一个客服机器人,需要以友好和专业的态度与用户交流。首先,向用户问好。如果用户提出技术问题,提供详细的解决方案。
如果用户抱怨,请安抚他们的情绪,并提供折扣券。如果用户询问商品信息,提供最新的商品详情和价格。
如果用户要求与人工客服对话,礼貌地询问他们的具体需求,并尝试解决问题。
所有回应必须简洁明了,同时体现个性化和温暖。
问题
这个提示词看似全面,但实际上过于复杂,可能导致模型无法正确执行。例如:
•模型可能无法识别用户是抱怨还是询问产品,导致回应不准确。
•由于指令太多,模型可能忽略了关键的服务流程。
解决方案
首先, 需要简系统提示词, 只需要将模型的基本角色和行为描述清楚即可, 避免过多的细节.例如:
你是一个客服机器人,负责帮助用户解决问题,以专业和友好的态度与用户交流。
其次, 需要上下文的动态添加指令.我们以langchain4J的框架为例, 可以将这些指令通过封装多个AI Service实现, 然后串并联这些模块,实现整体的业务需求, 这里一般引入一个业务编排框架会使得架构更清晰, 比如liteflow这种.
然后回归这个案例, 我们可以如下拆分指令:
• 如果检测到用户在抱怨或情绪激动,添加安抚情绪的指令。
•如果用户提出技术问题,添加提供解决方案的指令。
•如果用户询问商品信息,添加提供商品详情的指令。
最后, 在这种业务场景下,我们可以引入一个中间层(如意图识别模块),先对用户的输入进行分析,然后根据分析结果决定模型需要执行的操作。
比如如下代码: 我们封装一个用户意图识别的AI Service, 先让大模型判断客户的意图, 然后决定下里该执行哪个指令.
public enum UserIntentEnum {
@Description("问候语, 例如:你好|您好|嗨|早上好|晚上好")
GREETING,
@Description("技术问题, 例如:技术问题|无法使用|出错|故障")
TECHNICAL_ISSUE,
@Description("客户抱怨评价, 例如:差评|不好用|生气|投诉|抱怨")
COMPLAINT,
@Description("客户商品咨询, 例如:价格|多少钱|商品信息|详情")
PRODUCT_INQUIRY,
@Description("客户想转人工, 例如:人工客服|真人")
REQUEST_HUMAN
}
interface UserIntent {
@UserMessage("Analyze the priority of the following issue? Text: {{it}}")
UserIntentEnum analyzeUserIntent(String text);
}
基于以上的不同场景, 封装对应的AI-Service, 然后通过liteflow这种业务编排工具串联起来即可.
其实大家有没有发现, 这种实现方式,就是prompt开发中, 大家经常提到的思维链/思维树架构模式.
二. 工具和上下文,不是越多越好
在构建智能对话系统时,开发者常常希望模型能够具备尽可能多的功能和信息。他们可能会认为,为模型提供更多的工具和更丰富的上下文,模型就能表现得更出色。然而,事实并非如此。过多的工具和上下文不仅不会提升模型性能,反而可能导致一系列问题,如成本飙升、响应速度变慢,甚至模型产生幻觉(hallucination)。因此,我们需要理性地看待工具和上下文的使用,避免陷入“越多越好”的误区.
Fuction Call工具, 避免模型“消化不良”
现代大型语言模型(LLM)的函数调用(Function Call)功能,为我们在聊天机器人中集成各种工具提供了可能。通过这种功能,模型可以调用外部API、数据库查询、计算器等,实现复杂的任务处理。这听起来令人兴奋,许多开发者也因此产生了“我有这么多工具,干脆都给模型用吧!”的想法。
然而,这种贪多求全的做法可能会导致模型的“消化不良”。具体来说,过多的工具会引发以下问题:
1.成本飙升:每增加一个工具,都会增加对话的复杂性。模型需要在生成回复时考虑更多的可能性,这会消耗更多的计算资源和令牌(tokens),直接导致使用成本的增加。
2.模型产生幻觉(Hallucination) :当模型被赋予过多的工具时,它可能无法正确识别何时调用哪些工具,进而在不适当的情况下调用错误的工具。
3.用户体验受损:模型的不当行为会让用户感到困惑或不满,影响对产品的整体评价。
案例分析:
想象一下,用户简单地对聊天机器人说了一句:“你好。”本来机器人只需要回一句问候即可。然而,由于模型被赋予了过多的工具,它可能会过度解读用户意图,结果调用了数据库查询、访问外部API,甚至替用户订了一份外卖。这样的响应显然是令人费解的。
这种情况不仅浪费了系统资源,还可能造成用户数据的泄露或引发其他安全问题。
解决方案:
•精选工具:只为模型提供在当前场景下必要的工具。通过对用户需求的分析,明确哪些工具是真正需要的。
•意图识别:在模型调用工具之前,先进行用户意图识别,确保只有在确实需要的情况下才调用相关工具。
•设置调用条件:为工具的调用设置严格的条件和限制,防止模型在不适当的情况下使用工具.
RAG, 上下文避免成本高昂
RAG技术使得模型可以根据提供的上下文生成更准确的回答。这对于需要提供具体信息、背景知识的场景非常有用。然而,过度提供上下文同样会带来负面影响。
问题分析:
1.令牌消耗巨大:大量的上下文意味着更多的令牌消耗。模型的成本通常与令牌数量直接相关,过多的上下文会显著提高使用成本。
2.响应时间延长:模型需要处理更多的信息,导致响应速度变慢,用户需要等待更长的时间才能得到回复。
3.注意力分散:过多的上下文可能使模型无法专注于最相关的信息,反而降低了回答的准确性。
4.增加错误风险:上下文信息越多,模型可能在不相关的信息中“迷路”,生成与用户需求不符的回答。
举例说明:
如果用户问:“你能告诉我今天的天气吗?”模型只需要提供当前的天气信息即可。但如果为模型提供了大量的气象数据、历史天气记录等上下文,不仅增加了无谓的成本,还可能让模型给出冗长的回答,影响用户体验。
优化策略:
•动态上下文管理:根据用户的具体需求,动态地提供最相关的上下文信息,而不是一股脑地全部塞给模型。
•上下文精简:对提供的上下文进行筛选,只保留与当前对话高度相关的部分。
•上下文缓存:对于多轮对话,合理地缓存上下文,但避免上下文长度无限增长。
•用户引导:设计对话流程,引导用户提供更精确的信息,减少对大段上下文的依赖。
•
思考一下
在使用工具和上下文时,关键在于适度和相关性。过多的工具和上下文不仅不会提升模型的表现,反而可能适得其反。我们应该以用户需求为核心,合理配置模型的能力,既满足功能要求,又控制成本.
所以啊,下次再想给模型塞一大堆工具和上下文的时候,不妨先问问你的钱包:“还能撑得住吗?”毕竟,模型“消化不良”可不是闹着玩的,钱包“消瘦”了,也别怪它不给你打声招呼。总而言之,在构建智能对话系统时,我们需要坚持“适度”原则。工具和上下文的使用,应当服务于模型性能的提升和用户体验的优化,而不是一味地追求数量。只有精心设计和合理配置,我们才能打造出高效、可靠、令人满意的聊天机器人.
三. 总结
在大型模型AI-Agent的开发中,我们需要像传统软件开发一样,遵循模块化、可测试、易维护的原则。不要迷信模型的强大能力,而忽视了架构设计的重要性。
通过将复杂的逻辑拆解成更小的组件,我们可以:
•降低成本:避免不必要的模型调用,节省令牌消耗。
•提高性能:减少响应时间,提升用户体验。
•提高可靠性:模块化的设计更容易测试和维护,减少错误。
最后,希望大家在AI-Agent的开发中,既能发挥模型的强大能力,又能保持对架构的掌控。这样,我们就不会被“大块头”吓倒,而是能驾驭它,为我们所用。
俗话说得好,“不要试图一口吃成个胖子”,即使是AI-Agent,也是需要慢慢“调教”的。祝大家在AI的浪潮中,乘风破浪,勇往直前!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。