关键要点

  • 对于具有自主性的智能体系统而言,我们不应采用传统的软件开发生命周期模型,而需要一种新的开发模式——这种新模式不仅要规定智能体应该做什么,还要明确它们绝对不能做的事情。
  • 智能体系统的开发并不一定非得采取特设的方案。事实上,已经存在一些可复用的设计模式,这些模式能够有效解决常见的智能体开发难题,例如“监督者模式”、“反应型智能体”以及“人类参与迭代开发”的机制。我们需要找到一种方法,将这些模式融入常规的开发流程中,同时不会限制开发人员的创造力。
  • 提示语、工具配置文件、策略设置、内存结构以及评估数据集都需要进行版本控制,并且应当被纳入基于代码的基础设施管理框架中。我们需要通过版本控制、语义差异分析以及正式的变更审批流程,来减少与提示语相关的问题所带来的生产故障。
  • 智能体系统需要采用截然不同的质量保证方法,这些方法更侧重于行为层面的评估。我们需要特定的工具和方法论,来帮助规范这一开发过程,并将其与标准的开发实践相结合。
  • “模型上下文协议”为智能体与工具之间的集成提供了跨供应商的标准,这种标准能够缩短集成开发时间并提升系统的可维护性。我们希望OpenAI、Google DeepMind和Microsoft都能采用基于MCP的JSON-RPC 2.0规范来进行集成开发。

大型语言模型能够根据所学到的概率分布生成文本,但它们本身并不具备采取实际行动的能力。智能体技术正是将这类模型包裹在一种迭代式的改进机制中的一种技术——这种机制包括自我反思、工具使用、规划制定以及多智能体之间的协作。智能体技术正是连接大型语言模型的核心技术(如GPT-5、Claude Opus 4.1等)与实际商业价值之间的桥梁。因此,企业迫切需要学习如何开发、部署、保障安全并运营这些智能体应用。

本文为实践者提供了构建智能体应用并将其投入生产环境进行扩展的具体指导。文章重点介绍了那些能够帮助开发者顺利实现智能体应用规模化部署的开发方法。

引言

Google Brain的联合创始人之一、人工智能领域最具影响力的专家之一吴恩达,在他的博客《Andrew Ng的信件》中提到,由于智能体技术具有前所未有的实际应用价值,它将在人工智能发展的诸多领域发挥主导作用。正如这篇关于“智能体设计模式”的文章所指出的那样,智能体技术有潜力推动各种商业流程的优化。


智能代理AI的核心理念在于通过不断进行推理、采取行动,然后再重新进行推理,直到确保特定任务的目标得以实现。因此,在针对各种智能代理方法开展的研究中,虽然使用GPT-3.5和GPT-4在编码测试中分别取得了约48%和67%的准确率,但智能代理AI通过迭代机制与GPT-3.5结合使用后,其准确率竟然达到了95.1%。

从GPT-3.5到GPT-4的基础模型改进,其效果都被这种基于迭代机制的智能代理技术所掩盖了——即使使用相对较老的模型,也能取得这样的成果。这对企业来说意味着什么呢?根据Andrew Ng在这段采访中的观点,对于大多数企业而言,开发基于智能代理AI的实际应用应该才是首要任务,而不是一味追求最新的基础模型。

从原型到量产的差距

传统的软件开发过程通常包括先进行原型设计来验证相关概念,随后再按照规模更大的类似流程来完成软件的开发与部署工作。对于具有自主行为能力的智能系统而言,其开发原理大体上仍然相同,但存在一个根本性的区别:这类系统的行为并不具有确定性,因此原型测试所模拟的环境并不能真实反映现实世界的情况。在处理这类系统时,我们需要面对非确定性的行为模式、新出现的功能以及自主决策机制。例如,对于具有非确定性行为的系统而言,进行测试的方法与传统的软件工程实践截然不同——传统方法是通过输入数据及预期的输出结果来设计测试用例,而针对这类系统,则必须采用其他不同的测试方式。

理解智能体的发展机制

