构建可观测性:如何监控和调试复杂的 Multi-Agent 系统

各位同行、分布式系统/Multi-Agent 爱好者,大家好!我是深耕分布式可观测性与 Agent 协作领域多年的老周。

最近这一年,Multi-Agent 系统(以下简称 MAS)的热度简直是“火箭上天——直窜云霄”:从 OpenAI 的 Devin 程序员代理人框架、LangChain 的 Agents 4.0 迭代、微软的 Semantic Kernel 自动团队协作(AutoGen 开源后更是火到 GitHub 星标破 10 万),再到国内的智谱 AI 多智体平台、阿里通义千问的 Agent Studio,越来越多的企业和开发者开始尝试用 MAS 解决复杂问题——从企业内部知识库问答升级到“多角色团队协作完成需求分析-设计-编码-测试-部署全流程”,再到金融风控的“多维度风险排查 Agent 集群”、智慧城市的“多区域监控-调度-决策 Agent 联盟”……

但现实是骨感的:当我们把 MAS 从玩具级的 Demo(比如“搜索 Wikipedia 回答问题”的单链 Agent)搬到生产环境,把 Agent 数量从 1-2 个扩展到 10-100 个甚至跨区域、跨语言、跨框架的“超级 Agent 联盟”时,监控和调试 MAS 简直是一场噩梦

昨天晚上还在和朋友吐槽:“Devin 要是上线出问题,你根本不知道是‘需求理解 Agent’读错了用户输入、‘技术调研 Agent’找了过时的 Python 2.7 文档、‘代码生成 Agent’偷偷加了 import * 引发了命名空间污染、‘代码审查 Agent’和‘测试 Agent’在‘代码覆盖率标准’上吵架导致任务卡死,还是‘Docker 部署 Agent’忘拉镜像、‘任务调度层’(比如 Celery 或者 LangGraph 的 StateGraph 分布式执行引擎)掉了链——没有可观测性的 MAS,就是黑箱里的一群无头苍蝇!

别慌,今天我就把这几年踩过的坑、总结的经验、实践过的最佳方案,从基础概念到架构设计、从监控指标到链路追踪、从告警策略到调试工具、从 Demo 级实现到生产级落地,全流程、全维度、深入浅出地 分享给大家!


1. 引言:MAS 可观测性的痛点与价值

1.1 痛点引入:你踩过这些坑吗?

为了让大家更有共鸣,我们先来看几个我亲身体验或亲眼所见的生产级 MAS 事故

事故1:金融风控 Agent 联盟的“误杀率暴增”

场景:某头部互联网金融公司上线了一套“多维度风险排查 Agent 联盟”,由 8 个 Agent 组成:

  1. UserInfoAgent:提取用户基本信息(年龄、职业、征信报告)
  2. TransactionAgent:分析用户近 3 个月的交易流水
  3. SocialAgent:爬取(合规授权的)用户社交关系风险(比如是否和失信人员有联系)
  4. DeviceAgent:检测用户登录设备的风险(比如是否是模拟器、是否是新设备)
  5. BehaviorAgent:分析用户的行为轨迹风险(比如是否是异地登录、是否在凌晨频繁申请贷款)
  6. BlacklistAgent:查询内部/外部黑名单
  7. RiskWeightAgent:根据业务规则给每个维度的风险评分分配权重
  8. DecisionAgent:根据加权总分输出“通过/拒绝/人工审核”的结果

问题:上线第 3 天,人工审核团队的工单量暴增了 500%,而正常通过的贷款申请数量下降了 40%——误杀率(即应该通过但被拒绝/人工审核的比例)从原来的 1% 飙升到了 25%!

排查过程的噩梦

  • 一开始怀疑是 TransactionAgent 的阈值改了?翻遍所有 Agent 的配置文件和代码历史,没有找到任何修改;
  • 然后怀疑是 SocialAgent 爬取的数据有问题?但 SocialAgent 的数据源是第三方合规平台,API 返回的 JSON 格式看起来没问题;
  • 接着怀疑是 RiskWeightAgent 的权重算错了?但手动测试了几个样本,权重分配完全符合业务规则;
  • 最后怎么找到问题的?——靠人工!排查人员手动跑了 100 个误杀的样本,每个样本都手动打印了 8 个 Agent 的输入输出,花了整整 3 天,才发现问题:UserInfoAgent 从征信报告里提取“收入”字段时,把“月收入:12000元”里的数字当成了字符串存储,然后传给 RiskWeightAgentDecisionAgent 时,直接用字符串进行了比较(“12000” < “2000” 是 True!),导致低风险的高收入用户被当成了高风险低收入用户!

损失

  • 直接经济损失:估算流失了约 2000 个正常客户,预计损失年化收益约 120 万元;
  • 间接损失:客户投诉量暴增 300%,品牌口碑受损;
  • 人力成本:排查问题花了 3 天,修复+回测+重新上线花了 2 天,共占用 5 名资深工程师的时间。
