让 AI 真正完成开发任务:Windows 上的 DSH Headless、Git Worktree 与自动编译实践

5 阅读12分钟

让 AI 真正完成开发任务:Windows 上的 DSH Headless、Git Worktree 与自动编译实践

AI-CODING 实践系列(二)

关键词:AI 自动编码、DeepSeek Harness、Git Worktree、Python、Scheduler、MSBuild、C++、Windows

前言

在上一篇文章中,我介绍了如何通过 DeepSeek Harness(DSH)和飞书机器人建立一个远程开发入口。

但能通过手机与 AI 讨论代码,并不意味着拥有一套真正的自动开发系统。

要让 AI 从聊天走向实际开发,还需要解决几个工程问题:

  • 如何让 AI 自动进入正确的项目?

  • 如何避免多个任务修改同一个工作目录?

  • 如何自动编译 AI 生成的 C++ 代码?

  • 如何知道任务是成功了,还是只得到一个看起来合理的回答?

  • 如何取消异常任务,避免后台残留进程?

  • 如何在程序重启后恢复任务状态?

这些问题最终通过一套轻量的 Python Runner + Scheduler 得到了解决。

本文记录这部分工程实现和真实验证结果。

一、先明确目标:不是让 AI 写代码,而是让它完成任务

AI 编码工具已经能够根据自然语言生成和修改代码。

但对于无人值守开发,我希望最终得到的不只是代码,还包括:

  1. 实际的文件修改。

  2. 可复现的构建结果。

  3. 可检查的测试结果。

  4. 可追踪的执行记录。

  5. 与原始开发分支隔离的修改。

  6. 明确的成功、失败或取消状态。

因此,我把一次自动开发定义为:

接收开发任务
    ↓
创建独立工作区
    ↓
启动 AI 编码 Agent
    ↓
检查代码修改
    ↓
执行 MSBuild
    ↓
运行验证
    ↓
保存结果与日志

这才是可以交给后台系统调度的完整任务单元。

二、为什么使用 Git Worktree?

如果直接让 AI 修改原始工作目录,风险比较明显。

一旦任务中断、修改失败或者同时存在多个任务,就可能影响开发者正在使用的代码。

为此,我使用 Git Worktree 为每个任务创建独立的工作目录。

例如:

repositories/
└── demo-project/          # 原始 Git 仓库

workspaces/
├── task-001/              # 任务 1
├── task-002/              # 任务 2
└── task-003/              # 任务 3

每个任务拥有自己的分支和工作目录。

一个典型的操作是:

git worktree add -b ai/task-001 ../workspaces/task-001 master

这样 AI 可以在独立目录内修改代码,而不需要切换原始仓库的当前分支。

在实际验证中,Runner 自动创建了独立 Worktree 和任务分支,DSH Headless 只修改了测试任务中的目标源文件,原仓库 HEAD 和工作状态在执行前后保持一致。

这里需要特别说明:

Git Worktree 提供的是版本管理层面的隔离,而不是完整的操作系统安全沙箱。

它能有效隔离不同任务的 Git 工作状态,但不能单独限制进程读取其他目录或访问网络。

三、DSH Headless:将编码 Agent 变成可调度程序

交互式 Agent 适合讨论需求,而自动化系统更需要可独立启动、执行和退出的进程。

DSH Headless 正好可以承担这个角色。

它能够通过命令行接收任务,并将执行过程输出为结构化事件。

在实际工程中,我主要利用以下能力:

  • 为任务指定独立工作目录。

  • 通过 Headless Profile 调用已经授权的模型。

  • 使用 JSON 事件流记录运行过程。

  • 获取模型 Session ID。

  • 通过进程退出码判断执行状态。

  • 在任务完成后结束进程。

Runner 不依赖用户一直打开 DSH Web 页面。

它会根据任务配置启动一个独立 Headless 进程,完成当前任务后退出。

这也意味着,飞书聊天中的 Session 与实际编码 Session 可以完全分离。

前者保存讨论上下文,后者专门负责某一次开发任务。

四、Runner v0.1:最小自动编码执行器

第一阶段实现了一个 Python Runner。

核心模块包括:

模块主要职责
models.py解析和校验任务规格
gitops.py创建、检查和清理 Worktree
dsh.py启动 DSH Headless,解析事件
build.py执行受信任的构建与验证命令
process.py管理子进程、超时和终止
orchestrator.py串联完整执行流程

Runner 提供统一的 CLI:

