构建可靠Agent系统的设计模式指南
Martin Fowler发布Agent系统的架构最佳实践,覆盖系统设计、错误处理、可观测性等维度。是Agent开发的高质量参考。
Martin Fowler发布Agent系统的架构最佳实践,覆盖系统设计、错误处理、可观测性等维度。是Agent开发的高质量参考。
本论文介绍了由拜耳公司与Thoughtworks联合开发的云托管平台Preclinical Information Center(PRINCE),该平台旨在解决制药行业药物开发中面临的挑战。PRINCE利用智能体检索增强生成(Agentic RAG)和Text-to-SQL技术,集成了数十年的安全性研究报告。我们描述了PRINCE从基于关键词的搜索到能够回答复杂问题并起草监管文件的智能研究助手的演进过程。我们通过上下文工程——信息如何在专业化智能体之间被塑造和路由——的视角来反思关键工程决策,以及通过护栏工程——如何在模型周围构建编排、恢复和可观测性以保持控制和可靠性。该系统通过透明度、可解释性和人工参与的整合来优先确保信任。PRINCE展示了AI在制药领域的变革潜力,显著提高了数据可访问性和研究效率,同时确保了治理和合规性。
Sarang Kulkarni是Thoughtworks的首席顾问,在软件工程、数据平台和应用AI的交汇处工作。他专注于构建生产级GenAI系统,特别是Retrieval-Augmented Generation(RAG)和多智能体工作流,帮助团队将这些系统从早期概念转变为现实应用。Sarang还为Thoughtworks全球AI服务开发团队做出贡献,并教授O'Reilly关于构建生产就绪RAG应用的课程。
临床前药物发现本质上是复杂且数据密集的。研究人员面临着在这一关键阶段有效访问和分析大量生成的信息的重大挑战。传统的基于关键词的搜索方法,通常依赖于严格的布尔逻辑,在面对临床前研究问题的细微和复杂特性时,经常效果不佳。
大语言模型(LLM)的出现提供了一个变革性的机会。通过将LLM的生成能力与信息检索系统的精确性相结合,Retrieval-Augmented Generation(RAG)已成为一项有前景的技术。这种方法有可能彻底改变临床前数据访问,使研究人员能够用自然语言提出复杂问题,并获得基于专有数据的准确、富有上下文的答案。
拜耳公司很早就认识到了这一潜力,致力于探索这些技术如何能够解决临床前研究中的长期挑战。
在这篇文章中,我们分享了这一旅程——拜耳公司对生成AI的早期投资如何导致了PRINCE的开发,一个基于智能体RAG的AI智能体系统。本案例研究探讨了技术架构、工程决策,以及在将临床前数据检索从一个充满挑战的迷宫转变为直观对话体验中汲取的经验。
PRINCE背后的许多工程决策现在可以通过上下文工程和护栏工程的视角来理解,尽管当该系统最初设计时,我们并没有使用这些术语。上下文工程塑造了每个模型接收的信息、它不接收的信息,以及上下文如何在研究、反思和编写等专业化步骤之间移动。护栏工程塑造了模型周围的脚手架:编排、工具边界、状态持久化、重试、回退、验证、反思循环、可观测性和人工审查。
虽然这篇文章专注于技术架构和工程挑战,但我们发表在《人工智能前沿》上的论文更详细地涵盖了产品演进和商业影响。
拜耳公司的临床前研究景观,就像许多大型制药组织一样,由多样化和广泛的数据阵列组成。这包括来自各种研究的高度结构化数据集,以及嵌入在文本文档(如研究报告、出版物和监管提交)中的大量非结构化信息。研究人员经常在有效地访问和分析这些信息方面遇到重大障碍:
数据孤岛:信息分散在众多不同的系统和存储库中,使得获得与特定化合物或研究相关的临床前数据的全面整体视图变得极其困难。
搜索能力有限:传统的基于关键词的搜索引擎难以处理临床前术语和研究问题的复杂性和可变性,经常产生不相关、不完整或过多的结果。
耗时的手动分析:提取特定见解或跨多个文档编译信息需要大量的手动工作,使宝贵的研究人员时间远离核心科学活动。
这些固有的挑战突出了对更高效、更智能和更集成的临床前数据检索和分析方法的明确需求。
为了解决这些挑战,拜耳公司开发了Preclinical Information Center(PRINCE)平台。PRINCE被构想为临床前数据的统一网关,最初专注于整合之前孤立的结构化研究元数据,并以"可搜索"的方式公开它们。这个初始阶段允许用户应用高级过滤器并主要从结构化研究元数据中检索信息。
然而,拜耳公司宝贵的临床前知识的重要部分存在于多年来积累的非结构化PDF研究报告中。由于多年来众多系统迁移,与这些报告相关的结构化元数据可能不完整、缺失,甚至包含不正确的注释。至关重要的是,权威的"黄金标准"信息一致地存在于已批准的PDF研究报告中。
生成AI的出现,特别是RAG,提供了解开这一财富的非结构化数据的钥匙。通过整合RAG能力,PRINCE开始从基于过滤器的"搜索"工具转变为自然语言"询问"系统,使研究人员能够直接查询这些研究报告的内容。
这一演进反映了PRINCE通过三个不同阶段的进展:
搜索:初始阶段专注于为数千份临床前研究报告创建统一网关,将来自各种临床前领域的多个内部数据孤岛整合为可搜索的格式,主要利用结构化元数据。
询问:这一阶段引入了利用Retrieval Augmented Generation(RAG)的AI驱动的问答系统。这使研究人员能够通过用自然语言提出问题,直接从非结构化数据(包括来自历史报告的扫描PDF)中获得见解。
执行:当前阶段将PRINCE定位为能够执行复杂任务的活跃研究助手。这通过整合多智能体系统来实现,允许该平台处理复杂查询、编排工作流,并支持起草监管文件等活动。
这种从搜索到询问到执行的刻意演进代表了对行业在临床前开发中更高效率和创新需求的战略响应。通过为研究人员提供越来越强大的工具来访问、分析和作用于临床前数据,PRINCE旨在使更快的数据驱动决策、减少不必要实验的需要,并最终加速更安全、更有效的治疗的开发。
该系统作为一个交互式对话UI运行,由强大的后端基础设施提供支持。其架构设计用于处理复杂查询并提供准确、富有上下文的答案,使用LangGraph进行编排,并通过FastAPI应用程序提供服务。
图 1 展示了系统上下文——UI、后端、数据存储、LLM 回退机制和可观测性——而图 2 则进一步展示了系统如何协调其专用智能体。
图 1:系统上下文及支撑平台。
用户请求:当用户通过基于 React 构建的对话式 UI 提交请求时,整个流程便由此开始。
编排:用户请求会被路由到后端基于 LangGraph 的编排层。这个工作流引擎负责协调一个多阶段流程,依次完成澄清用户意图、思考与规划、开展研究(使用 RAG 和 Text-to-SQL)、验证数据完整性,并最终通过 Writer Agent 生成响应。工作流中包含特意设置的暂停点和反馈循环,以确保数据完整后再继续执行。(我们将在后文的专门章节中详细探讨这一智能体工作流。)
数据检索与状态管理:Researcher Agent 与一个全面且分布式的数据生态系统进行交互:
所有研究报告的向量表示都存储在 OpenSearch 中,构成用于信息检索的核心知识库。
经过各种 ETL 和数据协调流程生成的精选结构化数据通过 Athena 访问。
智能体的执行状态会受到细致跟踪。每完成一个逻辑步骤(即执行一个 LangGraph 节点),相应状态都会通过 LangGraph checkpointer 持久化到 PostgreSQL 中。
更广泛的应用级状态由 DynamoDB 管理。
该系统利用内部 GenAI 平台托管来自 OpenAI、Anthropic、Google 和开源提供商的模型。这些平台通过统一的 OpenAI 兼容端点公开所有模型,因此可以轻松切换模型,并为每项任务选择最合适的工具。它们还负责管理控制平面,实施速率限制及其他保护措施,以防止滥用。
韧性与错误处理:稳健性是一项关键的设计原则,系统中设置了多种回退机制:
如果某个特定 LLM 发生故障,系统会先自动重试请求数次,然后再回退到其他模型或平台,以确保服务连续性。
为了从瞬时故障中快速恢复,系统同时在单次 LLM 调用层面和逻辑节点层面(即智能体计划中的一个完整步骤)实现了重试机制。
此外,系统还会向智能体提供错误的上下文,使其能够据此规划不同的执行路径或替代行动方案。
可观测性与评估:系统会对整体性能和可靠性进行监控:
系统的整体健康状况和指标使用 CloudWatch 跟踪。
Langfuse 是主要的可观测性工具,可提供所有生产流量的详细追踪信息,从而支持对问题进行深入调试。此外,评估数据集也存储和管理在 Langfuse 中,便于分析性能分数并诊断具体故障。评估使用 RAGAS 评估框架完成。实时流量评估每天执行一次;每当核心工作流、提示词或底层模型发生重大变更时,则会执行数据集评估。
最终响应:智能体处理完请求并生成令人满意的响应后,该响应会被发送回对话式 UI,呈现给用户。
贯穿这一架构的一项设计原则是上下文纪律。更大的上下文窗口并未消除选择性控制每个智能体所见内容的必要性。在早期迭代中,向上下文中放入过多信息,反而使系统更难引导,也更难评估。因此,PRINCE 不会将提示词视为容纳所有可用信息的单一大型容器。相反,不同阶段会接收不同的上下文:Think & Plan 接收规划上下文,Researcher Agent 接收检索上下文,Reflection Agent 接收证据上下文,而 Writer Agent 接收综合上下文。这种方式减少了上下文污染,使系统更易于调试、评估和改进。
通过运用先进的多智能体架构以及多样化的强大工具和数据源,这些步骤确保系统能够针对广泛的复杂查询,提供可靠且符合上下文的答案。
PRINCE 整合了一个智能体式 RAG 系统(图 2),用于处理需要多个步骤、推理以及与不同工具或数据源交互的复杂用户请求。该系统使用 LangGraph 实现,负责编排整体工作流,并利用 Researcher Agent、Writer Agent 和 Reflection Agent 执行特定任务。系统以稳健性和可靠性为设计目标,设置了多种回退机制,以确保即使某些组件发生故障,系统仍能继续运行。
图 2:研究工作流。
Clarify User Intent 步骤是抵御歧义的第一道防线。随着系统扩展到毒理学和药理学等不同领域,简单的用户查询也经常变得模棱两可,导致系统难以自动选择正确的工具。系统不会在所有数据源上进行代价高昂的反复试错,而是主动提出澄清问题,以确定具体领域或数据类型。
这可以确保系统使用必要的约束条件来增强查询,从而定位正确的工具。我们还在通过 UI 中的领域级选择功能对此进行优化,让用户能够预先筛选有效工具。为进一步减少操作阻力,系统还会提供 AI 辅助的数据源推荐:当用户未选择任何数据源,或选择了多个数据源但缺乏明确重点时,模型会分析用户查询背后的意图,并推荐最相关的数据源。用户始终拥有完全控制权,可以接受、调整或覆盖推荐,从而确保领域专业知识始终拥有最终决定权。这种“快速失败”机制可以避免在模糊查询上浪费执行资源,而通过细致调优,当意图已经明确时,系统也不会造成干扰。
从上下文工程的角度来看,这一步是工作流中的第一个组装决策:在任何检索开始之前,它便限定了纳入范围的工具、领域和数据源,从而确保后续智能体接收到的是一个聚焦的问题,而不是一个开放式问题。
Think & Plan 步骤负责制定满足用户请求的策略。这个关键组件为系统提供了一个专门的空间,使其能够在采取行动之前推理后续步骤——这一技术受到 Anthropic Think tool 的启发。重要的是,该步骤执行的是过程反思:评估智能体是否正在朝最终目标取得正确进展,以及是否处于正确的执行轨迹上,而不是评估数据本身。
在多步骤智能体工作流中,尤其是涉及大量连续操作的工作流中,过程反思至关重要。设想这样一种场景:系统需要执行 50 个步骤才能完成一项复杂任务。在每一个节点,系统都必须自问:我是否正以正确的方式执行这些步骤?我是否取得了应有的进展?当前轨迹是否正朝着用户的目标前进?Think & Plan 步骤提供了这种元认知能力,使系统能够反思自身的工作流,并相应调整策略。
事实证明,这个“思考空间”在涉及多次工具调用的场景中尤其有价值。PRINCE 最初开发时只有少数几个工具:一个用于基于 RAG 的检索,另一个用于 Text-to-SQL 查询。然而,随着我们接入更多数据源以扩展系统能力,可用工具的数量显著增加。工具数量激增也带来了一项固有挑战:不同工具之间存在职责重叠和领域边界交叉。
例如,多个工具可能服务于相似但又略有差异的目的——查询结构化元数据与查询非结构化报告,或者检索研究摘要与检索详细实验数据。面对属于相似领域但处理略有不同数据的工具时,LLM 有时难以针对特定查询选择最合适的工具。通过引入专门的思考步骤,系统可以明确推理哪个工具与用户意图最匹配,评估每个可用工具的特征,并做出更明智的决策。这种方法显著提高了工具选择的准确率。
除了工具选择外,思考与规划步骤对于编排多步骤流程至关重要。PRINCE 中的许多复杂查询需要一系列工具调用,其中一个工具的输出必须在确定下一步行动之前进行分析。例如,系统可能首先查询结构化元数据以识别相关研究,然后使用这些研究 ID 从非结构化报告中检索详细信息,最后综合这些发现。如果没有专门的流程反思空间,系统将尝试线性执行这些步骤,而不评估每一步是否正在推进目标完成。有了思考步骤,系统可以暂停、评估其在工作流中的进展,并智能地规划完成用户请求所需的后续工具调用。
研究员智能体充当系统的主要信息收集器。当我们将新的科学领域纳入 PRINCE 时,我们一致观察到数据分为两个主要类别:结构化和非结构化。虽然具体的实现技术可能因领域而异——例如,对药理学查询利用 Snowflake Cortex Analyst 进行文本转 SQL,对毒理学利用其他更定制的方法——这些检索策略背后的基础原理保持一致。
随着 PRINCE 跨越多个临床前领域的扩展,具有平面工具列表的单一研究员智能体变得越来越难以管理。许多工具在类似的概念上运作——"研究"、"发现"、"检测"——但根据领域指向不同的底层数据集、模式和监管解释。例如,当用户提及"该研究"时,相关的上下文可能是重复给药毒理学研究、心血管安全药理学包或聚合大数据表中的特定检测,每个都有自己的权威数据源。
为了避免一个庞大的智能体在重叠工具和微妙不同的数据契约之间苦苦挣扎,我们正在积极地将研究员功能演进为特定领域子智能体的层级结构。在这个提议的架构中,每个领域智能体将拥有自己的工具集(例如,毒理学 RAG + 毒理学元数据 SQL,或药理学 RAG + 检测级别 SQL),以及定制的提示指令,这些指令编码了该领域数据模型的工作方式、哪些表或索引是权威的,以及如何解释关键概念。我们预期这将保持职责的一致性,减少意外的跨领域泄露,并使每个领域的检索行为更容易进行推理和测试。
为了有效地从这个多样化的数据源收集洞见,研究员智能体采用了混合检索方法,专注于两个不同的模式:
检索增强生成(RAG):用于处理非结构化数据,主要是 PDF 报告。
文本转 SQL:用于查询存储在 Amazon Athena 中的结构化数据。
这种双策略方法允许系统在叙述性科学报告和定量实验数据之间架起桥梁。
在这个更新的设想中,顶层研究员智能体被设计为充当协调者而不是单一的全能组件。根据澄清的用户意图和 UI 中的任何显式领域选择,它将查询路由到适当的领域子智能体,后者随后可以决定如何在其自己的边界内结合 RAG 和文本转 SQL。这种模式旨在从用户的角度保持"一个研究员"的简洁性,同时在内部允许每个领域演进其自己的工具、模式和检索方案,而不会破坏系统的其余部分。
鉴于拥有数千份临床前研究报告和其他非结构化文档的庞大存储库,RAG 对于通过将 LLM 回复基于此特定知识库来提取相关洞见至关重要。RAG 管道包括综合摄入过程和复杂的查询时架构。
摄入过程:临床前研究报告(主要是跨越数十年的 PDF,通常包括具有复杂表格的扫描文档)首先被集中到 S3 数据湖中,并通过为该数据集调优的提取管道处理。提取的文本被规范化为结构化 JSON,然后使用保留足够科学背景同时保持块高效检索的策略进行分块。
每个块都使用来自 Amazon Athena 的研究和章节级元数据进行丰富(例如研究 ID、化合物、物种、路线、页面和父章节),这稍后能够在 RAG 层中实现精确的元数据过滤。最后,这些带注解的块被嵌入并索引到 Amazon OpenSearch Service 中,形成向量存储,该存储支持对历史语料库和新报告到达时的每日增量进行语义和元数据感知检索。
查询时 RAG 管道:当用户提交查询时,系统启动多阶段检索过程。此管道设计用于从向量数据库有效检索最相关和最可信的信息,以为 LLM 的回复提供基础。
为了说明此管道,考虑示例查询:"在研究 T123456-2 中是否观察到以下任何临床发现:竖毛、共济失调、眼睛半闭、粪便松散?"系统通过以下步骤处理此查询:
关键词提取:用户的自然语言查询首先由 LLM 分析。通过精心的提示工程,模型被指示提取与我们文档语料库内关键词搜索高度相关的关键词(例如"竖毛"、"共济失调"、"眼睛半闭"、"粪便松散")。
元数据过滤器生成:同时,LLM 根据查询生成元数据过滤器。例如,提取过滤器 eq(study_id, T123456-2) 以缩小搜索范围。此过滤器使用少样本提示动态生成,并提供了各种排列和组合示例给模型,确保它可以处理多样化的过滤请求。
查询扩展:为了确保全面检索并考虑措辞和术语的变化,由较小、更快速的模型执行查询扩展(多查询或查询重写)。这基于原始问题生成 n=5 个语义相似的查询。对于示例查询,这可能包括以下变化:
"研究 T123456-2 中报告的临床症状,包括鸡皮疙瘩、缺乏协调、半闭眼"