跳转到主要内容
Chinese, Simplified

category

TL;DR

 

有很多关于使用强大的大型语言模型(LLM)进行知识检索的教程。然而,如果考虑到这些技术在现实世界中的应用,则需要应用工程最佳实践,并应扩展这些实践,以减轻与LLM相关的一些新风险,如幻觉。在这篇文章中,我们探讨了如何实现LLM操作所需的一些关键领域,如安全、提示工程、接地和评估——开发一个简单的提示流,创建一个简单演示的人工智能助手,使用ReliefWeb平台上的情况报告中的信息回答有关人道主义灾难的问题。Prompt Flow包括一组用于编排LLM工作流的强大工具,而deep eval等包提供了使用LLM动态测试输出的方法(尽管有一些注意事项)。

操作大型语言模型应用程序


在之前的一篇博客文章“关于LLM应用程序操作的一些想法”中,我们讨论了在启动LLM应用时,除了生成人工智能这一闪亮的新技术之外,还有一系列因素需要考虑。许多工程要求适用于任何软件开发,如DevOps和有一个坚实的框架来监控和评估性能,但其他领域,如减轻幻觉风险,都是相当新的。任何组织推出一个新颖的生成性人工智能应用程序都会忽视这些,这将带来危险,尤其是在有偏见、不正确和缺失信息的高风险环境中。

Some of the key areas that should be considered before launching applications that use Large Language Models (LLMs). Source: Some thoughts on operationalizing LLMs

许多组织现在正在经历这一操作过程,并试图弄清楚如何准确使用新一代人工智能。好消息是,我们正处于一个支持产品和服务的阶段,这些产品和服务开始使应用程序安全、经济高效和准确的坚实原则变得更加容易。AWS Bedrock、Azure机器学习和工作室、Azure AI工作室(预览)以及各种其他供应商和开源产品都使LLM解决方案的开发更加容易。

提示流(Prompt Flow)


在这篇文章中,我们将重点关注使用Prompt Flow,一个由微软开发的开源项目…

Prompt Flow是一套开发工具,旨在简化基于LLM的人工智能应用程序的端到端开发周期,从构思、原型设计、测试和评估到生产部署和监控。它使提示工程变得更容易,并使您能够构建具有生产质量的LLM应用程序。

为什么提示流?


经过大量的个人研究,Prompt Flow已经成为在某些情况下开发LLM应用程序的一种很好的方法,因为以下原因…

  • 直观的用户界面。正如我们将在下面看到的,即使是简单的LLM应用程序也需要复杂的工作流程。Prompt Flow提供了一个很好的开发用户界面,使流更容易可视化,具有内置的评估功能,并与有可靠支持文档支持的Visual Studio代码进行了强集成。
  • 开源。这在应用程序被运送到具有不同基础结构需求的组织的情况下非常有用。正如我们将在下面看到的,Prompt Flow不与任何特定的云供应商绑定(尽管它是由微软开发的),并且可以通过多种方式进行部署。
  • Azure中的企业支持。尽管是开源的,但如果您使用Azure,Prompt Flow是本机支持的,并提供了广泛的企业级功能。作为Azure机器学习工作室和预览版Azure AI工作室的一部分,它提供了现成的安全性、可观察性和部署集成,从而腾出时间专注于业务用例
  • 易于部署。如上所述,在Azure上进行部署只需点击几下即可。但即使您在本地或其他云供应商上运行,Prompt flow也支持使用Docker进行部署

当然,它可能不适合所有情况,但如果你想要两全其美——Azure中的开源和企业支持——那么Prompt Flow可能适合你。

人工智能助理回答有关活跃的人道主义灾难的问题


在这篇文章中,我们将开发一个具有Prompt Flow的人工智能助手,该助手可以在令人惊叹的ReliefWeb平台上使用人道主义报告中包含的信息回答问题。ReliefWeb包括人道主义组织提交的内容,这些内容提供了有关世界各地灾难发生情况的信息,常用格式为“情况报告”。可能有很多内容,因此能够快速提取所需的关键信息比逐一阅读每份报告要省力。

请注意:本文的代码可以在这里找到,但需要注意的是,这是一个基本示例,仅用于演示LLM的一些关键概念。为了在生产中使用它,需要围绕ReliefWeb的集成和查询进行更多的工作,以及包括对PDF文档的分析,而不仅仅是对其HTML摘要的分析,但希望该代码提供一些人们可能会觉得有用的示例。

