Subagents监控与可观测性

子代理集群监控与可观测性

一、监控指标总览

在子代理架构中,监控指标是掌握系统运行状态的核心数据来源。合理的指标分类能帮助开发者快速定位问题、评估系统健康度,并为容量规划提供依据。监控指标主要覆盖以下三个维度。

任务相关指标

任务指标反映子代理集群的工作负载和任务执行情况,是最直观的监控数据。主要包括:任务总数(累计提交的任务数量)、完成数(成功执行完毕的任务数量)、失败数(执行出错或异常终止的任务数量)、进行中(当前正在处理的任务数量)。通过这四个核心指标,可以计算出任务成功率(完成数 / 总数)和任务失败率(失败数 / 总数),这两个比率是衡量集群稳定性的关键参考。当失败率突然升高时,往往预示着系统或代码层面存在问题。

时间指标

时间维度上的指标能够反映任务执行的效率。平均完成时间体现集群的整体处理能力,可以通过滑动窗口计算(如最近5分钟的平均值)来消除偶发波动。最长等待时间反映任务在队列中的排队压力,当该值持续增长时说明集群资源可能不足。此外,P50 / P90 / P99 百分位完成时间能更精细地刻画任务延迟分布情况——P99 指标尤其有助于发现异常的长尾任务。

健康指标

健康指标用于描述子代理自身的运行状态。包括:子代理状态(在线 / 离线 / 忙碌)、错误率(单位时间内出错请求占比)、资源使用率(CPU / 内存 / 网络IO)。健康指标通常需要结合心跳机制来实现:每个子代理定期向监控中心发送心跳包,若超过一定时间未收到心跳,则判定为离线状态。错误率指标的阈值需要根据业务场景动态调整,过低的阈值会导致误报,过高则可能错过关键告警。

最佳实践:建议将监控指标按照"红黄绿"三色分级展示。绿色表示指标在正常范围内,黄色表示接近阈值需要关注,红色表示超过阈值需要立即处理。这种直观的视觉编码能大幅降低值班人员的认知负担。

二、日志收集策略

日志是子代理系统可观测性的基石。完善的日志收集策略不仅要确保数据不丢失,还要兼顾存储成本和查询效率。

Output 文件自动保存

每个子代理在执行任务时会产生完整的对话记录和输出结果。系统应自动将这些输出保存到独立的文件中,按照时间或任务ID进行组织。Output 文件通常包含:子代理收到的指令、思考推理过程(如链式思考)、工具调用记录、最终输出内容。这些数据对于问题复现和调试至关重要,建议保留至少30天的历史记录。文件命名建议采用"任务ID_子代理ID_时间戳"格式,便于检索和关联。

SendMessage 消息记录

子代理之间的通信内容通过 SendMessage 机制传递。这些消息内容需要被完整记录,形成通信日志。每条消息应包含:发送方ID、接收方ID、消息类型、时间戳、消息正文。通信日志对于理解子代理之间的协作流程、排查消息丢失或重复处理问题至关重要。当出现预期之外的行为时,通过回放通信日志可以还原整个协作过程,找到问题的根源。

TaskUpdate 记录

任务状态的每一次变更都应记录为 TaskUpdate 事件。典型的状态变更包括:已创建 → 已分配 → 执行中 → 已完成 / 已失败。每个 TaskUpdate 记录应包含:任务ID、变更前状态、变更后状态、变更时间、触发者(哪个子代理或调度器触发了状态变更)。通过分析 TaskUpdate 记录,可以重建任务执行的完整生命周期,对任务进行全链路追踪。

日志的分级存储和定期归档

不是所有日志都需要同等的存储策略。建议采用分级存储方案:热数据(近7天)存放在高性能存储中,支持实时查询和分析;温数据(7-30天)存放在标准存储中,支持快速查询;冷数据(30天以上)归档到低成本存储中,支持后台批量检索。定期归档机制可以自动将超过保留期限的数据迁移到冷存储,并在必要时进行压缩和加密。这种分级策略在保证可查询性的同时,能显著降低存储成本。

