« 主页

探云月刊 2024-04 AIGC 项目实践

发布于

版权声明:眯眼探云原创,可随意转载,请保留该版权声明及链接:https://tyun.fun/post/95.tanyun-monthly-2024-04/

这是我2024年04月20日在 iTechClub 活动中做的一次分享,原标题是 AIGC 落地工程 - 但不止是工程,分享的内容是关于我们如何在智能私教中集成 LLM,来提升用户体验。

现在把这次分享的文字稿整理出来,以更与更多的人一起交流。

先来看具体的例子,用户可以通过对话的方式,让智能私教推荐课程,计划,询问健身方面的知识,以及产品服务相关的内容。

这个功能上线以后,我们通过问卷调查的方式收集了一些用户的反馈,用户整体上给到了 4.06/5分 的高分。虽然用户也提到了不少值得改进的问题,但这个分数,是稍稍超出我们心中的预期的,给我们带来了很大的信心。

接下来我就从技术决策、AI 程序流程、提示词工程、团队协作这几个方面来讲一讲,我们的一些做法和思考。

我作为这个项目的技术负责人,设计了与 AI 集成部分的流程 & 架构,我也是团队中唯一的提词工程师,负责了所有 Prompt 的设计与研发。相信接下来所讲到的内容,对你会有帮助。

技术决策

技术决策的目标肯定不是为了技术本身,而是要结合现实情况和业务目标来进行考虑,为了去实现业务目标。因此,我为我们的技术决策确立了两个大前提:应用层,低成本

我们是一家做健身的公司,主要服务的是 C 端用户。大语言模型可以给我们带来某些方面的提升,但肯定不是我的核心。因此我们如果去搞模型训练,或者算力方面都不太合适,我们的重点就是把 AI 用起来,用好。# 应用层

当前互联网的环境在发生变化,以前先做规模在考虑盈利的时代逐渐过去了,一是规模很难做,二是规模做起来后,盈利模式也很难找。当前无论是企业本身的发展,还是想着去拿投资,都必须得先把盈利模式跑通,足够低的成本,才会为盈利留出足够的操作空间。# 低成本

AI 负责接客,常规软件提供服务。

我们从推荐课程说起。如何给用户推荐到合适的课程,这算是我们的一项核心业务能力。刚开始的时候,很多人都会问我,是不是我们把所有的信息给到 AI,然后 AI 就可以帮用户挑出合适的课程?我也认真去试了,答案是:不行。有几个方面的关键限制。

第一个限制是上下文窗口。上下文窗口,听起来有点专业,其实它就是指的大模型一次能够处理的数据是有限的。比如以 4k token 的上下文限制为例,可以简单理解为,大模型一次可以处理总共(输入+输出)3000字左右,我们显然无法把所有课程信息塞给它。那现在很多大模型都能处理十几万字,甚至上百万字,这个问题是不是就解决了呢?只能说部分解决了,因为现在大模型收费都是按 token 数(也可以理解字数)收费的,用的多,就很贵,所以并没有办法真正用起来。

第二个关键的限制是,大模型的能力并没有我们想象的那么强,也就是它的智商没那么高。我们想想,大模型的能力来源于什么?是来源于人类已有的文字资料。如果一些问题还没有被人类解决好,或者没有被人类记录下来,那么 AI 肯定是不会的。

在 FITURE 的场景下,为用户推荐合适的健身课程,显然不属于已经被解决好、并且已经被完整记录下来的知识,所以没办法期望纯靠 AI 的能力来解决这些问题。

这听起来也许会有点令人失望,但反过来想,正因为 AI 的能力有限,我们现在做的事情才有价值,不然就直接被大模型给替代了。

虽然不能完全依赖 AI 为用户提供服务,但部分依赖是可以的。现在都说大模型是通用大模型,它真有一部分能力是通用的,那就是它的语言能力。大模型可以理解用户的语言,然后转化为标准化的输出,我们就可以基于这些标准化的输出,来针对性的为用户提供服务。

正所谓:AI 负责接客,常规软件提供服务。

只通过 Prompt 来使用大模型,不微调 & 训练模型

