设计原则#
当我们启动这个项目时,LangChain 已经很流行,尤其是在 ChatGPT 发布之后。我们被问到的一个问题是 prompt flow 和 LangChain 之间有什么区别。本文旨在阐明构建 prompt flow 的原因以及我们所做的深思熟虑的设计选择。简而言之,prompt flow 是一套开发工具,用于通过实验构建 LLM 应用程序,并强调质量,而不是一个框架——LangChain 是一个框架。
虽然 LLM 应用程序大部分处于探索阶段,但微软在这一领域起步较早,我们有机会观察开发人员如何将 LLM 集成到现有系统或构建新应用程序。这些宝贵的见解塑造了 prompt flow 的基本设计原则。
1. 暴露提示而非隐藏它们#
LLM 应用程序的核心本质在于提示本身,至少目前是这样。在开发一个相当复杂的 LLM 应用程序时,大部分开发工作应该是“调整”提示(注意此处有意使用了“调整”一词,我们稍后将进一步探讨)。任何试图在该领域提供帮助的框架或工具都应专注于使提示调整变得更轻松、更直接。另一方面,提示是非常不稳定的,不太可能编写一个适用于不同模型甚至同一模型不同版本的单一提示。构建一个成功的基于 LLM 的应用程序,你必须理解引入的每个提示,以便在必要时对其进行调整。LLM 简单来说还不够强大或确定,以至于你可以像在传统编程语言中使用库一样使用他人编写的提示。
在这种情况下,任何试图通过在库中封装一些提示来提供智能函数或代理的设计,在实际场景中都不太可能产生有利的结果。将提示隐藏在库的代码库中只会使人们难以改进或调整提示以满足其特定需求。
Prompt flow 被定位为一个工具,避免在其核心代码库中封装任何提示。您唯一会看到提示的地方是我们的示例流,这些流当然可供采用和利用。每个提示都应由开发人员自己编写和控制,而不是依赖我们。
2. 一种新的工作方式#
LLM 拥有卓越的能力,使开发人员无需深入了解机器学习的复杂性即可增强其应用程序。同时,LLM 也使这些应用程序更具随机性,这给应用程序开发带来了新的挑战。仅仅在门控测试中断言“无异常”或“结果 == x”已不再足够。采用新的方法和工具势在必行,以确保 LLM 应用程序的质量——需要一种全新的工作方式。
这一范式转变的核心是评估,这是一个在机器学习领域频繁使用的术语,指的是评估训练模型性能和质量的过程。它涉及衡量模型在给定任务或数据集上的表现如何,在理解模型的优点、缺点和整体有效性方面发挥着关键作用。评估指标和技术因具体的任务和问题领域而异。一些常见的指标包括准确率、精确率和召回率,您可能已经熟悉。现在,LLM 应用程序与机器学习模型具有相似之处,它们需要一种以评估为中心的方法集成到开发工作流程中,并以一套强大的指标和评估作为确保 LLM 应用程序质量的基础。
Prompt flow 提供了一系列工具来简化新的工作方式
将您的评估程序开发为评估流,以计算您的应用程序/流的指标,并从我们的示例评估流中学习。
迭代您的应用程序流并通过 SDK/CLI 运行评估流,从而比较指标并选择最佳候选版本进行发布。这些迭代包括尝试不同的提示、不同的 LLM 参数(如温度等)——这被称为“调整”过程,有时也称为实验。
将评估集成到您的 CI/CD 管道中,使门控测试中的断言与所选指标对齐。
Prompt flow 引入了两个概念组件来促进此工作流
评估流:一种流类型,表明此流不用于部署或集成到您的应用程序中,而是用于评估应用程序/流的性能。
运行:每次您使用数据运行流,或对流的输出进行评估时,都会创建一个运行对象来管理历史记录并允许进行比较和额外的分析。
虽然新概念会增加额外的认知负担,但我们坚信它们比抽象不同的 LLM API 或向量数据库 API 更重要。
3. 优化“可见性”#
由于 LLM,正在出现一些有趣的应用程序模式,例如检索增强生成 (RAG)、ReAct 等。虽然 LLM 的工作原理对许多开发人员来说可能仍然是个谜,但 LLM 应用程序的工作原理并非如此——它们本质上涉及一系列对外部服务(例如 LLM、数据库和搜索引擎)的调用,所有这些都连接在一起。从架构上讲,没有太多新内容,一旦开发人员理解了 RAG 和 ReAct 等模式是什么,它们都很容易实现——带有对外部服务 API 调用的纯 Python 程序可以完全有效地实现目的。
通过观察许多内部用例,我们了解到深入了解执行细节至关重要。建立一种系统方法来跟踪与外部系统的交互是我们的设计重点之一。因此,我们采用了一种非常规方法——prompt flow 有一个 YAML 文件,描述了函数调用(我们称之为工具)如何执行以及如何连接成一个有向无环图(DAG)。
这种方法提供了几个关键优势,主要集中在增强可见性上
在开发过程中,您的流可以以易于理解的方式可视化,从而清晰地识别任何有故障的组件。作为副产品,您将获得一个可与他人共享的架构描述图。
流中的每个节点都以一致的方式可视化其内部细节。
可以单独运行或调试单个节点,而无需重新运行之前的节点。
prompt flow 设计中对可见性的强调有助于开发人员全面了解其应用程序的复杂细节。这反过来又使开发人员能够进行有效的故障排除和优化。
尽管有一些控制流功能,如“activate-when”来满足分支/switch-case的需求,但我们不打算让 Flow 本身是图灵完备的。如果您想开发一个完全动态且由 LLM 引导的代理,将 Semantic Kernel 与 prompt flow 结合使用将是一个不错的选择。