# 日志分级存储配置示例 log_config: levels: - name: hot retention_days: 7 storage: ssd index: full - name: warm retention_days: 30 storage: hdd index: summary - name: cold retention_days: 365 storage: archive index: metadata_only

三、状态监控方法

状态监控是确保子代理集群持续健康运行的关键手段。通过多种监控方法的组合,可以在第一时间发现并响应异常情况。

定期检查 TaskList 获取全局状态

通过定时轮询 TaskList API,可以获取集群中所有任务的全局快照。轮询间隔通常设置为 5-30 秒(根据集群规模和业务要求调整)。TaskList 返回的数据结构应包含:每个任务的当前状态、所属子代理、创建时间、最后更新时间等字段。通过聚合 TaskList 数据,可以生成全局状态面板,实时展示集群中待处理、执行中和已完成任务的分布情况。

通过任务通知了解状态变更

相比轮询,基于事件驱动的通知机制更加高效。当任务状态发生变化时,系统主动推送通知给监控模块,监控模块实时更新状态缓存。这种方式避免了频繁轮询带来的资源浪费,同时能实现更低的延迟。通知内容应包含状态变更的上下文信息(如失败原因、处理耗时等),方便监控系统进行聚合分析和告警判定。

子代理主动报告自身状态

子代理应当具备主动报告自身状态的能力,这种机制称为"健康报告"或"状态心跳"。每个子代理在初始化时注册到监控中心,之后按照固定的时间间隔(如 10 秒)发送心跳报告。心跳报告中包含:子代理ID、运行时长、当前正在处理的任务数、最近一次错误信息(如有)。如果监控中心连续三次未收到某个子代理的心跳,则判定该子代理离线并触发恢复流程——重新分配其任务并尝试重启子代理。

状态异常的及时发现

异常检测是状态监控的最终目的。常见的异常模式包括:子代理失联(无心跳)、任务卡住(长时间处于"执行中"状态未变化)、任务失败率突增(超出历史基线)、消息积压(通信队列持续增长)。针对每一种异常模式,都应制定明确的检测规则和响应流程。例如,对于卡住的任务,可以设置超时阈值(如最大执行时间的 3 倍),超过阈值后自动终止并重新调度。

注意:异常检测的阈值设置需要在"灵敏度"和"误报率"之间取得平衡。建议采用基于历史数据的动态阈值,相比固定阈值能更好地适应不同时间段和不同负载下的系统行为变化。

四、性能分析

性能分析是从监控数据中提炼洞察、驱动系统优化的核心环节。通过持续的性能分析,可以发现系统瓶颈、指导资源配置,并为容量规划提供数据支撑。

任务完成时间的统计和趋势

对任务完成时间进行统计建模,建立性能基线。采集最近 N 个窗口的数据,计算平均完成时间、标准差、以及 P50 / P90 / P99 百分位值。趋势分析方面,绘制完成时间随时间变化的折线图,观察是否存在周期性波动或持续上升趋势。持续上升可能意味着系统负载在加重或存在资源泄漏问题。此外,按任务类型(如简单查询 vs 复杂分析)分别统计,可以发现特定类型任务的性能退化。

子代理效率的横向对比

当集群中包含多个同类子代理时,横向对比可以揭示个体差异。对比指标包括:单位时间处理任务数、平均任务完成时间、任务成功率、资源利用率。如果某个子代理的效率明显低于同类其他代理,可能原因包括:该代理分配的硬件资源不足、该代理的网络连接不佳、该代理的本地缓存损坏。横向对比应借助可视化图表(如柱状图、箱线图)直观呈现,并在指标偏离超过 2 个标准差时发出告警。

瓶颈识别(等待资源 / 任务依赖)

瓶颈分析是性能优化的核心。常见的瓶颈类型包括:资源瓶颈(CPU 饱和、内存不足、IO 等待)、任务依赖瓶颈(子代理A需要等待子代理B的结果才能继续)、队列瓶颈(任务积压导致等待时间过长)。通过链路追踪和火焰图分析,可以精确定位耗时环节。例如,如果发现大量时间消耗在"等待子代理B返回结果"上,就应考虑对子代理B进行扩容或优化其处理逻辑。