这可能和很多人想的不一样,难道微调不是更牛逼一些?

首先要明白一点,微调并不是对大模型的能力增强,而只是让它在处理特定任务的时候,能够输出更符合业务需要的结果。也就是说,如果模型能力不足,并不能通过微调的方式来提升。而且相对于直接使用 Prompt,微调还会带来各方面的成本提升,挨个来说一下。

首先是时间成本,微调的迭代周期会显著的更长,毕竟 Prompt 改几个字立马就可以看效果。微调则需要先收集、整理数据,然后训练模型。这背后还涉及到不少专业知识,才能够分析 & 改进微调效果。

微调依赖数据,但在做新功能的时候,其实我们是没有数据的,我们脑袋中通常只有一些相对抽象的定义和方向。Prompt 对数据依赖更小,可以边做边积累 & 调整。

微调整体费用更高。有训练成本,模型托管成本,甚至调用费用都会比标准模型更高。而且由于并非公共资源池,并发的带宽受限也比较明显。

因此,对于应用层,低成本的大前提下,直接使用 Prompt 是我们的首选方案。OpenAI 在官方文档中也提到,建议从 Prompt 开始,在做的过程中,可以逐渐搞清楚问题,并且积累数据。如果真到了有一天需求特别强烈,再上微调也不迟。

如果不用微调,很多人可能还会有个疑问:那怎样让模型学会我们的东西呢?比如模型并不知道我们教练相关的信息,那它如怎么回答呢?好,接下来就讲这个部分,RAG。

RAG - 直接采用第三方框架

RAG 全称是Retrieval Augmented Generation,检索增强生成。术语听起来总是很晦涩,没关系,我们直接来看例子。

如果有持续关注 AIGC,那应该会知道,早期的大模型是没有网络访问能力的,是后来才给加上的。现在如果你问大模型一个他不知道的问题,大模型就可以去先去网上搜索相关的资料,然后再来回答你的问题。这,就是检索增强生成,来细看一下。

大模型是如何访问网络的呢?答案可能要让你失望了,大模型自身并不能访问网络,访问网络的是常规的程序。流程是这样的:

  1. 大模型理解了问题,判断是否需要访问网络,以及用什么词进行搜索。
  2. 常规软件根据大模型给的信息进行搜索,并做简单的整理汇总。
  3. 常规软件把你的问题,以及网页相关的信息整体喂给大模型。
  4. 大模型根据提供的所有信息,回答问题。

因为这个过程中,涉及到先进行资料检索,然后把检索的资料给到大模型,然后生成结果,因此被称为检索增强生成

如果要大模型回答公司业务相关的问题,我们可以可以采用相同的方式,先根据用户的问题检索相关的资料,把检索到的资料 & 用户的问题一起给到大模型,大模型就能够回答公司业务相关的问题了。当然这里的检索就不需要到网上去检索,而通常是通过一种叫语义检索的技术来查找相关的资料。

这个语义检索通常是由一种叫 ebmedding 的技术实现的,而且相对比较标准化,因此对于大部分公司而言,直接采用开源的第三方方案就好。其中具体的技术细节,比较偏技术,短时间不容易讲清楚,但即使不理解也不影响使用。

技术决策小结

回顾一下几个关键的技术决策:

  • 关键词:低成本,AI应用层
  • AI 提供的自然语言交互的能力,但核心业务依然是通过常规软件提供。
  • 我们应该选用 Prompt 的方式使用大模型,而不是微调大语言模型
  • RAG - 直接采用第三方框架

这些技术决策并非一开始就那么清晰。比如 RAG,项目刚开始的时候,我只看到了相关的使用方式,还并没有出现成熟的开源应用,因此原本计划中有考虑到这部分功能的开发。但后来看到 dify 已经在这块做了成熟的功能,那自研的必要性就不大了,直接用起来就好。即使在未来,自研的必要性也不大,因为这部分的场景是相对标准化的,自研大概率比较难做的比开源的更好。

那未来这些技术决策会变吗?可能会变。比如未来小尺寸的大语言模型如果能力足够强,那么就可以考虑本地部署使用。随着业务的发展,如果对 LLM 依赖持续增强,那么微调模型也会是合理的选项。

