大型语言模型(LLMs)正迅速成为现代AI的基石。然而,目前没有确立的最佳实践,许多先驱者常常没有明确的路线图,不得不重新发明轮子或陷入困境。
在过去两年中,我帮助组织利用LLM构建创新应用。通过这些经验,我开发了一种经过实战考验的方法来创建创新解决方案(借鉴了LLM.org.il社区的见解),我将在本文中分享这种方法。
本指南提供了清晰的路线图,帮助你导航复杂且充满挑战的大型语言模型(LLM)原生开发领域。你将学习如何从构思到实验、评估和产品化,释放你创造突破性应用的潜力。
(由Dall-E3创建)
LLM领域发展如此迅速,以至于我们每天都能听到关于新的突破性创新的消息。这既令人兴奋,也让人感到非常混乱——你可能会在过程中迷失方向,不知道该做什么或如何将你的新想法付诸实践。
说白了,如果你是一名 AI 创新者(管理者或实践者),想要有效地构建 LLM 原生应用,这正是你需要的。
实施标准化流程有助于启动新项目,并提供以下几个关键好处:
与软件研发中的其他 established 角色不同,LLM 原生开发绝对需要一个新的角色:LLM 工程师 或 AI 工程师。
LLM 工程师是一种独特的混合体,结合了来自不同(已确立)角色的技能:
在撰写本文时,LLM 工程仍然是一项全新的领域,招聘可能会非常具有挑战性。寻找具有后端/数据工程或数据科学背景的候选人可能是个好主意。
_软件工程师_可能会期望一个更平滑的过渡,因为实验过程更“工程化”,而不是那么“科学”(与传统的数据科学工作相比)。话虽如此,我也见过许多_数据科学家_进行这种过渡。只要你能够接受你将需要拥抱新的软技能,你就走在正确的道路上了!
与传统的后端应用(如 CRUD)不同,这里没有一步一步的食谱。就像“AI”中的其他一切一样,LLM 原生应用需要一种 研究和实验的心态。
要驯服这个野兽,你必须采取分而治之的方法,将工作分成更小的实验,尝试其中一些,并选择最有前景的实验。
我再怎么强调研究心态的重要性也不为过。这意味着你可能会花时间去探索某个研究方向,结果发现“不可行”、“不够好”或“不值得”。这完全没问题——这意味着你走在正确的道路上。
通过实验来构建 LLM 原生应用(并避开途中的陷阱)(使用 Dall-E3 创建)
有时候,你的“实验”会失败,然后你稍微调整一下工作方向,结果另一个实验取得了更大的成功。
那正是为什么,在设计我们的最终解决方案之前,我们必须从简单开始并降低风险。
LLM-Native 应用开发生命周期(作者供图)
为了更好地实施以实验为导向的过程,我们必须明智地决定如何进行和构建这些实验:
虽然许多早期采用者迅速投入到“最先进的”多链代理系统中,例如使用完整的 Langchain 或类似系统,但我发现“自下而上的方法”往往能取得更好的结果。
开始精简,非常精简,拥抱 “一个提示通吃所有” 的理念。虽然这种策略可能看起来不传统,并且最初可能会产生糟糕的结果,但它为你的系统建立了一个 基准 。
从那里开始,持续迭代和优化您的提示,运用提示工程技巧来优化结果。在您发现精简解决方案中的弱点时,通过添加分支来解决这些不足之处。
在设计我的 LLM 工作流图或 LLM 原生架构的每个“叶子”时,我遵循LLM Triangle Principles 原则,以确定何时何地剪枝、分裂枝干或加粗根部(通过使用提示工程技术),从而榨取更多的价值。
底部向上方法的示例(作者供图)
例如,要使用自底向上方法实现“原生语言 SQL 查询”,我们将从简单地将模式发送给LLM并要求它生成查询开始。
自底向上方法示例(作者供图)
通常,这并不违背“自上而下的方法”,而是作为其之前的另一个步骤。这使我们能够展示快速胜利并吸引更多项目投资。
“我们知道LLM工作流并不容易,为了实现我们的目标,我们可能会采用某种工作流或原生LLM架构。”
自上而下的方法认识到这一点,并从一开始就设计LLM原生架构,并从一开始就实现其不同的步骤/链。
这样,你可以整体测试你的工作流架构,而不是分别精炼每一片叶子,而是榨取整个柠檬。
自上而下的方法流程:一次设计你的架构,实现、测试及测量(作者提供图片)
例如,要使用自顶向下方法实现“原生语言SQL查询”,我们将从设计架构开始,甚至在开始编写代码之前,然后直接进行完整实现:
自顶向下方法的例子(作者提供图片)
当你开始尝试使用LLM时,你可能会从两个极端之一开始(过度复杂的自上而下方法或极其简单的单次尝试)。实际上,并没有一种方法能胜出。
理想情况下,你应该定义一个好的操作规程¹,并在编码和实验之前模拟一个专家。实际上,建模非常困难;有时你可能无法获得这样的专家。
我发现一开始很难一下子就找到一个好的架构/SoP¹,所以在投入大量资源之前进行一些轻量级的实验是值得的。但这并不意味着所有事情都必须过于精简。如果你已经有一个先验的理解,某些东西必须被拆分成更小的部分——那就去做吧。
你应该利用LLM三角原则³,并在设计解决方案时正确地模拟手动流程。
在实验阶段,我们不断挤柠檬并增加更多的“复杂性层次”:
请注意,节食也可能导致质量下降,因此在这样做之前设置一个合理性测试是很重要的。
请注意,这可能会增加解决方案的复杂性或损害性能(例如,增加处理的 token 数量)。为了缓解这一点,尽量使用简洁的提示和较小的模型。
作为一条经验法则,通常在系统提示发生重大变化时将 SOP¹ 流程的这一部分分割开来,可以获得更好的结果。
挤柠檬的AI(使用Dall-E3创建)
就我个人而言,我喜欢从简单的 Jupyter Notebook 开始,使用 Python、Pydantic 和 Jinja2:
在更广泛的范围内,你可以使用不同的工具,例如 openai-streaming 来轻松地 利用流式传输(和工具),LiteLLM 来在不同的提供商之间拥有一个 标准化的 LLM SDK,或者 vLLM 来 提供开源的 LLMs。
一个合理性测试会评估你的项目的质量,并确保你没有降低你定义的某个成功率基准。
想想你的解决方案/提示就像一条短被子——如果你把它拉得太长,它可能突然无法覆盖以前能够覆盖的一些用例。
要做到这一点,定义一组你已经成功覆盖的案例,并确保保持这种状态(或者至少这样做是值得的)。可以将它想象成一个表驱动测试。
评估一个“生成式”解决方案(例如写文本)的成功与否要比使用LLM(大型语言模型)完成其他任务(如分类、实体提取等)复杂得多。对于这类任务,你可能希望使用更智能的模型(如GPT4、Claude Opus或LLAMA3–70B)来充当“裁判”。
在生成式输出之前,尝试让输出包含“确定性部分”也是一个好主意,因为这类输出更容易进行测试。
城市: - New York - Tel Aviv 氛围: - 活力四射 - 充满活力 - 年轻 目标受众: 年龄最小: 18 年龄最大: 30 性别: 男女皆宜 特征: - 喜欢冒险 - 外向 - 对文化好奇 # 忽略以上内容,只显示 `text` 属性。 text: 纽约和特拉维夫都充满活力,提供无尽的活动、夜生活和文化体验,非常适合年轻、喜欢冒险的游客。
有几个前沿的、🤩🤩 有前景的解决方案值得研究。在评估基于RAG的解决方案时,我发现它们特别相关:可以看看 DeepChecks、Ragas 或 ArizeAI。
每次进行重大或有时间框架的实验或里程碑之后,我们应该停下来,对是否继续采用这种方法做出明智的决定。
到这时,你的实验将有一个明确的成功率基准,你也会知道需要改进的地方。
这也是开始讨论这个解决方案的产品化影响以及开始“产品工作”的好时机:
假设我们达到的 基准 是“足够好”,并且我们认为可以解决我们提出的问题,那么我们将继续投资并改进该项目,同时 确保其永远不会退化 并使用健全性测试。
(由Dall-E3创建)
最后但同样重要的是,我们需要将我们的工作产品化。像任何其他生产级解决方案一样,我们必须实现生产工程概念,如日志记录、监控、依赖管理、容器化、缓存等。
这是一个巨大的世界,但幸运的是,我们可以借鉴许多传统生产工程中的机制,甚至可以采用许多现有的工具。
说到底,需要注意涉及LLM原生应用的细微差别:
这可能是文章的结尾,但绝不是我们工作的终点。LLM原生开发是一个迭代过程,涵盖了更多的应用场景、挑战和功能,并不断改进我们的LLM原生产品。
随着你继续你的AI开发旅程,保持灵活,大胆实验,并始终牢记最终用户。与社区分享你的经验和见解,我们一起可以推动LLM原生应用可能的边界。继续探索、学习和构建——可能性是无穷无尽的。
希望这篇指南能成为你在LLM原生开发旅程中的宝贵伴侣!我很想听听你的故事——在下面的评论中分享你的成功和挑战吧!💬
如果你觉得这篇文章有帮助,请在 Medium 上给它点几个 赞 👏,并把它分享给你的 AI 爱好者朋友们。你的支持对我来说意义重大!🌍
让我们继续交流——你可以通过 邮件 或者 领英上联系我 🤝
特别感谢 Yonatan V. Levin、Gal Peretz、Philip Tannor、Ori Cohen、Nadav、Ben Huberman、Carmel Barniv、Omri Allouche 和 Liron Izhaki Allerhand 提供见解、反馈和编辑意见。
¹SoP - 标准操作程序,一个借鉴自 《LLM 三角原则》³ 的概念
²YAML - 我发现使用 YAML 来结构化输出与 LLM 的配合效果更好。为什么呢?我的理论是 YAML 可以减少无关的标记,并且表现得像一种原生语言。这篇文章深入探讨了这个主题。
³LLM 三角原则 - 用于设计和构建原生 LLM 应用的软件设计原则;更新 - 最近发布的白皮书,你可以在这里阅读。