优化前后性能对比分析

任何性能优化措施都需要通过对比分析来验证效果。优化前后应在相同条件下(相同数据集、相同并发量)采集至少 24 小时的性能数据。对比分析的指标包括:P50 / P90 / P99 完成时间的变化、吞吐量的变化(每秒完成任务数)、资源利用效率的变化(单位资源完成的任务数)。通过 A/B 测试或蓝绿部署的方式逐步灰度新方案,确保优化不会引入回归问题。对比结果应以可视化报告形式呈现,并记录到系统性能演进档案中。

核心要点:性能分析不是一次性的工作,而是一个持续循环的过程——测量、分析、优化、再测量。建立自动化的性能回归检测机制,在每次代码部署后自动运行性能测试,确保系统性能不会随着功能迭代而退化。

五、告警配置

告警系统是可观测性闭环的最后一环,它将监控数据转化为可执行的行动指令。一个设计良好的告警系统能帮助团队在问题影响用户之前进行干预。

任务失败率超过阈值告警

任务失败率是最直观的系统健康指标。当一定时间窗口内(如 5 分钟)的任务失败率超过预设阈值(如 10%)时,触发告警。阈值设置应结合业务重要性分级:核心业务路径上的失败率阈值应更严格(如 1%),而非核心路径可以适当放宽。告警应包含失败任务的分布信息(按子代理、按任务类型、按错误类型分类),帮助值班人员快速定位问题范围。避免在失败率仅有单次抖动时立即告警,建议连续两个窗口均超阈值再触发,以减少误报。

子代理长时间无响应告警

基于心跳机制,当某个子代理超过设定的超时时间(如 30 秒)未发送心跳时,触发"子代理无响应"告警。告警级别取决于该子代理承担的角色:关键角色(如主调度器、协调器)的告警级别应为 Critical,需要立即响应;普通工作节点的告警级别可以设为 Warning,允许一定时间内自动恢复。告警触发后,系统可自动执行预设的恢复动作,如重启子代理进程、将任务重新分配给其他可用代理。若自动恢复失败,则升级告警级别并通知人工介入。

任务排队过长告警

当任务队列的长度超过预设阈值,或任务的排队等待时间超过预期时,触发排队过长告警。这个告警通常预示着集群的消费能力不足,需要增加子代理数量或优化任务处理效率。排队告警的阈值应参考历史 P99 值设定:当排队等待时间超过历史 P99 的 2 倍时触发 Warning,超过 3 倍时触发 Critical。告警消息中应包含当前队列长度、预计清空队列所需时间、以及扩容建议(如"建议增加 2 个工作节点")。

告警通知渠道(日志 / 消息)

告警通知需要多渠道送达,确保不同严重级别的事件能触达到对应的人员。日志告警:所有告警事件必须记录到告警日志中,包含告警名称、触发时间、当前值、阈值、持续时间、处理建议。日志告警可供事后审计和复盘分析。消息告警:实时告警通过即时消息渠道推送,如企业微信、钉钉、Slack 等。不同级别的告警采用不同的通知策略——Critical 告警需要立即通知到值班人员(可结合电话告警),Warning 告警发送到团队群组,Info 告警仅记录日志。告警应支持静默期配置,避免在非工作时间重复发送同一类告警造成通知疲劳。

告警配置原则:每一类告警都应配备清晰的"如何处理"文档(Runbook)。告警通知中直接附上 Runbook 链接或处理步骤摘要,帮助值班人员快速响应。没有处理方案的告警是无效告警,只会增加噪声。
# 告警规则配置示例 alert_rules: - name: 任务失败率过高 metric: task_failure_rate condition: "> 0.1" window: 5m consecutive: 2 severity: critical channels: [log, wechat, phone] - name: 子代理离线 metric: agent_heartbeat condition: "missing > 30s" severity: critical channels: [log, wechat] - name: 任务排队过长 metric: queue_depth condition: "> 100" window: 1m severity: warning channels: [log, wechat]