python -m runner run --spec task.json --task-id task-001

这里的 task.json 不只是自然语言需求,还包含经过校验的仓库、构建、超时和允许修改路径等配置。

一个重要原则是:

模型负责修改源代码,不负责随意决定系统应该执行什么构建命令。

构建命令来自受信任配置。

这可以减少 AI 因为理解错误而选择错误工具链、构建路径或系统命令的风险。

当然,受信任的构建命令并不意味着构建过程本身完全安全,因为参与编译的源码可能由 Agent 修改。

五、Windows 进程管理比想象中重要

自动化 Agent 可能启动多个子进程。

例如:

Python Runner
    └── Node.js / DSH
          └── PowerShell
                └── 其他开发工具

如果只终止最外层进程,内部启动的子进程可能继续存在。

这对于长期运行的开发机尤其麻烦。

Runner 使用 Windows Job Object 管理任务进程树,并提供 taskkill /T /F 作为经过身份校验后的回退方式。

这里有一个非常重要的约束:

不能通过结束所有 **node.exe** 进程来清理任务。

因为长期运行的 DSH Web Host 本身也依赖 Node.js。

错误的清理操作可能把整个远程开发入口一起关闭。

因此,执行器只针对当前任务所属的进程树进行清理。

测试中验证了任务超时后的进程树终止,真实 Runner 端到端执行结束后也未发现新增的残留 DSH Headless 进程。

六、真实 C++ 编译验证

自动编码的关键验收,不应该是 AI 说“代码已经修改完成”,而应该是编译和测试确实通过。

本次验证使用 Windows 11、Visual Studio 2026、MSVC 和 Windows SDK。

测试任务要求 DSH Headless 创建一个简单的 C++ 加法程序,并通过 MSBuild 编译。

核心逻辑类似:

#include <iostream>

int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(2, 3);

    if (result == 5) {
        std::cout << result << std::endl;
        return 0;
    }

    return 1;
}

执行结果:

  • DSH Headless 成功生成源代码。

  • MSBuild 成功编译。

  • 生成的 EXE 正常运行。

  • 程序输出 5。

  • 任务退出码为 0。

  • 原始仓库没有被修改。

  • 结果与日志成功保存。

最终 Runner v0.1 的真实端到端测试耗时约 17 秒,10 项自动化测试全部通过。

当然,这只是一个简单 C++ 工程的验证,不代表复杂 CAD 插件工程也能在相同时间内完成。

它证明的是底层执行链路可行,而不是 AI 对复杂工程的开发质量已经得到充分验证。

七、为什么还需要 Scheduler?

Runner 解决的是如何执行一个任务。

但真正从飞书远程发起任务,还需要处理多个任务之间的关系。

例如:

  • 用户连续提交两个需求。

  • 第一个任务仍在执行。

  • 用户希望取消第二个任务。

  • 开发机突然重启。

  • 聊天消息重复投递。

  • 某个任务执行失败,需要查看历史记录。

如果把这些逻辑全部交给 Agent 自己处理,很容易产生状态混乱。

因此,我增加了独立的 Python Scheduler。

它只负责几个确定性的功能:

任务提交
    ↓
SQLite 持久化
    ↓
FIFO 队列
    ↓
单 Worker
    ↓
调用 Runner
    ↓
保存结果

为什么只采用单 Worker?

因为当前使用的是一台资源有限的 Windows 开发机,而且 C++ 编译本身会消耗较多 CPU、内存和磁盘资源。

在这种环境下,与其提前开发复杂的并发调度,不如先保证任务依次完成。

八、Scheduler v0.2 的实现

Scheduler 使用 SQLite 保存任务状态、执行记录和任务事件。

任务状态包括:

queued
running
succeeded
failed
cancelled
interrupted

一次正常执行的状态变化为:

queued → running → succeeded
                 → failed
                 → cancelled

它还提供了几个基础能力:

FIFO 排队

按照数据库中的任务序号依次执行,防止任务插队。

幂等提交

相同幂等键重复提交时,返回已有任务,避免重复运行。

单实例运行

通过 Windows 文件锁和 SQLite 原子领取机制,防止多个 Worker 重复执行同一个任务。

任务取消

可以取消尚未执行的任务,也可以向正在运行的 Runner 发送取消请求。

异常恢复

程序重启后,排队中的任务继续保留;原先处于运行状态的任务标记为 interrupted,默认不自动重复执行,避免出现未知状态下的二次修改。

清理预览