企业团队一直在努力扩大其智能体人工智能的应用范围,在这一过程中,他们面临着产品与市场匹配这一经典问题。这个问题的根源在于两个截然相反的问题:

“是否存在现实世界中可以通过应用智能体人工智能来解决的问题?”

versus

“既然我想使用智能体人工智能,那么我现有的哪些问题最适合用这种方法来解决?”

关键在于要明白:如果整个流程完全由固定的、确定性的步骤构成,且几乎不需要任何主观判断,那么使用传统方法反而会更有效。而当需要做出非确定性决策,并根据这些决策采取实际行动时,智能体人工智能才能发挥其优势。

人工智能系统的软件开发生命周期具有本质上的不同特性。A. Gill进行的敏捷性研究指出了六个能够将人工智能系统与传统软件区分开来的特征:自主性、适应性、内容生成能力、决策能力、可预测性以及推荐功能。这些特性要求在敏捷的软件开发生命周期框架中融入“决策科学”的理念,从而使开发过程超越单纯的功能实现阶段,转向行为层面的协调与优化。

同样,国际标准化组织也发布了首个针对人工智能系统开发的综合性框架,即ISO/IEC 5338:2023标准——“信息技术——人工智能——人工智能系统的生命周期流程”。该标准强调了在整个开发过程中进行风险管理的重要性,并明确指出了验证自主系统行为的各项挑战。

这些发展理念反映了我们在为非确定性系统设计软件时思维方式的深刻变化。

架构与设计模式

在进一步探讨具体的开发实践之前,让我们先来看看一些对智能体应用程序的开发有帮助的架构与设计模式。开发者可以利用这些通用设计模式来简化智能体应用程序的开发流程。

智能体会控制与大型语言模型的输入/输出过程,确保模型始终返回结构化的输出结果,而这些输出结果可以被解释并转化为一个或多个函数调用(这些函数调用被称为智能体的“工具”)。智能体会从自身的工具库中查找相应的工具,并使用大型语言模型提供的参数来调用这些工具。

这个过程可以只执行一次,也可以通过多种设计模式循环执行。

智能体应用程序开发的核心架构模式

有一些核心架构模式能够覆盖大多数实际应用场景。开发智能体应用程序的开发者需要熟悉这些模式。

ReAct智能体

ReAct智能体的设计理念源于一篇相关的基础研究论文,该论文的链接为ReAct Agent。ReAct是一种非常灵活的智能体设计模式,它由智能体、大型语言模型以及函数调用这三个部分组成,会形成一个循环结构,直到满足某个终止条件或通过外部逻辑触发停止机制为止。

下图展示了ReAct代理循环的基本工作流程,说明了在单次循环交互中会发生哪些步骤。这些步骤按顺序编号为1到8,在每次迭代中都会重复执行,直到满足终止条件为止。

图1:ReAct代理循环

ReAct模式特别适用于那些需要代理通过迭代方式来解决问题的工作流程。例如,一个用于调试数据库的代理可能会执行查询操作、分析性能瓶颈、检查现有的索引结构,并持续进行这样的循环,直到找到问题的根本原因。

以下是ReAct核心循环的伪代码示例(推理 → 行动 → 观察)

