设计原则#

当我们开始这个项目时,LangChain已经变得非常流行,尤其是在ChatGPT发布之后。我们经常被问到的一个问题是,prompt flow和LangChain之间有什么区别。本文旨在阐明构建prompt flow的原因以及我们所做出的深思熟虑的设计选择。简而言之,prompt flow是一套开发工具,用于通过实验构建LLM应用程序,并特别强调质量,而不是一个框架——LangChain是框架。

虽然LLM应用大多处于探索阶段,但微软在这一领域起步较早,我们有机会观察开发者如何将LLM集成到现有系统中或构建新的应用程序。这些宝贵的见解塑造了提示流的基本设计原则。

1. 暴露提示与隐藏提示#

LLM应用的核心本质在于提示本身,至少在今天是这样。当开发一个相当复杂的LLM应用时,大部分开发工作应该是“调整”提示(注意我们有意使用了“调整”这个词,我们稍后会进一步探讨)。任何试图在这一领域提供帮助的框架或工具都应该专注于使提示调整更容易和更直接。另一方面,提示非常不稳定,不太可能编写一个可以在不同模型甚至同一模型的不同版本中工作的单一提示。要构建一个成功的基于LLM的应用程序,你必须理解引入的每一个提示,以便在必要时进行调整。LLM还不够强大或确定性,你不能像在传统编程语言中使用库那样使用别人编写的提示。

在这种情况下,任何试图通过在库中封装一些提示来提供智能功能或代理的设计,在现实场景中都不太可能产生有利的结果。将提示隐藏在库的代码库中只会使人们难以改进或调整提示以适应他们的特定需求。

Prompt flow,作为一种工具,避免在其核心代码库中包含任何提示。你唯一会看到提示的地方是我们的示例流程,这些示例流程当然可供采用和使用。每个提示都应由开发者自己编写和控制,而不是依赖我们。

2. 一种新的工作方式#

大型语言模型(LLMs)拥有显著的能力,使开发者能够在不深入机器学习复杂性的情况下增强他们的应用程序。同时,LLMs使这些应用程序变得更加随机,这对应用程序开发提出了新的挑战。仅仅在门控测试中断言“无异常”或“结果 == x”已经不够了。采用新的方法和使用新的工具变得至关重要,以确保LLM应用程序的质量——需要一种全新的工作方式。

这一范式转变的核心是评估,这个术语在机器学习领域经常使用,指的是评估训练模型性能和质量的过程。它涉及衡量模型在给定任务或数据集上的表现,这对于理解模型的优势、劣势和整体有效性起着关键作用。评估指标和技术根据具体任务和问题领域的不同而有所变化。一些常见的指标包括准确率、精确率和召回率,你可能已经熟悉这些。现在,LLM应用程序与机器学习模型有相似之处,它们需要在开发工作流程中集成以评估为中心的方法,并建立一套强大的指标和评估体系,以确保LLM应用程序的质量。

Prompt flow 提供了一系列工具来简化新的工作方式:

  • 将您的评估程序开发为评估流程,以计算您的应用程序/流程的指标,从我们的示例评估流程中学习。

  • 通过SDK/CLI迭代您的应用程序流程并运行评估流程,使您能够比较指标并选择最佳发布候选。这些迭代包括尝试不同的提示、不同的LLM参数(如温度等)——这在前文中被称为“调优”过程,有时也被称为实验。

  • 将评估集成到您的CI/CD管道中,使您的门控测试中的断言与所选指标保持一致。

Prompt flow 引入了两个概念组件来促进这个工作流程:

  • 评估流程:一种流程类型,表示此流程不用于部署或集成到您的应用程序中,而是用于评估应用程序/流程性能。

  • 运行:每次使用数据运行流程,或对流程的输出进行评估时,都会创建一个运行对象来管理历史记录,并允许进行比较和额外的分析。

虽然新概念引入了额外的认知负担,但我们坚信它们比抽象不同的LLM API或向量数据库API更为重要。

3. 优化“可见性”#

由于大型语言模型(LLMs)的出现,出现了许多有趣的应用模式,如检索增强生成(RAG)、ReAct等。尽管LLMs的工作原理对许多开发者来说可能仍然是个谜,但LLM应用的工作原理并非如此——它们本质上涉及一系列对外部服务(如LLMs、数据库和搜索引擎)的调用,所有这些都被粘合在一起。从架构上看,并没有太多新意,一旦开发者理解了这些模式,像RAG和ReAct这样的模式实现起来都很直接——只需使用Python程序调用外部服务的API就可以完全有效地达到目的。

通过观察许多内部使用案例,我们了解到深入了解执行细节至关重要。建立一种系统的方法来跟踪与外部系统的交互是设计优先事项之一。因此,我们采用了一种非常规的方法——prompt flow 有一个 YAML 文件,描述了函数调用(我们称之为工具)如何执行并连接成有向无环图(DAG)。

这种方法提供了几个关键优势,主要集中在增强可见性上:

  1. 在开发过程中,您的流程可以以易于理解的方式可视化,从而清晰地识别任何有问题的组件。作为副产品,您将获得一个具有架构描述性的图表,可以与其他人共享。

  2. 流程中的每个节点都以一致的方式可视化其内部细节。

  3. 单个节点可以单独运行或调试,而无需重新运行之前的节点。

promptflow-dag

在提示流设计中强调可见性有助于开发者全面了解其应用程序的复杂细节。这反过来使开发者能够进行有效的故障排除和优化。

尽管有一些控制流特性,如“activate-when”来满足分支/switch-case的需求,但我们并不打算使Flow本身成为图灵完备的。如果你想开发一个完全动态并由LLM引导的代理,结合Semantic Kernel和提示流将是一个有利的选择。