你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文介绍在创建具有 AI 功能的应用程序时做出技术和方法决策时要考虑的常见设计领域和因素。 本指南适用于传统的机器学习和生成式 AI 工作负载。 它涵盖了 TensorFlow、Keras 和 PyTorch 等框架,以及各种服务和托管选项,包括批处理、流和联机处理。
在将智能功能设计到工作负荷时,需要考虑许多选择。 独特的功能和非功能要求可帮助你确定是需要基本推理功能还是需要更多动态问题解决功能。 这些要求指导你的高级设计决策。 从高级设计区域移动到较低级别的设计区域时,请考虑这些选择。
如 入门 一文中所述,无论是构建自己的模型还是使用预生成模型,都是要做出的第一个重要决策之一。 使用预生成模型时,请考虑以下几点:
目录源: 浏览像 Hugging Face 模型中心、TensorFlow 中心和 Azure AI Foundry 门户 模型目录等存储库,来查找预训练模型。 这些平台为各种任务提供了广泛的模型目录。
发 牌: 确保模型的许可条款符合安全、合规性和应用程序目标,尤其是在计划分发应用程序或将其与其他服务集成时。
关键组件: 查看模型的体系结构、训练数据和性能,以确定它是否针对任务或域进行了微调。
有关如何选择托管平台的指导,请参阅 模型托管和推理平台的注意事项。
应用程序层体系结构
设计智能功能时,请在设计中跨以下五个关键层建立明确的边界。
客户端层: 用户或进程体验工作负载智能功能的用户界面和客户端应用程序。 将此层精简,并将大多数功能委托给其他层。
智能层: 协调 AI操作的路由、编排和代理能力。 此层包括模型路由、聊天管理和智能决策。
推理层: 运行经过训练的模型,以基于数据生成预测或决策。 此层处理模型加载和运行时调用、输入预处理和输出后处理,以及通过 API 或嵌入式系统提供预测。
知识层: 为智能层提供相关上下文和信息的地面数据、知识图和检索服务。 此层强制实施数据访问策略和授权。
工具层: 智能层可以调用的业务功能接口、外部服务和动作能力。 此层应使用标准化接口并强制实施自己的安全策略。
每个层都强制实施自己的策略、标识和缓存策略,以实现其自己的本地化可靠性、安全性和性能要求。 这些层还支持重点开发、测试和故障排除。
建议
下表总结了本文中提供的建议。
| 建议 | 说明 |
|---|---|
| 确定安全性和负责任的 AI 控件的优先级。 | 将传统的应用程序安全性以及 AI 特定的安全措施作为主要设计驱动程序实现。 强制实施提供者安全系统、输入/输出过滤、基于身份的速率限制和配额、以及令牌和提示上限。 安全和安全控制必须经过验证,并且无法从托管服务中假定。 |
| 使智能远离客户端。 | 设计后端服务来处理跨领域问题,例如速率限制、故障转移作和 AI 处理逻辑。 将客户端的行为和智能抽象化,以提高设计的未来适应性和可维护性。 |
| 阻止直接访问数据存储。 | AI 系统中的代码不应直接访问数据存储。 通过 API 或类似的数据访问抽象路由所有数据请求,该抽象强制实施授权并将用户或租户上下文传播到检索和筛选中。 传递用户标识,以便应用数据级安全性。 |
| 抽象模型和工具。 | 使用抽象层将应用程序与特定模型、工具和技术分离。 实现标准化接口和协议,以随着技术的发展提供灵活性,从而使设计更具可维护性和前瞻性。 |
| 隔离行为和动作。 | 设计跨客户端、智能(路由/业务流程/代理)、知识(地面数据)和工具(业务 API)层的明确边界。 每个层都应强制实施自己的策略、标识和缓存策略,以减少爆炸半径和重点开发工作。 |
| 确定预生成解决方案的优先级。 | 当软件即服务(SaaS)或平台即服务(PaaS)满足安全性、安全、合规性和配额需求时,可以使用软件即服务(SaaS)或平台即服务(PaaS)来处理工作负荷功能。 通过强制身份验证、配额、安全和日志记录的网关实施补偿控制。 尽可能使用预生成模型和预训练模型,以最大程度地减少工作负荷和运营团队的作和开发负担。 |
区分推理和智能应用程序
在设计应用程序体系结构时,首先确定是构建以推理为中心的应用程序还是以智能为中心的应用程序,因为此区别会驱动设计决策。
推理应用程序
推断应用程序执行分类、翻译或汇总等单步作。 这些应用程序具有更简单的体系结构。
典型体系结构: 客户端与提供身份验证、配额、安全和路由的 AI 网关通信。 该网关调用模型服务层,包括 Azure AI Foundry、Azure Kubernetes 服务(AKS)或托管在线终端。 在实际情况下,在返回到客户端之前,可能会缓存结果以供将来推理调用使用。
推断应用程序通常具有直接模型调用的功能,需要最少的业务流程,专注于性能和吞吐量,并且不需要复杂的状态管理。
智能应用程序
智能应用程序执行规划、协调和多步骤推理,通常通过代理和代理编排进行处理。 他们需要在其体系结构中解决更多概念。
典型体系结构: 客户端调用代理或代理业务流程协调程序。 根据设计或自治功能,此层调用工具层,例如模型上下文协议(MCP)服务器或自定义 API。 代理可能需要调用基础知识服务,例如搜索索引、数据库或图形。 在此过程中,可以在多个点调用模型。 缓存还可以在多个级别进行,以优化进程。
智能应用程序通常具有复杂的工作流协调、自主代理模式,以及模型路由,与多个数据源和工具集成,并需要对话管理和上下文管理。
基本 AI 应用程序设计指南
设计 AI 应用程序时,请遵循以下基本准则来创建可复原且可维护的系统。
从业务成果开始
在选择技术之前,请明确定义要解决的业务问题。 此定义指导技术选择和体系结构设计。 请考虑下列因素:
成功指标: 定义可衡量的结果,这些结果演示了价值,例如准确性改进、成本降低或用户满意度分数。
用户体验要求: 了解用户和流程如何与 AI 功能交互,以及他们期望的响应时间。
法规约束: 确定可能影响设计选择的符合性要求,例如数据驻留或可解释性要求。
从第一天起就注重安全设计
AI 工作负载要求从一开始就采用安全优先的方法。 使用标识传播和可审核的控制跨所有组件实现分层安全性。 有关详细信息,请参阅 安全设计策略。
从第一天起设计可观测性
AI 应用程序需要超越传统应用程序指标的监控。 从一开始就将可观测性构建到设计中:
模型性能跟踪: 监视准确性偏差、推理延迟和预测置信度分数。
数据质量监视: 跟踪可能影响模型性能的输入数据分布更改。
用户交互分析: 了解用户如何与 AI 功能交互,以确定改进机会。
规划抽象化和未来的灵活性
使用抽象层设计系统,以便随着 AI 技术的发展而适应:
模型抽象: 在一致的接口后面抽象模型,以便在不更改应用程序的情况下进行交换或升级。
标准化协议: 首选开放、记录的接口和格式,例如用于工具的 OpenAPI、ONNX 用于模型可移植性,以及遥测的 OpenTelemetry。
基于功能的设计: 围绕功能而不是特定技术进行设计,以保持灵活性。
外部化提示和配置
根据 十二要素应用 设计原则,应将命令视为需外部化的配置。
版本控制: 在版本控制中保留提示信息,清晰地进行部署跟踪,以便将遥测和安全结果与特定的提示版本关联起来。
角色分离: 使业务分析师和领域专家能够在不更改代码的情况下优化提示。
安全部署: 实现受控的推出过程,以便进行提示更改,并将它们视为重要的配置更新。
规划模型弃用
基础模型最终达到生命周期结束,并已由模型托管平台停用。 这些模型被性能更好的模型所取代,这些模型更具成本效益,具有更新的训练知识,并支持新功能。 设计抽象层,以最大程度地减少工作负载中即将进行的模型转换的影响。
提供程序抽象: 使用抽象层,允许在不更改应用程序的情况下在模型提供程序之间切换。
版本管理: 实现支持模型版本之间的逐步迁移的版本控制策略。
回退策略: 设计首选模型不可用时的回退机制。
有关解决模型生命周期问题的体系结构设计技术,请参阅 设计以支持基础模型生命周期。
容器化组件
为了确保独立可部署的组件是自包含的,为了提高部署一致性,请考虑容器化作为设计策略的一部分。 应容器化以下组件:
微服务: 容器化处理应用程序的特定功能的各个微服务,例如数据处理、模型推理和用户身份验证。 此方法可实现独立的部署和缩放,并有助于更高效的更新和维护。
AI 模型: 容器化 AI 模型,以确保所有依赖项、库和配置捆绑在一起。 此方法将模型环境与主机系统隔离,以防止版本冲突,并帮助确保不同部署环境中的一致行为。
数据处理管道: 将用于模型推理前后数据处理的任务容器化,例如数据清理、转换和特征提取。 此方法增强了可重现性,并简化了依赖项的管理。
基础结构服务: 容器化提供基础结构支持的服务,例如数据库和缓存层。 此方法有助于保持版本一致性,并简化这些组件的缩放和管理。
实现多层缓存策略
多层缓存方法可帮助提高 AI 应用程序中的性能并降低成本。 请考虑在应用程序堆栈的多个级别实现缓存:
结果和答案缓存: 如果适合这种情况,请使用此方法重复使用相同或语义上相似的查询的响应。 在可缓存响应的工作负荷中,此方法可以显著减少对模型的调用,从而提高性能并降低模型调用成本。
检索和基础代码段缓存: 缓存经常检索的知识片段和基础数据,以避免重复的数据库查询、搜索查询或 API 数据操作。
模型输出缓存: 缓存可跨请求重复使用的中间模型输出。
在每个层中设计缓存方法时,需要了解经常访问哪些数据,以及应用程序用户的角色和权限如何影响他们可以访问的数据。 若要使缓存有效,您需要预期较高的缓存命中率。 专注于缓存高流量路径(如产品目录搜索),同时监视缓存逐出。
缓存密钥组件: 缓存值需要绑定到工作负荷中的特定运行时因素。 在缓存密钥中包含租户或用户标识、策略上下文、模型版本和提示版本等值,以确保缓存的值仅在适合请求时返回。
生存时间(TTL)策略: 根据数据新鲜度要求和内容敏感度设置适当的过期时间。
缓存失效触发器: 实现数据更新、模型更改和提示变更的缓存失效触发机制。
用户隐私保护: 除非密钥和策略正确限定范围,否则从不缓存用户专用内容。 通常,缓存最适合跨多个用户应用的数据。 在大多数情况下,不要为单个用户缓存。 避免将特定于用户的响应缓存为所有用户的有效响应。 例如,缓存的响应“我还剩多少小时的带薪休假时间?”只能适用于请求数据的用户,即便其他用户提出相同的查询也是如此。
风险: 缓存可提高性能和降低成本,但引入了安全性和数据新鲜度风险。 这些风险包括数据泄露、过时数据和隐私违规。
评估生成式 AI 解决方案中的业务流程和代理的使用
根据应用程序确定性和探索性功能的要求选择适当的协调方法。
何时使用编排
编排器通过协调 AI 解决方案中不同组件之间的通信来管理工作流,否则在复杂工作负载中将难以处理。 如果工作负荷需要以下任何特征,建议将业务流程协调程序构建到设计中:
可预测工作流: 具有定义完善的序列和决策点的多步骤过程。
合规性要求: 需要确保执行特定步骤以符合法规的方案。
性能关键路径: 必须严格控制延迟和资源使用情况的工作流。
简单协调: 不需要动态推理的直接任务委派。
何时使用代理协作
代理是在应用程序中包装、提取和定义智能行为的方法。 代理提供上下文绑定功能,并且可与业务流程框架(如语义内核、Autogen 或 Microsoft Agent Framework)配合使用。
使用代理路由的协作方法进行探索或组合任务:
多步骤推理: 需要跨多个步骤进行规划和决策的任务
工具协调: 涉及协调多个专用工具和服务的复杂工作流
自适应行为: 系统需要根据中间结果或更改条件调整其方法的方案
上下文管理: 需要跨交互维护聊天状态和用户上下文的应用程序
代理设计注意事项
设计基于代理的系统时,请考虑隔离和边界、通信模式和工具抽象策略。 设计不同的代理功能之间的明确边界,以减少爆炸半径并提高可测试性。 使用已建立的模式(如主题队列系统)进行代理通信。 通过标准化接口抽象工具能力,以实现代理的灵活性。
重要
不要在要完成的任务和模型调用之间自动添加代理。 评估所传递的智能是否需要代理模式的复杂性,或者直接模型调用是否足以用于用例。 代理层会增加延迟、扩展表面区域,并使测试复杂化。
代理状态持久性
对于多轮对话和长时间运行的任务,设计包含持久状态存储的代理,以便其能够在请求、会话或部署周期中保留上下文。 使用安全共享存储(如 Azure Cosmos DB、Azure 托管 Redis 或 Azure 表存储)来存储相关的元数据、聊天历史记录和任务进度。 将持久化的状态限定为最小的必要信息,以减少隐私风险和令牌开销,并实施 TTL 策略以使过期数据失效。 确保代理可以在恢复时解除冻结状态以继续工作流,而无需重复完成的步骤。
混合方法
请考虑混合设计,其中编排器将特定的子任务委托给代理。
采用灵活步骤的结构化的工作流: 使用编排来管理整体工作流,同时允许代理处理复杂的单个步骤。
升级模式: 从确定性业务流程开始,在预先确定的逻辑不足时升级到基于代理的推理。
领域特定的推理: 使用编排进行跨域协调,同时为领域特定的任务使用专门代理。
折衷: 业务流程提供可预测性和控制性,但限制了适应性。 代理协作可实现动态问题解决,但引入了可变性和复杂性。
实现 AI 网关以实现策略实施
在设计中使用 AI 网关在工作负荷中提供 网关卸载、 网关路由和 网关聚合 功能。 网关通常通过使用 Azure API 管理等平台或通过自定义编码的解决方案(例如 Envoy 或 NGINX 实现)来实现。 网关可用于将请求代理到模型提供程序、代理终结点、工具和知识存储。
核心 AI 网关功能
AI 网关可以解决交叉问题,并充当目标系统的抽象和间接层。 设计 AI 网关策略时,请考虑以下功能:
协议规范化: 对于跨提供程序的共享 AI 功能,请通过网关规范化通用协议的接口,以提高可维护性。 对于特定于提供程序的功能,请使用网关作为反向代理,而无需规范化。
身份验证和授权: 强制实施基于标识的访问控制,并将用户上下文传播到下游服务。
速率限制和配额: 实现每用户、每应用程序或每租户费率限制和令牌配额,以防止滥用和管理成本。
请求和响应筛选: 在网关级别应用输入验证、提示筛选和输出安全检查。
令牌和提示上限: 强制实施最大令牌限制和提示大小限制,以防止资源耗尽,方法是先发制人地拒绝对系统表示比所需或可能需求更高的请求。
模型路由策略: 根据用户权限、请求特征或成本优化目标将请求路由到适当的模型。 当容量或定价在一个模型上使用但在另一个模型部署上可用时,网关通常用于实现多个模型之间的溢出。
标头注入和转换: 为下游服务添加所需的标头、用户上下文和安全令牌。
退款管理: 跨共享 AI 工作负荷组件的部门(例如单个 Azure OpenAI 实例)分配费用。
小窍门
若要深入了解 AI 网关如何用于交叉问题,以及如何将网关引入额外的复杂性,请参阅 通过网关访问 Azure OpenAI 和其他语言模型。
多供应商场景
使用多个模型提供程序或共享模型托管平台时,AI 网关尤其有用。 在您的组织中,这些网关通常是集中资源,您的工作负载被鼓励或需要依赖这些资源。 一个足够复杂的工作任务也可能在其设计中通过构建此抽象层而获益。
统一接口: 提供一个用于抽象多个后端提供程序的 API 图面。
故障转移和冗余: 当主服务不可用时,将请求路由到备用服务提供商。
成本优化: 根据请求特征将请求路由到最经济高效的提供程序。
重要
不要只依赖于 SDK 重试和超时。 在网关和策略层强制实施限制、身份验证、配额和超时,以便进行全面控制。
使用 AI 应用程序设计模式
此行业定义了几个适用于 AI 应用程序的常见设计模式。 可以使用它们来简化设计和实现。 这些设计模式包括以下类型:
模型合奏: 此设计模式结合了来自多个模型的预测,通过缓解各个模型的限制来提高准确性和稳定性。
微服务体系结构: 此设计模式将组件分成独立可部署的服务,以提高可伸缩性和可维护性。 它使团队能够同时处理应用程序的不同部分。
事件驱动的体系架构: 该设计模式使用事件来触发操作,使解耦组件和实时处理能够使系统更具响应性并适应不断变化的数据。
基础和知识集成模式
许多 AI 应用程序访问外部知识源以提供准确的最新信息。 将检索视为强制授权的服务背后的代理工具或知识调用。
知识路由: 根据查询类型、域或用户上下文将查询定向到适当的知识源。
上下文分层: 构建可以组合多个知识源和上下文类型的系统,以提供全面的响应。
动态锚定: 实现能够根据不断变化的要求或数据的可用性来调整其知识源和定位策略的系统。
授权感知检索: 确保基础服务在检索信息时强制实施用户权限和租户上下文。
若要更深入地了解设计支持工作负荷特定的地面数据进行语义检索的专用矢量索引,请参阅 设计和开发检索扩充生成 (RAG) 解决方案。
多模型路由模式
当另一个模型处于不正常状态时,使用模型路由器可以将请求路由到正常模型来提高工作负荷的可用性,或者通过实时为特定任务选择最佳模型来帮助提高响应质量。 模型路由器增加了灵活性,但引入了额外的可变性。 有选择地使用它们:
何时使用模型路由器: 当工作负荷可以容忍增加的可变性和延迟时,使用模型路由器,用户体验需要跨模型类型的广泛性,或者你需要在不同的模型中平衡成本和功能。
何时避免使用模型路由器: 在工作负荷需要针对特定任务进行优化的精确答案的场景中,请勿使用模型路由器,在使用包含窄服务级别目标(SLO)的微调模型时,或在需要确定性行为(包括一致性能)对于用例至关重要的情况下,避免使用模型路由器。
将模型路由器添加到应用程序时,首选提供程序原生路由(如果可用),并监视性能影响和用户满意度。
折衷: 模型路由器提供灵活性和成本优化,但为测试和故障排除添加不确定行为和复杂性。
如果您的工作负载是多租户应用程序,请参阅 设计安全多租户 RAG 推理解决方案的指南,获取有关访问每租户基础数据的建议。
何时使用设计模式
请考虑对以下方案使用这些设计模式:
复杂的工作流: 在多个 AI 模型之间具有复杂的工作流或交互时,RAG 或微服务等模式有助于管理复杂性并确保组件之间的清晰通信。
可伸缩性要求: 如果应用程序的需求波动,微服务等模式使各个组件能够独立缩放以适应不同的负载,而不会影响整个系统性能。
数据驱动型应用程序: 如果应用程序需要广泛的数据处理,事件驱动的体系结构可以提供实时响应性和高效的数据处理。
注意
较小的应用程序或概念证明(POC)通常不会受益于这些设计模式。 应为简单起见设计这些应用程序。 同样,如果有资源约束,比如预算、时间或人员,你可以选择使用一个简单的设计,这样以后便可以进行重构,这比直接采用复杂的设计模式要更好。
选择正确的框架、库和协议
框架和库的选择与应用程序设计紧密相连。 它们会影响性能、可伸缩性和可维护性。 但是,设计要求可能会限制框架选择。 例如,使用语义内核 SDK 通常鼓励基于微服务的设计,其中每个代理或函数封装在其自己的服务中。 选择框架和库时,请考虑以下因素:
应用程序要求: 应用程序的要求(如实时处理或批处理)可能会限制框架的选择。 例如,如果应用程序需要低延迟,则可能需要使用具有异步功能的框架。
集成需求: 设计可能需要与其他系统或服务进行特定的集成。 如果框架不支持必要的协议或数据格式,则可能需要重新考虑设计或选择其他框架。
团队专业知识: 开发团队的技能集可以限制框架选择。 依赖于不太熟悉框架的设计可能会导致开发时间和复杂性增加,因此请考虑使用更熟悉的工具。
社区和支持: 考虑框架的成熟度和支持生态系统。 活动社区和全面的文档可降低实施风险。
性能特征: 评估特定用例的框架性能,包括内存使用情况、启动时间和推理速度。
采用标准化工具协议来提高治理并实现灵活性:
使用 MCP 样式的服务器: 使用 MCP 或其他合适的标准将业务功能包装为可发现的工具服务器。
使用具有广泛 SDK 支持的规范。 例如,使用 OpenAPI 规范定义工具,以实现接口文档和验证的统一。
宣传能力: 设计工具来宣传其能力,这允许编排器适当地发现和路由请求。 例如,将企业资源规划(ERP)读取和写入操作打包为展示功能的工具服务器。 此方法允许在不更改代理逻辑的情况下优化 ERP 交互。
协议首选项
选择协议和标准时,首选打开的、记录的接口而不是专有格式。 业内有很多新兴协议。 考虑到代理到代理和控制用例时,请考虑技术债务,这些债务可能来自正在快速发展或被弃用的协议。 抽象层有助于使设计在不同的 AI 框架和提供程序之间保持可互作。
为工作负荷的 AI 组件设计安全策略
AI 组件需要传统应用程序安全性以外的安全注意事项。 在使用标准标识提供者(如Microsoft Entra ID)进行基础身份验证和授权时,在所有应用程序层上实现安全措施。
核心安全原则
实现以下基本安全做法:
标准身份验证和授权: 使用已建立的标识提供者和基于角色的访问控制 (RBAC) 系统。
使用用户上下文传播的数据世系安全性: 确保在整个数据管道中维护访问控制。 使用代理流传递用户标识,以便用户只能根据他们有权查看的数据访问结果。
审核线索: 实现 AI 交互的详细日志记录,以实现合规性和安全监视。
特定于 AI 的安全措施
解决 AI 应用程序特有的安全难题:
提示筛选和注入防护: 实施安全措施,以防止可以操控AI行为或提取敏感信息的提示注入攻击。
安全工具使用情况控制: 使用具有工具访问权限的代理时,实施控制以防止有害作,并在调用之前验证工具使用情况。
代理行为监视: 监视代理作和决策,以检测异常或潜在有害的行为模式。
模型访问控制: 为 AI 系统中的不同模型和功能实现精细的权限。
响应筛选和安全检查: 筛选 AI 输出以防止生成有害、不恰当或敏感的内容。
安全修整的地面
不仅仅是阻止直接数据库访问,还要实现安全意识的技术信息检索:
标识传播: 将Microsoft Entra 组声明或等效的标识信息传递到知识工具的调用中,使基础服务永远不会检索未经授权的数据或媒体。
基于组和访问控制列表(ACL)的裁剪: 在知识层面实施基于安全组和 ACL 的过滤。
可审核拒绝: 由于权限不足导致日志和审核日志记录请求拒绝。
授权强制: 要求代码位于代理和知识源之间,以强制实施授权策略。
例如,可以将 Microsoft Entra 的组声明信息传递到知识工具调用中,以确保避免检索未经授权的文档。 此配置保证缓存的结果,并确保 AI 响应尊重用户权限。
考虑非功能要求
由于 AI 技术固有的因素,工作负荷可能具有非功能要求,这会带来挑战。
模型推理的延迟或超时: AI 应用程序通常需要实时或近乎实时的响应。 设计为低延迟至关重要。 它涉及优化模型体系结构、数据处理管道和硬件资源。 实施缓存策略并确保有效的模型加载对于避免超时并提供及时响应至关重要。
令牌或请求吞吐量限制: 许多 AI 服务对令牌数或请求吞吐量施加限制,尤其是基于云的模型。 针对这些限制进行设计需要仔细管理输入大小、在必要时批处理请求,并可能实施速率限制或排队机制来管理用户期望并防止服务中断。
成本和退款方案: 设计成本透明度涉及实现使用情况跟踪和报告功能,以方便退款模型。 这些功能使组织能够跨部门准确分配成本。 退款管理通常由 API 网关处理,例如 API 管理。
模型准确性和偏移: 随着数据模式的变化,AI 模型可能会随着时间推移而下降。 设计监视系统以检测准确性偏移,并在必要时实现自动重新训练管道。
合规性和可解释性: 某些行业需要可解释的 AI 决策。 设计系统以在需要时捕获和提供 AI 生成的输出的原因。
数据隐私和驻留: 确保设计符合数据保护要求,包括删除用户数据并符合地理数据驻留规则的能力。