def react_agent_loop(user_query, available_tools, max_iterations=5):
    """
    ReAct模式:通过迭代进行推理和行动,直至达成目标
    ```
    conversation_history = []
    conversation_history.append({"role": "user", "content": user_query})
    
    for iteration in range(maxiterations):
        # 第一步:推理 – 大语言模型决定下一步该采取什么行动
        llm_response = llm_client.generate(
            messages=conversation_history,
            tools=available_tools,
            temperature=0.7
        )
        
        # 第二步:行动 – 如果大语言模型建议使用某种工具,就执行该工具
        if llm_response.has_tool_call():
            tool_name = llm_response.tool_call.name
            tool_args = llm_response/tool_call.arguments
            
            # 执行选定的工具
            tool_result = execute_tool-tool_name, tool_args, available_tools)
            
            # 将工具执行结果添加到对话记录中
            conversation_history.append({
                "role": "assistant",
                "content": None,
                "tool_calls": [llm_response.tool_call]
            })
            conversation_history.append({
                "role": "tool",
                "content": tool_result,
                "tool_call_id": llm_response/tool_call.id
            })
            
            # 第三步:观察 – 判断是否应该继续迭代
            if should_terminate-tool_result, user_query):
                break
        else:
            # 如果大语言模型直接给出了最终答案,就返回该答案
            return llm_response.content
    
    # 在所有迭代结束后生成最终回复
    final_response = llm_client.generate(
        messages=conversation_history + [{
            "role": "user",
            "content": "根据以上讨论结果,提供最终答案"
        }]
    )
    return final_response.content


def should_terminate-tool_result, original_query):
    """
    终止循环的条件:
    – 大语言模型发出了明确的完成信号。
    – 达到了预定的置信度阈值。
    – 出现了需要人工干预的错误情况。
    ```
    if "COMPLETE" in tool_result:
        return True
    if "ERROR" in tool_result and "ESCALATE" in tool_result:
        return True
    return False

监督者代理模式

在那些用例足够复杂的多智能体环境中,在执行各项任务之前进行集中规划往往会很有帮助。这种模式包含一个负责集中规划的监督者代理,它会将工作分配给多个专门的工作者代理。监督者会在每一步决定接下来应该调用哪个代理来执行任务,或者如果目标已经实现,则结束整个工作流程。现实世界中的一个例子是Anthropic的多智能体研究系统,该系统利用多个智能体来探索复杂的科研课题,其中有一个中央代理会根据用户的请求来规划研究流程,然后使用专门的并行智能体来执行计划中的各个步骤。

下图展示了监督者代理的具体结构:

图2:监督者代理模式

[点击此处将上图放大到全尺寸]

分层智能体模式

当某个监督者需要管理过多的工作者代理时,整个智能体系统就会变得效率低下。而采用分层结构就可以解决这个问题——通过创建由多个代理组成的团队,每个团队都有自己的监督者,同时还有一个更高层次的监督者来管理这些团队级的监督者。

例如,在电子商务订单履行系统中,可能会使用分层模式:一个主履行代理负责协调各个区域的监督者(比如北美、欧洲、亚洲),而这些区域监督者则分别管理负责库存检查、拣选、包装和发货等工作的具体仓库代理。

下图展示了分层智能体模式的具体结构:

图3:分层智能体结构

[点击此处将上图放大到全尺寸]

人类参与其中的模式

许多工作流程中都存在这样的决策点:只有经过人类的审核和批准,这些节点才能被解除阻塞。在这种场景下,结合人工智能带来的效率提升与人类的决策或审核,能够显著提高工作效率。Microsoft的Magentic-UI研究专门针对这种人类参与其中的智能系统进行了探讨。

我们以贷款审批工作流程为例来说明这一模式。

图4:人类参与其中的模式

其他相关模式的参考信息

其他智能系统相关的模式列在下表中,每一种模式都提供了进一步探索的链接。

模式名称 描述 权威来源 适用场景
顺序协调模式 线性流程处理 Microsoft AI智能系统的协调模式 适用于工作流程中存在明确的步骤依赖关系的情况。
并发协调模式 并行任务执行 Microsoft AI智能系统的协调模式 适用于工作流程中包含独立且可并行执行的任务的情况。
任务交接模式 智能系统之间的任务传递 Microsoft AI智能系统的协调模式 当某项任务最适合由哪个智能系统来完成尚不明确时,可以在工作流程进行中再进行分配。
事件驱动模式 异步协同处理 Confluent:事件驱动的多智能体系统 适用于可扩展的分布式系统。
调度器-智能体-监督者模式 企业级工作流程管理 Microsoft的调度器-智能体-监督者模式 适用于复杂的业务流程管理场景。
黑板模式 共享知识下的协同工作 Confluent:事件驱动的多智能体系统 适合需要大量知识输入的任务。
市场机制模式 基于经济规律的协调机制 Confluent:事件驱动的多智能体系统 适用于资源分配相关的场景。

表1:其他模式的参考表格

规划你的智能体实现方案

作为第一步,可以通过提出一些简单的问题并反复回答这些问题,来有针对性地识别出应用程序中适合应用智能体技术的部分。在多次迭代中不断调整答案,有助于优化决策过程。

问题 目的 第一次迭代 第二次迭代 第三次迭代
我的应用程序中是否有明确定义的工作流程? 在确定智能体组件之前,先明确应用程序的范围和边界。

是的。有些工作流程已经有了明确的定义,其中的具体步骤也都能被清晰地识别出来。
但也有一些工作流程还需要进一步明确。

是的。我的所有工作流程都已经完成并且定义得很清楚(可提供相关文档链接)。 所有工作流程都已记录在案。
哪些工作流程中的步骤涉及非确定性决策? 明确哪些地方需要使用大语言模型的推理能力,哪些地方则适合使用确定性逻辑。 目前已经明确的包括:
工作流程1的第3步
工作流程3的第2步
……
清单已经完整。补充了:工作流程2的第1步;工作流程4的第5步。 所有涉及推理的工作流程都已完成了映射记录。
我们是否为每个工作流程都准备好了能力矩阵(参见表3)? 区分确定性组件和智能体组件,以便优化成本和可靠性。 工作流程1的能力矩阵已经准备完成。 所有工作流程的能力矩阵都已经准备好。 所有的能力矩阵都已经过审核和验证。
我们是否为每个智能体组件确定了所需的工具? 确定相应的架构模式(如ReAct、Supervisor)以及集成复杂性。 初步列出的工具包括:工作流程1所需的数据库访问功能、电子邮件API和支付网关。 所有工具的清单都已完整编制,并明确了相应的权限要求(可提供文档链接)。 已经创建了工具清单,同时也定义了MCP(模型上下文协议)的相关规范。
我们是否为每个智能体组件确定了输入/输出接口? 明确界定接口,以便进行测试并减少出现意外行为的可能性。 已经为7个智能体组件中的3个制定了接口规范草案。 所有的接口规范都已经制定完成。还需要进一步验证数据格式是否正确。 已经使用样本数据对接口规范进行了验证(可提供文档链接)。
我们是否为智能体组件制定了明确的成功标准? 制定可量化的质量评估标准和行为测试方案。 初步确定的指标包括:准确性和响应时间。 还补充了其他综合性的评估标准,如行为一致性、故障处理能力以及升级触发条件等。 成功标准已经明确了可量化的阈值(可提供文档链接)。
我们是否制定了追踪机制,以便跟踪智能体组件的各种操作,比如大语言模型的调用、工具的调用等等? 这样的追踪机制对于实现调试、审计以及行为回归测试非常必要。特别是在非确定性系统中,运行时的大语言模型决策必须能够被清晰地追踪起来。 已经确定需要使用LangSmith/OpenTelemetry等工具进行追踪。目前正在评估不同的追踪平台。 已经选定了追踪框架,并为所有智能体组件确定了相应的追踪点。 追踪机制已经实施完成,同时也建立了数据保留策略和基准轨迹记录系统。

表2:智能体AI组件的迭代评估示例

一旦获得了这些高层次的分析结果,你就可以着手设计各个工作流程的能力矩阵(详见表3),或者规划其他开发活动。

如果能够认真执行上述流程,它将会成为后续开发的指导性清单。例如,表格中的第三个问题(比如“我们是否为每个工作流程都准备了一份能力矩阵?详见表3”)就可以用来为你的应用程序的每个工作流程创建相应的能力矩阵(具体内容见下一节的表3)。通过这些能力矩阵,我们可以将每个工作流程的范围分解成智能体部分和非智能体部分。需要记住的是,智能体通常涉及大语言模型的调用以及各种工具的运用,而这些操作可能会在循环中执行。从图5中可以看出(该图展示了使用LangSmith进行智能体追踪的过程),大语言模型的调用会带来较大的延迟,因此,在那些适用于确定性规则或固定规则的场景中,我们就不应该使用智能体来实现相关功能。一般来说,如果我的代码能够根据某些固定的规则做出明确、无歧义的决策,那么在应用程序的这些部分就没有必要使用智能体进行推理了——因为通过大语言模型进行智能体推理往往会牺牲程序的简洁性和性能。

实现智能体特性(能力矩阵方法)

在智能体应用开发中,最常见的反模式之一就是试图让所有功能都具备智能体的特性。根据上述原则,对智能体应用的需求分析必须包括一个系统化的流程,用于确定应用程序的哪些部分应该运用非确定性的大语言模型推理机制,哪些部分则应遵循确定性规则。当某些任务更适合以确定性的方式来完成时,避免这种反模式就显得尤为重要了。下面我们来看一个简单的示例:一个能够协调端到端客户服务工作流程的智能体客户支持系统。下表3列出了这样一个示例工作流程中的每个步骤,并试图说明实现其目标的正确方法。

我们会逐一分析每个工作流程步骤,判断它们应该是确定性的(基于规则、可预测的)还是非确定性的(需要运用大语言模型进行推理的)。关键在于要认识到,大多数实际应用都会同时包含确定性功能和非确定性功能。

支持流程:客户提交支持请求,表示无法访问自己的账户或下载发票。
流程步骤 执行内容 确定性环节 非确定性环节
初始工单接收 系统应创建工单并确定客户使用的联系渠道。

生成工单编号。
确认客户使用的联系渠道(电子邮件/IVR/网站)。
查询客户信息。
在工单上设置SLA计时器。

通过分析请求内容了解客户的真实需求。
)识别核心问题,如“无法访问账户”或“无法下载发票”等。

分类与路由分配 系统应确定工单所属类别,并将其分配到相应的处理组或队列中。 根据上一步中非确定性环节的分类结果进行分组/排队。

确定问题类别及处理方向(分类阶段)。
>结合请求内容中的紧急程度信息及业务规则来评估优先级。
>判断问题的复杂性(是独立问题还是关联问题)。

知识库搜索与解决方案匹配 系统应查找现有的解决方案。

在数据库中查询相关知识库信息。
>对于频繁查询的内容,可进行缓存处理。
>从知识库中检索合适的解决方案。

生成用于查询的SQL语句。
>判断搜索到的解决方案是否适用于当前问题。
>如果可能,将多个解决方案整合成一条可行的解决方案。

可选解决方案的实施 系统应判断是否可以应用某种解决方案。 执行必要的操作来应用该解决方案,例如查询数据库或执行相关命令。 根据目前掌握的信息决定是否采用该解决方案。
生成回复内容 系统应为客户生成合适的回复。 回复内容的生成流程包括:
使用回复模板。
>替换模板中的占位符(如客户名称、工单编号等)。
>确定回复的发送渠道。
在回复内容上做出一些定性决策,例如:
>根据客户情况进行个性化处理。
>根据问题的紧急程度调整回复的语气。

解决方案或回复的发送 系统应将回复内容发送给客户。 回复发送流程包括:
)确定客户偏好的接收渠道(如电子邮件)。
>记录发送过程并生成相关数据。
>通过客户选定的渠道发送回复。
一些非确定性的决策环节,例如:
>决定是否需要进一步联系客户。
>评估解决方案的实际效果。
解决方案的管理与关闭 系统应管理工单的整个生命周期,直至问题得到解决。 向客户发送通知和提醒信息。
>跟踪SLA执行情况。
>确定需要沟通的相关人员,并通知他们问题已解决。

提供关闭建议。
>总结处理过程,并在必要时改进现有的解决方案步骤。

表3:工作流能力矩阵

这种能力矩阵的方法有助于揭示以下关键要点:从非结构化/结构化文本内容中进行非确定性推理,是区分“智能型”应用组件与“非智能型”应用组件的重要依据。任何需要基于动态推理来决定的操作——比如理解用户的意图,或者是否需要对某个问题采取进一步行动——都应当被设计为“智能型”功能;为此,可以创建相应的函数调用工具,让智能体根据大语言模型的推理结果来执行这些操作。而那些基于当前应用/系统状态来执行的操作,则完全可以、也应该被编码为传统的“非智能型”规则来实现。

尽管大多数应用都适合采用“智能型”设计方式,但其中仍会有相当一部分功能需要通过规则来驱动,而非依赖智能体进行判断。

应用程序的架构及开发过程应当以可靠性要求作为指导原则。那些不存在多种解释可能性的功能,如果出现错误,必然会导致整个应用程序无法正常运行;因此,这类功能的实现方式必须是确定性的。例如,服务水平协议应该根据工单类型来确定固定的值,或者工单编号的生成规则也必须是一成不变的。而对于那些可能存在多种解释可能性的功能来说,利用大语言模型的推理能力反而会带来好处——比如可以根据当前的解决方案及用户需求来生成不同的响应内容,或者选择不同的API调用方式、查询执行策略等。

成本优化也是设计考虑的重要因素之一,因为调用大语言模型往往会产生较高的成本,因此这类技术只应该用于那些确实需要非确定性推理的任务中。

因此,任何“智能型”工作流或应用场景都应当明确以下内容:

  • 定义工作流边界的高层确定性框架;
  • 为每个工作流步骤指定具体的执行方式;
  • 根据推理需求对各类工作流步骤进行分类。

开发工作流

开发者工作流——实现智能体角色与规划逻辑

在智能体的调度方式上并没有严格限制,它们可以按顺序执行、同时运行,或者采用任意协调策略来进行调度。不过,大多数应用其实都可以归入某种标准的调度模式之中。微软Azure在智能体调度领域的研究确定了五种主要的协调模式,每种模式都是针对不同的运营需求进行优化的:

顺序调度

图5:顺序编排模式(参考:Microsoft编排模式

各代理按预定义的线性顺序执行任务,每个代理都会处理前一个阶段产生的结果。这种模式在那些各个阶段之间需要经过严格质量审核的文档处理工作中表现得尤为有效。摩根大通的COiN(合同智能系统)就展示了顺序文档分析技术的强大功能:它能在几秒钟内处理一万两千份商业信贷协议,且错误率几乎为零,从而每年为该公司节省三十六万个小时的法律工作时间。

并发编排模式

多个代理同时执行任务,并对结果进行合并处理。这种模式能够显著降低那些由独立子任务组成的任务的延迟。谷歌云的Agent Assist就体现了并发处理的优势:它使客户服务工作流程中处理的对话数量增加了28%,响应时间也缩短了15%。

图6:并发编排模式(参考:Microsoft编排模式

分层编排模式

主管代理负责协调各个专业工作代理,从而实现复杂的任务分解。张等人的最新研究表明,AgentOrchestra的分层架构在各种测试中都明显优于扁平结构的设计;刘等人的独立验证也证实,三层分层架构能使任务成功率相比现有最佳方法提高32%。

除了这些例子之外,选择单次执行、循环执行还是多代理协作模式,主要取决于任务的复杂程度以及对于可靠性的要求。如Max Pavlov的文章所介绍的,单次执行系统非常适合那些具有明确成功标准的简单任务,比如数据验证或API调用;类似地,循环执行系统(可参考谷歌的代理开发工具包)能够实现迭代优化,但需要设置复杂的终止条件来避免无限循环,比如设定质量阈值、迭代次数上限或提前终止策略;而多代理协作模式则为复杂任务提供了最强的支持,不过这种架构要求有精妙的协调机制,而且相关系统平均会消耗多出15倍的计算资源(可参考Anthropic的研究型代理系统)。

自主性等级设计
这种类型的协调机制需要针对人类监督功能的整合做出明确的决策。该框架将这类机制分为四种类型:人工干预型(直接参与控制)、人工辅助型(提供有意义的指导)、战略管理型(进行宏观决策)以及事后分析型(在操作结束后进行分析),更多相关信息可参考Pawel Rzeszucinski关于AI与人类协作机制的文章。同样,Amazon Bedrock的多智能体协作框架也证明了:将不同的协调方法与内置的安全机制相结合,才能在自动化效率与运营安全性之间实现最佳平衡。

开发人员的工作流程——版本控制

智能体系统带来了更为复杂的新版本控制需求。与传统的非智能体后端应用程序相比,智能体系统引入了许多新的管理环节,这些环节也会成为潜在的故障点,例如系统提示信息、相关工具、大语言模型的配置设置等。接下来,我们就来逐一分析这些因素,探讨如何对这些组件的版本进行有效管理。

微软的Azure AI平台指出,某些关键类型的智能体组件确实需要实施版本控制:

提示模板或系统提示信息
研究表明,对于相同的输入,不同智能体的执行路径可能存在高达63%的变化幅度Mark Hornbeek。因此,必须对提示模板进行版本控制,这样不仅能够追踪其中的变更情况,还能在修改导致系统行为异常时及时恢复到之前的正常状态。现代的提示管理工具通常提供基于Git的版本控制系统,并具备性能监控功能PortKey的版本控制指南;同时,这些工具还支持为生产环境中的智能体提供运行时的提示控制功能Launch Darkly,并且具备完善的可观测性分析框架LangSmith。此外,Model Context Protocol (MCP)也为智能体工具的集成提供了标准化接口,从而确保了智能体运行环境中的版本控制与数据一致性。利用这些工具,我们甚至可以在运行时修改提示内容,同时依然保持有效的版本管理机制。

工具清单
JSON/YAML格式的文件用于定义各种工具的可用功能、参数以及授权要求。由于工具的添加或修改会直接影响智能体的功能表现,因此需要对这类工具进行类似软件包那样的依赖关系管理LangSmith。例如,某个工具的输出结果如果被用于后续的大语言模型请求中,就可能会影响整个智能体工作流程的运行结果。

下图展示了在典型的通用版本控制流程中所涉及的各种组件。

图7:智能体的版本控制组件

[点击此处将上图放大到全尺寸]

受版本控制的提示与策略

毋庸置疑,提示是控制智能体系统中大型语言模型行为及决策过程的最直接手段,因此必须对其进行精细的管理,以避免任何形式的偏差(无论是有意还是无意的)。事实上,在RisingWave开展的一项研究中,提示的偏差被认定为最严重的故障类型。大多数生产环境中的智能体故障都是由于提示内容被擅自修改,而这些修改会与系统更新或数据变化产生不可预测的交互作用所导致的。

因此,应该将提示视为“代码即基础设施”(IaC),并将它们存储在Git仓库中,同时建立正式的变更审批流程。采用这种做法的组织会使用渐进式交付模式,包括对提示内容的A/B测试,并设置自动回滚机制,以便在行为指标超出可接受范围时及时进行恢复(详见Open Policy Agent)。

“黄金轨迹”作为回归测试工具

那么,在智能体AI领域,行为回归测试的基础是什么呢?我认为就是“黄金轨迹”这一概念。所谓“黄金轨迹”,指的是经过验证的智能体交互序列——这些序列不仅记录了最终的输出结果,还包含了完整的推理过程、所使用的工具以及决策节点等信息。像LangChain和LangSmith这样的框架,能够帮助我们对智能体使用的工具功能及其他代码部分进行追踪分析。这种可追溯性为我们审核智能体与工具、大型语言模型以及其他接口之间的交互提供了有力手段。下图展示了一个此类系统在工作流程执行过程中所发生的所有智能体交互行为。

图8:使用LangSmith追踪平台展示的“黄金路径”分析结构。

[点击此处将上图放大到全尺寸]

图中所示的生产追踪数据来自一个用于修复安全漏洞的代理程序,它完整地展示了进行行为回归测试所需的所有信息:包括多次大语言模型调用所形成的完整推理链条、带有参数的工具调用过程、防止无限循环出现的决策机制,以及包含Git版本信息的系统状态记录。当修改该代理程序的提示语句后,其新的执行结果可以与这个基准数据进行对比;一旦出现任何显著差异,系统就会自动回滚到之前的配置状态。

智能体的自动化测试

测试智能体系统与测试传统应用程序有何不同?无论采用何种测试方法,测试智能体应用都必须基于对确定性系统与非确定性系统在架构上的差异的深刻理解。智能体应用属于非确定性系统,因为它们会利用大语言模型来进行推理,并通过调用工具来执行具体操作。

测试方法

这里介绍的各种测试方法借鉴了论文《重新思考大语言模型应用的测试策略`中的观点,即智能体系统大致可由三层结构组成:

系统外壳层

这一层包含API接口、集成组件以及工具调用模块等确定性元素。

编排层

该层负责根据当前的应用程序状态、用户输入等其他变量,为大语言模型生成执行指令。这些指令虽然具体内容会因环境而异,但它们都是基于智能体的静态提示模板生成的,其中包含了一些用于存储运行时数据的占位符,这些数据可能来源于用户输入或应用程序的状态计算结果。

大语言模型推理核心层

大语言模型本身被视为一个“黑盒”,但其行为仍会受到提示内容调整和/或当前应用程序状态的影响。

基于上述理解,让我们来看看这篇综合性指南中探讨的一些针对非确定性软件进行测试的基本方法。

基于属性的测试

基于属性的测试旨在验证系统在面对随机生成的输入时,其行为是否满足特定的逻辑规则(参见论文QuickCheck)。Hypothesis这一领先的基于属性的测试框架证明,与传统的单元测试方法相比,它能够更有效地检测出人工智能系统中的错误。行为测试框架
行为测试框架提供了模拟API、仿真的用户交互机制以及可控的故障场景。

变形测试
《重新思考测试》这篇论文中描述的变形测试方法,侧重于输入与输出之间的关系,而非单个输出的正确性。这种方法尤其适用于人工智能系统,因为在这些系统中,判断标准往往具有主观性。

