今天介绍微软开源 Prompt 工程开发工具 PromptFlow,该工具旨在简化基于 LLM 的人工智能应用程序的端到端开发周期:从构思、原型设计、测试、评估到生产部署和监控。它使 Prompt 工程变得更加容易,并使您能够构建具有生产质量的 LLM 应用程序。
使用该工具可以:
• 创建将 LLM、提示、Python 代码和其他工具链接在一起的可执行工作流程。
• 轻松调试和迭代您的流程,尤其是与 LLM 的交互。
• 使用更大的数据集评估流程的质量和性能。
• 将测试和评估集成到您的 CI/CD 系统中,以确保流程的质量。
• 将您的流程部署到您选择的服务平台或轻松集成到应用程序的代码库中。
GitHub 地址
https://github.com/microsoft/promptflow
快速入门
下面演示如何:
• 设置 Python 环境以运行 Prompt Flow
• 克隆和运行示例流并了解什么是 Prompt Flow
• 使用可视化编辑器或 yaml 编辑流程
• 使用 CLI、SDK 和 VS Code 扩展来测试流
设置开发环境
使用 Python 3.9 以上的版本,还是使用我们最喜欢的 conda 来创建一个新环境:
conda create --name pf python=3.9
conda activate pf
安装promptflow 和 promptflow-tools:
pip install promptflow promptflow-tools
使用 pf -v 查看安装版本信息:
> pf -v
0.1.0b4
什么是流
这里的流是由函数组成的有向无环图(DAG),用 YAML 文件描述, 然后通过 Prompt Flow 执行器执行。
看看下面的例子就能明白:
• 左边是 YAML 表示
• 右边是可视化展示,YAML 的每个节点都和右边的节点对应
工程化
现阶段大多数的工具、框架(比如 LangChain)都没有提供工程化的相关支持,比如目录约定、构建发布等等。而 Prompt Flow 作为一个可以构建生产质量 LLM 应用的工具,提供了很好的工程目录供我们参考和使用。
我们可以直接去 Github 上下载查看样例:
https://github.com/microsoft/promptflow/tree/main/examples/flows
克隆项目,然后进入到样例目录:
git clone https://github.com/microsoft/promptflow.git
cd promptflow-main/examples/flows/standard/web-classification
比如官方推荐的模板项目:经典的 Web 分类任务。
有如下文件:
•
flow.dag.yaml:用于创作目的的具有输入/输出、节点、工具和变体的流定义;•
.promptflow/flow.tools.json:它包含 中引用的所有包工具元;• 源代码和模板(
.py、.jinja2):用户管理的,工具引用的代码脚本;•
requirements.txt:此流程的 Python 包依赖项;•
data.jsonl:json 数据文件;•
run.yaml:运行脚本;•
run_evaluation.yml:评估脚本。
创建连接
连接(connection)可以让我们安全地存储和管理与 LLM 等外部工具(例如 OpenAI、各种网络服务)交互所需的密钥或其他敏感凭据。
新建 connection.yaml 文件,填写你的 openai key:
$schema: https://azuremlschemas.azureedge.net/promptflow/latest/AzureOpenAIConnection.schema.json
name: open_ai_connection
type: open_ai
api_key: sk-***
organization: "" # optional
执行命令 pf connection create -f connection.yaml 创建 连接:
测试 Flow
刚才我们说了,这个样例目录任务是 Web 分类流,它将 URL 分类为几个预定义的类(分类是一项传统的机器学习任务)。
测试之前,先更改你想测试的网址作为默认输入,我们使用网速测试器 baidu 网站:
然后使用命令行运行:
pf flow test --flow . # 最后的点表示当前目录
可以看到控制台输出判断该网站是应用(APP):
然后我们再测试下清华大学的网站:
• https://www.tsinghua.edu.cn/xxgk.htm
可以看到得到的分类是大学(Academic):
PromptFlow 原理
我们刚刚运行完,也看到了结果,但是大家肯定都和我一样是一脸懵逼,有很多疑问:
• 刚才是啥?
• 做了什么?
• 为什么有了结果?
• 执行的逻辑是什么?
• 。。。
下面我们一起看看其背后的逻辑。
流程描述文件结构
首先查看 flow.dag.yaml 文件,主要有以下节点:
• $schema
• inputs
• outputs
• nodes
• node_variants
• environment
我们平时关心的就是输入、输出和节点三部分,节点部分会有多个节点相关连接,可视化如下:
输入
输入我们定义了一个叫 url 的参数,他是字符串类型,并且指定了默认值。
inputs:
url:
type: string
default: https://www.tsinghua.edu.cn/xxgk.htm
输出
输出定了两个参数 category 和 evidence,他们都是 convert_to_dict 方法的 output,所有的输出参数会以对象的方式方式返回(比如 JSON 或者 Dict), 也就是刚才我们执行流最后的输出:
outputs:
category:
type: string
reference: ${convert_to_dict.output.category}
evidence:
type: string
reference: ${convert_to_dict.output.evidence}
节点
节点就是具体处理流的步骤,以 DAG 的形式组织,这个流里面一共定义了五个节点:
读取网页
我们看下第一个节点,这是一个python 类型的节点,调用 fetch_text_content_from_url.py 文件, 使用 ${inputs.url} url 参数作为 python 代码的输入。
- name: fetch_text_content_from_url
type: python
source:
type: code
path: fetch_text_content_from_url.py
inputs:
url: ${inputs.url}
打开这个文件,可以看到使用 @tool 注解定义了方法,并接收了刚才声明的 url 参数,请求网页并,返回网页的前面 2000 个字符。
这个节点返回的数据可以被后来的节点使用。
LLM 判断
我们下面直接看第四个节点:节点的类型是 llm,使用 source 指定 Prompt 模板文件,以及输入参数,也就是模板文件的变量。
参数直接使用 任务名.output 来使用之前任意任务的输出结果,比如 ${summarize_text_content.output} 和 ${prepare_examples.output}。
- name: classify_with_llm
type: llm
source:
type: code
path: classify_with_llm.jinja2
inputs:
# This is to easily switch between openai and azure openai.
# deployment_name is required by azure openai, model is required by openai.
deployment_name: gpt-35-turbo
model: gpt-3.5-turbo
max_tokens: 128
temperature: 0.2
url: ${inputs.url}
text_content: ${summarize_text_content.output}
examples: ${prepare_examples.output}
我们再看一下 Prompt 模板文件:
模板语法看不懂的话可以忽略,是不是和我们平时的 OpenAI Prompt 编程一样!
这里明确了分类的判断逻辑,你的分类可以是哪些以及证明可以是哪些:
最后还明确了返回数据的格式,就像我们之前《万物皆可 LLM》系列文章一样。
OUTPUT:
{"category": "{{ex.category}}", "evidence": "{{ex.evidence}}"}
其他的节点类似,我们不挨个看了。
回顾流程
在回头看可视化的流程就很清晰了:
• 首先定义输入的参数
• 执行 python 节点:获取网页内容
• 执行 llm 节点:对网页内容进行摘要
• 同时使用 Python 节点:准备样例数据(少样本学习)
• 执行 llm 节点:把摘要和样例的结果给 llm 判断,输出指定格式
• 执行 python 节点:把 llm 判断结果格式化输出
是不是很清晰,也很简单,我们不需要进行复杂的逻辑组织,只需要专注每个节点的逻辑,以及输入输出, Prompt Flow 会自动进行 DAG 图的组织。
总结
今天我们从零开始了解微软这个开源工具如何将 LLM 开发进行工程化的一个实现。
它还有很多其他的能力,比如 可视化的编辑、SDK 的编程、部署、发布、调试、监控等一些生产级别的特性,我们以后慢慢聊。
--- END ---

