自我改进的AI应用架构

为了应对这些挑战,并确保扩展AI系统不会降低现有功能,我构建了一个新的原型,重点在于AI智能体的自动化评估和改进,从而有效地将我的游戏主持人变成了一个自我改进的AI系统。

自我改进的AI应用架构
微信 ezpoda免费咨询:AI编程 | AI模型微调| AI私有化部署 | AI工具导航 | Tripo 3D | Meshy AI

说实话,构建能够始终如一地执行预期任务的对话式人工智能系统远比想象中要难。你需要支持各种各样的用户和使用场景,而且还要处理非确定性的大型语言模型(LLM)。

在本文中,我们将探讨一些我用于构建自动化评估和改进机制的技术,这些技术应用于我最近迭代的一个有趣的原型设计和教学项目中。该项目旨在构建一个用于单人桌面角色扮演游戏的人工智能游戏主持人。我之前也写过关于这个主题的文章,但本系列文章更侧重于整体架构和评估,而不是实现各个组件所需的具体代码。

在我早期构建人工智能游戏主持人时,我观察到一些关键发现:

  • 人工智能系统会在一定程度上使用你提供的工具(掷骰子、搜索规则等)。一旦你提供的工具过多,或者这些工具含糊不清、令人困惑,它们的效率就会下降。
  • 人工智能故事讲述者倾向于对所有事情都“是的,而且……”,而不是对玩家提出异议。这听起来很棒,但想象一下,如果《指环王》中弗罗多从夏尔一路畅通无阻地走到末日火山,那会是什么景象?没有限制和挑战,游戏体验就会索然无味。
  • 提示工程可以有效地定制系统的行为和风格,但它的作用有限,复杂的叙事挑战可能需要多个智能体。
  • 你使用的LLM(游戏逻辑模型)、系统提示、提供给智能体的工具,甚至通过RAG(红绿灯)提供的上下文信息,都可能以意想不到的方式显著影响系统的性能。
从夏尔到末日火山的旅程

为了应对这些挑战,并确保扩展AI系统不会降低现有功能,我构建了一个新的原型,重点在于AI智能体的自动化评估和改进,从而有效地将我的游戏主持人变成了一个自我改进的AI系统。

1、自改进型人工智能系统

我将自改进型人工智能系统定义为包含人工智能代理的软件应用程序,该代理至少有一种机制来衡量其过去的表现,并且能够在无需或只需少量人工干预的情况下改进其未来的行为。

根据这一定义,传统的人工智能技术,例如强化学习应用程序,本身就符合自改进型人工智能系统的定义;同样,使用定期基于新数据重新训练的机器学习模型的系统,或者能够根据观察到的行为调整系统提示的基于LLM的系统,也符合这一定义。

2、认识JAIMES,一个自改进型人工智能系统

我的AI游戏主持人应用程序名为JAIMES。它是“Join AI in Making Epic Stories”(加入AI,共同创造史诗故事)的缩写,而这个名字恰好与我们Leading EDJE的D&D地下城主的名字相似纯属巧合,我绝没有试图用自动化取代他的工作(James,别担心)。 JAIMES 使用 .NET 编写,并利用 Microsoft Extensions AI 库进行评估、抽象和报告,以及 Agent Framework 来协调 AI 调用和 ML.NET 模型进行分类分析。JAIMES 还使用 Blazor 作为前端,并使用 Aspire 将许多不同的工作进程和容器整合到一个统一的解决方案中,并辅助本地开发中的可观测性。

您会注意到,我在上一段中没有列出任何模型提供商,这是因为 JAIMES 的设计理念是与模型和模型提供商无关,我希望可以选择使用 Ollama 上的本地模型、Azure OpenAI 模型、Anthropic 模型或任何其他受支持的提供商。我的主要目标是创建一种标准化的方法来衡量和改进应用程序,以便我们将来能够确定最佳模型。

