如何构建一个有效运作的 AI Agent 系统?又如何在开发过程中发现那些可能会在投入生产后引发巨大麻烦的潜在问题呢?
要回答这些问题,你需要将Agent系统分解为三个部分:工具、推理和行动。每一层都有其自身的挑战。一个层次的错误可能会波及到其他层次,以意想不到的方式引发故障。检索功能可能会提取出不相关数据。推理不当可能会导致不完整或循环的工作流程。行动在生产中可能会失误。
Agent 系统只在其最薄弱的环节处才显得强大,本指南将向你展示如何设计避免这些陷阱的系统。目标是:在最关键的时候构建出可靠、可预测且有韧性的代理。
架构概览
Agent 系统在三个逻辑层面上运行:工具层、推理层和行动层。每一层都有其特定的作用,使代理能够有效地检索、处理和行动信息。理解这些层之间的相互作用对于设计既实用又可扩展的系统至关重要。
下面的图表展示了这三个层面及其内部的组成部分:

工具层:系统的基石。这一层与外部数据源和服务进行交互,包括API、向量数据库、运营数据、知识库和用户交互等。它负责获取系统所依赖的原始信息。设计良好的工具能够确保代理高效地检索相关、高质量的数据。
行动层:有时也称为编排层。这一层负责协调大型语言模型(LLM)与外部世界(工具)之间的交互。它处理与用户的交互(如适用)。它接收来自LLM的关于下一步要采取的行动的指令,执行该行动,然后将结果提供给推理层的LLM。
推理层:系统智能的核心。这一层利用大型语言模型(LLM)处理检索到的信息。它确定代理下一步需要做什么,借助上下文、逻辑和预定义的目标来做出决策。推理不当会导致错误,如重复查询或行动不一致。
Agentic工作流
行动/编排层是推动代理系统行为向前发展的主要引擎。这一层提供了一个主要的处理循环,大致如下所示:

Agent 应用与大型语言模型(LLM)之间的首次交互定义了系统试图实现的总体目标。这可以是任何事情,从生成房地产列表到撰写博客文章,再到处理在客户支持应用中等待的用户的开放式请求。
除了这些指令,还有一个LLM可以调用的函数列表。每个函数都有一个名称、描述以及它接受的参数的JSON模式。这个简单的函数示例来自OpenAI的文档:
{ "model": "gpt-4o", "messages": [ { "role": "user", "content": "What's the weather like in Boston today?" } ], "tools": [ { "type": "function", "function": { "name": "get_current_weather", "description": "Get the current weather in a given location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["location"] } } } ], "tool_choice": "auto"}
由推理层中的大型语言模型(LLM)来决定下一步应该调用哪个函数,以便更接近实现指定的目标。
当LLM做出响应时,它会指出应该调用哪个函数以及应提供给该函数的参数。
根据用例以及推理层中所使用的LLM的能力,LLM可能能够指定一组应被调用的函数(理想情况下是并行调用),然后才进入循环的下一个环节。
提供一个退出函数是个好主意,这样推理层就可以在完成处理时发出信号,告知行动层可以成功退出。
设计原则
表面上,这一切看起来都很简单。然而,随着任务复杂性的增加,函数列表也随之增长。需要处理的方面越多,推理层就越容易出错。一旦你开始添加新的API、专业子代理和多个数据源,你就会发现,要管理的远不止是插入一个提示然后点击“开始”那么简单。
在第二部分中,我们将深入探讨模块化的概念。我们会讨论为什么将你的代理系统分解为更小、更专注的子代理,能帮助你避免单体设计的陷阱。

每个子代理都可以处理其自身专门的领域——退货、订单、产品信息等,这种分离使得父代理能够自由地分配任务,而无需在一个庞大的提示中同时处理所有可能的函数。
在第三部分中,我们将深入探讨代理之间的交互。即使有了很好的模块化,构建统一的接口以允许子代理以一致的方式进行交互仍然是一个真正的挑战。我们将探讨如何定义清晰、标准化的交接流程,让每个代理都能完成自己的工作,而不会形成一个令人困惑的调用和回调网络。你会看到为什么拥有一个一致的接口很重要,以及这如何帮助你在出现问题时进行故障排除或升级问题。
在第四部分中,我们将研究数据检索和检索增强生成(RAG)。如果没有最新、相关数据,你的语言模型所能做的也是有限的,因此我们将讨论如何连接到数据库、API和向量存储,以提供你的代理所需的上下文。我们将涵盖从现有系统中提取结构化数据到索引PDF等非结构化内容的一切内容,以确保你的系统在扩展时仍然快速且准确。

最后,在第五部分,我们将探讨横向关注点。这包括设计任何健壮的代理系统时至关重要但又容易被忽视的方面——可观测性、性能监控、错误处理、安全性、治理和伦理。这些要素决定了你的代理是否能够处理现实世界的流量、保护用户数据,并在架构不可避免地演变过程中保持韧性。
这就是路线图。等我们完成时,你将拥有构建一个可靠、可扩展的代理系统所需的工具和模式——一个不仅在理论上听起来不错,而且能够在生产环境的实际压力下真正经受住考验的系统。