基于LangChain与LangSmith构建制药行业多智能体研究平台
1. 从零到一为什么制药行业需要一个“智能研究副驾”如果你在制药或生物科技公司待过哪怕只是短暂接触过研发或市场情报部门你一定会对下面这个场景感到无比熟悉一个研究员为了撰写一份关于某个靶点的竞争格局报告需要同时打开PubMed、ClinicalTrials.gov、公司内部专利数据库、各种行业新闻网站甚至还要去翻找几个月前某个会议的内部纪要。他像一个信息世界的“八爪鱼”在不同的浏览器标签页、PDF文档和Excel表格之间来回切换复制、粘贴、整理、核对。这个过程不仅耗时数天而且极易出错——你可能漏掉一篇关键文献或者误解了某个临床试验的入组标准。更糟糕的是当你好不容易整理出一份报告新的数据又发布了一切又得重来。这就是传统医药信息研究的痛点信息孤岛、流程僵化、高度依赖个人经验、难以规模化。而Madrigal公司一个虚构的、但极具代表性的名字代表了那些走在技术前沿的制药或生物技术公司面临的挑战正是如此。他们需要的不是一个更快的搜索引擎而是一个能够理解复杂生物医学问题、自主规划研究路径、协调不同“专家”能力、并最终生成可信赖情报的“智能研究副驾”。这个副驾不是替代人类专家而是将专家从繁琐的、重复的信息搜集与初步整理中解放出来让他们专注于更高价值的分析、洞察和决策。LangChain和LangSmith的出现为构建这样的“副驾”提供了前所未有的可能性。LangChain不是一个具体的应用而是一个框架它像乐高积木一样将大语言模型LLM与各种数据源、工具如计算器、代码执行器、API以及记忆系统连接起来构建出能够执行复杂任务的“智能体”Agent。而LangSmith则是这个智能体世界的“控制塔”和“训练场”它提供了从开发、调试、测试到监控、部署的全链路工具。简单来说用LangChain“造车”用LangSmith“开车和修车”。那么Madrigal是如何利用这两者打造出一个既灵活又可扩展的多智能体研究与情报平台的呢这篇文章我将以一个深度技术参与者的视角为你拆解这个平台背后的架构思想、核心组件、实战中的技术选型逻辑以及我们趟过的那些“坑”。无论你是制药行业的从业者想了解AI如何落地还是技术开发者想学习如何用LangChain构建复杂企业级应用相信都能从中获得启发。2. 架构蓝图拆解“多智能体”平台的四大核心支柱一个成功的平台首先源于清晰的顶层设计。Madrigal的平台并非一蹴而就其架构演进始终围绕四个核心支柱展开任务规划与分解、专业化智能体分工、可信数据源集成、以及全流程可观测性。这四大支柱共同支撑起了平台的灵活性与可扩展性。2.1 支柱一基于有向无环图的任务规划与编排平台的核心是一个“任务规划器”。当用户提出一个复杂请求如“分析PD-L1抑制剂在非小细胞肺癌一线治疗中的最新临床进展及主要玩家专利布局”时系统不会直接扔给一个大模型去生成一篇可能充满幻觉的文章。相反它会将这个宏大的任务分解成一个有向无环图DAG。这个DAG中的每个节点代表一个子任务边代表任务间的依赖关系。例如节点A文献检索从PubMed、BioRxiv等获取近两年关于PD-L1抑制剂NSCLC的临床研究论文。节点B临床试验检索从ClinicalTrials.gov获取相关III期临床试验的状态、主要终点和结果。节点C专利检索从Derwent、智慧芽等数据库检索关键公司的相关专利。节点D新闻与市场情报从特定行业新闻源获取最新交易、监管动态。节点E综合分析依赖A、B、C、D的输出进行交叉验证、矛盾消解和综合报告生成。为什么选择DAG而不是简单的线性链线性链Chain适用于步骤固定、顺序执行的简单任务。但对于研究任务子任务间存在复杂的依赖关系如分析需要等待所有数据检索完成且可能需要并行执行以提高效率文献和专利检索可以同时进行。DAG能天然地表达这种依赖与并行关系。在LangChain生态中LangGraph库正是为此而生。它允许你以图的方式定义智能体的工作流每个节点可以是一个简单的函数、一个工具调用甚至是另一个智能体。LangGraph提供了状态管理、循环、分支等控制流原语使得构建复杂、动态的工作流变得直观。注意这里有一个常见的混淆点。LangChain本身包含“Chain”的概念但那是更基础的、线性的组合单元。而LangGraph是构建在LangChain之上的、用于编排多个Chain或Agent的图工作流库。你可以理解为Chain是“句子”LangGraph是“段落”或“章节”的编排器。2.2 支柱二专业化智能体分工与“委员会”决策机制平台没有设计一个“全能型”的超级智能体而是遵循了“专业的人做专业的事”的原则创建了一系列专业化智能体Specialist Agent文献解析智能体精通生物医学文献结构能提取研究目的、方法、结果、结论PICO框架并能识别研究类型RCT、回顾性研究等和证据等级。临床试验智能体熟悉ClinicalTrials.gov的字段体系能精准解析试验阶段、干预措施、主要/次要终点、入组状态和结果摘要。专利分析智能体理解专利权利要求书和说明书的语言能提取IPC分类、主权项、实施例要点等。数据提取与清洗智能体负责从非结构化的PDF、网页中提取表格数据并进行标准化如统一单位、药物名称。综合报告生成智能体接收所有上游智能体的输出进行信息整合、去重、矛盾排查并按照预设的模板生成结构化的报告如Word、PPT或Markdown。这些智能体如何协同工作它们通过一个“委员会Council”或“主管Supervisor”智能体来协调。主管智能体接收用户任务将其分解为DAG然后根据DAG调度相应的专业智能体去执行子任务。专业智能体将结果返回给主管主管负责汇总和推进工作流。这种架构的好处是高内聚、低耦合每个智能体功能单一易于开发、测试和迭代。更新文献解析逻辑不会影响专利分析。易于扩展当需要新增能力时例如增加一个“基因组学数据库查询智能体”只需开发新的智能体并注册到主管的调度列表中即可平台核心架构无需大改。性能优化可以为不同智能体配置不同规格的LLM。例如对逻辑推理要求高的综合报告生成智能体使用GPT-4而对模式匹配为主的提取任务使用成本更低的Claude Haiku或本地模型。2.3 支柱三构建可信赖的“数据飞轮”——RAG与工具调用对于医药研究数据的准确性和时效性是生命线。平台绝不能依赖于LLM的“固有知识”因为会过时且可能产生幻觉。因此我们采用了“检索增强生成RAG”与“工具调用Tool Calling”双轮驱动的数据策略。RAG用于内部知识库我们将公司内部的既往研究报告、标准操作程序SOP、化合物数据库、历史项目文档等非公开信息进行向量化存入向量数据库如Chroma、Weaviate。当智能体需要背景信息时优先从这部分知识库中检索最相关的片段作为上下文提供给LLM。这确保了输出的内容与公司内部认知和规范保持一致。工具调用用于实时外部数据对于需要获取最新外部信息的任务我们为智能体装备了“工具”。例如search_pubmed_tool(keywords: str, max_results: int) - List[Dict]fetch_clinical_trial_detail_tool(nct_id: str) - Dictquery_internal_compound_db_tool(cas_number: str) - Dict智能体在规划任务时会自主决定在何时调用何种工具。LLM负责生成符合工具输入格式的调用请求平台执行工具并将结果返回给LLM进行后续处理。这里的关键是工具的可靠性。我们为每个工具都编写了严格的输入验证、错误处理和结果解析逻辑并设置了速率限制和重试机制确保外部API的调用稳定。一个重要的实战心得不要试图让一个智能体同时处理RAG和复杂工具调用。我们最初的设计中一个智能体既要做向量检索又要规划调用多个工具导致其Prompt极其复杂性能不稳定。后来我们将其拆解一个“检索协调员”智能体专门负责根据问题类型决定是查询向量库还是调用某个工具API然后将获取到的原始数据交给下游的“解析专家”智能体进行处理。职责分离后系统的可维护性和稳定性大幅提升。2.4 支柱四全链路可观测性与持续迭代——LangSmith的核心价值这是将项目从“演示原型”推向“生产级平台”的关键。如果没有LangSmith开发多智能体系统就像在黑暗中调试分布式系统——你只知道最终结果不对但完全不知道是哪个智能体、哪步推理、哪个工具调用出了问题。LangSmith为我们提供了三大核心能力精细化的追踪Tracing平台中每一次LLM调用、每一次工具执行、每一次智能体的决策步骤都会被LangSmith自动记录并可视化。你可以清晰地看到一个用户请求的完整生命周期像看一张详细的调用链图谱。当报告出现错误时我们可以快速定位到是“文献检索智能体”错误地解析了某个关键词还是“报告生成智能体”在整合时丢失了重要信息。数据集管理与测试Testing我们将历史上典型的用户查询和期望的正确输出构建成测试数据集。每次对智能体的Prompt或逻辑进行修改后都可以在LangSmith上针对这个数据集运行回归测试精确评估修改是带来了改进还是引入了回归。这让我们能放心地进行迭代。提示词工程与版本管理Prompt Management每个智能体的系统提示词System Prompt都是其“灵魂”。在LangSmith中我们可以对提示词进行版本化管理A/B测试不同版本的提示词对输出质量和成本的影响。例如我们发现为“专利分析智能体”的提示词中加入“请特别注意独立权利要求中的‘其特征在于’句式”的指令能显著提升其提取核心保护范围的准确率。提示LangSmith不是免费的但对于企业级应用其带来的开发效率提升、问题诊断速度加快和系统稳定性保障其价值远超成本。在项目早期就集成LangSmith能为后续的复杂化铺平道路。3. 实战深潜关键组件的技术选型与实现细节理解了架构蓝图我们深入到几个关键的技术实现环节看看具体是如何做的以及为什么做出这样的选择。3.1 智能体类型选择ReAct模式与OpenAI Functions的融合LangChain支持多种智能体类型如Zero-shot ReAct、Structured Chat等。我们的选择是在需要复杂推理和规划的任务上使用ReAct模式在需要严格结构化输出的工具调用上使用基于OpenAI Function Calling的智能体。ReActReasoning Acting模式是让LLM以“思考… 行动… 观察…”的循环来工作。这对于我们的“主管智能体”和“综合报告生成智能体”非常合适。例如思考用户需要PD-L1抑制剂的竞争分析。我需要先获取最新的临床数据再获取专利信息最后进行整合。我应该先启动文献和临床试验检索这两者可以并行。 行动调用 search_pubmed_tool关键词为“PD-L1 inhibitor NSCLC first-line phase 3”。 观察[工具返回了10篇文献摘要] 思考我已获得初步文献列表。现在需要同时获取临床试验信息。 行动调用 search_clinical_trials_tool条件为“PD-L1 NSCLC Phase 3”。 ...ReAct模式的优势在于其推理过程对人类透明便于调试。我们可以在LangSmith中查看完整的“思考链”理解智能体为何做出某个决策。而对于“文献解析智能体”其任务相对固定输入一篇文献的文本输出结构化的JSON包含标题、作者、期刊、PICO要素等。这里我们使用了基于OpenAI Function Calling或类似架构如Anthropic的Tool Use的智能体。我们预先定义好一个extract_pico函数指定其输入参数和输出格式。LLM的任务只是从文本中提取信息并填充这个函数调用。这种方式输出格式严格解析简单非常适合标准化信息提取任务。性能对比实测在相同任务下纯ReAct智能体因为要生成大量的“思考”文本其延迟和Token消耗都更高。而Function Calling智能体更加高效直接。因此我们的原则是上层规划用ReAct保灵活下层标准化提取用Function Calling保效率。3.2 记忆管理如何让智能体记住“上下文”多轮对话和复杂任务中记忆至关重要。平台需要处理两种记忆会话记忆Conversation Memory记住当前用户对话的历史以便处理指代如“上面提到的那个试验”和保持连贯性。任务记忆Task Memory在长工作流中跨智能体、跨步骤传递和共享中间结果。对于会话记忆我们采用了ConversationSummaryBufferMemory。它不会无限制地保存所有历史消息而是定期让LLM对之前的对话进行摘要只保留最近的原始消息和之前的摘要。这很好地平衡了上下文长度限制和记忆完整性。对于任务记忆这是LangGraph发挥威力的地方。我们在LangGraph的“状态State”对象中定义了一个共享的字典例如from typing import TypedDict, List, Annotated import operator class State(TypedDict): # 用户输入 user_query: str # 各个步骤的产出 literature_results: List[Dict] clinical_trial_results: List[Dict] patent_results: List[Dict] # 最终报告 final_report: str工作流中的每个节点智能体都可以读取和修改这个状态。例如“文献检索”节点将结果存入state[‘literature_results’]“综合分析”节点则读取所有results字段进行整合。LangGraph的状态管理机制自动处理了数据的流动和持久化。3.3 处理“脏数据”与不确定性智能体的自我验证与纠错机制医药数据源质量参差不齐。一篇文献的摘要可能模糊一个临床试验的登记信息可能更新不及时。我们不可能要求上游数据完美因此必须在平台内部建立容错和自我验证机制。策略一置信度评分与溯源。每个智能体在输出结构化数据时必须附带一个“置信度评分”0.0-1.0和对原始文本的“引用片段”。例如专利智能体提取“权利要求1”时会标记其置信度为0.9并引用原文中对应的段落。下游的综合智能体在发现不同来源信息冲突时如A文献说有效率70%B文献说65%会优先采纳置信度高、来源权威如顶级期刊 vs. 预印本的信息并在报告中以脚注形式标明冲突和选择理由。策略二设置“验证员”智能体。对于关键信息如药物剂量、主要终点指标在流水线中插入一个专门的“验证员”节点。它的任务非常简单接收上游提取的数据和原始文本回答一个问题“根据提供的原文提取的信息[X]是否准确”。这个智能体使用与提取智能体不同的Prompt甚至可以使用不同的LLM例如用GPT-4做验证用GPT-3.5-Turbo做初筛通过“第二双眼睛”来降低错误率。策略三人机回环Human-in-the-loop, HITL。平台并非全自动。我们定义了若干“检查点”。例如当系统识别出一个“突破性疗法认定”的新闻但置信度低于阈值时或者当不同智能体对同一事实的提取结果严重矛盾时工作流会暂停并通过Slack或邮件向相关研究员发送通知请求人工确认。确认后的结果会反馈给系统用于优化后续的模型判断。4. 从开发到生产规模化部署与性能优化实战构建一个能在实验室运行的原型是一回事将其部署为可供多个团队同时使用的稳定生产平台是另一回事。以下是我们在规模化过程中遇到的核心挑战和解决方案。4.1 部署模式微服务化与异步任务队列我们最初的单体应用很快遇到了瓶颈一个耗时的研究任务如分析一个疾病领域的所有竞品会阻塞整个应用影响其他用户的简单查询。解决方案是微服务化和异步化。我们将核心的“研究引擎”拆分为独立的微服务Orchestrator Service编排服务接收用户请求初始化LangGraph工作流将工作流任务提交到Redis任务队列使用Celery或RQ。Agent Worker Pool智能体工作池一组独立的Worker进程从队列中领取任务如“运行文献解析智能体”。每个Worker都加载了所需的智能体、模型和工具。Worker可以水平扩展根据负载动态增加或减少。State Store状态存储使用Redis或PostgreSQL存储LangGraph的工作流状态。这样即使某个Worker崩溃任务也可以由其他Worker基于持久化的状态恢复执行。Callback Service回调服务处理LangSmith的回调将追踪数据、日志和最终结果存入数据库并向前端推送实时进度更新。这种架构实现了请求的异步处理、资源的弹性伸缩和高可用性。用户提交任务后立即得到一个任务ID可以随时通过ID查询进度和结果。4.2 成本与延迟优化模型路由、缓存与流式输出成本和响应速度是生产级AI应用必须面对的两座大山。模型路由Model Routing不是所有任务都需要最强大、最昂贵的模型。我们实现了一个简单的路由层。根据任务的复杂度和对可靠性的要求将其路由到不同的LLM后端简单信息提取/分类使用低成本的本地模型如通过Ollama部署的Llama 3或性价比高的API模型如Claude Haiku。复杂推理、规划、报告润色使用GPT-4或Claude Opus。 路由规则可以基于任务类型、输入Token长度、历史准确率等动态调整。向量检索与工具结果缓存许多查询具有重复性。我们对向量检索的结果基于查询语句的Embedding进行缓存。同样对于调用外部API获取的、不常变动的数据如已结束临床试验的官方结果也进行TTL生存时间缓存。这大幅减少了对外部服务的调用和LLM的Token消耗。流式输出Streaming对于最终的报告生成我们使用LLM的流式响应。报告不是等全部生成完毕才一次性返回给用户而是逐段生成、逐段推送到前端。这极大地提升了用户体验让用户感觉系统在“实时思考和工作”。LangChain和LangGraph都对流式输出有很好的支持。4.3 监控、告警与持续学习基于LangSmith的运维体系上线后运维成为重点。我们利用LangSmith建立了核心监控仪表盘质量监控跟踪每个智能体每次调用的“置信度评分”分布。如果某个智能体的平均置信度持续下降会触发告警提示可能需要优化Prompt或检查数据源。成本监控按智能体、按项目、按用户统计Token消耗和API调用成本识别异常使用模式。延迟监控记录每个工作流步骤的耗时定位性能瓶颈。例如我们发现“专利检索”工具因为依赖的外部API响应慢是整个工作流的主要延迟来源随后我们为其增加了并行查询和更积极的缓存策略。错误监控集中收集所有工具调用失败、LLM响应格式错误、工作流执行异常等信息。更重要的是我们将所有用户对生成报告的反馈如“这条信息不准确”、“请补充XX方面的内容”也收集起来与对应的请求追踪关联形成一个高质量的“强化学习数据集”。定期用这个数据集来评估和微调我们的智能体Prompt甚至考虑对某些专用的小模型进行微调实现平台的自我进化。5. 避坑指南那些只有踩过才知道的“雷”回顾整个项目有几个“坑”如果提前知道能节省大量时间和精力。第一个大坑Prompt的脆弱性与版本化。早期我们直接硬编码Prompt在代码里。一次微小的调整比如把“请总结”改成“请概括”可能导致某个智能体的行为发生不可预知的变化。教训必须从第一天起就将所有Prompt外部化、版本化。我们后来使用LangSmith的Prompt Management功能并将Prompt存储在数据库中每个智能体运行时根据版本号拉取对应的Prompt。任何更改都需经过A/B测试才能上线。第二个大坑工具调用的错误处理黑洞。最初我们只考虑了工具调用成功的场景。但当外部API返回429速率限制、503服务不可用或超时时智能体往往会陷入困惑生成无意义的“思考”。教训为每一个工具调用包裹完善的错误处理。不仅要在代码层面捕获异常、进行重试还要在Prompt层面教导LLM如何应对失败。例如在系统指令中加入“如果调用工具[X]失败你将收到错误信息[Y]。你应该尝试另一种查询策略或者将失败信息记录在报告中并继续执行其他任务。”第三个大坑LLM的“创造性”过度发挥。即使提供了严格的输出格式要求如JSON SchemaLLM有时仍会“创造性”地添加额外字段或改变结构导致下游解析失败。教训不要100%信任LLM的结构化输出。在解析前增加一个“语法修正”步骤。可以使用一个轻量级的、专门训练过的文本到JSON的模型进行后处理或者使用像Pydantic这样的库进行强制验证和清洗对无法解析的部分提供默认值或标记为缺失。第四个大坑低估领域知识注入的难度。通用的LLM对“ORR客观缓解率”、“PFS无进展生存期”、“双盲双模拟”等专业术语的理解是表面的。最初生成的报告常常出现概念混淆。教训必须在多个层面注入领域知识。1)在Prompt中提供详细的领域术语定义和示例。2)在Few-shot示例中在上下文中包含大量本领域的正确输入输出对。3)在工具设计中工具本身就应该封装领域逻辑比如一个calculate_hr风险比的工具内部会处理置信区间的计算而不是让LLM去算。4)在RAG知识库中确保向量库包含公司内部的术语表和标准定义。构建这样一个平台是一场马拉松而不是冲刺。它不仅仅是技术栈的堆砌更是对领域工作流的深度理解、对AI能力边界的清醒认知以及对工程化严谨性的不懈追求。Madrigal的案例表明通过LangChain和LangSmith的组合我们能够搭建起连接人类专家与海量信息世界的智能桥梁让研究变得更高效、更系统、更可追溯。而这一切的起点是首先想清楚你希望你的“智能副驾”具体在哪一个环节以何种方式为你的业务创造价值。