根据范围、检查项及工具来划分测试类型

下表展示了各类适用于各种智能体应用的测试方法,包括其适用范围、相关的检查项以及相应的测试框架/工具。

测试类型 适用范围 检查项 工具/框架
单元测试 单个智能体功能的测试(相关工具)

提示语解析的正确性。
工具调用的正确性。
响应格式的合法性验证。

使用PyTest和Hypothesis进行测试。
)针对JavaScript智能体的Jest框架。
基于属性的测试方法。

集成测试 智能体与系统之间的交互测试。

API连接的正确性。
数据库访问逻辑的验证。
认证流程的合理性检查。

Testcontainers框架。
WireMock工具。
)智能体测试专用框架。

行为测试 智能体的端到端行为检测。

任务执行顺序的合理性。
推理逻辑的一致性及输出结果的结构验证。
工具选择的合理性检查。
)整体行为是否与任务目标相符。

Microsoft智能体测试框架。
)自定义的行为测试环境。

场景测试 实际应用场景的模拟测试。

特定领域的工作流程验证。
边缘情况的处理能力检测。
)多轮对话功能的测试。

目标行为的正确性验证。
)智能体交互过程的追踪(例如使用LangSmith工具)。
)变形测试套件(详见《重新思考测试》论文)。

混沌测试

在逆境下的抗干扰能力检测。

对恶意输入的抵抗能力。
工具故障时的处理机制。
)资源耗尽情况下的系统表现测试。

针对人工智能系统的Chaos Monkey工具。
)自定义的对抗性测试环境。

表4:具有智能行为特性的应用程序的测试类型

结论

在将具有智能行为特性的人工智能应用推向实际生产环境时,会面临一系列独特的挑战。这些挑战涉及从识别这些智能组件,到实现、部署、测试以及追踪这些组件的整个过程。实际上,使用这类智能技术的应用程序很少能够完全具备智能行为特性,这意味着这些应用程序通常会包含一些非智能组件。因此,每当这些智能组件被纳入应用程序中时,相关的开发流程就会变得更为复杂,因为它们会影响到应用程序的实现方式、测试过程以及其他各个方面。例如,现在要为这类应用程序定义明确的测试目标已经不再那么容易了,因为在不同的环境下,即使使用相同的输入条件,这些智能组件也可能产生不同的行为结果(这主要是由于大型语言模型产生的输出可能存在差异所致)。我们尝试分析了这种影响对各种主要开发流程的影响,并通过在实际开发过程中积累的经验,提出了相应的解决方案来应对这些问题。

Comments are closed.