AI 程序流程

这应该算是 AI 应用层的基本流程,应该还是比较容易理解的。不同的 AI 程序,可能就是具体的流程不同,或者其中的环节有多有少,基本的思路应该都是差不多的。

其中对应的 AI Agent 都是通过 Prompt 来实现的,Prompt 工程就这个项目中的重点。所以接下来会详细讲一下这个部分。

提示词工程 Prompt Engineering

如果你要研究 Prompt,那你多半会找到这个网站 https://www.promptingguide.ai,上面有不少关于 Prompt 的资料。

这个网站的首页,会提到:

  • 提示工程不仅仅是关于设计和研发提示词。它包含了与大语言模型交互和研发的各种技能和技术。提示工程在实现和大语言模型交互、对接,以及理解大语言模型能力方面都起着重要作用。用户可以通过提示工程来提高大语言模型的安全性,也可以赋能大语言模型,比如借助专业领域知识和外部工具来增强大语言模型能力。

就像路桥工程,显然不止是路和桥,挖挖车也是工程的一部分。

那提词工程,应该包含哪些事情呢?在当前的行业阶段,我重点想提三方面的内容:

  1. 首先当然是提示词设计和研发。这个部分是我们控制和使用大模型的手段。
  2. 然后是相关的软件工程,比如动态的组合提示词,获得不同的结果。比如你希望大模型能叫出用户的名字,那就得把名字的信息动态的塞到 Prompt 里面。
  3. 另外一个非常重要的工作,那就是去建立团队认知。要完成一个项目,需要许多人的协作,在当前阶段,相信大多数团队对这部分的工作并不了解。因此,通过一些方式,比如分享,比如搭建相应的工具,来帮助同事理解相关的信息,会是当前提词工程工作中相当重要的一部分。

接下来会重点讲提示词设计研发,以及建立团队认知这两块。软件工程虽然重要,但本身成熟度比较高,因此只是强调一下重要性即可,并不在这里展开细讲。

大语言模型的可靠性

我们都知道大模型能力是有限的,而且还会出现“幻觉”问题,那我们用大模型,怎样才能让它的输出相对可靠呢?要做 Prompt 开发,这是避不开的第一个问题。如果没有足够可靠性,就谈不上用它来提供服务。

先给结论:如果问题本身(Prompt)足够清晰,没有歧义,并且落在大模型的能力范围内,那么大模型就会给出可靠的结果。

来看下面的例子:

我们都知道大模型不太擅长数学问题,如果你问它一个稍微复杂点数学计算,那它就会给一个不靠谱的答案,比如:


我:333x5591等于多少

GPT3.5:333乘以5591等于1861233。

(正确答案是:1861803)

但如果你问 1+1 等于几,它永远都会回答你,等于2。这就落在了大模型的能力范围内。

虽然大语言模型不太擅长数学,但很擅长文字,所以文字相关的内容大概率会落在大模型的能力范围内。拿不准的时候,多试试便知。

怎么才算问题足够清晰呢?比如用户说想提升一下力量,那无论是推荐一节健身课程还是推荐一个完整的健身计划都是合理的。那大模型就会根据一些微小的描述变化来判断该选哪一个。为了把让大模型的输出更符合业务想要的结果(我们的场景是让他多推荐课程),我花了相当多的时间去搞它,依然不稳定。这就是语言本身的模糊性带来的不稳定。

最终我们的解决办法是,通过调整描述,缩小了计划推荐的适用场景,从而让大模型在模糊的情况下,尽可能多选择推荐课程。

响应开放式提问的基本策略

既然明白了 Prompt 的可靠性是有一定保障的,那么下一个问题自然是,这样的可靠性,可以保障到什么程度?

用户是用自然语言输入,那就意味着,他可以讲任意的内容。那我们可以很好的响应用户的任意请求吗?显然不能。我们的智能私教限定是健身场景,而且重点是要结合我们的核心业务功能:视频课程推荐。那就是说,用户提的要求里,必定会出现我们处理不了的情况。因此,对于我们功能应该做到什么程度,我拟定了一个基本的标准:

  • 全力处理好核心业务问题
  • 严格规避红线问题
  • 边界情况,宽容接受