Process flow used in this article — A demonstration AI agent for answering questions about humanitarian disasters using information from situation reports on ReliefWeb. The full code can be found here.

演示应用程序已设置为演示以下内容…

  • 内容安全监控
  • 编排LLM任务
  • 自动自检以确保事实准确性和覆盖范围
  • 接地性批量测试
  • 在GitHub操作中使用Prompt Flow运行的自检
  • 部署


演示Prompt Flow应用程序的设置


本文的演示应用程序附带requirements.txt,如果您想在现有环境中安装它,请使用Python 3.11.4运行,否则请参阅下面的设置步骤。

如果您还没有这些,请安装…

  1. Visual Studio代码
  2. 提示流加载项
  3. Miniconda
    然后运行以下步骤…

4.您需要来自OpenAI或Azure OpenAI的LLM API密钥,以及您要使用的模型的部署名称

5.查看本文中包含Prompt Flow应用程序的应用程序回购

6.在回购的顶部文件夹中,将.env.example复制到.env,并在该文件中设置API密钥

7.在命令行设置一个环境,打开一个终端,然后在repo-top目录中运行:conda-env-create-f environment.yml。这将构建一个名为pf rweb demo的conda环境

8.打开VS代码

9.使用“文件”>“打开文件夹”打开repo,然后选择repo的顶部目录

10.在VS代码中,单击提示流图标——它看起来像左侧栏上的“P”


11.当你第一次点击这个时,你应该会在左上角看到下面的消息,点击“安装依赖项”链接


12.单击“选择Python解释器”,然后选择步骤7中构建的conda Python环境pf rweb demoyou。完成此操作后,库部分应


13.您现在应该在左侧导航栏上看到一个名为“Flows”的部分,单击“relief web_chat”并选择“Open”


这将打开提示流用户界面…


提示流用户界面为本文的演示代码。该流程展示了如何在LLM应用程序中编排阶段
12.单击左侧垂直条中的“P”(提示流),您应该会看到一个连接部分


13.根据您使用的服务,点击Azure OpenAI或OpenAI的“+”。

 

14.在连接编辑窗口中,将名称设置为合理的名称,如果使用Azure,则将字段api_base设置为基本URL。不要填充api_key,因为系统会提示您这样做。


15.单击小的“创建连接”,当提示输入您的API密钥时,您的连接现在已经创建

16.如果您正在使用Azure,并将连接称为Azure_openai,并且具有模型部署“gpt-4-turbo”和“got-35-turbo-16k”,则应进行配置,否则,请单击提示流用户界面中的任何LLM节点,并适当设置连接和部署名称。有关用于“extract_entities”LLM节点的设置,请参见下文


运行演示Prompt Flow应用程序


既然你已经做好了准备,任何时候你想运行流…

  • 按照上述步骤9-11所述打开流程
  • 点击流顶部的小双击图标

这应该运行完整的流程。要查看输出,您可以单击任何节点并查看输入/输出,甚至可以作为调试的一部分运行单个节点。

现在,让我们来了解一下应用程序的一些主要组件…

内容安全


任何使用LLM的聊天应用程序都应该进行一些测试,以确保用户输入和LLM输出是安全的。安全检查应包括以下方面:

  • 偏见
  • 仇恨言论/毒性
  • 自残
  • 暴力
  • 提示注入(黑客攻击以获得LLM的不同提示)
  • 侵犯知识产权


此列表并不详尽,也不是所有列表都适用,具体取决于应用环境,但应始终进行审查并确定适当的安全测试。

Prompt Flow与Azure内容安全集成,涵盖了上述部分内容,在流中创建新节点时选择“内容安全”非常容易实现。我最初将演示应用程序配置为使用它,但意识到并不是每个人都会使用Azure,因此流包括两个Python占位符节点content_safety_in和content_safety _out,以说明可以在哪里应用内容安全检查。这些并没有在演示应用程序中实现实际的安全验证,但Guardrails AI和deep eval等库提供了一系列可以在这些脚本中使用的测试。

content_safety_innode控制下游流,如果内容被认为不安全,则不会调用这些任务。