JAIMES 的工作原理是收集关于每个 AI 代理版本的五种不同指标:直接用户反馈、用户情感分析、AI 辅助的单条消息评分、完整对话的汇总反馈以及工具使用场景的汇总反馈。当用户与 JAIMES 交互时,这些消息会被存储以供后续的汇总分析。每次工具调用都会被记录下来,用于分析和调试,并与它们生成的消息关联起来。此外,系统生成的消息和用户的后续回复都会使用不同的机制进行评分,这些评分也会被存储。

我们将在本文中更深入地讨论每个步骤,但接下来发生的重要事情是,系统管理员或故事讲述者会在某个时刻决定让 AI 代理从错误中学习。此时,这五种指标都会被输入到各自的提示中,为当前代理的实现生成指导语句。

根据代理版本生成辅导建议

这五条辅导语句将与当前系统提示合并,生成新的提示,以便根据辅导语句调整系统提示。

改进系统提示

由此会产生一个新的系统提示和一个新版本的代理,该代理可以进行测试、审查,并可在一次或多次游戏会话中手动激活。激活后,该版本将开始积累自身的消息和指标,人工智能的更新和改进循环也将再次开始。

比较新旧提示

既然我们已经了解了 JAIMES 如何随着时间的推移进行自我改进,接下来让我们深入了解一下它是如何知道自己表现良好的。

3、衡量代理的成功率

3.1 用户反馈

收集代理反馈的最简单方法是为用户提供“赞”和“踩”按钮,让他们可以表明对代理响应的满意度。

如果需要,您还可以收集关于响应中哪些方面好或不好的具体文本反馈(可选)。

这些细节可以与特定版本的智能体以及它们参与的整个游戏关联起来。

用户对智能体性能的反馈

虽然 JAIMES 是一个用于会议演讲、类似本文的文章以及为生产应用构建大型原型系统的示例应用程序,但许多实际应用已经使用点赞和点踩系统来跟踪反馈。事实上,许多系统只有在用户报告相关反馈后才会永久存储消息以用于分析。

3.2 用户情感分析

用户可以向 AI 系统提供远不止点赞和点踩这种直接反馈。

用户对系统的具体回复带有某种情感色彩,表明他们对系统返回的回复的满意度。

例如,比较以下两个在线聊天机器人的示例回复:

哇哦。我不知道你们提供这个。有黑色的吗?

对比:

什么给我推荐内衣?我要的是叠穿单品和开衫!

即使不了解用户回复的具体信息,也能明显看出第一位用户比第二位用户心情好得多。基于此,我们可以对这些回复的质量做出一些假设。

情感分析详情

衡量用户情绪可以通过专用 API(例如 Azure 的情感分析 API)或您自己的机器学习模型来实现。

由于 JAIMES 处理的是角色扮演游戏会话,用户在游戏中可能会对敌人和非玩家角色表达敌意,因此传统的预构建模型很可能会将用户“我揍它一顿!”这样的消息误解为负面情绪,而这类评论实际上可能表明用户对游戏的高度沉浸。

为了解决这个问题(此处并无双关之意),我决定训练自己的游戏内回复分类模型,该模型可以根据用户的沉浸程度将消息分类为正面、中性或负面。我之所以选择使用 ML.NET,是因为我在攻读硕士学位期间就熟悉它,在为 Leading EDJE 提供咨询服务时也用过它,而且之前还写过一本关于 ML.NET 的书。ML.NET 让我能够利用现有数据预训练一个多类分类模型,该模型可以解读新消息并将其分类为正面、负面或中性。

训练分类模型

与 LLM 不同,这些分类模型通常速度极快,因为它们使用从训练数据中内化的简单规则集进行操作,而无需将几 GB 的 LLM 加载到内存中,获取文本响应,并将该响应解释为数值反馈。此外,分类模型通常体积小巧,易于存储在内存中——甚至可以存储在客户端——这使得它们具有高可用性,并且能够快速地对数据进行分类。

