大多数从业者在构建智能体(Agent)系统时,并不是从一份宏大的设计文档开始的。通常都是始于一个棘手的问题、一个基础模型的 API 密钥,以及一个关于如何解决问题的初步想法。本章将作为一份快速入门指南,助你迅速上手。虽然我们在本书的其余部分会深入探讨以下每个主题(许多主题甚至有单独的章节),但本章将基于一个管理电商平台客户支持的具体案例,为你提供设计智能体系统的全景概览。
本书代码请见:https://github.com/alanhou/ai-agent。
我们的第一个智能体系统
先从我们要解决的问题开始。每天,你的客户支持团队都要处理数十甚至数百封邮件,要求退款破损的马克杯、取消未发货的订单或更改送货地址。对于每条信息,人工客服必须阅读格式多样的文本,在后台查找订单,调用相应的 API,然后输入确认邮件。这种重复的两分钟流程是自动化的绝佳机会——但前提是必须选取合适的切入点。当我们意识到人类主要是敲击键盘和点击按钮,且通常遵循规则和指南时,会发现许多相同的模式可以通过设计良好的、依赖基础模型的系统来执行。
我们希望由智能体接收原始的客户消息加上订单记录,决定调用哪个工具(issue_refund、cancel_order 或 update_address_for_order),使用正确的参数调用该工具,然后发送一条简短的确认消息。这个两步工作流足够精简,可以快速构建;同时又有价值,可以释放人力时间;也足够丰富,可以展示智能行为。只需几行代码,我们就可以为此用例构建一个可运作的智能体:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
from dotenv import load_dotenv load_dotenv() from typing import Annotated, TypedDict, List from langchain.tools import tool from langchain_openai import ChatOpenAI from langchain_core.messages import BaseMessage, SystemMessage, HumanMessage from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode, tools_condition # -- 1) 定义我们唯一的业务工具 @tool def cancel_order(order_id: str) -> str: """取消尚未发货的订单。""" # (在这里调用真实的后台 API) return f"订单 {order_id} 已被取消。" tools = [cancel_order] # -- 2) 定义 State class AgentState(TypedDict): # add_messages 会自动处理消息的追加,而不是覆盖 messages: Annotated[List[BaseMessage], add_messages] order: dict # -- 3) 定义节点 def call_model(state: AgentState): order = state.get("order", {"order_id": "UNKNOWN"}) # 系统提示词告诉模型具体要做什么 system_prompt = ( f'''你是一名电商客服代理。 订单 ID: {order['order_id']} 如果客户要求取消订单,请调用 cancel_order(order_id) 然后发送一个简单的确认。 否则,只需正常回复。''' ) # 将系统消息放在消息列表的最前面 # 注意:我们不在 state 中持久化 SystemMessage,而是每次调用模型时动态添加 # 这样可以保持 state['messages'] 干净,且允许根据 order 动态改变 prompt messages = [SystemMessage(content=system_prompt)] + state["messages"] # 初始化模型并绑定工具 # 使用 gpt-4o 或其他支持工具调用的现代模型 llm = ChatOpenAI(model="gpt-4o", temperature=0) llm_with_tools = llm.bind_tools(tools) response = llm_with_tools.invoke(messages) # 返回的内容会被 add_messages reducer 追加到 state 的 messages 中 return {"messages": [response]} # -- 4) 构建图 def construct_graph(): workflow = StateGraph(AgentState) # 添加节点 workflow.add_node("assistant", call_model) workflow.add_node("tools", ToolNode(tools)) # 设置入口点 workflow.add_edge(START, "assistant") # 添加条件边: # 如果 assistant 返回了 tool_calls,tools_condition 会路由到 "tools" # 否则路由到 END workflow.add_conditional_edges( "assistant", tools_condition, ) # 工具执行完后,返回给 assistant 继续生成回复 (ReAct 循环) workflow.add_edge("tools", "assistant") return workflow.compile() graph = construct_graph() if __name__ == "__main__": example_order = {"order_id": "A12345"} # 注意:这里我们只传入初始的 HumanMessage convo = [HumanMessage(content="Please cancel my order A12345.")] # 运行图 result = graph.invoke({"order": example_order, "messages": convo}) # 打印结果 for msg in result["messages"]: print(f"{msg.type}: {msg.content}") |
注:出于学习目的,我们代码使用更新的langchain和langgraph 0.3版进行了改造,Eino示例代码请见:https://github.com/alanhou/ai-agent/blob/main/examples/chapter02/main.go(在测试时关于温度的设计我发现将
gpt-4o换成gpt-5会后出现一些问题,所以暂时注释了改配置参数,等进一步验证)
太棒了——你现在拥有了一个可运作的“取消订单”智能体。在扩展我们的智能体之前,让我们反思一下为什么我们要从如此简单的切入点开始。确定范围(Scoping)始终是一种平衡的艺术。如果任务范围太窄——比如仅限取消订单——就会错过退款或地址更改等其他高频请求,从而限制了实际效果。但如果将范围扩得太宽——“自动化每一个支持咨询”——将被诸如账单纠纷、产品推荐和技术故障排除等边缘情况淹没。如果保持模糊——“提高客户满意度”——你将永远不知道何时才算成功。
相反,通过专注于一个清晰、有界限的工作流——取消订单——我们确保了具体的输入(客户消息 + 订单记录)、结构化的输出(工具调用 + 确认信息)以及紧密的反馈循环。例如,想象一封写着“请取消我的订单 #B73973,因为我在别处找到了更便宜的选择”的电子邮件。人工客服会查找订单,核实未发货,点击“取消”,并回复确认。将其转化为代码意味着调用 cancel_order(order_id="B73973") 并向客户发送一条简单的确认消息。
既然我们有了一个可运作的“取消订单”智能体,下一个问题是:它真的有效吗?在生产环境中,我们不仅希望智能体运行,还希望知道它表现如何、哪里做对了、哪里失败了。对于这个取消订单智能体,我们关心的问题包括:
- 它是否调用了正确的工具 (
cancel_order)? - 它是否传递了正确的参数(正确的订单 ID)?
- 它是否向客户发送了清晰、正确的确认消息?
在我们的开源仓库中,你可以找到一个完整的评估脚本来自动化此流程:
以下是一个最小化的简化版逻辑,展示了可以如何直接测试智能体:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 最小化评估检查 example_order = {"order_id": "B73973"} convo = [HumanMessage(content='''Please cancel order #B73973. I found a cheaper option elsewhere.''')] result = graph.invoke({"order": example_order, "messages": convo}) # check if tool calls were made has_tool_call = False for m in result["messages"]: if getattr(m, "tool_calls", None): for tc in m.tool_calls: if tc["name"] == "cancel_order": has_tool_call = True break assert has_tool_call, "未调用取消订单工具 (Cancel order tool not called)" assert any("cancel" in m.content.lower() or "取消" in m.content for m in result["messages"]), \ "缺失确认消息 (Confirmation message missing)" print("✅ Agent passed minimal evaluation.") |
这段代码片段确保了工具被调用且确认消息已发送。当然,真正的评估会更深入:你可以测量工具的精确度、参数的准确性以及数百个示例中的总体任务成功率,以便在部署前捕获边缘情况。我们将在第九章深入探讨评估策略和框架,但现在请记住:未经测试的智能体是不可信的智能体。
因为这两个步骤都使用 @tool 装饰器实现了自动化,所以针对真实工单编写测试变得微不足道——而且可以立即获得可衡量的指标,如工具召回率、参数准确性和确认质量。既然我们已经构建并评估了一个最小化的智能体,下面来探索将塑造其能力和影响力的核心设计决策。
智能体系统的核心组件
设计一个有效的智能体系统需要深入理解使智能体能够成功执行任务的核心组件。每个组件在塑造智能体的能力、效率和适应性方面都起着至关重要的作用。从选择合适的模型到为智能体配备工具、记忆和规划能力,这些元素必须协同工作,以确保智能体能够在动态和复杂的环境中运行。本节深入探讨关键组件——基础模型、工具和记忆——并探索它们如何交互以形成一个内聚的智能体系统。图 2-1 展示了智能体系统的核心组件。
图 2-1. 智能体系统的核心组件
模型选择
每个基于智能体的系统的核心都是驱动智能体决策、交互和学习能力的模型。选择正确的模型是基础:它决定了智能体如何解释输入、生成输出以及适应环境。这一决策影响系统的性能、可扩展性、延迟和成本。选择合适的模型取决于智能体任务的复杂性、输入数据的性质、基础设施限制,以及通用性、速度和精度之间的权衡。
广义上讲,模型选择始于评估任务的复杂性。大型基础模型——如 GPT-5 或 Claude Opus 4.5——非常适合在开放式环境中运行的智能体,这种环境需要细致的理解、灵活的推理和创造性的生成。这些模型提供了令人印象深刻的泛化能力,擅长处理涉及歧义、上下文细微差别或多步骤的任务。然而,它们的优势是有代价的:它们需要大量的计算资源,通常需要云基础设施,并带来更高的延迟。它们最好保留给像个人助理、研究智能体或必须处理各种不可预测查询的企业系统等应用。
相比之下,较小的模型——如蒸馏版的 ModernBERT 变体或 Phi-4——通常更适合执行定义明确、重复性任务的智能体。这些模型在本地硬件上运行效率高,响应迅速,部署和维护成本较低。它们在结构化设置中表现良好,如客户支持、信息检索或数据标注,这些场景需要精确度,但对创造力和灵活性的要求较低。当实时响应能力或资源限制至关重要时,较小的模型可能仅凭其实用性就能胜过较大的模型。
模型选择中一个日益重要的维度是模态(Modality)。今天的智能体通常不仅需要处理文本,还需要处理图像、音频或结构化数据。多模态模型,如 GPT-5 和 Claude 4.5,使智能体能够解释和结合多种数据类型——文本、视觉、语音等。这扩展了智能体在医疗保健、机器人和客户支持等领域的作用范围,在这些领域,决策依赖于整合多种形式的输入。相比之下,纯文本模型仍然是纯语言用例的理想选择,在额外模态几乎没有附加价值的场景中提供较低的复杂性和更快的推理速度。
另一个关键考虑因素是开放性和可定制性。开源模型,如 Llama 和 DeepSeek,为开发人员提供了完全的透明度,以及根据需要微调或修改模型的能力。这种灵活性对于隐私敏感、受监管或特定领域的应用尤为重要。开源模型可以托管在私有基础设施上,针对独特的用例进行定制,且部署无需许可费用——尽管它们确实需要更多的工程开销。相比之下,专有模型(如 GPT-5、Claude 和 Cohere)通过 API 提供强大的能力,并附带托管的基础设施、监控和性能优化。这些模型是寻求快速开发和部署的团队的理想选择,尽管定制通常受到限制,且成本可能随着使用量迅速增加。
选择使用预训练的通用模型还是自定义训练的模型取决于智能体领域的特异性和风险。预训练模型——在广泛的互联网规模语料库上训练——适用于通用语言任务、快速原型设计以及领域精度不够关键的场景。这些模型通常可以通过提示工程技术进行轻微微调或调整,以最小的努力实现强大的性能。然而,在专业领域——如医学、法律或技术支持——自定义训练的模型可以提供显著的优势。通过在精心策划的、特定领域的数据集上进行训练,开发人员可以赋予智能体更深厚的专业知识和上下文理解,从而产生更准确和可信的输出。
成本和延迟的考量往往是现实部署中的决定性因素。大模型性能高但运行昂贵,并可能导致响应延迟。在这种情况不可接受时,较小的模型或大型模型的压缩版本提供了更好的平衡。许多开发人员采用混合策略,即由强大的模型处理最复杂的查询,而轻量级模型处理常规任务。在某些系统中,动态模型路由确保每个请求根据复杂性或紧迫性被路由到最合适的模型——使系统能够同时优化成本和质量。
斯坦福大学基础模型研究中心(CRFM)发布了语言模型整体评估(HELM),提供了对各种模型严格的第三方性能测量。在表 2-1 中,展示了一小部分语言模型及其在海量多任务语言理解(MMLU)基准测试中的表现,这是一个常用的模型能力通用评估标准。这些测量并不完美,但它们为我们提供了一把比较性能的通用标尺。总的来说,我们看到越大的模型表现越好,但也不一定(有些模型的表现优于其参数量所暗含的水平)。获得高性能通常需要多得多的计算资源。
表 2-1. 部分开放权重(Open Weight)模型的性能与规模
| 模型 | 维护者 | MMLU | 参数量 (十亿) | VRAM (全精度模型, GB) | 所需硬件示例 |
| Llama 3.1 Instruct Turbo | Meta | 56.1 | 8 | 20 | RTX 3090 |
| Gemma 2 | 72.1 | 9 | 22.5 | RTX 3090 | |
| NeMo | Mistral | 65.3 | 12 | 24 | RTX 3090 |
| Phi-3 | Microsoft | 77.5 | 14.7 | 29.4 | A100 |
| Qwen1.5 | Alibaba | 74.4 | 32 | 60.11 | A100 |
| Llama 3 | Meta | 79.3 | 70 | 160 | 4xA100 |
反之,这意味着只需花费一小部分成本即可获得中等性能。如表 2-1 所示,高达约 140 亿参数的模型可以在单个消费级图形处理单元(GPU)上运行,例如具有 24 GB 显存的 NVIDIA RTX 3090。然而,超过这个阈值,可能就需要服务器级 GPU,如 NVIDIA 的 A100,它有 40 GB 和 80 GB 两种规格。当模型的架构和权重(或参数)已向公众免费发布时,这些模型被称为“开放权重”模型,因此任何拥有必要硬件的人都可以加载和使用该模型进行推理,而无需支付访问费用。我们不会深入探讨硬件选择的细节,但这些精选的开放权重模型展示了不同尺寸下的性能水平范围。这些小型的开放权重模型继续快速改进,将越来越多的智能带入更小的形态中。虽然它们可能无法很好地解决你最困难的问题,但能以极低的价格处理更简单、更常规的任务。对于我们的电商支持智能体示例,一个小而快的模型就足够了——但如果我们扩展到产品推荐或基于情感的升级处理,更大的模型可能会解锁新的能力。
现在再看看几个大型旗舰模型。请注意,其中两个模型——DeepSeek-v3 和 Llama 3.1 Instruct Turbo 405B——已作为开放权重模型发布,但其他的还没有。即便如此,这些大型模型通常至少需要 12 个 GPU 才能获得不错的性能,甚至可能需要更多。这些大型模型几乎总是运行在大型数据中心的服务器上。通常,模型训练者根据输入和输出的 Token(词元)数量收取模型访问费用。这样做的好处是开发人员不需要担心服务器和 GPU 利用率,可以立即开始构建。表 2-2 显示了在相同的 MMLU 基准测试下的模型成本和性能。
表 2-2. 部分大型模型的性能与成本
| 模型 | 维护者 | MMLU | 每百万输入 Token 的相对价格 | 每百万输出 Token 的相对价格 |
| DeepSeek-v3 | DeepSeek | 87.2 | 2.75 | 3.65 |
| Claude 4 Opus Extended Thinking | Anthropic | 86.5 | 75 | 125 |
| Gemini 2.5 Pro | 86.2 | 12.5 | 25 | |
| Llama 3.1 Instruct Turbo 405B | Meta | 84.5 | 1 | 1 |
| o4-mini | OpenAI | 83.2 | 5.5 | 7.33 |
| Grok 3 | xAI | 79.9 | 15 | 25 |
| Nova Pro | Amazon | 82.0 | 4 | 5.33 |
| Mistral Large 2 | Mistral | 80.0 | 10 | 10 |
在表 2-2 中,价格为 Llama 3.1 每百万 Token 价格的倍数,Llama 3.1 是发布时最便宜的。在发布时,Meta 的收费标准是每百万输入 Token 0.20 美元,每百万输出 Token 0.60 美元。你可能还会注意到,性能与价格并不直接相关。同时也请知晓,基准测试的性能提供了有用的指导,但这些基准测试与你的特定任务的一致性可能会有所不同。如有可能,请针对具体任务比较模型,并找到能提供最佳性价比的模型。
归根结底,模型选择不是一次性的决定,而是一个战略性的设计选择,必须随着智能体能力、用户需求和基础设施的发展而重新审视。开发人员必须权衡通用性与专业性、性能与成本、简单性与可扩展性。通过仔细考虑任务复杂性、输入模态、操作限制和定制需求,团队可以选择能够使他们的智能体在现实世界中高效行动、可靠扩展并精确执行的模型。
工具 (Tools)
在基于智能体的系统中,工具是使智能体能够执行特定动作或解决问题的基本能力。工具代表了智能体的功能构建块,提供了执行任务以及与用户和其他系统交互的能力。智能体的有效性取决于其工具的范围和复杂程度。
为特定任务设计能力
工具通常是针对智能体旨在解决的任务进行定制的。在设计工具时,开发人员必须考虑智能体在不同条件和上下文下的表现。精心设计的工具集可确保智能体能够精确且高效地处理各种任务。工具可以分为三大类:
- 本地工具 (Local Tools)
这些是智能体基于内部逻辑和计算执行的动作,无需外部依赖。本地工具通常是基于规则的或涉及执行预定义的函数。例如数学计算、从本地数据库检索数据或基于预定义规则的简单决策(例如,根据既定标准决定批准或拒绝请求)。 - 基于 API 的工具 (API-based Tools)
基于 API 的工具使智能体能够与外部服务或数据源进行交互。这些工具通过获取实时数据或利用第三方系统,使智能体能够将其能力扩展到本地环境之外。例如,虚拟助手可能会使用 API 拉取天气数据、股票价格或社交媒体更新,从而使其能够为用户查询提供更具上下文相关性的回答。 - 模型上下文协议 (Model Context Protocol, MCP)
基于 MCP 的工具使智能体能够使用模型上下文协议向语言模型提供结构化的实时上下文,这是一种将外部知识、记忆和状态传递到模型提示词中的标准化模式。与需要完整往返执行的传统 API 调用不同,MCP 使智能体能够将丰富、动态的上下文——如用户资料、对话历史、世界状态或特定任务的元数据——直接注入模型的推理过程中,而无需调用单独的工具。它们在减少冗余工具使用、保持对话状态以及将实时态势感知注入模型行为方面特别有效。
虽然本地工具使智能体能够使用内部逻辑和基于规则的函数独立执行任务(如计算或从本地数据库检索数据),但基于 API 的工具使智能体能够连接外部服务。这允许访问实时数据或第三方系统,以提供上下文相关的响应和扩展功能。
工具集成与模块化
模块化设计对于工具开发至关重要。每个工具应设计为一个独立的模块,可以根据需要轻松集成或替换。这种方法使开发人员能够在不彻底检修整个系统的情况下更新或扩展智能体的功能。一个客户服务聊天机器人可能从一组处理简单查询的基本工具开始,随后在不中断智能体核心操作的情况下添加更复杂的工具(如纠纷解决或高级故障排除)。
记忆 (Memory)
记忆是一个基本组件,它使智能体能够存储和检索信息,使其能够保持上下文、从过去的交互中学习并随着时间的推移改进决策。有效的记忆管理确保智能体能够在动态环境中高效运行,并根据历史数据适应新情况。我们将在第六章更详细地讨论记忆。
短期记忆
短期记忆指的是智能体存储和管理与当前任务或对话相关的信息的能力。这种类型的记忆通常用于在交互过程中保持上下文,使智能体能够实时做出连贯的决策。一个能记住用户在一个会话中之前查询内容的客户服务智能体可以提供更准确且具有上下文意识的响应,从而增强用户体验。
短期记忆通常使用滚动上下文窗口来实现,这使智能体能够保持最近信息的滑动窗口,同时丢弃过时的数据。这在像聊天机器人或虚拟助手这样的应用中特别有用,因为智能体必须记住最近的互动,但可以忘记旧的、无关的细节。
长期记忆
另一方面,长期记忆使智能体能够在更长的时间内存储知识和经验,使其能够利用过去的信息来指导未来的行动。这对于需要随着时间的推移进行改进或根据用户偏好提供个性化体验的智能体尤为重要。
长期记忆通常使用数据库、知识图谱或微调后的模型来实现。这些结构使智能体能够存储结构化数据(如用户偏好、历史性能指标)并在需要时检索它。一个医疗健康监测智能体可能会保留患者生命体征的长期数据,使其能够检测趋势或向医疗服务提供者提供历史洞察。
记忆管理与检索
有效的记忆管理涉及组织和索引存储的数据,以便在需要时能够轻松检索。依赖记忆的智能体必须能够区分相关和无关的数据,并快速检索信息以确保流畅的性能。在某些情况下,智能体可能还需要忘记某些信息,以避免过时或不必要的细节干扰其记忆。
一个电商推荐智能体必须存储用户偏好和过去的购买历史以提供个性化推荐。然而,它还必须优先考虑最近的数据,以确保随着用户偏好的随时间变化,推荐仍然相关且准确。
编排 (Orchestration)
编排是将孤立的能力转化为端到端解决方案的关键:它是组合、调度和监督一系列技能的逻辑,使每个动作都能流畅地进入下一个动作,并朝着明确的目标努力。其核心在于,编排评估工具或技能调用的可能序列,预测其可能的结果,并选择最有可能在多步骤任务中成功的路径——无论是规划平衡交通、时间窗口和车辆可用性的最佳配送路线,还是组装复杂的数据处理管道。
由于现实世界的条件可能瞬间发生变化——新信息到达、优先级转移或资源变得不可用——编排器必须持续监控进度和环境,根据需要暂停或重新路由工作流以保持正确的方向。在许多场景中,智能体以增量方式构建计划:它们执行少量步骤,然后根据新的结果重新评估并更新剩余的工作流。例如,一个对话助手可能会在规划下一步之前确认每个子任务的结果,动态调整其顺序以确保响应能力和鲁棒性。
如果没有一个坚实的编排层,即使是最强大的技能也有可能相互冲突或完全停滞。我们将在第五章深入探讨构建弹性、灵活的编排引擎的模式、架构和最佳实践。
设计权衡
设计基于智能体的系统涉及平衡多个权衡,以优化性能、可扩展性、可靠性和成本。这些权衡要求开发人员做出战略决策,这可能会显著影响智能体在现实环境中的表现。本节探讨创建有效智能体系统所涉及的关键权衡,并提供如何应对这些挑战的指导。
性能:速度/准确性权衡
智能体设计中的一个关键权衡是平衡速度和准确性。高性能通常使智能体能够快速处理信息、做出决策并执行任务,但这可能会以牺牲精度为代价。相反,专注于准确性可能会减慢智能体的速度,特别是当需要复杂的模型或计算密集型技术时。
在实时环境中,如自动驾驶车辆或交易系统,快速决策至关重要,毫秒之差有时会产生决定性影响;在这里,为了确保及时响应,可能需要优先考虑速度而非准确性。然而,像法律分析或医疗诊断这样的任务需要高精度,为了确保可靠的结果,牺牲一些速度是可以接受的。
混合方法也是有效的,即智能体最初提供快速、近似的响应,然后通过后续更准确的跟进来完善它。这种方法在推荐系统或诊断中很常见,其中快速的初步建议会随着额外的时间和数据得到验证和改进。
可扩展性:为智能体系统设计可扩展性
可扩展性是现代基于智能体的系统面临的一个关键挑战,特别是那些严重依赖深度学习模型和实时处理的系统。随着智能体系统在复杂性、数据量和任务并发性方面的增长,管理计算资源,特别是 GPU,变得至关重要。GPU 是加速大型 AI 模型训练和推理的支柱,但高效的扩展需要仔细的工程设计,以避免瓶颈、利用率不足和运营成本上升。本节概述了通过优化 GPU 资源和架构来有效扩展智能体系统的策略。
GPU 资源通常是扩展智能体系统中最昂贵和限制最大的因素,使其高效使用成为首要任务。适当的资源管理使智能体能够处理不断增加的工作负载,同时最大限度地减少与高性能计算相关的延迟和成本。可扩展性的一个关键策略是动态 GPU 分配,这涉及根据实时需求分配 GPU 资源。与其静态地将 GPU 分配给智能体或任务,动态分配确保仅在必要时使用 GPU,从而减少空闲时间并优化利用率。
弹性 GPU 供应进一步提高了效率,使用云服务或本地 GPU 集群根据当前工作负载自动扩展资源。
优先级队列和智能任务调度增加了另一层效率,让高优先级任务立即获得 GPU 访问权限,而在高峰时段将不太关键的任务排队。
在大规模智能体系统中,延迟可能成为一个重大问题,特别是当智能体需要在实时或近实时环境中交互时。优化最小延迟对于确保智能体保持响应能力并能够满足性能要求至关重要。在分布式系统中高效调度 GPU 任务可以减少延迟并确保智能体在重负载下平稳运行。
一种有效的策略是异步任务执行,这使 GPU 任务可以并行处理,而无需等待先前的任务完成,从而最大限度地提高 GPU 资源利用率并减少任务之间的空闲时间。
另一种策略是跨 GPU 的动态负载均衡,通过将任务分配给未充分利用的资源,防止任何单个 GPU 成为瓶颈。对于依赖 GPU 密集型任务(如运行复杂的推理算法)的智能体系统,有效扩展不仅仅是简单地添加 GPU;它需要仔细优化以确保资源得到充分利用,使系统能够高效地满足不断增长的需求。
为了有效地扩展 GPU 密集型系统,不仅需要添加 GPU——还需要确保 GPU 资源得到充分利用,并且系统可以随着需求的增长而高效扩展。
水平扩展涉及通过添加更多的 GPU 节点来扩展系统以处理不断增加的工作负载。在集群设置中,GPU 可以协同工作来管理高容量任务,如实时推理或模型训练。
对于工作负载变化的智能体系统,使用混合云方法可以通过结合本地 GPU 资源和基于云的 GPU 来提高可扩展性。在需求高峰期,系统可以使用爆发扩展(burst scaling),将任务卸载到临时的云 GPU 上,在不需要对物理基础设施进行永久投资的情况下扩大计算能力。一旦需求下降,这些资源就可以释放,确保成本效率。
在非高峰时段(需求较低且价格更优惠时)使用基于云的 GPU 实例,可以显著降低运营成本,同时保持在需要时扩展的灵活性。
有效扩展智能体系统——特别是那些依赖 GPU 资源的系统——需要在最大化 GPU 效率、最小化延迟以及确保系统能够处理动态工作负载之间取得仔细的平衡。通过采用动态 GPU 分配、多 GPU 并行、分布式推理和混合云基础设施等策略,智能体系统可以扩展以满足不断增长的需求,同时保持高性能和成本效率。GPU 资源管理工具在此过程中起着关键作用,提供了必要的监督以确保随着智能体系统复杂性和范围的增长实现无缝扩展。
可靠性:确保稳健一致的智能体行为
可靠性指的是智能体随时间推移一致且准确地执行任务的能力。可靠的智能体必须能够在不发生故障的情况下处理预期和非预期的情况,确保获得用户和利益相关者的高度信任。然而,提高可靠性通常涉及系统复杂性、成本和开发时间的权衡。
容错性 (Fault Tolerance)
可靠性的一个关键方面是确保智能体能够处理错误或意外事件而不会崩溃或表现出不可预测的行为。这可能涉及建立容错性,即智能体可以检测故障(如网络中断、硬件故障)并优雅地恢复。容错系统通常采用冗余——复制关键组件或流程,以确保系统某一部分的故障不会影响整体性能。
一致性和鲁棒性
为了使智能体可靠,它们必须在不同的场景、输入和环境中表现一致。这在安全关键型系统中尤为重要,如自动驾驶车辆或医疗智能体,因为错误可能会产生严重后果。开发人员必须确保智能体不仅在理想条件下表现良好,而且在边缘情况、压力测试和现实世界约束下也能表现良好。实现可靠性需要:
- 广泛的测试智能体应经过严格的测试,包括单元测试、集成测试和真实场景模拟。测试应涵盖边缘情况、意外输入和对抗性条件,以确保智能体能够处理多样化的环境。
- 监控和反馈循环可靠的智能体需要在生产中进行持续监控,以检测异常并根据不断变化的条件调整其行为。反馈循环使智能体能够从环境中学习并随着时间的推移提高性能,从而增加其鲁棒性。
成本:平衡性能与开销
成本是基于智能体的系统设计中一个经常被忽视但至关重要的权衡。开发、部署和维护智能体的相关成本必须与预期收益和投资回报率 (ROI) 进行权衡。成本考虑影响与模型复杂性、基础设施和可扩展性相关的决策。
开发成本
开发复杂的智能体可能很昂贵,特别是当使用需要大数据集、专业知识和大量计算资源进行训练的高级机器学习 (ML) 模型时。此外,迭代设计、测试和优化的需求也会增加开发成本。
复杂的智能体经常需要一个拥有专业人才的团队,包括数据科学家、ML 工程师和领域专家,以创建高性能系统。此外,构建可靠且可扩展的智能体系统需要广泛的测试基础设施,通常涉及仿真环境以及对测试工具和框架的投资,以确保功能的稳健性。
运营成本
部署后,运行智能体的运营成本可能会变得相当可观,特别是对于需要高计算能力的系统,如涉及实时决策或连续数据处理的系统。这些费用的主要贡献者包括对大量算力的需求,因为运行深度学习模型或复杂算法的智能体通常依赖昂贵的硬件(如 GPU 或云服务)。
此外,处理大量数据或维护广泛记忆的智能体在数据存储和带宽方面会产生更高的成本。定期维护和更新,包括错误修复和系统改进,进一步增加了运营费用,因为需要资源来确保系统随时间推移的可靠性和性能。
成本与价值
归根结底,基于智能体的系统的成本必须通过它所交付的价值来证明。在某些情况下,优先考虑用于非关键任务的更便宜、更简单的智能体,而大力投资用于任务关键型应用的更复杂的智能体是有意义的。关于成本的决策必须在系统整体目标和预期寿命的背景下做出。一些优化策略包括:
- 精简模型 (Lean Models)在适当的情况下使用更简单、更高效的模型有助于降低开发和运营成本。例如,如果对于给定任务,基于规则的系统可以实现与深度学习模型相似的结果,那么更简单的方法通常更具成本效益。
- 基于云的资源利用云计算资源可以降低前期基础设施成本,建立更具可扩展性的按需付费模式。
- 开源模型和工具利用开源 ML 库和框架有助于最大限度地减少软件开发成本,同时仍能交付高质量的智能体。
设计智能体系统涉及平衡几个关键的权衡。优先考虑性能可能需要牺牲一些准确性,而扩展到多智能体架构会带来协调和一致性方面的挑战。确保可靠性需要严格的测试和监控,但这会增加开发时间和复杂性。最后,必须从开发和运营的角度考虑成本因素,确保系统在预算约束内交付价值。在下一节中,我们将回顾构建有效智能体系统时使用的一些最常见的设计模式。
架构设计模式
基于智能体的系统的架构设计决定了智能体如何构建、如何与其环境交互以及如何执行任务。架构的选择影响系统的可扩展性、可维护性和灵活性。本节探讨基于智能体系统的三种常见设计模式——单智能体和多智能体架构——并讨论它们的优势、挑战和适用的用例。我们将在第八章更详细地讨论这一点。
单智能体架构
单智能体架构是最简单、最直接的设计之一,其中单个智能体负责管理和执行系统内的所有任务。该智能体直接与其环境交互,并独立处理决策、规划和执行,而不依赖其他智能体。
这种架构非常适合定义明确且范围较窄的任务,最适合单个实体可以管理的工作负载。单智能体系统的简单性使其易于设计、开发和部署,因为它们避免了与多个组件之间的协调、通信和同步相关的复杂性。凭借清晰的用例,单智能体架构在不需要协作或分布式架构的小范围任务中表现出色,例如处理基本客户查询(如常见问题解答和订单跟踪)的简单聊天机器人,以及用于数据录入或文件管理的特定任务自动化。
单智能体设置在问题领域定义明确、任务直截了当且没有显著扩展需求的环境中运作良好。这使它们适合客户服务聊天机器人、通用助手和代码生成智能体。我们将在第八章更多地讨论单智能体和多智能体架构。
多智能体架构:协作、并行与协调
在多智能体架构中,多个智能体协同工作以实现共同目标。根据任务的性质,这些智能体可以独立运行、并行运行或通过协调方式运行。多智能体系统通常用于复杂的环境中,其中任务的不同方需要由专门的智能体管理,或者并行处理可以提高效率和可扩展性,它们带来了许多优势:
- 协作与专业化:多智能体系统中的每个智能体都可以设计为专注于特定任务或领域。例如,一个智能体可能专注于数据收集,另一个处理数据,第三个管理用户交互。这种分工使系统能够比单个智能体更有效地处理复杂任务。
- 并行性:多智能体架构可以利用并行性同时执行多个任务。例如,物流系统中的智能体可以同时规划不同的配送路线,从而减少整体处理时间并提高效率。
- 提高可扩展性:随着系统的增长,可以引入额外的智能体来处理更多任务或分配工作负载。这使得多智能体系统具有高度可扩展性,能够管理更大、更复杂的环境。
- 冗余与弹性:因为多个智能体独立运行,一个智能体的故障不一定会危及整个系统。其他智能体可以继续运作,甚至接管故障智能体的职责,从而提高整体系统的可靠性。
尽管有这些优势,多智能体系统也伴随着重大挑战,包括:
- 协调与通信:管理智能体之间的通信可能很复杂。智能体必须高效地交换信息并协调其行动,以避免重复工作、冲突行动或资源竞争。没有适当的编排,多智能体系统可能会变得混乱且低效。
- 复杂性增加:虽然多智能体系统功能强大,但它们的设计、开发和维护也更具挑战性。对通信协议、协调策略和同步机制的需求增加了系统架构的复杂性层级。
- 效率降低:虽然情况并非总是如此,但在完成任务时,多智能体系统通常会因为更高的 Token 消耗而导致效率降低。因为智能体必须频繁通信、共享上下文并协调行动,与单智能体系统相比,它们消耗更多的运算能力和资源。这种增加的 Token 使用量不仅导致更高的计算成本,而且如果通信和协调未优化,还可能减慢任务完成速度。因此,虽然多智能体系统为复杂任务提供了强大的解决方案,但其效率挑战意味着仔细的资源管理至关重要。
多智能体架构非常适合任务复杂、分布式或需要跨不同组件进行专业化的环境。在这些系统中,多个智能体有助于解决复杂的分布式问题,例如在金融交易系统、网络安全调查或协作 AI 研究平台中。
单智能体系统提供简单性,是定义明确任务的理想选择。多智能体系统提供协作、并行性和可扩展性,使其适合复杂环境。选择正确的架构取决于任务的复杂性、可扩展性的需求以及系统的预期寿命。在下一节中,我们将讨论一些我们可以遵循的原则,以便从我们构建的智能体系统中获得最佳结果。
最佳实践
设计基于智能体的系统不仅仅是构建具有正确模型、技能和架构的智能体。为了确保这些系统在现实条件下表现最佳,并随着环境的变化继续发展,在整个开发生命周期中遵循最佳实践至关重要。本节重点介绍三个关键的最佳实践——迭代式设计、评估策略和真实环境测试——它们有助于创建适应性强、高效且可靠的智能体系统。
迭代式设计
迭代式设计是智能体开发中的一种基本方法,强调在不断整合反馈的同时增量构建系统的重要性。迭代式设计不追求在初始构建中提供完美的解决方案,而是专注于创建小型的、功能性的原型,可以在多个周期中对其进行评估、改进和完善。这个过程允许快速识别缺陷、迅速修正路线和持续改进系统,它具有多重好处:
- 早期定位问题:通过发布早期原型,开发人员可以在设计缺陷或性能瓶颈深置系统之前识别它们。这使得能够迅速修复问题,降低长期开发成本并避免重大重构。
- 以用户为中心的设计:迭代式设计鼓励来自利益相关者、最终用户和其他开发人员的频繁反馈。这种反馈确保智能体系统保持与用户需求和期望的一致。随着智能体在现实场景中进行测试,迭代改进可以微调其行为和响应,以更好地服务于用户。
- 可扩展性:从最小可行性产品 (MVP) 或基本智能体开始,使系统能够以可管理的增量增长和发展。随着系统的成熟,可以逐步引入新功能和能力,确保每次新增在全面部署前都经过彻底测试。
为了有效地采用迭代式设计,开发团队应该:
- 快速开发原型:首先专注于构建核心功能。在这个阶段不要追求完美——构建一些能工作并交付价值的东西,即使很基础。
- 测试并收集反馈:在每次迭代后,从用户、开发人员和其他利益相关者那里收集反馈。利用这些反馈来指导改进并决定下一次迭代的优先级。
- 完善并重复:基于反馈和性能数据,进行必要的更改并在下一次迭代中完善系统。继续此循环,直到智能体系统满足其性能、可用性和可扩展性目标。
有效的迭代式设计涉及快速开发功能性原型,在每次迭代后收集反馈,并根据洞察力持续完善系统,以满足性能和可用性目标。
评估策略
评估基于智能体的系统的性能和可靠性是开发过程的关键部分。稳健的评估确保智能体能够处理现实世界的场景,在不同条件下表现良好,并满足性能预期。它涉及一种系统的方法来测试和验证智能体在不同维度的表现,包括准确性、效率、鲁棒性和可扩展性。本节探讨创建全面智能体系统评估框架的关键策略。我们将在第九章更深入地介绍度量和验证。
稳健的评估过程涉及开发一个全面的测试框架,涵盖智能体功能的所有方面。该框架确保智能体在各种预期和意外的场景下都经过彻底测试。
功能测试侧重于验证智能体是否正确执行其核心任务。智能体的每个技能或模块都应单独测试,以确保其在不同输入和场景下的行为符合预期。重点领域包括:
- 正确性:确保智能体根据其设计始终如一地提供准确和预期的输出。
- 边界测试:评估智能体如何处理边缘情况和极端输入,如非常大的数据集、异常查询或模糊指令。
- 特定任务指标:对于处理特定领域任务(如法律分析、医疗诊断)的智能体,确保系统满足该领域的准确性和合规性要求。
对于智能体系统,特别是那些由 ML 模型驱动的系统,评估智能体泛化到其训练场景之外的能力至关重要。这确保智能体可以处理新的、未见过的情况,同时保持准确性和可靠性。
智能体经常遇到其原始训练领域之外的任务。稳健的评估应测试智能体在不需要大量重新训练的情况下适应这些新任务的能力。这对于通用智能体或设计用于在动态环境中运行的智能体尤为重要。
用户体验是决定智能体系统成功的关键因素。重要的是不仅要评估智能体的技术性能,还要评估它在实际应用中满足用户期望的程度。
收集实际用户的反馈提供了关于智能体在实践中表现如何的关键见解。这些反馈有助于完善智能体的行为,提高其有效性和用户满意度,包括以下内容:
- 用户满意度评分:使用净推荐值 (NPS) 或客户满意度 (CSAT) 等指标来衡量用户对其与智能体互动的感受。
- 任务完成率:衡量用户在智能体帮助下成功完成任务的频率。低完成率可能表明智能体设计中存在混淆或低效。
- 显式信号:创造机会让用户提供反馈,形式包括赞/踩、星级评级,以及根据上下文接受、拒绝或修改生成结果的能力。这些信号可以提供丰富的见解。
- 隐式信号:分析用户与智能体的交互,以识别常见的故障点,如误解、延迟、情绪或不恰当的回复。可以挖掘交互日志,以获得关于智能体需要改进领域的见解。
在某些情况下,有必要让人类专家参与评估过程,以评估智能体的决策准确性。人类介入验证 (Human-in-the-loop validation) 将自动化评估与人类判断相结合,确保智能体的表现符合现实世界的标准。在可行的情况下,人类专家应审查智能体输出的样本,以验证正确性、伦理合规性以及与最佳实践的一致性,这些审查随后可用于校准和改进自动化评估。
我们应该在密切模拟其现实世界应用的环境中评估智能体。这有助于确保系统在受控开发条件之外能够可靠地运行。在智能体运行环境的全谱系中评估它,从数据摄取和处理到任务执行和输出生成。端到端测试确保智能体在多个系统、数据源和平台之间按预期运行。
真实环境测试 (Real-World Testing)
虽然在可控开发环境中构建智能体对于初始测试至关重要,但在真实环境中验证智能体同样重要,以确保它们在与实时用户或环境交互时表现符合预期。真实环境测试涉及将智能体部署在实际生产环境中,并在现实生活条件下观察其行为。这一测试阶段使开发人员能够发现在早期开发阶段可能未浮现的问题,并评估智能体的鲁棒性、可靠性和用户影响。
真实环境测试对于确保智能体能够管理实时环境的不可预测性和复杂性至关重要。与受控测试不同,这种方法揭示了边缘情况、意外的用户输入以及高需求下的表现,帮助开发人员完善智能体以实现稳健、可靠的操作:
- 暴露于现实世界的复杂性:在可控环境中,智能体使用可预测的输入和响应进行操作。然而,现实世界环境是动态且不可预测的,拥有多样化的用户、边缘情况和不可预见的挑战。在这些环境中进行测试可确保智能体能够处理现实场景的复杂性和可变性。
- 发现边缘情况:现实世界的交互经常暴露出在设计或测试阶段可能未考虑到的边缘情况。例如,一个使用脚本化查询测试的聊天机器人可能在开发中表现良好,但在暴露给真实用户时,它可能会在处理意外输入、模糊问题或自然语言变体时遇到困难。
- 评估负载下的性能:真实环境测试还使开发人员能够观察智能体在高工作负载或增加的用户需求下的表现。这对于在流量波动的环境中运行的智能体(如客户服务机器人或电商推荐引擎)尤为重要。
真实环境测试通过验证其在现实生活条件下的表现来确保智能体已准备好部署。此过程涉及分阶段发布、持续监控关键指标、收集用户反馈以及迭代完善智能体以优化其能力和可用性:
- 分阶段部署:分阶段推出智能体,从有限环境中的小规模测试开始,然后扩展到全面部署。这种分阶段的方法有助于增量地识别和解决问题,而不会让系统或用户崩溃。
- 监控智能体行为:使用监控工具跟踪真实环境测试期间智能体的行为、响应和性能指标。监控应关注关键绩效指标 (KPI),如响应时间、准确性、用户满意度和系统稳定性。
- 收集用户反馈:在真实环境测试期间与用户互动,收集他们与智能体交互时的体验反馈。用户反馈在识别差距、提高可用性和确保智能体满足现实需求方面非常有价值。
- 基于洞察力迭代:真实环境测试提供了宝贵的洞察力,应将其反馈到开发周期中。利用这些洞察力来完善智能体,提高其能力,并为未来的迭代优化其性能。
遵循迭代式设计、敏捷开发和真实环境测试等最佳实践对于构建适应性强、可扩展且具有弹性的基于智能体的系统至关重要。这些实践确保智能体设计灵活,在现实条件下经过彻底测试,并持续改进以满足不断变化的用户需求和环境挑战。通过将这些方法纳入开发生命周期,开发人员可以创建更可靠、高效和有效的智能体系统,使其能够在动态环境中蓬勃发展。
结语
你不需要一份 30 页的计划书才能开始构建一个优秀的智能体系统——但也需要一点远见卓识。正如我们在电商支持智能体中所看到的,选取一个易于处理的功能——如取消订单——这样能够构建一些小型的、可测试的且立即有用的东西。定义成功的标准,避免模糊或范围过大的野心,并专注于快速交付明确的价值。
有效的智能体系统不仅仅是其各部分的简单总和。它们依赖于强大的架构、严谨的工程设计和紧密的反馈循环。选择正确的结构模式为可扩展性和弹性奠定了基础,而迭代开发和稳健的评估则能确保智能体随着时间的推移不断改进。像分阶段发布和真实环境测试这样的最佳实践,将有前景的原型——就像我们简单的取消订单智能体——转变为在生产中值得信赖的可靠系统。
在第三章中,我们将把重点转移到等式的另一边——人,探讨如何设计清晰、响应迅速且直观的智能体体验,以服务于那些依赖它们的人。归根结底,无论你的系统架构多么强大,其成功与否取决于它在人类手中的应用效果。
翻译整理自Building Applications with AI Agents一书,仅供学习交流使用