事故2:多角色协作 Agent 团队的“任务无限循环”

场景:我自己的团队做了一套“需求文档生成 Agent 团队”的 Demo,由 3 个 Agent 组成,用 LangChain 的 SequentialAgent 升级成了带状态回溯的 LangGraph StateGraph

  1. ProductManagerAgent:根据用户的一句话需求(比如“做一个在线点餐系统的后端API”),生成“需求规格说明书初稿”
  2. TechLeadAgent:根据“需求规格说明书初稿”,生成“技术架构设计初稿”和“接口文档初稿”,如果发现需求有问题,会把状态回退给 ProductManagerAgent 补充/修改
  3. QAEngineerAgent:根据“需求规格说明书初稿”、“技术架构设计初稿”和“接口文档初稿”,生成“测试用例初稿”,如果发现技术架构或接口文档有问题,会把状态回退给 TechLeadAgent 补充/修改;如果发现需求有问题,会把状态回退给 ProductManagerAgent

问题:上线测试(其实是内部演示)时,输入“做一个在线点餐系统的后端API”,整个团队无限循环了 2 个小时——ProductManagerAgent 生成初稿 → TechLeadAgent 回退补充“用户角色权限” → ProductManagerAgent 补充后再次生成 → TechLeadAgent 回退补充“支付系统对接” → ProductManagerAgent 补充后再次生成 → QAEngineerAgent 回退补充“压力测试要求” → ProductManagerAgent 补充后再次生成 → TechLeadAgent 又回退补充“数据库缓存策略”…… 我当时在客户面前脸都绿了!

排查过程的噩梦

  • 一开始以为是 LangGraphConditionalEdge(条件边)写错了?翻了好几遍代码,逻辑看起来没问题——只有当 TechLeadAgent 的输出包含“需要补充需求”时才会回退给 ProductManagerAgent
  • 然后以为是 Prompt 写得不好?把 Prompt 改了又改,加上了“最多只能回退 3 次需求”的限制,但没用——LLM(大语言模型)根本不听指令!
  • 最后怎么找到问题的?——靠手动打印 LangGraphState(状态)每一步的变化!花了 1 个小时,才发现问题:ProductManagerAgent 每次补充需求时,都会把新补充的内容加在旧文档的末尾,而不会覆盖旧文档里的冗余内容(比如一开始旧文档里写了“支付系统对接支付宝”,后来 TechLeadAgent 要求补充微信支付,ProductManagerAgent 就在末尾加了“还需要对接微信支付”,但没有整合到原来的支付系统章节);然后 TechLeadAgent 又会觉得需求文档结构混乱,需要重新组织,所以又回退给了 ProductManagerAgent
事故3:跨区域 MAS 调度层的“消息丢失”