考虑到LLM输出在所提供的数据中有很大的基础,并且是动态评估的,对该应用程序的输出进行安全检查可能有些过头了,但它说明了在LLM应用程序中可以强制执行两点安全。

还应该注意的是,如果使用Azure模型库,Azure还提供LLM级别的安全过滤器。这是一种实现内容安全的方便方法,无需开发代码或指定流中的节点,单击按钮并为安全服务支付一点额外费用有时是更好的选择。

实体提取


为了查询ReliefWeb API,从用户的问题中提取实体并使用这些实体而不是原始输入进行搜索是很有用的。根据远程API,这可以产生更合适的情况报告来寻找答案。

演示应用程序中的一个示例如下…

用户输入:“有多少儿童受到苏丹危机的影响?”

LLM实体提取:

[
   {
      "entity_type": "disaster_type",
      "entity": "sudan crises"
   }
]


ReliefWeb API查询字符串:“苏丹危机”

这是一个非常基本的实体提取,因为我们只对一个简单的搜索查询感兴趣,该查询将在ReliefWeb API中返回结果。API支持更复杂的过滤,实体提取可以相应地扩展。其他命名实体识别技术,如GLiNER,可以提高性能。

从ReliefWeb API获取数据


一旦生成查询字符串,就可以调用ReliefWeb API。对于演示应用程序,我们将结果限制为前5个最新的情况报告,其中Python代码创建以下API请求…


{
   "appname": “<YOUR APP NAME>”,
   "query": {
       "value": "Sudan crises",
       "operator": "AND"
   },
   "filter": {
       "conditions": [
           {
               "field": "format.name",
               "value": "Situation Report"
           }
       ]
   },
   "limit": 5,
   "offset": 0,
   "fields": {
       "include": [
           "title",
           "body",
           "url",
           "source",
           "date",
           "format",
           "status",
           "primary_country",
           "id"
       ]
   },
   "preset": "latest",
   "profile": "list"
} 


【以上与本网站查询一致】

关于调用API需要注意的一点是,如果LLM直接处理API结果,它们可能会产生成本。我在这里写了一些关于这方面的内容,但对于少量的数据,上述方法应该足够了。

概述


尽管演示应用程序的重点是回答特定问题,但流程中包含了一个摘要节点,以说明LLM执行多个任务的可能性。这就是Prompt Flow在编排复杂的多任务流程时发挥良好作用的地方。

LLM摘要是一个活跃的研究领域,并提出了一些有趣的挑战。任何摘要都会丢失原始文档中的信息,这是意料之中的事。但是,控制哪些信息被排除在外是很重要的,并且将是特定于需求的。在总结救济网情况报告时,在一种情况下,确保准确反映与难民移民相关的所有指标可能很重要。其他情况可能需要将与基础架构相关的信息作为重点。要点是,摘要提示可能需要根据受众的要求进行定制。如果不是这样的话,有一些有用的通用摘要提示,如密度链(CoD),旨在捕捉相关信息。

演示应用程序有两个摘要提示,一个非常基本的提示…

system:
You are a humanitarian researcher who needs produces accurate and consise 
summaries of latest news
========= TEXT BEGIN =========
{{text}}
========= TEXT END =========
Using the output from reliefweb above, write a summary of the article.
Be sure to capture any numerical data, and the main points of the article.
Be sure to capture any organizations or people mentioned in the article.


以及使用CoD的变体…

system:

Article:

{{text}}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

You are an expert in writing rich and dense summaries in broad domains.

You will generate increasingly concise, entity-dense summaries of the above 
JSON list of data extracted.

Repeat the following 2 steps 5 times.

- Step 1: Identify 1-3 informative Entities from the Article
which are missing from the previously generated summary and are the most
relevant.

- Step 2: Write a new, denser summary of identical length which covers
every entity and detail from the previous summary plus the missing entities

A Missing Entity is:

- Relevant: to the main story
- Specific: descriptive yet concise (5 words or fewer)
- Novel: not in the previous summary
- Faithful: present in the Article
- Anywhere: located anywhere in the Article

Guidelines:
- The first summary should be long (5 paragraphs) yet
highly non-specific, containing little information beyond the entities
marked as missing.

- Use overly verbose language and fillers (e.g. "this article discusses") 
to
reach approx. 

