Learn Claude Code:CodeAgent 与后端程序大搭配——定时任务、Git Worktree 和MCP 服务

工程化扩展:后台任务、Cron、Worktree 与 MCP

当 Agent 能调用工具、管理上下文和拆分任务后,仍然有四个现实问题:

  1. 慢命令会阻塞主循环;
  2. 周期任务需要按时间触发;
  3. 多个 Agent 会修改同一份代码;
  4. 外部服务的工具接入缺少统一标准。

后台任务、Cron、Git Worktree 和 MCP 正好对应这四个问题。

一、后台任务:慢操作不应阻塞主循环

以下命令可能运行数分钟:

bash 复制代码
npm install
pytest
docker build
mvn package

如果工具调用一直等待命令返回,Agent 无法处理其他工作。

因此 Bash 工具可以支持:

json 复制代码
{
  "command": "pytest",
  "run_in_background": true
}

Harness 立即返回占位结果:

text 复制代码
后台任务 bg_0003 已启动,完成后会发送通知。

命令在独立线程或进程中执行,完成后生成独立事件:

xml 复制代码
<task_notification>
  <task_id>bg_0003</task_id>
  <status>completed</status>
  <summary>128 tests passed</summary>
</task_notification>

通知在下一轮注入 messages

这里必须注意:原始工具调用已经返回过一次 tool_result,后台完成通知不应再次伪装成同一个 tool_result,而应作为新的异步事件。

二、真正的后台任务需要完整生命周期

教学 Demo 用线程就能演示,但生产实现还要处理:

text 复制代码
进程 ID
stdout/stderr 重定向
增量读取输出
超时和看门狗
主动终止
异常退出
任务恢复
最大并发数
结果持久化

后台任务的本质不是"开线程",而是:

管理一个脱离当前工具调用生命周期的执行单元,并在未来把状态变化重新送回 Agent。

在 Node.js/Bun 等单线程事件循环环境中,真正的 Shell 命令通常由独立子进程运行,主进程只负责管理状态和输出文件。

三、Cron:调度与执行必须解耦

"每天早上九点运行测试"和"现在运行测试"不是同一种触发方式。

Cron 系统可以拆成四层:

text 复制代码
Scheduler
→ Queue
→ Queue Processor
→ Agent Loop

Scheduler

独立线程或定时器负责判断时间是否到达。

Queue

到期任务只进入队列,不直接执行。

Queue Processor

检查 Agent 是否空闲,决定何时交付。

Agent Loop

将调度消息当作新的用户输入处理。

这种拆分保证:

  • 调度器不需要理解 Agent;
  • Agent Loop 不需要每轮计算 Cron;
  • 忙碌时任务可以排队;
  • 一个坏任务不会拖垮整个调度线程。

四、Agent 内部 Cron 不是操作系统定时任务

Agent 自带调度器通常依赖 Agent 进程存活。

即使任务配置被持久化,进程关闭时也不会自动触发。重新启动后可以恢复配置,但无法替代系统级 Cron、Kubernetes CronJob 或云调度服务。

因此:

  • 需要强准时、跨进程保证的任务,使用系统调度器;
  • 需要把事件注入当前 Agent 会话的轻量任务,可以使用 Agent 内部 Cron。

为了避免多个任务同时整点触发造成惊群,还可以加入随机抖动。代价是任务不会绝对精确到秒。

五、Worktree:任务系统解决"做什么",Worktree 解决"在哪做"

多个 Agent 在同一个目录修改代码时,会出现覆盖和脏状态混合。

Git Worktree 是 Git 原生能力:

bash 复制代码
git worktree add .worktrees/auth -b wt/auth HEAD
git worktree add .worktrees/ui -b wt/ui HEAD

此时:

text 复制代码
Alice → .worktrees/auth
Bob   → .worktrees/ui

两个工作目录拥有独立分支,但共享同一个 Git 对象数据库,成本远低于完整复制仓库。

Worktree 隔离系统需要完成三件事:

text 复制代码
创建
绑定
清理

创建

为任务建立独立目录和分支。

绑定

在任务记录中保存:

json 复制代码
{
  "task_id": "task_001",
  "worktree": "auth"
}

Agent 认领任务后,所有 Bash 和文件工具都在对应目录执行。

清理

任务完成后:

  • keep:保留分支等待 Review;
  • remove:删除 Worktree;
  • 有未提交改动时默认拒绝删除;
  • 强制删除必须显式确认。

六、Worktree 本身并不负责 Agent 绑定

Git 只提供多个工作目录,不知道哪个 Agent 应该使用哪个目录。

因此 Harness 必须维护:

