大模型(LLM)已经成为当前人工智能的重要部分。但是,在这个领域还没有固定的操作标准,开发者们往往没有明确的指导,需要不断尝试和摸索。
在过去两年中,我帮助了许多公司利用LLM来开发了很多创新的应用产品。基于这些经验,我形成了一套实用的方法,并准备在这篇文章中与大家分享。
这套方法将提供一些步骤,帮助需要的小伙伴在LLM应用开发的复杂环境中找到方向。从最初的构思到PoC、评估再到产品化,了解如何将创意转化为具有影响力的应用程序。
1、为什么标准化流程至关重要
大模型(LLM)的发展非常快,几乎每天我们都能听到一些新的创新。这种快速发展让人感到既兴奋又有点乱——你可能会感到迷茫,不知道接下来该怎么办,或者怎样用这些大模型(LLM)来推动公司业务的发展。
采用一个标准化的流程对启动新项目非常有帮助,主要能带来以下几个好处:
统一流程 — 一个统一的流程可以帮助团队成员更好地协作,特别是在混乱的时候,也能让新人更顺利地加入团队。
设定清晰的里程碑 — 这是一个直接的方法,帮你跟踪工作进度,评估成效,确保你正朝着目标前进。
找出决策点 — 在开发大模型应用时,我们会遇到很多未知情况和需要做的小实验(PoC)。设定清晰的决策点可以帮我们降低风险,确保开发工作始终高效。
2、大模型工程师的必备技能
与软件研发领域的其他角色不同,专门从事大模型开发的工作需要一种全新的职业角色:大模型工程师,也就是我们常说的AI工程师。
大模型工程师需要具备多种技能,包括:
软件工程技能 — 这部分工作很像拼积木,需要把各种技术组件正确组合并确保它们能够协同工作。
研究技能 — 深入了解大模型的PoC性质非常重要。虽然制作一个看起来很好的演示应用相对简单,但要将这种演示转化成真正有用的解决方案,需要不断试验和调整。
商业和产品理解 — 了解业务目标和流程比单纯遵循我们设定的技术架构更重要。能够将手工过程转换成自动模型是大模型工程师的一项重要技能。
在写这篇文章的时候,大模型(LLM)工程还是一个非常新的领域,招聘合适的人才可能会有些困难。候选人可以考虑那些有后端开发、大数据或有算法背景的,他们可能会更适合这个职位。
软件工程师可能转换会比较顺畅,因为这里的PoC工作更多的是偏向工程操作,而不像传统的人工智能那样偏算法研究。不过,我也看到很多算法工程师成功地转换成大模型工程师,我今年年底准备出版的一本书中有介绍如何使用python编写大模型api的介绍。只要愿意接受并学习新的软技能,你已经走在了LLM应用的道路上了!
3、大模型(LLM)应用开发的关键要素
不像传统的后端应用(比如CRUD),在大模型(LLM)的开发中,目前没有一套固定的操作指南。像在人工智能领域的其他领域一样,开发这类应用需要你具备一种研究和尝试的心态。
要掌控这种复杂性,我们需要把大任务拆分成一系列小任务,尝试这些任务,然后挑选出最有希望的一个继续深入。
通过多个项目的实践经验,构建大模型(LLM)应用开发拥有一种尝试的心态是极其重要的。这意味着我们需要花时间去探索一个研究方向,最终发现这个方向“行不通”、“不够好”或者“不值得继续”。这是完全可以接受的——实际上,这表示我们在找到符合我们业务的专有大模型应用。
4、尝试的重要性:这是核心流程
有时候,我们第一个小应用可能会失败,这时我们就需要稍微调整方向,尝试另一个新的方向。往往这种调整后的新方向能带来意想不到的结果。
这就是为什么在设计我们的最终解决方案之前,我们需要从简单做起并小心规避风险。
设定一个“预算”或时间范围。 我们来看看在接下来的几周内能完成什么,然后再决定是否继续。通常来说,2-4周的时间足以帮我们了解基本的概念验证(PoC)。如果这个方向看起来有潜力,我们就继续投入资源去完善它。
实验(PoC) — 无论是选择自下而上还是自上而下的方式进行PoC,我们的目标都是尽可能提高成功率。第一轮实验结束时,应该得到一些初步的产品概念(PoC),利益相关者可以初步使用并评估这些产品。
复盘 — 研究阶段结束时,我们能够明确这个应用的可行性、局限性以及成本。这有助于我们决定是否将其转化为产品,以及如何设计最终的产品和用户体验。
产品化 — 开发一个准备好投入生产的版本,并按照软件工程的标准最佳实践,将其与其他解决方案整合,并实施反馈与数据收集机制。
要想好好执行这种注重实验(PoC) 的过程,我们需要决定如何策划和进行这些PoC:
4.1从简单开始:自下而上的方法
很多人一开始就直接使用成熟的Langchain或类似的复杂多链代理系统,但我发现,采取“自下而上”的方法往往能获得更好的效果。
从最简单的开始,极其简单,遵循“一条指令掌控一切”的理念。虽然这种方法可能看起来有点非主流,一开始可能会出现一些不尽如人意的结果,但它能帮助我们为系统建立一个基础水平。
从这点开始,需要持续改进prompt,使用prompt来获得更好的结果。当发现简化方案存在缺陷时,尝试通过增加新的处理分支来弥补这些不足。
在设计大模型(LLM)工作流程图中的每一个节点,或者说LLM专用架构时,我会遵循LLM三角原则来决定何时添加分支、何时进行分割,或者通过使用prompt来加强基础,从而更好地利用每一次机会。
例如,若要采用自下而上的方法实现“本地语言 SQL 查询”,我们会从一个基本的步骤开始:将数据库的结构(schema)发送给大模型(LLM),让它根据这些信息生成 SQL 查询语句。
通常,这并不会与“自上而下的方法”冲突,而是先进行一个额外的步骤。这样我们能快速展示一些初步成果,帮助领导层看到进展,从而决定是否继续投入更多资源。
4.2 从总体布局着手:自上而下的策略
“我们知道,大模型(LLM)的工作流程并不简单,为了实现我们的目标,我们很可能需要一些特定的工作流程或LLM专属架构。”
自上而下的策略正是基于这个理解,从第一天起就开始设计LLM专用架构,并从一开始就实施其各个步骤和环节。
采用这种方法,我们可以将工作流架构作为一个整体进行测试,从而充分利用整个系统的潜力,而不是逐个细节进行优化。
例如,使用自上而下的方法来实现“本地语言SQL查询”,我们会先从设计整体架构开始,然后再开始编码,直接进入完整的实施阶段:
4.3寻找合适的平衡点
当开始使用大模型(LLM)进行PoC时,很可能会从一个极端开始——不是过于复杂的自上而下策略,就是过于简单的一次性尝试。实际上,没有哪一种方法总是最佳的。
在理想状态下——在开始编写代码和进行模型试验之前,应该制定一个有效的标准操作程序(SoP)并尝试模拟一个专家。但实际上,模拟专家是非常困难的,有时甚至可能无法接触到相关的专家。
在最初尝试确定一个有效的架构或标准操作程序(SoP)时,我发现这个过程充满挑战,因此在开始真正产品实施之前,进行初步的验证是非常有价值的。然而,这并不意味着所有事情都必须执行得非常简化。如果我们已经明白某些步骤必须细分为更小的部分,需要马上实施并验证。
在设计解决方案时,我们应该运用大模型三角原则(LLM Triangle Principles),并正确模拟手动过程,以确保方案的实用性和有效性。
4.4优化解决方案:最大化利用资源
在PoC阶段,我们不断地增加更多的复杂性层级:
prompt 技术 — 比如使用很少的样本来训练模型、分配不同的角色给模型,或者利用动态样本学习来改进。
扩大考虑范围 — 从处理简单的数据信息到处理复杂的查询生成流程,这样可以帮助我们得到更好的结果。
尝试多种模型 — 不同的模型适合不同的任务。大模型虽然功能强大,但成本较高,寻找更专门针对某一任务的模型往往更经济。
简化prompt — 通过简化模型的prompt和期望输出,可以让模型反应更快。
缩短prompt 长度和减少处理步骤 — 这可以减少模型需要处理的数据量。会发现简化操作有时候甚至能提高处理质量!
不过要注意,过度简化有时会影响结果的质量,因此在做出这些调整前,进行一些基本的效果测试是很重要的。
将复杂流程拆分成更小的步骤,可以使得每个子步骤的优化更加容易实现,也更有效。
请注意,这种做法可能会增加解决方案的复杂度或影响性能(例如,增加处理的Tokens)。为了降低这种风险,应当尽量使用简洁的prompt和更小的模型。
一个基本的原则是,如果系统提示的变化在标准操作程序(SOP)的某个环节能够显著提高结果,那么进行分割通常是最好的选择。
4.5大模型(LLM)验证的结构
我个人比较喜欢从一个基础的Jupyter Notebook开始PoC,这个Notebook使用Python、Pydantic和Jinja2来配置:
使用Pydantic:定义模型输出的结构化模式,这是确保输出数据符合预期格式的关键。
利用Jinja2:编写模板来生成模型所需的提示,这对控制模型的输入非常重要。
设定结构化输出格式:采用YAML来格式化输出。这样可以确保模型按照既定的“思考步骤”进行,严格遵循我的标准操作程序(SOP)。
应用Pydantic的验证功能:验证输出的准确性,必要时可以进行重试,这是保证输出质量的一个重要步骤。
代码结构化:将代码组织成Python文件和包,这不仅有助于维护,也方便未来的扩展和管理。
在更广泛的应用中,可以使用诸如openai-streaming之类的工具,这样可以方便地实现流处理;使用LiteLLM,以便在不同的服务提供商之间使用标准化的大模型(LLM)软件开发工具包(SDK);或者使用vLLM来运行开源的大模型。这些工具都可以帮助您更有效地使用和部署大模型技术。
4.6通过基础测试和评估保证质量
基本测试是一种评估项目质量的有效方法,确保项目的成功率达到或超过您预先设定的标准。
为此,您需要列出一些您已经成功处理的案例,并确保这些案例能持续保持成功的状态(或至少确保持续投入是值得的)。将这个过程视为表格驱动的测试可能会帮助您更系统地进行管理和评估。
评估“生成式”解决方案(比如写作)的效果,要比使用大模型(LLM)处理其他类型的任务(如分类、提取信息等)复杂得多。对于这些任务,我们可能需要使用更高级的模型(如GPT-4、Claude Opus或LLAMA3–70B)来帮助评判效果。
另外,一个好方法是在生成性内容输出之前,先产生一些确定性的内容。这种内容因为更容易进行测试,所以可以帮助我们更好地评估整体输出的质量。
cities:
- New York
- Tel Aviv
vibes:
- vibrant
- energetic
- youthful
target_audience:
age_min: 18
age_max: 30
gender: both
attributes:
- adventurous
- outgoing
- culturally curious
# ignore the above, only show the user the `text` attr.
text: Both New York and Tel Aviv buzz with energy, offering endless activities, nightlife, and cultural experiences perfect for young, adventurous tourists.
有一些前沿而有前途的解决方案非常值得探索。在评估基于RAG的解决方案时,我发现特别有用的是这几个工具:DeepChecks、Ragas和ArizeAI。可以去了解一下。
5、关键决策:复盘的重要性
每次完成重要PoC或达到阶段性目标后,我们都应该停下来,仔细认真复盘,然后做出关键决策,决定是否以及如何继续这条路。
这时候,PoC应该已经有了一个明确的成功率基准,我们也会清楚哪些地方还需要改进。
这是一个很好的开始,讨论这个解决方案如何产品化以及这将带来哪些影响,我们需要综合考虑以下几个问题:
这个解决方案在产品中将如何实现?
我们面临哪些限制和挑战?我们将如何应对这些问题?
当前的响应速度如何?它能满足我们的需求吗?
应该设计怎样的用户体验?我们可以利用哪些界面技巧?流式处理能起到什么作用?
预计将在Tokens上花费多少?我们是否可以通过使用更小的模型来降低成本?
什么是优先级?有没有什么挑战可能成为项目的障碍?
如果我们认为已经达到了一个“足够好”的基线,并且能够解决我们面临的问题,那么我们将继续投资并改进这个项目,同时确保其性能不会退化,并执行必要的基础测试。
6、从PoC到产品:实现您的解决方案
最后,我们必须将我们的工作转化为产品。像处理任何成熟的解决方案一样,我们需要引入诸如日志记录、监控、依赖管理、容器化和缓存等生产工程的基本概念。
虽然这是一个复杂的领域,但幸运的是,我们可以借鉴传统生产工程的许多方法,并且还可以使用很多现成的工具。
虽然如此,我们还需要特别关注一些与大模型(LLM)原生应用相关的细节问题:
反馈循环 — 我们应该如何衡量成功?是仅靠简单的“点赞/点踩”机制,还是需要一个更复杂的系统,来考虑我们解决方案的实际应用情况?
同样重要的是要收集这些数据;随着时间的推移,这可以帮助我们重新定义我们的基准线,或者使用动态少示例技术微调结果,或者对模型进行微调。
缓存 — 不同于传统软件工程,当我们的解决方案包含生成内容时,实现缓存可能非常有挑战性。为了解决这个问题,可以探索缓存相似结果的方法(例如使用RAG),或通过设定严格的输出格式来减少生成内容。
成本追踪 — 许多公司倾向于从使用功能全面的模型(如GPT-4或Opus)开始,但在生产环境中,成本可能迅速增加。为了避免在最后成本上惊讶,确保测量输入/输出的Tokens 数量,并持续跟踪你的工作流程的影响(没有这些实践,以后很难进行性能分析)。
可调试性和追踪 — 确保已经部署了合适的工具来跟踪可能出现的问题,并在整个过程中进行追踪。这通常涉及保留用户的输入以供后续调查,并建立一个追踪系统。要记住:“与传统软件不同,人工智能的失败往往没有实际反馈可追踪的!”
7、总结
大模型(LLM)的应用开发是一个不断进化的过程,它涉及到扩展应用场景、解决新问题、添加新功能,并持续改进LLM产品。
在继续进行人工智能开发的过程中,保持灵活,勇于尝试新的方式,以最终用户的需求为中心。这样,我们可以不断推动技术前进,让产品更贴合用户需求,更好地服务于实际应用。