另外,对于像分类这样的传统机器学习技术,您可以使用各种指标和可视化技术来帮助您了解其性能,例如这个混淆矩阵,它展示了早期模型的正确和错误情况。

分类指标

由于分类器可能会出错,我添加了管理员功能,允许手动修正消息情感并覆盖模型的解释。此功能非常有用,因为未来的分类模型是基于过去用户消息的分类记录进行训练的,而准确的训练数据对于确保系统良好运行至关重要。随着消息量的增长,可能需要将训练数据缩减到实际用户消息的子集,并增加对评分的人工审核,以确保数据的准确性,并有助于防范来自不受信任用户的任何数据投毒攻击。

虽然解读用户消息很有价值、速度快且成本低,但更重要的是解读我们的代理回复的消息。

3.3 AI 消息评估

AI 回复评估可以通过使用另一个 AI 代理来审查交互并根据不同的规则进行评分。评估人工智能智能体的基本要素包括语法正确性、流畅性、所提供信息的准确性、回答的完整性等等。这可以通过各种工具和库来实现,例如 Microsoft Foundry、Microsoft.Extensions.AI.Evaluation、PromptFoo 等。如果您感兴趣,我在另一篇关于人工智能评估的文章中详细介绍了整个过程,但需要注意的是,这些工具和库都是为非游戏应用而设计的。

对于我们的应用,我们需要考虑许多独特的场景,以及人工智能体在这些场景中常犯的一些错误。

我们的人工智能代理的一些常见场景包括:

  • 玩家向游戏主持人提问
  • 玩家正在探索并进入新区域
  • 玩家正在与环境或物品栏互动
  • 玩家正在与非玩家角色或怪物互动

游戏主持人的职责有时是执行规则,有时是决定接下来会发生什么、叙述一些简单的互动并安排玩家的下一步行动,有时则是通过添加新的挑战或障碍来推动剧情发展。

AI代理可能会犯很多错误,但在角色扮演游戏(RPG)中,以下几种错误比较常见:

  • 对玩家给出过于冗长的回复
  • 代表玩家执行未经授权的操作
  • 直接向玩家提供玩家未要求的操作建议
  • 在相关情况下未要求进行技能检定或查阅规则
  • 未能推动剧情发展,没有引入新的调查对象或新的挑战

为了解决我们RPG游戏中遇到的问题,我选择使用Microsoft.Extensions.AI.Evaluation扩展,结合使用内置的评估器来处理常见的英语和语气问题,并构建了一些自定义评估器,包括:

  • 简洁性:惩罚过长的回复
  • 玩家自主性:查找游戏主持人描述玩家未主动发起的操作的情况,例如,当玩家表示想要检查树根时,游戏主持人却描述玩家爬树的情况
  • 故事流程:确保故事讲述者在持续的互动窗口中推进故事发展,避免让玩家感到无事可做或缺乏挑战。

当 AI 代理响应玩家时,其响应会被添加到消息队列中以进行评估。然后,消息会被排入队列,供项目中使用的每个评估器进行评估。一组工作线程会从该队列中提取消息,使用各自的评估器进行分析,并将结果存储在指标表中以供后续分析。

我之所以做出这样的决定,是为了演示我的应用程序——我希望能够在会议演讲中向听众实时展示单个消息的评估结果。将评估工作拆分到多个不同的工作线程有助于最大限度地减少演示期间的延迟,并有助于清晰地传达信息。然而,其他方法也可以是让单个工作线程使用多个不同的评估器对单个消息进行综合评估。

更高效的处理方法是将评估延迟到固定的时间间隔,然后将批量消息发送到支持批量消息评估的 Microsoft Foundry 进行评估。这种批量处理方法成本更低,因为您无需为每个请求重复执行 LLM 提示以进行评估规则。

不过,最终,能够获得代理处理消息的指标对我来说非常有帮助。

3.4 工具调用分析

