首页
/ claude-cookbooks Observability Agent 架构与通信流解析:从 MCP 到 GitHub API 的全链路监控设计

claude-cookbooks Observability Agent 架构与通信流解析:从 MCP 到 GitHub API 的全链路监控设计

2026-09-07 13:41:06作者:蔡丛锟

导读

本文以 claude-cookbooks 仓库 claude_agent_sdk/observability_agent/architecture_diagram.md 中的两张 Mermaid 架构图为骨架,完整拆解 Observability Agent(可观测性 Agent) 的组件拓扑与运行时消息流转:用户如何把查询交给 Agent,Agent 如何经容器化的 GitHub MCP Server 调用 GitHub API,并将结论返回给用户。通过对照同目录下的 agent.pydocker/Dockerfiledocker/docker-compose.yml 以及教程 02_The_observability_agent.ipynb,你将掌握这类 "Agent + MCP Server + 外部 API" 架构中每一层的职责边界、关键配置项(allowed_tools/disallowed_tools/permission_mode 等)及其底层原理,可直接复用于构建 CI/CD 健康度监控、issue/PR 分析等只读型 DevOps 助手。

架构图定位:一张图说清三层职责

architecture_diagram.md 全篇由两幅 Mermaid 图构成,是 observability_agent 这个例子的架构总纲。第一幅是静态拓扑图(组件依赖关系),第二幅是时序图(一次查询请求从发起到返回的完整消息序列)。它与同目录 Python 实现是一一对应的,不是"示意图",而是对真实运行结构的精确描述:

架构图中的节点 代码/配置中的落点
User 调用方(notebook 交互或程序化调用 send_query
Observability Agent agent.py 中由 ClaudeSDKClient 驱动的 Agent 循环
GitHub MCP Server agent.py get_github_mcp_server() 返回的 McpServerConfig,命令为 docker run ... ghcr.io/github/github-mcp-server
Docker Container 承载 GitHub MCP Server 的容器(详见 Dockerfiledocker-compose.yml
GitHub API GitHub 官方 REST/GraphQL 接口,由 MCP Server 在容器内代理访问
WebSearch / Read Files agent.py 中被显式禁用(disallowed_tools)的兜底工具

组件层架构解读:每个框都是什么、为什么存在

原图(第一幅)用 graph TD 定义了自上而下的数据/调用方向,Mermaid 图中以 style 高亮了核心节点。下面逐层还原其源码事实。

User → Observability Agent:一个面向值班工程师的系统提示词

Agent 之所以叫 "observability agent",根因在于 agent.py 内置的 DEFAULT_SYSTEM_PROMPT

DEFAULT_SYSTEM_PROMPT = """You are an observability agent specialized in monitoring \
GitHub repositories and CI/CD workflows. Provide concise, actionable insights \
suitable for on-call engineers. Focus on identifying issues, assessing severity, \
and recommending next steps."""

这正是架构图中 Agent 框的"人格"来源:只读式监控(read-only observability)。例如教程中给出的真实查询就要求 Agent "分析 facebook/react 仓库 CI 健康度——最近一次 CI workflow 运行的状态与触发方式、失败时定位具体 job/测试并评估严重性、通过时留意长耗时与 flaky 历史、最后给出带优先级的行动建议,且明确 不要创建 issue 或 PR"(见 02_The_observability_agent.ipynbprompt 定义)。系统提示词与用户提示词共同约束了 Agent 的行为边界,使架构图中的 User --> Agent 链路具备明确的领域语义。

Agent → GitHub MCP Server:为何必须以 Docker 方式接入

架构图中 Agent --> GitHub[GitHub MCP Server]GitHub --> Docker[Docker Container] 两层箭头,对应的正是 agent.py 的 MCP 配置:

def get_github_mcp_server() -> dict[str, McpServerConfig]:
    token = os.environ.get("GITHUB_TOKEN")
    if not token:
        return {}

    return {
        "github": {
            "command": "docker",
            "args": [
                "run",
                "-i",
                "--rm",
                "-e",
                "GITHUB_PERSONAL_ACCESS_TOKEN",
                "ghcr.io/github/github-mcp-server",
            ],
            "env": {"GITHUB_PERSONAL_ACCESS_TOKEN": token},
        }
    }

几个与架构图直接对应的实现要点:

  • 官方容器镜像:使用的是 GitHub 官方发布镜像 ghcr.io/github/github-mcp-server。Agent 通过本机 Docker CLI 以交互模式(-i)拉起容器,--rm 保证容器用后即删,不留残留进程——这正是架构图中 Docker Container 框的运行时语义:进程隔离、随用随灭
  • Token 透传方式-e GITHUB_PERSONAL_ACCESS_TOKEN(不带值)表示从父进程环境继承同名变量;随后 env 字段又把当前进程环境里的 GITHUB_TOKEN 显式注入。因此运行前必须在 .env 中配置 GITHUB_TOKEN="<token>" 并通过 load_dotenv() 加载(见 agent.py 第 28 行)。
  • 未配置 Token 时的降级get_github_mcp_server() 在缺少 GITHUB_TOKEN 时返回空字典,后续会由 allowed_tools 列表推导逻辑自动收敛(见下文),整个 Agent 仍可启动,只是失去 GitHub 能力。

容器镜像本身与安全基线由 observability_agent/docker/Dockerfile 保证:它以 python:3.11 为基底,安装 docker-ce-clinodejs,全局安装 @anthropic-ai/claude-code,随后 pip install claude-agent-sdkfastapiuvicorn[standard]mcp-server-git 等运行时依赖,并用 claude --version 验证安装。而 docker-compose.yml 提供了完整服务化编排:将宿主 Docker socket 挂载进容器(/var/run/docker.sock:/var/run/docker.sock)以便在容器内拉起 MCP Server 容器,声明 DOCKER_HOST=unix:///var/run/docker.sock、固定 DNS 与 restart: unless-stopped,并把容器 8000 端口映射到宿主机 8001(注释明确说明 "Different port to avoid conflict with research agent",即与本仓库 research agent 的端口隔离)。

GitHub MCP Server → GitHub API:超过 100 个工具的背后

教程 02_The_observability_agent.ipynb 的说明性文本指出:接入官方 GitHub MCP Server 后,Agent 将获得 超过 100 个与 GitHub 生态交互的工具,覆盖 issue/PR 管理、CI/CD workflow 监控、代码安全告警分析,且同时支持 public 与 private 仓库。架构图最底层 Docker --> API[GitHub API] 表达的就是这一层:真正的数据源是 GitHub API,MCP Server 在容器内部充当"协议翻译层",把 Agent 的 MCP 工具调用翻译为对 GitHub API 的 HTTP 请求。

Tools 层:WebSearch / Read Files 为何"存在又不可用"

架构图中有一组值得注意的节点:Agent --> Tools[Tools],其下又分出 WebSearchRead Files。结合 agent.py 的实现可以解释它的真实含义——这些工具默认被列入禁用清单

# Build allowed tools list based on configured MCP servers
allowed_tools = [f"mcp__{name}" for name in servers]

# Configure disallowed tools to ensure MCP usage
# Without this, the agent could bypass MCP by using Bash with gh CLI
disallowed_tools = ["Bash", "Task", "WebSearch", "WebFetch"] if restrict_to_mcp else []
  • allowed_tools 是按已配置 MCP server 动态拼出的 mcp__<server_name> 列表(例如启用 GitHub 时即为 ["mcp__github"]),实现"只开放已接入的 MCP 工具"。
  • disallowed_tools 显式封禁 BashTaskWebSearchWebFetch这是整个设计中最关键的一处强制约束:若不封禁 Bash,Agent 完全可以绕过 MCP、改用 gh CLI 甚至裸 curl 访问 GitHub API,导致架构图中 Agent → GitHub MCP → GitHub API 的链路名存实亡。代码注释与教程均强调:allowed_tools 只影响权限提示(permission prompting),真正"物理禁用"工具可用性的是 disallowed_tools
  • restrict_to_mcp 参数(默认 True)提供开关:设为 False 时禁用列表为空,Agent 拥有 Bash/Task 等兜底能力,用于需要灵活降级的场景。

换言之,架构图 Tools 分支与其说描述"Agent 有哪些工具",不如说描述"Agent 的默认工具面被刻意收窄到 MCP 通道",这是本项目的一个核心架构决策(见 agent.py 模块 docstring:"Uses disallowed_tools to ensure MCP tools are used (not Bash with gh CLI)")。

通信流时序解读:一次查询如何走完全程

原图(第二幅)是一段 sequenceDiagram,共 5 个参与者(User、Agent、GitHub MCP、GitHub API)与 6 条消息,描述一次完整请求的生命周期:

sequenceDiagram
    participant User
    participant Agent
    participant MCP as GitHub MCP
    participant API as GitHub API

    User->>Agent: Query about repo
    Agent->>MCP: Connect via Docker
    Agent->>MCP: Request data
    MCP->>API: Fetch info
    API-->>MCP: Return data
    MCP-->>Agent: Process results
    Agent-->>User: Display answer

对照 agent.pyClaudeSDKClient 会话代码,每条消息都有明确的代码落点:

options = ClaudeAgentOptions(
    model=model,
    allowed_tools=allowed_tools,
    disallowed_tools=disallowed_tools,
    continue_conversation=continue_conversation,
    system_prompt=DEFAULT_SYSTEM_PROMPT,
    mcp_servers=servers,          # 空 dict 合法,无需 None
    permission_mode="acceptEdits",
)
...
async with ClaudeSDKClient(options=options) as agent:
    await agent.query(prompt=prompt)                 # User -> Agent:提交查询
    async for msg in agent.receive_response():        # 持续接收流式消息
        ...
        if hasattr(msg, "result"):
            result = msg.result
  • User->>Agent: Query about repo:对应 await agent.query(prompt=prompt)。值得注意的是 Agent 初始化时 mcp_servers=servers 传入的正是上面 get_github_mcp_server() 的产物;当 use_github=False 或未配置 Token 时该 dict 为空,SDK 仍可正常工作(代码注释明确 "Empty dict is valid, no need for None")。
  • Agent->>MCP: Connect via Docker:SDK 根据 McpServerConfig 中的 command: docker 启动子进程,即执行 docker run -i --rm ... ghcr.io/github/github-mcp-server,通过 stdio 完成 MCP 握手,架构图中的 Docker 容器在此刻被拉起。
  • Agent->>MCP: Request dataMCP->>API: Fetch info:Agent 在推理循环中基于 allowed_tools 选出一个 mcp__github 工具(例如查看 workflow run),MCP Server 收到调用请求后代表 Agent 向 GitHub API 发 HTTP 请求——API-->>MCP: Return data 是同步应答。
  • MCP-->>Agent: Process results:MCP Server 把 API 响应整理为结构化的工具调用结果返回给 Agent;Agent 依据系统提示词("identify issues, assess severity, recommend next steps")将多轮工具结果综合成面向值班工程师的结论。
  • Agent-->>User: Display answer:在 notebook 场景中,结果经 utils/agent_visualizer.pyprint_activity()(实时反馈每个活动消息)、display_agent_response()(渲染最终答复)与 visualize_conversation()(绘制对话树)呈现给用户;display_result 参数设为 False 时则只返回文本、供程序化使用。

值得注意时序图里 User 与 Agent 的交互是一轮查询,而 send_query 通过 continue_conversation 参数把多轮会话也纳入了同一架构:首次调用会先 reset_activity_context() 清空可视化上下文,续接调用则保留历史消息,便于"先问 CI 状态、再追问 flaky 测试"这类纵深挖掘(见 notebook 中 result1 = await send_query(...)result2 = await send_query(..., continue_conversation=True) 的两段式示例)。

从两张图看两个通用架构模式

  • 协议桥接模式:Agent(Claude)不直接依赖任何一家 SaaS 的 SDK,而是通过 MCP(Model Context Protocol)这一开放标准接入 github-mcp-server,Server 与外部 API 之间再做一次协议转换。好处是同一套 Agent 逻辑可任意挂载 Git/MySQL/浏览器等不同 MCP Server 而无需改动业务代码——本仓库教程即演示了从本地 Git MCP Server 平滑切换到 GitHub MCP Server 的过程。
  • 只读可观测 + 工具面收窄:通过 disallowed_tools 强制 Agent 只能经 MCP 访问 GitHub,杜绝其用 Bash + gh 走"捷径",既保证调用路径可审计,也契合"监控而不改动"的定位。这种"能力面显式收窄"的做法,对任何追求可审计、可回放的生产级 Agent 都具有直接借鉴意义。

从架构图到可运行代码的快速对照

想亲手跑通架构图中的链路,最小步骤是(仓库为只读,以下均为本地运行方式):

  1. 准备凭据与运行时:在 .env 中写入 GITHUB_TOKEN="<token>"(建议在 GitHub 创建 Fine-grained Token,默认公开仓库权限即可跑通本示例),并确保本机 Docker 可用(docker --version 验证)。

  2. 本地直跑 Agent 模块:将 claude_agent_sdk 目录加入 Python 路径后调用 observability_agent/agent.py 导出的 send_query

    from observability_agent.agent import send_query
    
    result = await send_query(
        "Check the CI status for the last 2 runs in anthropics/claude-agent-sdk-python. Just do 3 tool calls, be efficient."
    )
    

    该模块已内部处理活动显示、上下文重置与结果可视化;多轮追问时追加 continue_conversation=True

  3. 容器化整体部署:参照 observability_agent/docker/docker-compose.yml 构建服务(它会从 ../../.env 读取环境变量并把 Docker socket 挂载进容器),宿主机访问映射端口 8001

  4. 对照验证:架构图中的每一条边都可在 agent.py(链路与选项配置)、docker/Dockerfiledocker-compose.yml(容器层)、02_The_observability_agent.ipynb(端到端演示)中找到对应的实现与调用证据。

小结

architecture_diagram.md 用一静一动两张 Mermaid 图精炼概括了 Observability Agent 的全部架构语义:静态拓扑交代"谁依赖谁、谁被谁隔离"(Agent 依赖容器化的 GitHub MCP Server,MCP Server 代理 GitHub API,WebSearch/Read 类兜底工具被刻意收窄),动态时序交代"一次查询如何分层穿透"(User → Agent → MCP → GitHub API → 原路返回)。两图叠加,即是对 agent.pyMcpServerConfigallowed_toolsdisallowed_toolsClaudeSDKClient 会话管理的可运行注脚——理解了这张图,就理解了如何用 Claude Agent SDK 构建"只读、可审计、面向值班运维"的 GitHub 监控型 Agent。

登录后查看全文
热门项目推荐
相关项目推荐