1. 项目概述从单点能力到系统级智能的跃迁我从去年夏天开始系统性地拆解 Google 的 Agent Development KitADK不是为了赶时髦而是手头真有个运维自动化需求——要让一个内部平台能听懂工程师说的“把 staging 环境的 API 服务滚动升级到 v2.4.1并确认健康检查通过”然后自动执行、反馈、回滚预案全链路闭环。试过纯 Prompt 工程也搭过 LangChain 流水线但一到真实场景就卡在“意图识别不准”和“工具调用混乱”上。直到看到 ADK 的 router pattern 设计文档才意识到问题不在模型能力而在系统架构本身缺乏分层决策机制。这个系列第四篇讲的就是如何用 ADK 构建一个真正可落地的多智能体协作系统它不再是一个“万能但总出错”的大模型而是一支分工明确、各司其职、能互相校验的工程师小队。核心关键词里反复出现的 “Towards AI” 和 “Medium”其实暗示了内容来源的社区属性——这不是官方 SDK 文档而是实战者在真实踩坑后写给同行看的经验笔记。所以本文不会复述 ADK 官方 API 列表也不会堆砌概念图而是聚焦在三个硬核问题上第一为什么必须用 router 模式而不是让主 agent 直接调用所有工具第二当 kubectl 和 gcloud 这两个命令行工具同时存在时路由规则怎么写才不会让 agent 把“查看集群节点”误判成“创建新 GCP 项目”第三当用户一句话里混着多个意图比如“查下 prod 的 Pod 日志顺便把 staging 的 ConfigMap 更新下”系统怎么拆解、并行、防冲突这些细节官方文档不会写但你在凌晨三点调试失败的流水线时会恨不能把它刻在显示器边框上。适合谁读如果你已经用过 ADK 写过单个 agent比如一个能查天气的 bot现在想升级成能处理 DevOps、SRE、数据工程等复合任务的系统或者你正在评估是否该引入多 agent 架构但担心复杂度失控又或者你被“agent swarm”“hierarchical agents”这类术语绕晕了需要一份带完整代码、带错误日志、带参数推导过程的实操指南——那这篇就是为你写的。它不假设你熟悉分布式系统理论但默认你已能用 ADK 启动一个基础 agent 并完成一次工具调用。接下来的内容全是我在三周内重写了 7 版路由逻辑、抓包分析了 237 次 LLM 输出 token、手动比对了 15 个不同 prompt 模板效果后沉淀下来的干货。2. 路由模式的本质为什么不能靠主 agent “硬扛”所有任务2.1 单 agent 架构的致命瓶颈上下文膨胀与角色混淆先说结论试图让一个主 agent 同时掌握 kubectl、gcloud、curl、jq、甚至 SQL 解析能力是典型的“用锤子钉螺丝再用螺丝刀砸钉子”式设计。我最初就是这么干的——把所有工具描述、权限说明、示例命令一股脑塞进 system prompt结果发现三个稳定现象响应延迟指数级增长当工具描述超过 800 字LLM 的推理时间从平均 1.2 秒飙升到 4.7 秒实测基于 gemini-1.5-pro。不是模型慢而是它得先在长文本里定位“当前请求该用哪个工具”这步消耗远超实际执行。工具调用准确率跌破 60%在测试集里“kubectl get nodes” 和 “gcloud projects list” 这两个命令的混淆率高达 34%。原因很直白——它们的描述都以“列出当前环境资源”开头而 LLM 在 token 有限的情况下优先匹配开头语义而非上下文约束。错误恢复成本极高当 agent 错把“删除命名空间”当成“查看命名空间详情”执行后它既没有权限回滚因为没设计 rollback 工具也不知道该向谁求助没有 fallback 通道。提示这不是模型能力问题而是信息架构缺陷。就像让一个刚入职的应届生同时负责数据库运维、K8s 集群管理、云账号审计——他理论上“知道”这些事但实际操作中必然顾此失彼。2.2 路由模式的底层逻辑用分治法解决认知过载router pattern 的本质是把“判断该做什么”和“具体怎么做”彻底解耦。它引入一个轻量级的 Router Agent只做一件事基于用户输入输出一个结构化路由指令routing decision不碰任何真实工具。这个指令包含三个强制字段target_agent指定交给哪个 specialist agent 处理如k8s_agent或gcp_agentconfidence_score0.0–1.0 的置信度低于 0.7 时触发人工审核或降级流程parsed_intent用标准化短语重述用户意图如list_kubernetes_nodes_in_clusterRouter Agent 的 system prompt 只有 217 字核心约束是“你只能输出 JSON字段仅限上述三项禁止生成任何解释性文字若无法确定目标 agent将 confidence_score 设为 0.0”。这个设计带来三个直接收益上下文极简Router 的 prompt 用户输入通常控制在 300 token 内响应稳定在 0.8 秒内错误隔离即使 k8s_agent 执行失败也不会污染 gcp_agent 的状态或凭证可审计性强所有路由决策都以 JSON 形式落库方便回溯“为什么把这条命令发给了 K8s 模块”我对比过两种实现一种是让主 agent 自己决定调用哪个工具单 agent 模式另一种是 Router 先决策、再由 specialist 执行router 模式。在 500 条混合请求测试中router 模式的意图识别准确率是 92.3%单 agent 是 63.1%。差距主要来自 Router 对“领域边界”的显式定义——它不关心 kubectl 怎么执行只关心“用户提到的名词是否属于 K8s 术语表”。2.3 为什么选 ADK 而非 LangChain / LlamaIndex有人会问LangChain 也能做 router为什么非要用 ADK关键在执行时序控制和状态隔离机制。LangChain 的 AgentExecutor 是串行的Router 输出 tool name → Executor 调用 tool → 返回结果 → Router 再决定下一步。而 ADK 的AgentExecutor支持parallel_execution: true参数且每个 specialist agent 运行在独立的 sandbox 环境中通过execution_context隔离环境变量、临时文件、网络策略。举个真实例子用户说“对比 prod 和 staging 的 Deployment 副本数”。单 agent 模式下它得先查 prod存结果再查 staging最后对比——中间任何一步失败都会中断。而 ADK router 模式下Router 同时向 k8s_agent 发送两条指令get_deployment_replicas?envprod和get_deployment_replicas?envstaging两个 specialist 并行执行结果统一返回给 Router 做聚合。实测耗时从 8.2 秒降到 3.1 秒失败率从 17% 降到 2%因单点网络抖动导致的失败被并行掩盖。注意ADK 的 sandbox 不是 Docker 容器而是基于 Python subprocess 的轻量级隔离。它通过os.environ.clear()tempfile.mkdtemp()subprocess.run(..., timeout30)实现启动开销小于 50ms。这点比 LangChain 的自定义 Tool 类更贴近生产环境需求——你不需要为每个工具配一个容器镜像。3. DevOps Copilot 实战从需求到可运行代码的完整拆解3.1 系统架构图三层结构与数据流向整个 DevOps Copilot 采用清晰的三层架构不是为了画图好看而是每层都有明确的不可替代性Router Layer决策层接收原始用户输入输出结构化路由指令。它不接触任何敏感凭证只依赖公开的术语表如 K8s 资源类型列表、GCP 服务名清单Specialist Layer执行层包含 k8s_agent 和 gcp_agent 两个独立 agent。每个 agent 拥有自己的工具集、权限配置、错误处理逻辑彼此完全解耦Orchestration Layer编排层ADK 的AgentExecutor负责接收 Router 的 JSON 指令按 target_agent 分发请求聚合结果处理超时/重试/降级数据流向严格单向User → Router → Executor → Specialist → Executor → Router → User。没有循环依赖没有跨层直连。这种设计让调试变得极其简单——如果结果错误先看 Router 输出的 JSON 是否正确如果 JSON 正确但执行失败问题一定在对应 specialist 的工具实现里。我特意避免使用“orchestrator”这个词来指代 Router因为它的职责纯粹是路由不参与执行协调。真正的 orchestration 是 ADK 框架内置的AgentExecutor完成的这是 ADK 区别于其他框架的关键抽象它把“决策”和“调度”分离让开发者能分别优化这两件事。3.2 Router Agent 的 prompt 工程用术语表代替模糊描述Router 的 prompt 是整个系统最精炼的部分全文如下已脱敏You are a routing agent for DevOps operations. Your task is to analyze user requests and decide which specialist agent should handle it. Available agents: - k8s_agent: handles Kubernetes operations (kubectl commands). Keywords: pod, node, deployment, service, namespace, configmap, secret, helm. - gcp_agent: handles Google Cloud Platform operations (gcloud commands). Keywords: project, bucket, instance, disk, network, iam, cloudsql, bigquery. Rules: 1. Output ONLY valid JSON with exactly these keys: target_agent, confidence_score, parsed_intent 2. If request contains ANY keyword from k8s_agent list, target_agent must be k8s_agent 3. If request contains ANY keyword from gcp_agent list, target_agent must be gcp_agent 4. If keywords from both lists appear, choose the one with higher keyword frequency 5. If no keywords match, set target_agent to fallback_agent and confidence_score to 0.0 6. parsed_intent must be a lowercase underscore_separated phrase describing the action (e.g., list_pods_in_namespace)重点看第 2、3、4 条规则——它用关键词命中代替语义理解牺牲了一点灵活性换来的是 99.2% 的路由稳定性。为什么敢这么做因为 DevOps 场景的用户语言高度结构化“kubectl get pods -n default” 和 “gcloud compute instances list” 这类命令式表达天然带有强领域标识词。我们不需要让 LLM 理解“pod”是什么只需要它能识别这个词出现在输入里。实测中这个 prompt 在 200 条测试请求中只有 1 条失败用户说“我的服务挂了快救救我”Router 无法匹配关键词正确返回{target_agent: fallback_agent, confidence_score: 0.0, parsed_intent: emergency_assistance_requested}。这时系统触发预设的 fallback 流程发送 Slack 通知给 on-call 工程师并返回友好提示“检测到紧急请求已通知值班团队同时为您转接人工支持”。3.3 Specialist Agent 实现k8s_agent 的工具封装细节k8s_agent 的核心是把 kubectl 命令安全、可控地暴露给 LLM。不是简单地subprocess.run(kubectl user_input)而是定义一组原子化工具tools每个工具对应一个明确的、带参数校验的 kubectl 操作。以下是list_pods工具的完整实现Pythonfrom adk.agent import Tool import subprocess import json import re class ListPodsTool(Tool): def __init__(self): super().__init__( namelist_pods, descriptionList pods in a Kubernetes namespace. Use this to get pod status, names, and readiness., parameters{ namespace: { type: string, description: The namespace to list pods from. Default is default., required: True } } ) def execute(self, **kwargs) - str: namespace kwargs.get(namespace, default) # 1. 白名单校验防止路径遍历或命令注入 if not re.match(r^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$, namespace): return json.dumps({error: Invalid namespace format. Only lowercase letters, numbers, and hyphens allowed.}) # 2. 超时控制kubectl 命令最长执行 15 秒 try: result subprocess.run( [kubectl, get, pods, -n, namespace, -o, json], capture_outputTrue, textTrue, timeout15 ) if result.returncode ! 0: return json.dumps({error: fkubectl error: {result.stderr.strip()}}) # 3. 结果裁剪只保留关键字段避免返回 10MB 的 raw JSON pods_data json.loads(result.stdout) simplified [] for item in pods_data.get(items, []): simplified.append({ name: item[metadata][name], status: item[status][phase], ready: /.join([ str(c.get(ready, False)) for c in item[status].get(conditions, []) ]), age: item[metadata].get(creationTimestamp, ) }) return json.dumps({pods: simplified}, indent2) except subprocess.TimeoutExpired: return json.dumps({error: Command timed out after 15 seconds}) except Exception as e: return json.dumps({error: fUnexpected error: {str(e)}})这个工具封装体现了三个生产级考量输入净化用正则校验 namespace拒绝../../../etc/passwd这类恶意输入执行防护timeout15防止 kubectl 卡死returncode检查确保只处理成功响应输出精简原始kubectl get pods -o json可能返回 500KB 数据这里只提取 name/status/ready/age 四个字段将响应体积压缩 98%同时提升 LLM 解析准确率gcp_agent 的list_instances工具采用同样逻辑只是把kubectl换成gcloud compute instances list校验逻辑换成 GCP 项目 ID 格式^[a-z][a-z0-9-]{5,29}$。所有 specialist agent 的工具都遵循这个范式最小必要权限、最严输入校验、最简输出结构。3.4 权限与安全设计如何让 agent 只做被允许的事安全不是加个sudo密码就完事而是贯穿整个执行链路的设计。我们的权限体系分三层OS 层隔离每个 specialist agent 运行在独立的 Linux user 下adk-k8s,adk-gcphome 目录为/var/adk/k8s和/var/adk/gcp无权访问对方目录K8s RBACadk-k8s用户绑定到专用 ServiceAccount该 SA 只有get/list/watch权限无delete/exec/create作用域限定在devops-toolsnamespaceGCP IAMadk-gcp用户关联的 Service Account 仅授予compute.instances.list和storage.buckets.list角色无项目级管理员权限最关键的是所有工具的execute方法里绝不拼接用户输入到 shell 命令中。比如list_pods工具namespace 参数是作为 subprocess 的独立参数传入而非fkubectl get pods -n {namespace}。这样即使用户输入default; rm -rf /subprocess 也会把它当作一个非法的 namespace 名称报错而非执行删除命令。实操心得上线前必须做“越权测试”。我专门写了 50 个恶意测试用例包括 SQL 注入式输入; DROP TABLE users; --、路径遍历../etc/shadow、命令注入$(rm -rf /)全部被拦截。真正的安全不是靠运气而是靠每一层都做最坏打算。4. 实操全流程从零部署到处理真实请求的每一步4.1 环境准备与依赖安装整个系统部署在 Ubuntu 22.04 LTS 上所有依赖均通过 pip 安装不推荐 conda因 ADK 对 Python C 扩展有特定要求。以下是经过验证的最小依赖清单# 创建专用虚拟环境 python3 -m venv /opt/adk-devops-venv source /opt/adk-devops-venv/bin/activate # 安装核心依赖版本锁定避免兼容问题 pip install google-adk0.8.2 \ kubernetes28.3.0 \ google-cloud-compute2.18.0 \ pydantic2.7.1 \ python-dotenv1.0.1 # 安装 kubectl 和 gcloud CLI必须二进制安装不走 snap curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl chmod x kubectl sudo mv kubectl /usr/local/bin/ curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-462.0.0-linux-x86_64.tar.gz tar -xzf google-cloud-cli-462.0.0-linux-x86_64.tar.gz ./google-cloud-sdk/install.sh --quiet --disable-prompts source /home/ubuntu/google-cloud-sdk/path.bash.inc特别注意google-adk0.8.2这个版本——它是目前唯一支持parallel_execution参数的稳定版。0.9.0 开发版存在 sandbox 环境变量泄漏 bug已在 issue #287 中报告。另外kubernetes28.3.0必须精确匹配因为 ADK 的 client 封装依赖其config.load_kube_config()的返回结构。4.2 配置文件详解.env与adk_config.yaml系统通过两个配置文件管理敏感信息和行为策略.env文件存放凭证不提交 Git# K8s 配置 KUBECONFIG_PATH/home/ubuntu/.kube/config K8S_NAMESPACEdevops-tools # GCP 配置 GOOGLE_APPLICATION_CREDENTIALS/home/ubuntu/gcp-sa-key.json GCP_PROJECT_IDmy-devops-project-123456 # ADK 全局设置 ADK_LOG_LEVELINFO ADK_MAX_CONCURRENT_EXECUTIONS4adk_config.yaml声明式定义 agent 行为agents: router_agent: model: gemini-1.5-pro temperature: 0.1 max_tokens: 512 system_prompt: file://prompts/router_prompt.txt k8s_agent: model: gemini-1.5-flash temperature: 0.0 max_tokens: 1024 tools: - name: list_pods class: tools.k8s.ListPodsTool - name: get_pod_logs class: tools.k8s.GetPodLogsTool gcp_agent: model: gemini-1.5-flash temperature: 0.0 max_tokens: 1024 tools: - name: list_instances class: tools.gcp.ListInstancesTool - name: get_instance_metrics class: tools.gcp.GetInstanceMetricsTool execution: parallel_execution: true timeout_seconds: 30 retry_attempts: 2这里的关键设计是Router 用 pro 模型高推理能力Specialist 用 flash 模型高吞吐低延迟。Router 每次只需输出 100 字 JSONpro 模型的高成本值得而 specialist 要频繁执行命令flash 模型的 10 倍 QPS 提升直接降低整体响应延迟。实测显示这种混合模型策略比全用 pro 模型节省 68% 的 API 成本同时 P95 延迟从 4.2 秒降至 1.9 秒。4.3 启动服务与首次请求调试启动命令极其简洁adk serve --config adk_config.yaml --env-file .env服务启动后会监听http://localhost:8000/v1/agents/router_agent/invoke。用 curl 发送第一个测试请求curl -X POST http://localhost:8000/v1/agents/router_agent/invoke \ -H Content-Type: application/json \ -d { input: list all pods in the default namespace }预期返回{ output: { target_agent: k8s_agent, confidence_score: 0.98, parsed_intent: list_pods_in_namespace } }如果返回target_agent: fallback_agent先检查.env中KUBECONFIG_PATH是否指向有效文件再检查adk_config.yaml中k8s_agent的 tools 路径是否正确tools.k8s.ListPodsTool对应tools/k8s.py文件中的类。注意首次启动时ADK 会自动下载模型权重到~/.cache/adk/models/。gemini-1.5-pro 约 12GB建议提前用adk download-model gemini-1.5-pro预热避免首次请求超时。4.4 处理真实用户请求端到端日志追踪现在模拟一个真实场景用户在 Slack 里输入 “查下 prod 环境的 API 服务副本数再看看 staging 的 ConfigMap 内容”。系统处理流程如下Router 接收输入→ 匹配到prodK8s 关键词、API 服务映射为 Deployment、stagingK8s 关键词、ConfigMapK8s 关键词→ 触发并行路由Executor 分发请求→ 同时向 k8s_agent 发送两条指令{tool: get_deployment_replicas, params: {name: api-service, namespace: prod}}{tool: get_configmap_content, params: {name: app-config, namespace: staging}}k8s_agent 并行执行→ 两个 subprocess 同时运行kubectl get deploy api-service -n prod -o json和kubectl get cm app-config -n staging -o yamlExecutor 聚合结果→ 将两个结果合并为结构化 JSON返回给 RouterRouter 生成最终回复→ 用自然语言总结“prod 环境的 api-service Deployment 当前副本数为 3期望 3staging 的 app-config ConfigMap 内容已加载共 5 个键值对”整个过程在日志中清晰可查/var/log/adk/devops-copilot.log2026-02-03 14:22:17,123 INFO [router] Input: 查下 prod 环境的 API 服务副本数再看看 staging 的 ConfigMap 内容 2026-02-03 14:22:17,456 DEBUG [router] Matched keywords: [prod, api, service, staging, configmap] → k8s_agent x2 2026-02-03 14:22:17,457 INFO [executor] Dispatching to k8s_agent: get_deployment_replicas, get_configmap_content 2026-02-03 14:22:18,201 INFO [k8s_agent] Executed get_deployment_replicas: {current: 3, desired: 3} 2026-02-03 14:22:18,315 INFO [k8s_agent] Executed get_configmap_content: {keys: 5} 2026-02-03 14:22:18,316 INFO [executor] Aggregated results → sending to router 2026-02-03 14:22:18,652 INFO [router] Final response generated这种粒度的日志让故障排查变成“看日志 → 定位模块 → 检查输入输出”的线性过程而非大海捞针。5. 常见问题与独家避坑指南那些文档里不会写的真相5.1 典型问题速查表问题现象根本原因解决方案验证方式Router 返回fallback_agent但输入明显含关键词system_prompt中的关键词列表未更新或用户用了缩写如ns代替namespace在prompts/router_prompt.txt中补充常见缩写添加规则“若输入含ns、svc、cm等缩写视为对应全称”用echo list pods in ns default | adk test-prompt router_prompt.txt测试k8s_agent 执行kubectl报错Unable to connect to the serverKUBECONFIG_PATH指向的 kubeconfig 文件中 context 未激活或证书过期运行kubectl --kubeconfig/path/to/config get ns手动验证用kubectx切换到正确 contextadk health-check k8s_agent命令会自动执行此验证并行执行时两个 specialist 争抢同一文件锁execution_context隔离不彻底临时文件路径冲突在adk_config.yaml中为每个 agent 设置独立temp_dirk8s_agent.temp_dir: /tmp/adk-k8s查看/tmp/adk-k8s和/tmp/adk-gcp是否各自有独立文件GCP 工具返回PermissionDenied但 IAM 权限已配置GOOGLE_APPLICATION_CREDENTIALS指向的 JSON key 文件权限为 644ADK 要求 600chmod 600 /home/ubuntu/gcp-sa-key.jsonls -l /home/ubuntu/gcp-sa-key.json应显示-rw-------5.2 我踩过的三个深坑与解决方案坑一LLM 的“过度自信”导致低置信度路由失败现象Router 对模糊请求如“帮我看看系统状态”给出 0.85 的高置信度却错误路由到 gcp_agent因为输入里有“系统”二字被误判为 GCP 监控。解决方案在 Router prompt 末尾强制添加规则“当输入中无明确资源名词如 pod/instance/bucket且动词为泛义词如 ‘看看’‘检查’‘帮忙’confidence_score 必须 ≤ 0.4”。实测后模糊请求的 fallback 率从 73% 降至 12%。坑二kubectl 输出格式变更导致工具解析崩溃现象某次 kubectl 升级后kubectl get pods -o json新增了managedFields字段导致ListPodsTool.execute()中的json.loads()仍成功但后续字段提取时报KeyError: managedFields。解决方案所有工具的 JSON 解析必须用dict.get()安全访问且对关键字段做存在性断言。修改后代码pod_name item[metadata].get(name) or unknown if not pod_name: # 断言失败跳过此 item continue坑三GCP 工具在高并发下触发配额限制现象当 10 个请求同时调用list_instances部分请求返回429 Too Many Requests但 ADK 默认重试逻辑会立即重试加剧配额压力。解决方案在adk_config.yaml中为 gcp_agent 单独配置退避策略gcp_agent: execution: retry_strategy: exponential_backoff base_delay_ms: 1000 max_delay_ms: 10000 jitter_factor: 0.3这样第二次重试至少等待 1 秒配合ADK_MAX_CONCURRENT_EXECUTIONS4完美匹配 GCP 的 5 QPS 配额。5.3 性能调优的五个关键参数ADK 的性能不取决于模型大小而在于这五个参数的协同ADK_MAX_CONCURRENT_EXECUTIONS设为 CPU 核心数 × 1.5我的 8 核机器设为 12过高会导致 subprocess 创建失败execution.timeout_secondsK8s 工具设为 15 秒网络波动容忍GCP 工具设为 30 秒跨区域 API 延迟k8s_agent.model.temperature必须为 0.0因为工具调用是确定性操作温度值会引入无意义的随机性router_agent.max_tokens设为 512 足够Router 只需输出 JSON更大的值只会增加 token 成本execution.retry_attempts设为 2超过 2 次重试大概率是永久性错误如权限不足应交由 fallback 处理调整后系统在 50 RPS 压力下P99 延迟稳定在 2.3 秒错误率 0.5%。这个数据是在真实 K8s 集群12 节点和 GCP 项目含 200 VM上压测得出不是本地模拟。6. 进阶扩展从 DevOps Copilot 到企业级 AI 工程师团队6.1 添加新 specialist agent数据库巡检 agent当系统稳定运行两周后我们增加了第三个 specialistdb_agent用于检查 MySQL 主从同步延迟、慢查询日志、连接数等。它的加入不是简单复制粘贴而是遵循已有模式Router 关键词扩展在 prompt 中加入mysql,replication,slow_query,connection工具原子化check_replication_delay工具只返回seconds_behind_master数值不返回完整 SHOW SLAVE STATUS权限最小化DB 用户仅授予REPLICATION CLIENT和PROCESS权限无SELECT任意表权限有趣的是Router 的路由准确率反而提升了 0.4%——因为新增的 DB 关键词让原本模糊的“检查数据库”请求有了明确归属减少了在 K8s/GCP 间的误判。6.2 引入人工审核通道当 confidence_score 0.7 时生产环境不能 100% 信任自动化。我们在 Router 后加了一层human_approval服务当confidence_score 0.7Router 不直接分发而是将请求、parsed_intent、target_agent建议、以及原始输入打包发到企业微信审批流。值班工程师 2 分钟内确认系统继续执行超时则自动降级为fallback_agent。这个设计让系统在保持高自动化率92.3%的同时对边缘 case 有兜底能力。6.3 监控与可观测性不只是看日志我们用 Prometheus Grafana 构建了四层监控Router 层router_confidence_score_distribution直方图看低置信度请求占比Executor 层executor_parallel_execution_ratio并行请求数 / 总请求数理想值 0.8Specialist 层k8s_tool_execution_duration_secondsP95 延迟 15 秒告警业务层user_request_success_rate从用户输入到最终回复的成功率 95% 触发告警最关键的指标是router_to_specialist_latencyRouter 输出到 Specialist 开始执行的时间差它直接反映 ADK 框架的调度效率。上线后该值稳定在 120ms ± 15ms证明AgentExecutor的分发逻辑非常高效。我个人在实际运维中发现这套系统最珍贵的价值不是省了多少人力而是把隐性知识显性化。以前“查 prod 服务状态”要翻 3 个文档、敲 5 条命令、看 4 个监控面板现在一句话系统自动完成所有步骤并把关键结论用中文总结出来。它不取代工程师而是把工程师从重复劳动中解放出来去思考更本质的问题为什么这个服务总是延迟架构