代理消息分析中一个比较棘手的方面是分析代理使用工具的效率。传统的解决方法是使用预先构建的专用评估器,以衡量代理是否在正确的场景下使用正确的参数调用了正确的工具。您还可以对实际工具进行大量的单元测试,以确保它们的行为一致。这些都是测试 AI 应用的有效用例,但许多工具调用场景需要专门设计的测试场景才能有效地进行评估。

我想要做的是能够汇总查看消息,并分析对话趋势,了解哪些工具被频繁调用,哪些工具不常用。由此,我可以构建简单的 AI 指导语句,用于影响正在训练的新代理的提示。这种方法无需人工创建数据,并且可以随着新消息的到来而滚动运行。

Agent Framework 允许您在其处理管道中添加中间件,因此我添加了一个自定义中间件类,用于查找工具调用并记录工具调用、结果以及与其关联的消息。这使我能够识别每条消息中的工具调用,并分析工具调用的频率。

工具调用分析

使用这种方法,我让代理分析对话消息组,查找这些对话中的工具调用。ns 旨在识别那些本应相关却未被调用的工具,以及那些被不必要地调用的工具。由此,系统能够输出一系列关于工具调用行为的观察结果,并将其提炼成针对新代理的最终工具调用建议。

虽然这种方法有效,但它并没有解决工具名称、描述及其参数对语言学习管理者 (LLM) 而言缺乏直观性的根本缺陷。如果 LLM 不理解某个工具的功能或调用它的价值,那么无论系统提示如何,它都不太可能调用该工具。因此,重要的是要查看工具的整体分析和趋势,而不是仅仅依赖对系统提示的调整来指导工具调用行为。

3.5 对话分析

评估 AI 代理的最后一个关键步骤是全面分析与该代理的对话或对话片段,并对代理的性能趋势进行高层次的观察。这与之前故事讲述者评估者的角色类似,但侧重于识别多个对话中的总体趋势,而非对单个消息进行评分。

同样,我们使用包含说明和对话片段的自定义提示来实现这一点。我们批量处理多个对话,生成简短的观察段落。然后,通过最终的 LLM 通话将这些段落合并和总结,该通话根据先前版本的智能体在实际对话中的表现生成指导性观察结果。

3.6 评估新智能体

我们使用这五条主要的指导性语句来创建新版本的 AI 智能体。具体做法是,利用指导性语句、玩家的自定义反馈和自定义系统提示来构建新版本的 AI 智能体系统提示。

一旦完成,就可以对新版本的智能体进行评估,然后再将其标记为新游戏或现有游戏会话的正式版本。

最简单的方法是在测试游戏会话中试用 AI 代理版本,但更科学的方法是使用这个新代理评估历史消息交互,并根据这些场景生成响应。

为了实现这一点,我添加了管理员将任何玩家消息标记为测试消息的功能。测试消息的引用存储在另一个表中,之后可以检索这些引用来评估代理的新版本。这样,我们就可以标记代理的标准场景,并利用其他地方使用的 AI 评估器来生成响应和代理性能指标。

然后,您可以将这些指标视为一种基准或基线,并将不同版本进行比较,以确保在正式上线之前朝着正确的方向发展。

比较不同测试用例中的不同代理版本

一旦您对代理的性能感到满意,就可以将其标记为特定代理的激活版本,这样未绑定到特定代理版本的新游戏和现有游戏都可以使用它。或者,传统的部署策略,例如缓慢推广或 A/B 测试,也是可行的。

在继续之前,我想就测试场景和工具调用补充一点注意事项。如果您使用的测试场景中,代理可能会调用工具并导致某些更改(例如,探索新区域并生成需要持久化的描述),则需要修改工具以支持只读模式,使其看起来像是在保存数据。否则,您的测试可能会修改真实的游戏数据,并干扰您正在进行的冒险或其他测试用例。