- Make every word count: re-write the previous summary to improve flow and
make space for additional entities.

- Make space with fusion, compression, and removal of uninformative phrases
like "the article discusses"

- The summaries should become highly dense and concise yet self-contained,
e.g., easily understood without the Article.

- Missing entities can appear anywhere in the new summary.

- Never drop entities from the previous summary. If space cannot be made,
add fewer new entities.

> Remember to use the exact same number of words for each summary.
Answer in JSON.

> The JSON in `summaries_per_step` should be a list (length 5) of
dictionaries whose keys are "missing_entities" and "denser_summary".


问答


演示应用程序包含一个节点,用于回答用户的原始问题。为此,我们使用了如下提示:

system:
You are a helpful assistant. Using the output from a query to reliefweb, 
anser the user's question.
You always provide your sources when answering a question, providing the 
report name, link and quote the relevant information.

{{reliefweb_data}}

{% for item in chat_history %}
user:
{{item.inputs.question}}
assistant:
{{item.outputs.answer}}
{% endfor %}

user:
{{question}}


这是一个基本提示,其中包括请求包括参考资料和与任何答案的链接。

信息来源的归因


即使有LLM输出的验证和自动事实核查,提供所用数据源的归因链接也是非常重要的,这样人类就可以进行自我核查。在某些情况下,提供一个不确定的答案——明确地告知用户不确定性——仍然是有用的,只要有信息线索可以找到来源进行进一步的人工验证。

在我们的示例中,这意味着链接到用于回答用户问题的情况报告。这使得提问者能够跳转到来源,自己检查事实,并阅读其他上下文。在演示应用程序中,我们包含了两种归因方法。第一种是在提示中包含一个请求,如上所示。与任何LLM输出一样,这当然会导致幻觉,但正如我们将在下面看到的,这些都是可以验证的。

第二种方法是简单地整理API调用中返回的文档列表,对所有来源进行审查,即使其中一些没有用于答案。能够查看完整列表可以帮助识别由于API的查询方式而可能遗漏关键报告的情况。

这两种归因方法都有助于用户了解他们的答案是如何找到的。

自动事实核查


LLM信息提取虽然令人惊叹,但并不完美。在对内容提出问题的情况下,可能会出现幻觉和信息遗漏。因此,关键是要验证答案,以确保它不会提供不正确或不完整的信息。由于我们本质上是将一个文本(从API返回的原始数据)与LLM生成的文本(问答)进行比较,因此我们也可以使用LLM进行验证。有了良好的即时设计,即使不是绝对完美,也可以使其工作良好。

在演示应用程序中,我们包含了两种方法来说明…

实时事实核查

针对源数据检查LLM生成的输出的一个有用库是deep-eval,它为LLM生成输出提供了广泛的测试。在我们的示例中,我们实现了忠实性检查,以将答案与原始API输出进行比较,并给出0–1之间的分数和该分数的原因,其中1是可能的最佳分数。在演示应用程序中,即使分数小于1,我们也选择允许向用户提供答案,以及分数不够完美的警告和原因。

以下是一个示例答案,显示了对“苏丹危机中互联网提供商的现状如何?”问题的警告,我们有意调整了答案,称其影响很小,而不是源数据中提到的真正的重大通信中断…

世界粮食计划署(粮食计划署)领导的紧急电信集群(ETC)在“苏丹,冲突——ETC情况报
告#15报告期:2024年2月1日至2024年02月29日”中报告的苏丹互联网提供商的现状表明,
由于苏丹武装部队(SAF)和快速支援部队(RSF)之间的冲突,电信基础设施只受到轻微干
扰。以下是报告的相关摘录:
“据报道,苏丹三家主要互联网运营商于2月7日全部离线,这是影响数百万人的最新一次轻
微网络通信中断。”
这一信息表明,截至本报告所述期间,苏丹发生了轻微的网络中断,主要互联网运营商处于
离线状态,这将对该国的通信和应对工作产生轻微影响。
有关更多详细信息,您可以访问ReliefWeb上的完整报告:苏丹,冲突——ETC情况报告#15。
警告事实核查员的评估结果为0.88/1.0
原因
得分为0.88,因为实际产出错误地低估了苏丹电信基础设施的破坏程度,表明只有轻微的
破坏,而检索上下文表明电信基础设施和国家电网受到了广泛的破坏。