比如推课就是我们目前最核心的一个业务点,我们花了很大的精力来处理这一部分。由 AI 根据用户的描述来提取相应的条件,然后有常规软件系统来使用这些条件,结合用户的运动历史偏好来为用户推荐课程。因为涉及到 Prompt 和常规程序的深度结合,并且有许多的不确定性,因此我们花了不少时间,先是搞 demo,然后逐步的完善功能,迭代效果。

红线问题就是我们应该明确避免的问题。比如宗教、政治等问题,我们无法限制用户讲这些内容,但可以在回复中拒绝这些问题。为此,我们专门在意图识别中增加了这些主题的识别,并拒绝回答此类问题。

我们知道软件开发都会有边界情况,一般指的是主逻辑之外的,不容易被注意到的情况。但在大模型开发的语境下,主要指的是大模型的能力边界 & 特定问题的自然语言的边界。在 Prompt 开发过程中,会把任务拆小,让每个 Agent 只完成一个简单的任务。拆任务的过程,就需要注意,一方面是让任务落在大模型的能力范围内,另一方面是尽可能考虑任务之间的边界,能够容易被自然语言表达清楚。

在这样的基础上,我们就需要宽容的接受无法处理的边界情况。好在通常这些边界情况不会在主要场景,所以对业务本身影响有限。

Zero-shot(零样本) VS Few-shot(少样本) VS CoT(链式思维)

在项目过程中,我经常被人问到few-shot/cot 我们用了吗?为什么?因此我认为值得拿出来讲一讲。

先上结论:目前主要采用的是零样本提示,既没有用少样本提示,也没有用到链式思维 CoT。

Few-shot 的做法是给 AI 举例子,让 AI 通过例子进行学习。现在的 AI 非常聪明,可以从少数的例子中学到规律并立即进行使用。但是,问题在于,AI 会通常会“充分”的学习例子中的规律,并且只学会了例子中的规律,AI 领域里有个专门的词,叫过度拟合。如下图中,AI 就严格根据我的例子来出题,但出题的形式非常单一。如果我直接给要求,他的出题形式就会很丰富:

链式思维(CoT) 稍微复杂一点。链式思维的提词模式,是利用了 AI 生成文字的一个特点:AI 生成文字的时候,实际的过程是根据已有的内容,来预测下一个最可能的字/词是什么。所以常见的 AI 聊天,文字也是一个字一个字出现的。也就是说,中间过程生成出来的内容,其实是会对后面生成的内容产生影响的。

CoT 模式利用了这个特点,先让 LLM 按步骤分析问题,把中间过程也生成出来,作为最终结果的参考,就更容易把题做对。可以参考下面这两个例子:

CoT 虽然可以提升 LLM 的推理能力,但对推理能力的提升幅度有限,而且会显著的提升整体响应时间。因为在我们的场景,很多中间过程的处理对用户是不可见的,如果在这些不可见的过程中使用 CoT,用户的等待时间会显著加长,这显然不是我们想看到的。所以整体而言,用有限的推理能力来让用户等待更久对我们是划不来的。

实际的场景下,我们可以通过把任务拆分的更简单,从而降低对大模型推理能力的要求来解决问题。

Context 与 Prompt 精调手段

Prompt 的开发并不是一个一次到位的过程,而是通过不断调整去逼近最终想要的结果。有时候会比较顺利拿到想要的结果,有时候可能会花了很大精力,但效果始终不理想,只能考虑换方案。

这其中我想重点讲的一个点是:上下文 - Context

我们人与人交流的时候,都喜欢和有默契的人交流,因为相互之间有着非常丰富的共识,交流起来就很轻松。因此很多人和大模型交流的时候,会感到困难,因为大模型和自己可能没啥共识。在给大模型交代任务的时候,必须要仔细的考虑补充足够的上下文(共识),大模型才更容易准确的理解任务内容。说起来简单,但其实很难做到,我能想到的唯一办法,就是在实践中通过反复的尝试,去积累经验,对上下文形成足够的敏感。