场景:某智慧城市公司上线了一套“多区域交通监控-调度-决策 Agent 联盟”,由 3 个城市(北京、上海、广州)的本地 Agent 集群和 1 个位于杭州的中央调度 Agent 集群组成,用 Kafka 作为消息队列传递跨区域的调度指令和监控数据:

  • 本地 Agent 集群:每个城市有 5 个 Agent(TrafficCameraAgentSignalLightAgentPublicTransportAgentEmergencyVehicleAgentLocalDecisionAgent
  • 中央调度 Agent 集群:由 3 个 Agent 组成(GlobalDataAggregationAgentGlobalDecisionAgentGlobalTaskAssignmentAgent

问题:上线第 5 天,上海浦东机场附近的高架发生了严重拥堵,但 中央调度 Agent 集群没有收到任何上海本地的监控数据,也没有发出任何跨区域的调度指令(比如临时调整虹桥机场到浦东机场的地铁班次、临时开放应急车道给救护车)——导致拥堵持续了 4 个小时,严重影响了市民的出行!

排查过程的噩梦

  • 一开始怀疑是上海本地的 TrafficCameraAgentLocalDecisionAgent 挂了?登录上海的服务器一看,所有 Agent 的进程都在运行,CPU、内存占用也正常;
  • 然后怀疑是 Kafka 挂了?登录杭州的 Kafka 集群一看,所有 Broker 都在运行,Topic 也存在,消费者也正常订阅;
  • 接着怀疑是网络问题?用 ping 和 telnet 测试了上海到杭州的网络连接,看起来没问题;
  • 最后怎么找到问题的?——靠检查 Kafka 的 Producer 日志和 Consumer 偏移量!花了 2 个小时,才发现问题:上海本地的 GlobalDataAggregationAgent 的 Kafka Producer 配置里,acks 参数被设成了 0(即不需要等待 Broker 的确认就直接发送下一条消息),而那天上海到杭州的网络发生了 短暂的丢包(丢包率约 0.1%),导致约 10% 的监控数据没有成功发送到 Kafka 集群;同时,上海本地的 GlobalDataAggregationAgent 也没有设置任何消息重试机制或失败告警!

1.2 为什么传统的可观测性工具对 MAS 无效?

看到这里,可能有朋友会问:“老周,你不是深耕分布式可观测性多年吗?传统的分布式可观测性三支柱(Metrics、Tracing、Logging)不是已经很成熟了吗?为什么不能直接用在 MAS 上?”

没错,传统的分布式可观测性三支柱确实解决了很多“单体应用→微服务架构”转型过程中的监控和调试问题——比如 Prometheus+Grafana 监控 Metrics、Jaeger/Zipkin 做链路追踪、ELK/Loki 做日志收集…… 但 MAS 和传统的微服务架构有本质的区别,这些区别导致传统的可观测性工具“水土不服”,甚至完全无效:

对比维度 传统微服务架构 Multi-Agent 系统(MAS)
交互模式 同步/异步调用,调用关系相对固定 协作模式(协商、竞争、拍卖),交互关系动态变化
执行逻辑 确定性的代码逻辑,输入输出可预测 基于 LLM/规则引擎的非确定性逻辑,输入输出不可预测
状态管理 无状态/数据库/Redis 管理状态,状态结构固定 有状态的协作上下文(State),状态结构动态变化(比如随着 Agent 的交互不断添加新的字段)
故障模式 常见的故障:服务挂了、超时、网络丢包、数据库死锁 常见的故障:任务无限循环、LLM 幻觉、Agent 之间的冲突、上下文溢出、Prompt 失效
数据量级 Metrics/Tracing/Logging 的数据量级相对可控 每个 Agent 调用 LLM 都会产生大量的 Prompt/Response 数据,协作上下文(State)的大小也会随着交互次数的增加呈指数级增长

我们来具体分析一下:

1.2.1 交互模式的区别:从“固定调用链”到“动态协作图”

传统的微服务架构是**“请求-响应”或“事件驱动”的固定调用链/拓扑结构**——比如用户登录请求会经过“API Gateway → User Service → Auth Service → Database”,拓扑结构是预先设计好的,很少会发生变化(除非我们部署了新的服务或修改了调用逻辑)。

但 MAS 是**“多角色协作”的动态交互图**——比如我们的“需求文档生成 Agent 团队”,拓扑结构可能是“ProductManagerAgent → TechLeadAgent → QAEngineerAgent”,也可能是“ProductManagerAgent → TechLeadAgent → ProductManagerAgent → TechLeadAgent → QAEngineerAgent”,甚至可能是“ProductManagerAgent → TechLeadAgent → QAEngineerAgent → TechLeadAgent → ProductManagerAgent → ……(无限循环)”——拓扑结构完全由 LLM 的输出或 Agent 的协作规则动态决定,没有任何预先设计好的固定调用链!

这就导致传统的链路追踪工具(比如 Jaeger/Zipkin)“水土不服”——传统的链路追踪工具是基于“Span(跨度)”和“Trace(追踪)”的概念,每个 Trace 对应一个固定的请求,每个 Span 对应一个微服务的调用,Span 之间的父子关系是预先确定的(比如 API Gateway 的 Span 是 User Service 的 Span 的父 Span)。但 MAS 里的 Trace 是什么?是整个协作任务的生命周期吗?那 Span 又是什么?是每个 Agent 的一次执行吗?那 Span 之间的父子关系怎么确定?比如 TechLeadAgent 把状态回退给 ProductManagerAgent 时,TechLeadAgent 的 Span 是 ProductManagerAgent 的新 Span 的父 Span 吗?如果是,那整个 Trace 的 Span 树就会变成“循环树”,传统的链路追踪工具根本无法渲染!

1.2.2 执行逻辑的区别:从“确定性代码”到“非确定性 LLM/规则”

传统的微服务架构是基于确定性代码的——比如 User Service 里的 login() 函数,输入是 usernamepassword,输出要么是 success 要么是 failure,只要输入相同,输出就一定相同(除非代码有 Bug 或外部依赖发生了变化)。

但 MAS 里的 Agent 是基于非确定性的 LLM 或复杂规则引擎的——比如我们的 ProductManagerAgent,输入是同一句话“做一个在线点餐系统的后端API”,今天生成的需求文档可能包含“用户角色权限”,明天生成的可能就没有;比如 RiskWeightAgent 用 LLM 分配权重(很多 MAS 现在会用 LLM 动态调整业务规则),输入是同一份用户信息,今天分配的收入权重可能是 0.3,明天分配的可能就是 0.5——LLM 的输出是有温度(Temperature)的,输入相同,输出也可能不同!

这就导致传统的日志收集和分析工具(比如 ELK/Loki)“不够用”——传统的日志收集工具只能收集“确定性的代码日志”(比如 INFO: User xxx logged in successfully),但 MAS 里我们需要收集的是“非确定性的 Agent 日志”:

  1. LLM 调用日志:每次 Agent 调用 LLM 的完整 Prompt、完整 Response、调用时间、调用成本、Token 消耗、Temperature 等参数;
  2. 协作上下文(State)日志:每次 Agent 执行前后的完整 State 快照、State 的变化量;
  3. Agent 决策日志:Agent 为什么做出这个决策?比如 TechLeadAgent 为什么把状态回退给 ProductManagerAgent?是因为需求文档里缺少“用户角色权限”吗?如果是,LLM 在 Response 里具体是怎么说的?

传统的日志收集工具虽然可以收集这些数据,但很难分析这些数据——比如我们怎么快速找到“导致任务无限循环的那一次 LLM 调用”?怎么快速对比“两次相同输入的 Agent 执行,State 和 Response 有什么不同”?怎么快速量化“LLM 的 Temperature 对任务成功率的影响”?

1.2.3 状态管理的区别:从“固定结构状态”到“动态结构协作上下文”

传统的微服务架构是无状态为主,有状态为辅——如果需要管理状态,一般会用数据库(比如 MySQL、PostgreSQL)或缓存(比如 Redis、Memcached),而且状态的结构是固定的(比如 User 表的字段是 idusernamepasswordemail,很少会发生变化)。

但 MAS 是完全有状态的——整个协作任务的所有信息(用户输入、每个 Agent 的执行结果、LLM 的调用历史、协作规则的调整记录……)都存储在一个动态结构的协作上下文(State)里——比如我们的“需求文档生成 Agent 团队”,State 一开始可能只有 user_input 一个字段,后来 ProductManagerAgent 执行完后会添加 prd_draft 字段,然后 TechLeadAgent 执行完后会添加 tech_arch_draftapi_doc_draft 字段,再然后 QAEngineerAgent 执行完后会添加 test_cases_draftfeedback 字段——State 的字段、大小、结构完全由 Agent 的交互动态决定,没有任何预先设计好的固定 Schema!

这就导致传统的监控工具(比如 Prometheus+Grafana)“很难监控到关键信息”——传统的监控工具主要监控“固定结构的指标”(比如 CPU 使用率、内存占用、API 响应时间、请求成功率……),但 MAS 里我们需要监控的是“动态结构的协作指标”:

  1. 任务级指标:任务的成功率、任务的平均执行时间、任务的平均 LLM 调用次数、任务的平均 LLM 调用成本、任务的无限循环率……
  2. Agent 级指标:每个 Agent 的执行成功率、每个 Agent 的平均执行时间、每个 Agent 的平均 LLM 调用次数、每个 Agent 的平均 LLM 调用成本、每个 Agent 的幻觉率(即输出错误信息的比例)、每个 Agent 的回退率……
  3. State 级指标:State 的平均大小、State 的最大大小、State 的字段数量变化趋势、上下文溢出率(即 State 的 Token 数量超过 LLM 的上下文窗口限制的比例)……

这些指标里,很多是“非数值型的”或“动态计算的”——比如“幻觉率”需要我们人工或用另一个 LLM 来判断 Agent 的输出是否正确;比如“任务的无限循环率”需要我们监控 State 的变化趋势,如果 State 在一段时间内没有实质性的变化(比如只是在相同的几个字段之间来回修改),就认为任务进入了无限循环——传统的 Prometheus 虽然可以通过自定义 Exporter 来收集这些指标,但很难实现这些动态的、非数值型的指标的计算和可视化!

1.2.4 故障模式的区别:从“常见技术故障”到“新型协作故障”

传统的微服务架构的故障模式是相对固定的、常见的技术故障——比如服务挂了、超时、网络丢包、数据库死锁、内存泄漏、CPU 过载…… 这些故障我们已经有了成熟的监控和告警策略(比如用 Prometheus 监控服务的健康检查接口,如果连续 3 次健康检查失败就告警;比如用 Jaeger 监控 API 的响应时间,如果超过 5s 就告警……)。

但 MAS 的故障模式是完全新型的、由协作引起的故障——比如:

  1. 任务无限循环:Agent 之间来回回退状态,没有任何实质性的进展;
  2. LLM 幻觉:Agent 输出了错误的、不存在的信息(比如 TechLeadAgent 说“我们用 Python 5.0 来开发”,但 Python 5.0 根本不存在);
  3. Agent 之间的冲突:两个或多个 Agent 对同一个问题有不同的看法,无法达成一致(比如 RiskWeightAgent 认为收入权重应该是 0.3,而 DecisionAgent 认为应该是 0.5);
  4. 上下文溢出:State 的 Token 数量超过了 LLM 的上下文窗口限制(比如 GPT-4 Turbo 的上下文窗口限制是 128K Token,如果 State 的 Token 数量超过了 128K,LLM 就会报错或忽略前面的内容);
  5. Prompt 失效:随着 LLM 的版本更新或微调,原来有效的 Prompt 现在变得无效了(比如 GPT-3.5 Turbo 的某个 Prompt 可以让 LLM 输出 JSON 格式的结果,但 GPT-4 Turbo 的同一个 Prompt 就不行);
  6. 任务死锁:两个或多个 Agent 互相等待对方的输出,导致任务无法继续执行(比如 Agent A 等待 Agent B 的输出,Agent B 等待 Agent C 的输出,Agent C 等待 Agent A 的输出)。

这些新型的协作故障,传统的监控和告警工具根本无法识别——比如传统的监控工具只能监控服务是否挂了,但无法监控任务是否进入了无限循环;只能监控 API 的响应时间,但无法监控 LLM 是否产生了幻觉;只能监控内存占用,但无法监控上下文是否溢出!


1.3 解决方案概述:MAS 可观测性的“新三支柱”

既然传统的可观测性三支柱对 MAS 无效,那我们应该怎么办?——我们需要一套专门针对 MAS 设计的可观测性体系,我把它叫做“MAS 可观测性的新三支柱”

传统可观测性三支柱 MAS 可观测性的新三支柱 核心区别
Metrics(指标) Collaboration Metrics(协作指标) 从“固定结构的技术指标”升级到“动态结构的协作指标”,包含任务级、Agent 级、LLM 级、State 级四个维度的指标
Tracing(链路追踪) Interaction Tracing(交互追踪) 从“固定的 Span 父子关系树”升级到“动态的交互图(Interaction Graph)”,可以清晰地展示 Agent 之间的协作过程、State 的变化趋势、LLM 的调用历史
Logging(日志) Contextual Logging(上下文日志) 从“分散的、无关联的代码日志”升级到“完整的、关联的上下文日志”,包含用户输入、每个 Agent 的完整输入输出、每次 LLM 调用的完整 Prompt/Response、每次 State 的变化量、Agent 的决策依据

除了“新三支柱”之外,我们还需要一套专门针对 MAS 设计的调试工具告警策略——比如“任务回放工具”(可以回放整个协作任务的执行过程,就像看电影一样)、“幻觉检测工具”(可以用另一个 LLM 来自动检测 Agent 的输出是否有幻觉)、“上下文窗口预警工具”(可以在 State 的 Token 数量接近 LLM 的上下文窗口限制时发出预警)、“无限循环检测工具”(可以监控 State 的变化趋势,自动识别任务是否进入了无限循环)……

好消息是,现在已经有一些开源的 MAS 可观测性工具了——比如 LangChain 官方推出的 LangSmith(虽然现在还是 Beta 版,而且需要付费,但功能非常强大)、开源的 LangFuse(完全开源,支持 LangChain、LlamaIndex、Semantic Kernel 等主流框架,功能也非常不错)、开源的 Phoenix(主要用于 LLM 的评估和调试,但也可以用于 MAS 的可观测性)…… 我们在后面的章节会详细介绍这些工具的安装、配置和使用。


1.4 最终效果展示:用 LangFuse 监控和调试我们的“需求文档生成 Agent 团队”

为了让大家更直观地感受到 MAS 可观测性的价值,我们先来看一下用 LangFuse 监控和调试我们的“需求文档生成 Agent 团队”的最终效果:

1.4.1 任务级监控面板

在 LangFuse 的“Traces”面板里,我们可以看到所有协作任务的执行情况:

  • 任务的 ID、创建时间、执行时间、执行状态(Success/Failure/Running);
  • 任务的用户输入;
  • 任务的平均 LLM 调用次数、平均 LLM 调用成本、总 Token 消耗;
  • 任务的交互图(Interaction Graph)预览。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
(图片来源:LangFuse 官方文档)

1.4.2 交互追踪(Interaction Tracing)面板

点击某个任务的 ID,我们可以进入该任务的“交互追踪”面板,在这里我们可以看到:

  1. 动态的交互图(Interaction Graph):清晰地展示 Agent 之间的协作过程——每个节点代表一个 Agent 的执行或一次 LLM 的调用,每条边代表 Agent 之间的交互或 State 的传递;如果任务进入了无限循环,交互图会明显地显示出一个循环结构。
  2. 完整的 State 快照和变化量:每次 Agent 执行前后的完整 State 快照,以及 State 的变化量(即哪些字段被添加了、哪些字段被修改了、哪些字段被删除了)。
  3. 完整的上下文日志:每个 Agent 的完整输入输出、每次 LLM 调用的完整 Prompt/Response、调用时间、调用成本、Token 消耗、Temperature 等参数、Agent 的决策依据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
(图片来源:LangFuse 官方文档)

1.4.3 协作指标(Collaboration Metrics)面板

在 LangFuse 的“Dashboard”面板里,我们可以看到自定义的协作指标:

  • 任务级指标:任务的成功率、任务的平均执行时间、任务的无限循环率、任务的上下文溢出率;
  • Agent 级指标:每个 Agent 的执行成功率、每个 Agent 的平均执行时间、每个 Agent 的回退率;
  • LLM 级指标:LLM 的平均响应时间、LLM 的平均调用成本、LLM 的总 Token 消耗、LLM 的错误率;
  • 这些指标都可以用折线图、柱状图、饼图等方式可视化,而且可以根据时间范围、Agent 类型、LLM 类型等条件进行筛选。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
(图片来源:LangFuse 官方文档)

1.4.4 任务回放(Task Replay)功能

最最最重要的是,LangFuse 支持**任务回放(Task Replay)**功能——我们可以回放整个协作任务的执行过程,就像看电影一样:

  • 可以快进、快退、暂停;
  • 可以跳转到任意一个 Agent 的执行或任意一次 LLM 的调用;
  • 可以修改某个 Agent 的输入或某次 LLM 的参数,然后重新执行该任务的某个部分,看看会有什么不同的结果;
  • 这个功能对于调试 MAS 来说简直是“神器”!

1.5 文章脉络:我们接下来会讲什么?

好了,引言部分就到这里了。接下来,我们会按照以下的脉络来详细讲解如何构建 MAS 的可观测性:

  1. 第 2 章:基础概念——什么是 MAS?什么是可观测性?MAS 可观测性的核心要素是什么?

    • 我们会先回顾一下 MAS 的定义、分类、架构、核心概念(Agent、协作、State、交互图);
    • 然后再回顾一下可观测性的定义、传统可观测性三支柱的概念;
    • 最后再详细讲解 MAS 可观测性的核心要素(新三支柱、调试工具、告警策略)。
  2. 第 3 章:核心步骤 1——数据收集:如何收集 MAS 的协作指标、交互追踪数据、上下文日志?

    • 我们会详细讲解如何在主流的 MAS 框架(LangChain、LlamaIndex、Semantic Kernel、AutoGen)中集成可观测性工具(LangFuse、LangSmith、Phoenix);
    • 我们会给出具体的 Python 代码示例;
    • 我们会讲解如何自定义数据收集器,收集我们自己需要的特定数据。
  3. 第 4 章:核心步骤 2——数据存储:如何存储 MAS 产生的海量可观测性数据?

    • 我们会讲解 MAS 可观测性数据的特点(海量、非结构化、动态结构、关联关系复杂);
    • 我们会对比不同的存储方案(关系型数据库、NoSQL 数据库、时序数据库、向量数据库、对象存储);
    • 我们会给出 LangFuse 的存储架构分析(LangFuse 用 PostgreSQL 存储结构化数据,用 S3/GCS 存储非结构化的 Prompt/Response 数据);
    • 我们会讲解如何优化存储方案,降低存储成本。
  4. 第 5 章:核心步骤 3——数据分析与可视化:如何分析 MAS 的可观测性数据,发现问题?

    • 我们会详细讲解如何用 LangFuse、Grafana 等工具可视化 MAS 的协作指标;
    • 我们会讲解如何用交互图(Interaction Graph)分析 Agent 之间的协作过程;
    • 我们会讲解如何用上下文日志分析 Agent 的决策依据和 LLM 的幻觉;
    • 我们会给出具体的数据分析示例(比如如何分析任务无限循环的原因、如何分析 LLM 的 Temperature 对任务成功率的影响)。
  5. 第 6 章:核心步骤 4——告警与调试:如何及时发现 MAS 的故障,快速修复?

    • 我们会详细讲解如何设计 MAS 的告警策略(比如什么情况下应该告警、告警的级别是什么、告警的通知方式是什么);
    • 我们会讲解如何用 LangFuse 的告警功能、Prometheus+Alertmanager 等工具实现告警;
    • 我们会详细讲解如何用任务回放(Task Replay)、幻觉检测、上下文窗口分析等工具调试 MAS;
    • 我们会给出具体的调试示例(比如如何调试任务无限循环的问题、如何调试 LLM 幻觉的问题)。
  6. 第 7 章:最佳实践与案例分析:生产级 MAS 可观测性的最佳实践是什么?

    • 我们会分享生产级 MAS 可观测性的最佳实践(比如如何采样可观测性数据、如何保护可观测性数据的隐私、如何优化 LLM 的调用成本、如何评估 MAS 的性能);
    • 我们会给出一个完整的生产级案例分析(比如如何用 LangFuse 监控和调试某金融公司的“多维度风险排查 Agent 联盟”);
    • 我们会对比不同的 MAS 可观测性工具的优缺点(LangSmith vs LangFuse vs Phoenix)。
  7. 第 8 章:总结与展望:MAS 可观测性的未来发展趋势是什么?

    • 我们会总结文章的核心内容和关键步骤;
    • 我们会展望 MAS 可观测性的未来发展趋势(比如 AI 驱动的可观测性、自动化调试、跨框架的可观测性标准);
    • 我们会提供相关的学习资源、文档链接或后续可以深入研究的方向。

2. 基础概念:MAS 可观测性的基石

在正式开始构建 MAS 的可观测性之前,我们需要先回顾一些基础概念——这些概念是我们后续讨论的基石,如果你已经对这些概念非常熟悉,可以跳过这一章,但我建议你还是快速浏览一遍,因为我会在这一章里定义一些专门针对 MAS 可观测性的术语,这些术语在后面的章节里会频繁用到。


2.1 什么是 Multi-Agent 系统(MAS)?

2.1.1 MAS 的定义

关于 Multi-Agent 系统(MAS)的定义,学术界和工业界有很多不同的说法,但我比较认可的是 Wooldridge 和 Jennings 在 1995 年提出的定义

A Multi-Agent System (MAS) is a system composed of multiple interacting intelligent agents within an environment. These agents can be autonomous, heterogeneous, and capable of acting in pursuit of individual or collective goals.

翻译成中文就是:

多智能体系统(MAS)是由多个在同一环境中交互的智能体组成的系统。这些智能体可以是自主的、异构的,并且能够为了实现个体或集体目标而采取行动。

不过,这个定义是针对传统的基于规则引擎或强化学习的 MAS 的。现在我们常说的 MAS,大多是基于大语言模型(LLM)的 MAS(我把它叫做 LLM-MAS),所以我对这个定义做了一个小小的修改:

基于大语言模型的多智能体系统(LLM-MAS)是由多个在同一协作上下文(State)中交互的 LLM 驱动的智能体组成的系统。这些智能体可以是自主的、异构的、使用不同 LLM 的,并且能够为了实现个体或集体目标而采取行动(比如调用工具、生成内容、与其他智能体交互)。

2.1.2 MAS 的核心属性

根据 Wooldridge 和 Jennings 的定义,以及 LLM-MAS 的特点,我们可以总结出 MAS 的 5 个核心属性:

核心属性 定义 LLM-MAS 的具体表现
Autonomy(自主性) 智能体能够在没有人类或其他智能体直接干预的情况下,自主地做出决策和采取行动。 LLM 驱动的智能体能够根据协作上下文(State)和自己的 Prompt,自主地决定下一步做什么(比如调用搜索工具、生成代码、与其他智能体交互)。
Heterogeneity(异构性) 智能体可以是不同的——可以使用不同的编程语言、不同的框架、不同的模型(比如 GPT-4 Turbo、Claude 3 Opus、Llama 3)、不同的工具集。 比如我们的“需求文档生成 Agent 团队”,ProductManagerAgent 可以使用 GPT-4 Turbo,TechLeadAgent 可以使用 Claude 3 Opus,QAEngineerAgent 可以使用 Llama 3。
Social Ability(社交能力) 智能体能够与其他智能体或人类进行交互——比如协商、竞争、拍卖、共享信息。 LLM 驱动的智能体能够通过协作上下文(State)或消息队列与其他智能体进行交互——比如 TechLeadAgent 把状态回退给 ProductManagerAgent 补充需求。
Reactivity(反应性) 智能体能够感知环境(或协作上下文)的变化,并及时做出反应。 LLM 驱动的智能体能够感知协作上下文(State)的变化(比如 ProductManagerAgent 补充了需求),并及时做出反应(比如 TechLeadAgent 根据新的需求重新生成技术架构设计)。
Pro-activeness(主动性) 智能体不仅能够被动地感知环境的变化并做出反应,还能够主动地采取行动,实现自己的个体或集体目标。 LLM 驱动的智能体不仅能够根据协作上下文(State)执行任务,还能够主动地提出建议(比如 TechLeadAgent 主动建议使用 Redis 作为缓存,而不是等 ProductManagerAgent 要求)。
2.1.3 MAS 的分类

根据不同的分类标准,MAS 可以分为不同的类型:

2.1.3.1 根据协作方式分类

根据智能体之间的协作方式,MAS 可以分为以下 3 种类型:

类型 定义 示例
Cooperative MAS(协作型 MAS) 所有智能体都有一个共同的集体目标,智能体之间的交互是为了实现这个共同目标。 我们的“需求文档生成 Agent 团队”、某金融公司的“多维度风险排查 Agent 联盟”。
Competitive MAS(竞争型 MAS) 智能体之间的目标是相互冲突的,智能体之间的交互是为了击败对方,实现自己的个体目标。 下棋 AI(AlphaGo Zero 其实可以看成是一个由两个 Agent 组成的竞争型 MAS)、拍卖系统。
Semi-Cooperative MAS(半协作型 MAS) 智能体之间既有共同的集体目标,又有相互冲突的个体目标,智能体之间的交互是为了在实现集体目标的前提下,最大化自己的个体目标。 供应链管理系统(供应商和采购商有共同的目标——完成交易,但也有冲突的目标——供应商想卖高价,采购商想买低价)。

现在我们常说的 LLM-MAS,大多是协作型 MAS——因为我们用 LLM-MAS 主要是为了解决复杂的、需要多角色协作的问题,比如需求文档生成、代码开发、风险排查等。

2.1.3.2 根据架构分类

根据智能体之间的架构关系,MAS 可以分为以下 3 种类型:

类型 定义 示例 优点 缺点
Centralized MAS(集中式 MAS) 有一个中央调度智能体(Central Coordinator),负责控制所有其他智能体的执行、分配任务、协调冲突。 早期的 LangChain SequentialAgentMultiActionAgent 架构简单、易于实现、易于协调冲突。 中央调度智能体是单点故障(Single Point of Failure)——如果中央调度智能体挂了,整个 MAS 就会崩溃;可扩展性差——随着智能体数量的增加,中央调度智能体的负担会越来越重。
Decentralized MAS(分布式 MAS) 没有中央调度智能体,所有智能体都是平等的,智能体之间通过协商或消息传递来协调冲突、分配任务。 AutoGen、一些基于区块链的 MAS。 没有单点故障、可扩展性好、鲁棒性强。 架构复杂、难以实现、难以协调冲突、可能会出现任务死锁或无限循环。
Hierarchical MAS(分层式 MAS) 有一个分层的架构——上层有几个中央调度智能体,负责控制下层的智能体;下层的智能体之间可以通过协商或消息传递来协调冲突。 某智慧城市公司的“多区域交通监控-调度-决策 Agent 联盟”(上层是杭州的中央调度 Agent 集群,下层是北京、上海、广州的本地 Agent 集群)。 结合了集中式 MAS 和分布式 MAS 的优点——没有完全的单点故障、可扩展性好、易于协调冲突、鲁棒性强。 架构比集中式 MAS 复杂,但比分布式 MAS 简单。

现在我们常说的 LLM-MAS,大多是分层式 MAS——因为分层式 MAS 既避免了集中式 MAS 的单点故障问题,又避免了分布式 MAS 的架构复杂和协调冲突困难的问题。

2.1.3.3 根据智能体的智能程度分类

根据智能体的智能程度,MAS 可以分为以下 3 种类型:

类型 定义 示例
Reactive Agents(反应式智能体) 只能根据环境(或协作上下文)的当前状态做出反应,没有记忆,没有规划能力。 早期的基于规则引擎的智能体、一些简单的 LLM 驱动的智能体(比如只会调用搜索工具回答问题的智能体)。
Deliberative Agents(慎思式智能体) 有记忆,有规划能力,能够根据环境(或协作上下文)的历史状态和当前状态,制定规划,实现自己的目标。 现在大多数 LLM 驱动的智能体(比如能够生成代码、然后审查代码、然后修改代码的智能体)。
Hybrid Agents(混合式智能体) 结合了反应式智能体和慎思式智能体的优点——对于简单的问题,能够快速做出反应;对于复杂的问题,能够制定规划,实现自己的目标。 现在最先进的 LLM 驱动的智能体(比如 Devin 程序员代理人)。

2.2 LLM-MAS 的核心概念与架构

为了后面讨论 MAS 可观测性的方便,我们需要先定义一些专门针对 LLM-MAS 的核心概念,并给出一个通用的 LLM-MAS 架构。

2.2.1 LLM-MAS 的核心概念
2.2.1.1 Agent(智能体)

在 LLM-MAS 中,Agent 是一个独立的执行单元,由以下 5 个部分组成:

  1. Identity(身份):Agent 的唯一标识符(比如 product_manager_agent_001)、角色(比如“产品经理”、“技术负责人”、“测试工程师”)、描述(比如“你是一位资深的产品经理,负责根据用户的一句话需求生成需求规格说明书初稿”)。
  2. LLM(大语言模型):Agent 的“大脑”,负责理解输入、生成输出、做出决策。可以是任何 LLM——比如 GPT-4 Turbo、Claude 3 Opus、Llama 3、Gemini Pro 1.5。
  3. Prompt(提示词):Agent 的“指令集”,告诉 Agent 应该做什么、怎么做、用什么格式输出。Prompt 一般包含以下几个部分:
    • System Prompt(系统提示词):定义 Agent 的身份、角色、描述、输出格式、限制条件等。
    • User Prompt(用户提示词):当前任务的具体要求(比如用户的一句话需求)。
    • Context Prompt(上下文提示词):协作上下文(State)的内容,让 Agent 了解之前的协作过程。
  4. Tools(工具集):Agent 可以调用的外部工具——比如搜索工具(Google Search、Wikipedia Search)、代码执行工具(Python REPL、Docker)、数据库查询工具(MySQL Connector、PostgreSQL Connector)、文件操作工具(Read File、Write File)等。
  5. Memory(记忆):Agent 的“短期记忆”和“长期记忆”——短期记忆一般存储在协作上下文(State)里,长期记忆一般存储在向量数据库(比如 Pinecone、Chroma、Weaviate)里,用于存储 Agent 的历史执行结果、用户的历史反馈等。
2.2.1.2 State(协作上下文)

在 LLM-MAS 中,State 是整个协作任务的“单一数据源”(Single Source of Truth),存储了协作任务的所有信息——比如:

  1. Task Info(任务信息):任务的唯一标识符、创建时间、用户输入、集体目标。
  2. Agent Execution History(Agent 执行历史):每个 Agent 的执行时间、输入、输出、决策依据。
  3. LLM Call History(LLM 调用历史):每次 LLM 调用的时间、模型、参数(Temperature、Top P、Max Tokens 等)、完整 Prompt、完整 Response、Token 消耗、调用成本。
  4. Tool Call History(工具调用历史)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