能够检查哪些历史 Worktree 符合清理条件,但不自动删除正在运行或身份不明确的工作区。

这些能力并不复杂,但对无人值守系统的可靠性非常重要。

九、Scheduler 的真实验证结果

Scheduler v0.2 完成后,使用同一个 C++ 测试仓库提交了两个任务。

每个任务均通过 Scheduler 调用真实的 Runner、DSH Headless 和 MSBuild。

验证结果如下:

验证项目结果
Scheduler 自动化测试18/18 通过
Runner 回归测试11/11 通过
管理模块 Python 回归测试142 项通过
管理插件 Node 测试24 项通过
真实编码任务2 个,全部成功
执行顺序严格串行
独立 Worktree通过
独立 DSH Session通过
MSBuild 编译两次成功
EXE 运行验证两次通过

两次真实任务的 Runner 执行时间分别约为 21 秒和 21 秒。

需要注意,本轮真实验证使用了两次独立的单任务 Worker 进程,证明了串行领取和执行链路有效。长期常驻 Worker 的稳定性、真实长任务取消和异常重启恢复,还需要进一步验证。

这也是开发报告中必须坚持的一点:

模拟测试通过、真实任务通过和生产长期运行稳定,是三个不同层级的结论。

十、最不能忽视的问题:安全边界

在自动编码系统中,安全不仅仅是防止 Agent 修改错误文件。

更大的风险来自自动执行 AI 生成的代码。

本次验证发现:

  • DSH 的 workspace-write 模式能够拒绝部分工作区外写入。

  • 工作区外文件读取并未受到同等限制。

  • Git Worktree 本身不提供操作系统隔离。

  • MSBuild 构建和生成的 EXE 运行不在 DSH 沙箱内。

  • 路径白名单检查主要发生在代码修改之后。

尤其需要注意:如果自动编译的源代码包含恶意行为,最终生成的程序可能以 Runner 用户权限运行。

因此,当前版本仍然属于受控环境中的自动化开发原型。

后续接入真实项目时,需要考虑:

  1. 使用独立的低权限执行账号。

  2. 限制构建进程可以访问的目录和凭据。

  3. 明确网络访问策略。

  4. 限制 CPU、内存、磁盘及执行时间。

  5. 在必要时使用独立虚拟机执行不可信构建。

  6. 对自动修改的代码保留人工审核。

这些问题比一味追求更多 Agent 并行更重要。

十一、从自动编码到实际开发助手

随着 Runner 和 Scheduler 完成,系统的三个核心部分逐渐清晰:

Control
    管理项目、话题和权限

Scheduler
    管理任务、队列与执行状态

Runner
    管理 Worktree、Agent、编译和验证

它们分别解决不同的问题。

而飞书和 DSH Host 负责将自然语言需求转化为可以提交的任务。

目前系统已具备通过飞书驱动开发的能力,形成了从远程交互到本地自动执行的初步闭环。

但这只是阶段性成果。

接下来真正重要的,不是继续增加架构层次,而是把它用于实际开发项目。

例如使用现有 C++ 工程完成一次功能修改、缺陷修复或构建问题排查,并观察它在需求理解、代码质量和编译修复方面的表现。

十二、阶段性反思

这次实践最大的收获,并不是写出了一套 Python 任务调度程序。

而是逐渐认识到:AI 自动开发系统的难点,不只是模型能否生成代码,更在于如何将不确定的模型行为纳入可靠的软件工程流程。

在这个过程中,几个设计原则逐渐明确:

  • 对话 Agent 和编码 Agent 可以分离。

  • 每个任务应拥有独立的工作区和执行上下文。

  • 任务状态应该由确定性程序管理。

  • 构建与测试结果比模型的文字总结更可信。

  • 自动化系统必须支持失败、取消和恢复。

  • 安全隔离不能仅依赖 Agent 的提示词或沙箱声明。

  • 不应为了未来可能出现的需求,过早开发复杂架构。

当前系统已经完成了第一阶段的主要目标。

下一阶段,我更希望它真正参与日常开发,而不是继续围绕基础设施进行迭代。

毕竟,衡量 AI 开发助手价值的最终标准,不是它拥有多少 Agent、多少插件或多少架构模块,而是:

它是否能够可靠地完成实际开发任务,并真正减少开发者的工作量。


本文中的性能和测试数据来自特定 Windows 测试环境,不构成其他机器或复杂业务工程的性能保证。阶段性验证结果不代表已经达到生产环境的安全性与可靠性要求。