text 复制代码
Agent
→ Task
→ Worktree ID
→ cwd

所有工具执行都应显式使用该 cwd,而不是依赖模型自己记住先执行一次 cd

只在 System Prompt 中告诉 Agent"请进入某目录"并不可靠,目录绑定应该是运行时状态。

七、MCP:统一外部工具的发现与调用

如果每接一个服务都手写工具,Agent 很快会出现大量重复适配代码。

MCP 将外部工具接入拆成三层:

text 复制代码
MCP              定义发现和调用工具的语义
JSON-RPC         定义请求与响应消息格式
stdio / HTTP     负责消息传输

典型流程:

text 复制代码
Client 连接 Server
→ tools/list
→ 获得工具 Schema
→ 将工具加入模型工具池
→ 模型调用工具
→ tools/call
→ 结果返回模型

MCP Server 可以由任何语言实现,只要遵守协议。

八、MCP 工具必须处理命名冲突

多个 Server 都可能提供 search 工具。

因此可以使用命名空间:

text 复制代码
mcp__notion__search
mcp__github__search
mcp__docs__search

连接后动态组装工具池:

python 复制代码
tools = BUILTIN_TOOLS + discovered_mcp_tools
handlers = BUILTIN_HANDLERS + mcp_handlers

名称还应经过规范化,避免特殊字符造成冲突或注入。

九、动态工具会影响 Prompt Cache

如果在对话中途连接 MCP Server,工具列表发生变化:

text 复制代码
之前:内置工具
之后:内置工具 + MCP 工具

如果所有完整 Schema 都位于请求前部,工具池变化可能破坏缓存前缀。

一种优化思路是延迟加载:

text 复制代码
固定前缀:基础工具 + ToolSearch + System Prompt + 历史
动态后缀:命中的 MCP 工具 Schema

模型先搜索工具,再只加载需要的定义。这样既控制上下文体积,也提高缓存复用。

十、MCP 不只是单向工具调用

标准 JSON-RPC 连接可以维持后台读取循环,因此 Server 还可以向 Client 发送通知:

text 复制代码
资源变化
进度更新
日志消息
工具列表变化

这意味着 MCP 不只是"远程函数调用包装",还可以成为 Agent 与外部系统之间的双向事件通道。

当然,反向通知必须经过:

  • 来源校验;
  • 消息类型校验;
  • 限流;
  • 权限判断;
  • 上下文注入策略。

否则外部 Server 可以持续向 Agent 注入噪声。

十一、完整 Harness 中各模块的位置

把前面的机制放回一个循环,可以得到:

text 复制代码
用户输入
→ UserPromptSubmit Hooks
→ 注入 Cron 和后台完成通知
→ 上下文压缩
→ 组装 Memory、Skills、MCP 状态
→ 调用模型
→ 错误恢复
→ 检查 Tool Use
→ PreToolUse Hooks 和权限
→ 内置/MCP/后台工具分发
→ PostToolUse Hooks
→ Tool Result 返回消息
→ 下一轮

多 Agent 则在外部共享:

text 复制代码
Task Store
Message Bus
Protocol State
Worktree Registry
Permission Channel

核心循环仍然没有发生本质变化,变化的是周围的运行环境越来越完整。

十二、总结

这四个模块分别解决:

模块 核心问题
Background Task 慢操作不能阻塞
Cron 任务如何按时间进入系统
Worktree 并行修改如何隔离
MCP 外部能力如何标准接入

它们共同体现了一个设计原则:

模型负责选择动作,Harness 负责执行、调度、隔离和接入。

当 Agent 从一次性 Demo 走向长期运行时,这些看似"外围"的工程能力,反而决定了系统是否真正可用。

相关推荐
xier_ran1 小时前
【infra之路】从 KV Cache 到逐层语义:理解 Decoder-Only LLM 的推理过程
llm·infra
JavaPub-rodert1 小时前
认识 Codex
ai·image·codex·guide
k4m7v2pz1 小时前
16GB Mac 本地跑大模型:ollama 局域网 OpenAI 兼容 API 实战(一:需求与配置)
llm·openai·api·mac·ollama·本地·atomcode
减瓦2 小时前
用 Git 为本地文件打造一台时光机
开发语言·git·编辑器
元Y亨H2 小时前
大模型技术-RAG 常用的向量数据库
langchain·llm
元Y亨H2 小时前
大模型技术 Agents 概述
langchain·llm
元Y亨H2 小时前
大模型技术 RAG 概述
llm
元Y亨H2 小时前
大模型技术 Agent添加MCP工具
langchain·llm
元Y亨H2 小时前
大模型技术-RAG 向量存储和检索 概述
langchain·llm