除了提供、完善 Context,还有许多 Prompt 的精调手段。在这篇短文中是无法挨个细讲的,但可以列出一些我认为比较有用的:

  1. 使用不同的 Prompt 结构。比如多轮对话形式的聊天结构,以及 Instruct 结构。
  2. 换语言。根据我目前的使用经验,英文效果会更好。
  3. 调结构。比如 Prompt 中的部分信息使用 xml 标签,或者 Markdown 格式来帮助 LLM 理解。
  4. 换措辞。这个应该是比较容易想到的,比如 briefly 和 concisely,LLM 的回复是会略有差别的。
  5. 调 Prompt 中内容的位置。根据我目前的经验,在 Prompt 中,越靠前的信息,权重越高,越靠后的指令,权重越高。
  6. 调接口参数。比如 temperature 控制了大模型的自由发挥程度。

如果你对其中某种做法感兴趣,或者自己有什么特别值得推荐的精调手段,欢迎交流。

技术工程以外 - 团队的协作

我们都沉浸在 AI 爆发的新闻当中,但实际上身边对 LLM 有较深理解的人是非常少的。一方面 ChatGPT 使用门槛较高,另一方面国内的大模型也就是去年底才逐渐达到了“可用”的程度。因此很多人实际使用 AI 的经验是比较少的。

因此对于集成 AIGC 的项目,除了工程本身,还面临着一个挑战,那就是在缺少团队共识的情况下,如何做好团队协作

新闻问答

我们的产品经理,因为要做这部分的功能,对 AI 关注度也很高。经常就会拿着新闻来问我,这个我们可不可以用,那个可不可以用。

在绝大部分情况下,答案当然是不可以。你想啊,新闻里报的东西,那都是挑最好的说,看起来牛逼到爆炸,但实际用起来就是各种问题各种限制。

但如果总是粗暴的回复不可以,那我们这个项目探索到一半多半也就终结了。啥都不能做,那搞个 P 啊。

得换个思路来看问题。

像 AI 这种非常前沿的项目,很重要的一件事情,一定是去提升团队对 AI 的认知。所以当产品拿着这些问题来的时候,那其实是一个非常好的机会。新闻里面的东西,做不到,用不上,没关系。

很多人都没有意识到,想要真正准确的描述一个问题,其实是困难的。因此当一个人拿着一个现成的方案去(比如新闻中的方案)去询问专家的时候,他其实是想解决某个问题,因为他认为这个方案中的某些东西可以解决他的问题。

想明白了这一点,也就知道了应对的方式:通过方案的探讨,引导到问题的探讨,然后再围绕问题,进行充分的交流。这样的方式,通常都可以达到一个比较理想的效果。

允许情绪存在

讲一个我们项目过程中的小故事。

我们的研发在成都,产品在上海,主要是线上沟通。而且吧这个功能本身不确定性非常高,刚开始的时候产品也不知道需求该怎么写,研发也不太清楚该怎么做。于是刚出来的第一版,QA 同学就测的很难受,有天在群里和产品沟通的时候就明显有点闹情绪。我看情况不太对,就赶紧线下找她。她情绪正在头上,对我也很不客气:怎么啦,工作还不许有情绪啦。

当然可以有。

现在很多网上的信息会讲,我们要成年人,不要把情绪带到工作中。相信愿意为这种观点买单的人也不少,但这显然是不符合现实情况的,只能是一个不切实际的愿望。

举个很简单的例子,难道会有人不希望团队成员积极工作吗?难道积极工作背后不是积极的情绪?人会有积极情绪,当然也会有消极情绪。

我对消极情绪的态度是:要能够包容消极情绪,但要积极的处理。

比如我想强调的是,由于是线上沟通,文字的沟通,很容易因为这些情绪引起误解 & 升级,影响信任 & 协作效率。因此如果遇到了消极情绪问题,那就尽量线下处理。

虽然会有点情绪,但其实那位 QA 同学非常认真负责,面对 AI 集成这种非常新的不确定的功能,几次都测到凌晨。

最终我们整个团队协作,还是保持顺畅的。

小结

差不多就到这里吧,回头一看,内容已经非常多,能读到这里的你也非常不容易。

Thanks for reading