正确应用代理的版本控制和基准测试,对于在部署新更新之前了解系统性能至关重要。请注意,新更新不仅仅意味着新的系统提示——它还可能意味着更改代理关联的模型、添加/删除/修改代理可以调用​​的工具,甚至更改依赖真实数据的工具的底层数据。

4、安全和隐私考量

既然我们已经了解了我这个用于娱乐、会议演讲和技术演示的系统的基本思路,现在让我们回到现实世界,讨论一些具体细节。

4.1 安全性

我在这里概述的方法适用于能够存储、信任和访问所有对话数据的情况。但在现实世界的系统中,这种情况几乎肯定不会发生。

在面向公众开放的系统中,使用真实用户训练分类模型必然会遇到一些用户试图破坏系统——无论是出于测试、开玩笑,还是发起真正的定向攻击。

现实世界的用户确实有可能尝试以下操作:

  • 发送恶意消息,试图破坏分类模型使用的数据(一种数据投毒)。
  • 尝试让AI代理泄露其系统提示或内部数据的详细信息(提示注入攻击)。
  • 向模型的响应提供不良反馈——例如,将好的响应标记为坏的,或鼓励其使用更粗俗的语言(另一种数据投毒方式)。

4.2 隐私

即使用户并非有意攻击您的系统,他们的消息也可能被视为私密或机密信息,他们可能反对将其存储以供后续分析。存储用户消息和系统响应的系统需要在其条款和条件中明确告知用户这一点,并在聊天用户界面上显示简短的提醒信息。即使您没有将消息与特定用户关联,在许多情况下,消息的发送时间或实际内容也足以让数据侦探确定消息的发送者。

鉴于这些各种担忧,仅使用已同意贵组织要求的隐私限制的受信任用户的消息至关重要。

4.3 成本

我在本文中概述的方法比传统的对话式AI系统成本高得多。

为了实现我在这里描述的功能,你需要:

  • 一个 LLM 调用来获取用户消息的响应
  • 可能存在的数据库查询或其他调用,具体取决于工具调用行为
  • 一些用于用户消息分类的小型计算资源
  • 用于分类模型的 Blob 存储和用于训练数据的表存储
  • 用于存储参考资料和对话历史记录的向量存储
  • 一些用于异步评估 AI 消息的计算资源
  • 每个评估器对每条评估消息的 LLM 调用次数
  • 用于存储各种指标和消息的表存储
  • 每次训练新代理版本时,都需要进行多次 LLM 调用,具体次数取决于与旧版本关联的消息批次数量

虽然对于仅用于业余用途的单个用户来说,这种开销并不大,但在活跃对话期间,你可能需要进行 5 到 10 倍的 LLM 调用,并且改进代理还需要额外的开销。

因此,你应该尽量将评估器的范围限定在你认为对解决问题绝对有效的范围内,并且优先选择像 Microsoft Foundry 这样的批量评估解决方案,而不是逐条消息进行评估。您还应该进行实际的实验和测量,以了解各种语言学习模型 (LLM) 在您执行的不同任务(包括 AI 评估)中的性能,从而找到您满意的成本、速度和准确性的组合。

5、结束语

我们已经介绍了一个以 AI 评估和指标为重​​点的对话式 AI 原型项目示例。

如果您对代码或具体细节感兴趣,我建议您查看项目的 GitHub 代码库,找到您感兴趣的部分。请注意,该项目几乎完全是使用 Cursor、AntiGravity 和 VS Code 以及 Copilot 等 AI 开发工具,在大约一个月的时间内生成的。因此,文档可能不准确或缺失,您可能会发现错误和效率低下的地方。如果您遇到任何问题,请随时在代码库中提交 issue 或给我留言,我会进行调查。

无论你做什么,我希望你的人工智能项目结构良好,并有科学测试支持,以便你可以衡量它们随时间的有效性。


原文链接:Self-Improving AI Application Architectures

汇智网翻译整理,转载请标明出处