请注意末尾的“警告”部分以及相关的“原因”。

然而,应该注意的是,尽管深度评估提供了一种评估LLM的巧妙方法,但由于它使用LLM,有时也会出现幻觉。对于演示应用程序,重新运行同一个问题20次的性能是可以接受的,但对于生产,包括自检来评估评估(!)并确保行为符合预期是有意义的。

批量接地性测试

Prompt Flow支持的另一种方法是能够创建带有输入和上下文信息的测试文件,该文件可以在Prompt Flow批处理运行中执行。这类似于软件自检,但在评估LLM时,每次响应可能略有不同,在测试中使用LLM也很有用。在演示应用程序中,有一个针对批处理运行的基础测试,可以对所有测试的输出进行整理和总结,以便随着时间的推移跟踪性能。

出于演示目的,我们在演示应用程序中包含了批测试节点,但在实时应用程序中,它们不是必需的,可以删除以提高性能。

最后,值得注意的是,尽管我们可以实施策略来缓解LLM相关问题,但任何软件都可能存在漏洞。如果从API返回的数据一开始不包含所需的信息,那么再多的LLM魔术也找不到答案。例如,ReliefWeb返回的数据在很大程度上受到搜索引擎的影响,因此如果不使用最佳搜索词,重要报告可能不会包含在原始数据中。LLM事实检查无法控制这一点,所以重要的是不要忘记好的老式自检和集成测试。

LLMOs


现在我们在Prompt Flow中有了批测试,我们可以将它们作为DevOps或LLMOps过程的一部分。演示应用程序repo包含一组GitHub操作,这些操作自动运行测试,并检查聚合结果以自动确认应用程序是否按预期运行。此确认可用于控制应用程序是否已部署。


部署


这让我们开始部署。Prompt Flow提供了简单的部署方式,这是一个非常好的功能,可以节省时间,从而可以投入更多的精力来满足用户的需求。

“Build”选项将建议两个选项“Build as local app”和“Build as Docker”。


第一个非常有用,将推出聊天界面,但它只用于测试,而不是生产。第二个将构建一个Docker容器,以呈现运行该流的API应用程序。该容器可以部署在支持docker的平台上,并与Streamline、chailit、Copilot Studio等前端聊天界面结合使用。如果使用docker进行部署,则需要在托管docker容器的服务上配置应用程序使用方式的可观察性,这是确保人工智能安全的必要条件。

对于那些使用Azure的人,可以将流导入Azure机器学习,在那里可以像在VS代码中一样进行管理。这里的一个附加功能是,只需单击按钮,就可以将其部署为API。这是一个很好的选择,因为部署可以配置为包括详细的可观察性和安全监测,只需很少的努力,尽管需要一些成本。

最后的想法


我们已经对如何实现LLM操作时所需的一些重要概念进行了快速探索:内容安全、事实核查(实时和批量)、事实归因、即时工程和DevOps。这些都是使用Prompt Flow实现的,Prompt Flow是一个用于开发LLM应用程序的强大框架。

我们使用的演示应用程序只是一个演示,但它展示了在安全地考虑LLM应用程序产品化的各个方面时,复杂的简单任务是如何快速完成的。

注意事项和权衡


与所有事情一样,在实现上面的一些项目时也会进行权衡。添加安全测试和实时评估将减缓应用程序的响应时间并产生一些额外成本。对我来说,这是一种可以接受的权衡,可以确保解决方案的安全性和准确性。

此外,尽管LLM评估技术是使应用程序更加可信和安全的一大步,但使用LLM并非万无一失,有时会失败。这可以通过演示应用程序中LLM输出的更多工程以及LLM功能的进步来解决——这仍然是一个相对较新的领域——但值得一提的是,应用程序设计应该包括评估技术的评估。例如,创建一组具有定义的上下文和问题答案的自检,并在评估工作流程中运行这些自检,以使其有信心在动态环境中按预期工作。

我希望你喜欢这篇文章!

工具书类


Prompt Flow documentation

 

原文地址
https://architect.pub/humanitarian-crises-situation-report-ai-assistant-exploring-llmops-prompt-flow
本文地址
Article

微信

知识星球

微信公众号

视频号