构思与实践
前提
在展开具体实践之前,先交代三个前提条件。

第一,使用集成开发环境(IDE)作为 Agent 协作的面板。本实践的 IDE 限定为 TRAE,因为它免费,且功能足以满足需求。更重要的是,IDE 本身就是可观测性和可交互性的来源——你能实时看到 Agent 在做什么,也能随时介入调整。

第二,使用 DeepSeek 作为 AI 模型。它足够便宜,即便是 Flash 这样较轻量的模型,产出质量也足够好。

第三,笔者有一个长期保持的习惯:使用单独的 Git 仓库作为日常工作区和知识库。在 AI 时代,这个习惯的好处被显著放大。Git 本身提供了优秀的版本控制和跨设备同步能力,而基于 Git 的语义检索又将"搜索"提升到了新的维度——你不需要记住文件存在哪里,只需要描述你想找什么。二者的结合使这套方案在信息的持久化和召回上胜过了常见的笔记系统。

核心实践
整个体系由三个子系统构成:工具系统、记忆系统、Skill 系统。三者各司其职,共同支撑 Agent 的高效协作。

工具系统
工具系统负责执行确定性的任务。笔者选择 .NET 10 的基于文件的应用程序(FBA)作为工具的构建基础。FBA 足够轻量,无需复杂的项目配置,一个 .cs 文件就是一个可执行的工具;而且它有编译缓存,重复执行时的冷启动开销极低。工具在设计时尽量支持管道运算,以便组合使用。

在使用 AI 调用工具的场景下,工具参数的接口设计有一个重要原则:宁可返回过量的内容,也不要增加参数来追求精确的输出。举例来说,假如要写一个获取项目连接字符串的工具,那么应该做一次全量扫描,通过模式匹配返回所有连接字符串,而不是添加一个 --project 参数来指定具体项目。原因很简单:AI 很可能会传递一个错误的参数值,而返回过量的数据至少不会漏掉目标。

核心的工具包括以下几种:

scheduler:用于定时任务触发,基于 cron 表达式,支持超过一个周期的遗漏补偿。当 Agent 离线期间积压的任务,在恢复后能够自动补齐。
event-logger:记录用户与 Agent 之间的交互事件,为记忆系统提供原材料。每行日志简洁精炼,仅记录关键信息。
agent-runner:在 .NET 进程中提供一个 Agent 执行环境,用于加载外部的 Agent 定义并执行。
vector-manage:向量索引系统,基于 Git 的变更历史做增量构建,实现工作区知识的语义检索。
记忆系统
记忆系统参考了腾讯的 TencentDB-Agent-Memory 设计,结合文件系统实现了一套分层记忆架构,并基于 Git 做增量构建和版本管理。

整个记忆系统围绕一个名为 Copilot 的 Agent 运转。Copilot 扮演个人助理的角色,能够根据用户与 Agent 的交互事件,自动构建和整理记忆。记忆的构建方式参考了 TencentDB-Agent-Memory 的分层设计:

L0 — 原始事件:每一条交互日志以 JSONL 格式按日期存储,作为记忆的原材料。
L1 — 结构化摘要:按天为单位,从原始事件中提炼关键信息,形成当日的活动摘要。
L2 — 上下文场景:将多个相关事件组织成场景块,描述一段完整的工作叙事。例如"SQL 优化 Skill 开发和线上实战"就是一个典型的场景。
L3 — 用户画像:从大量场景中蒸馏出用户的编码偏好、行为模式和关注领域,形成持久化的画像。
L4 — 持久化事实:原子级的知识节点,记录具体的偏好、规则和关键信息。
记忆的整理和消化由 scheduler 驱动,每 6 小时触发一次整理(L0 → L1 → L2 的流水线处理),每 12 小时触发一次消化(L2 → L3 → L4 的深度蒸馏)。这样的频率既保证了记忆的时效性,又不会过度消耗 API 配额。

Skill 系统
Skill 系统与工具系统不同,它不执行确定性的任务,而是处理那些复杂的、不确定的、需要多步推理的工作。

每个 Skill 是一份结构化的 Markdown 文档,定义了触发条件、使用流程、退出条件和输出标准。其中最具代表性的是 long-task Skill,它的执行流程体现了整个体系的核心理念。

当一个长期任务被触发时,long-task Skill 首先检索记忆系统(用户画像、相关场景、历史事实),同时搜索工作区的向量数据库,汇总出足够的信息作为任务规划的上下文。然后它理解用户的需求,创建一个 Readme.md 概述任务的目标和范围,同时创建一个 Tracking.md 记录进度和状态。

在任务真正开始执行之前,用户和 Agent 的主要工作集中在对这些前置规划的修正上——推敲目标是否清晰、范围是否合理、方案是否可行。这个过程确保了每一次执行都有一个经过审慎思考的上下文,从而产出较高质量的结果。

Skill 和工具的区别在于:工具是确定性的,同样的输入总是产生同样的输出;Skill 则不然,它可能包含多轮对话、多次工具调用、多次人工判断。工具是 Skill 的积木,Skill 是工具的使用者。

目录结构
整个 Copilot 体系以 Copilots/ 为根目录,纳入 Git 仓库管理。以下是精简后的目录结构:

Copilots/
├── agents/ # Agent 定义
│ └── copilot/ # Copilot 个人助理
│ ├── config.json # Agent 配置
│ └── skills/ # Agent 私有 Skill
│ ├── git-skill/
│ ├── memo-facts-skill/
│ ├── memo-persona-skill/
│ ├── memo-pipeline-skill/
│ ├── memo-recall-skill/
│ ├── memo-scenes-skill/
│ └── memo-summary-skill/ # 记忆分层体系(6 个 Skill + 管道编排)

├── commands/ # 命令定义(向用户开放的快捷入口)
├── rules/ # 规则文件(编码、写作、工作流等)

├── skills/ # 全局 Skill
│ ├── long-running-task-skill/ # 长期任务跟踪
│ ├── task-brainstorm-skill/ # 任务头脑风暴
│ ├── fba-tool-skill/ # FBA 工具编写规范
│ ├── yunshu-sql-optimizer-skill/# SQL 查询优化
│ └── … # 其他 Skill

├── tools/ # 可执行工具
│ ├── copilot-mcp-tool/ # MCP 服务端
│ ├── scheduler-tool.cs # 定时调度器
│ ├── event-logger.cs # 事件日志
│ ├── harness-agent-tool.cs # Agent 执行环境
│ ├── guard-tool.cs # 进程守卫
│ ├── sql-server/ # SQL Server 工具集
│ ├── vector-tool/ # 向量索引工具
│ └── lib/ # 共享工具库

└── memories/ # 记忆系统
├── l0.events/ # 原始事件(JSONL)
├── l1.summaries/ # 结构化摘要(JSON)
├── l2.scenes/ # 上下文场景(Markdown)
├── l3.persona/ # 用户画像
└── l4.facts/ # 持久化事实(JSON)
agents/ 与 skills/ 的分离是刻意的设计:agents/copilot/skills/ 中的 Skill(记忆体系相关)仅供 Copilot Agent 自身使用,受权限控制;skills/ 中的全局 Skill 则对所有 Agent 开放。tools/ 目录的扁平化结构便于工具发现和调用,功能相关的工具以子目录分组。

整体架构
下方这张图概括了整体设计。Copilot 个人助理位于中心,对接三个子系统。TRAE 内置 Agent 同样可以调用本体系中的 Agent、Skill 和 Tool,两个 Agent 共享同一套基础设施。

architecture

工具之间并非松散堆积,而是有一条清晰的依赖链条。下方这张图展示了各工具之间的调用关系和上下层依赖:

toolchain

核心的依赖关系可以概括为三层:Hooks 在最底层,负责采集一切原始输入;guard-tool 在中间层,确保常驻进程不会因异常退出而中断;scheduler 在调度层,驱动定时任务按周期执行。其余工具处于运行层——不驻留、不等待,被 MCP 或其他 Agent 按需调用,执行完成就退出。

实践案例
从构思到完成这个工程约莫花了一周时间——严格来说,编码工作几乎全部由 AI 完成,即便此刻你在阅读的这篇文章也不例外。下方选取三个具有代表性的案例,展示这套体系在实际工作中的运作方式。

案例一:设计 SQL 查询优化 Skill
背景:我司产品线基于 SQL Server,经常遇到慢查询问题。虽然已经积累了参数嗅探、快照隔离等知识点的 Wiki 文档,但整个优化流程仍然依赖人工分析,缺乏自动化手段。笔者决定开发一个标准化的 SQL 优化 Skill,让 Agent 能够自动执行从分析到建议的迭代闭环。

第 1 轮 — 可行性分析:Agent 首先评估了项目的技术现状,确认 SQL Server 数据库可以直连,存在连接字符串配置(main.json 中的 adoSql* 节点),具备工具开发的基础条件。Agent 输出了一份可行性分析报告,提出了四个 FBA 工具的技术方案:连接列表获取、Schema 读取、查询计划分析、查询执行。笔者确认方向可行,要求进入实施。

第 2 轮 — 工具开发与快速迭代:Agent 在一小时内完成了四个 FBA 工具的初版开发。笔者的要求是"先跑通再看",没有追求完美。四个工具涵盖从连接发现到执行验证的完整链路。笔者在这个过程中持续给出调整指令:工具从 Skill 目录迁移到 tools/ 下的独立目录(共享工具放 tools/sql-server/,私有工具放 tools/yunshu-sql-optimizer-skill/),增强 JSON 输出的结构化程度,添加多结果集支持,改进了 AOT 编译配置。

第 3 轮 — 流程标准化:Agent 设计了一套七文件的模板体系来规范优化产出。笔者审阅后给出关键意见:模板文件"太过零碎了",要求精简。最终确定为两文件范式——一份面向人的分析报告(optimization-report.md)和一份面向过程的技术记录(tracking.md),采用双环境闭环(Develop 环境验证可行性 + Debugger 环境执行线上变更)。Agent 按照这个要求重新设计了产出模板,并通过一次真实数据验证确认方案落地。

第 4 轮 — 经验沉淀:第一次实战暴露了 Sort 算子优化器代价与实际耗时严重脱节的问题。笔者要求补充服务器诊断步骤(sys.dm_os_wait_stats 区分 IO/锁/CPU 瓶颈),增加"读代码"前置环节(理解 SQL 是如何构造的——动态拼接还是 EF Core 生成——决定可改范围),增加可行性校验(区分"可加索引"“可改写 SQL”"不可修改"三种状态)。Agent 逐项更新了 SKILL.md。这些改进使 Skill 从"能跑"进化到了"可靠"的程度。

案例二:执行 SQL 查询优化 Skill——线上实战
Skill 设计完成后,立即投入了一次真实的线上 SQL 优化实战。这次实战不只是验证了 Skill 的有效性,更重要的是反哺了 Skill 本身的设计:这是一条 OnlineOrder 订单列表的分页查询,涉及 4 张表的 JOIN 加一个标量子查询(计算同物流单号的订单数)。筛选条件通过动态字符串拼接,最终 SELECT 近 50 列(含 nvarchar(MAX) 宽列)。OnlineOrder 表 51 万行的数据量不算大,但查询涉及多级排序(Number ASC, CreateTime DESC, LogisticsNumber ASC, Id ASC),加上近 50 列(含 nvarchar(MAX) 宽列)的 SELECT 负载,线上耗时高达 7,474 毫秒。排序规则硬编码在代码中,且无法使用 CTE 或两阶段拆分。

Agent 遵循刚刚完善的三步前置流程:先读了代码(确认 SQL 构造方式和可改范围),再做服务器诊断(确认 IO 是主要瓶颈),最后备份表结构。核心问题是 Sort——其 IO 代价 5,045 占查询总代价的 99.6%,严重溢出到 tempdb。

优化方案是创建一个与 ORDER BY 完全匹配的复合索引,以 IsDeleted 作为等式前导列,后续列顺序与排序完全一致。这是一个纯索引方案,零代码改动。

Develop 环境验证结果(100 条数据):

指标 优化前 优化后
Sort 算子 存在(代价 5,323) 已消除
总预估代价 5,324 0.79(-99.98%)
扫描方式 Clustered Index Scan Index Seek
笔者确认后在线上执行,效果显著:

查询 优化前 优化后 提升
COUNT 1,817 ms 1,499 ms -18%
数据查询 7,474 ms 1,695 ms -77%
Sort 算子 存在 已消除 —
数据查询从 7.5 秒降至 1.7 秒,改善了 77%。更重要的是,这次实战验证了双环境闭环流程的有效性:先在 Develop 验证计划变化,再到线上体现真实耗时——Develop 数据量小但能确认执行计划变更,线上才能体现耗时优化的真实幅度。

案例三:用这套体系写一篇博客——本文的诞生
long-task 的工作流程可以概括为三步:用户给出大纲(outline.md),Agent 生成任务说明书(Readme.md)和进度跟踪文件(Tracking.md),然后双方基于这两份文件迭代推进。下面就是本文从构思到产出的完整过程。

第一步:笔者给出了一份大纲。

一种适合程序员的Agent协作方式的实践

注意:本文使用AI辅助生成,本文章亦是本文章所述实践之产物。

背景

简述AI在这个时代的快速普及,以致于各行各业都无法忽视。
笔者尝试过多种AI的使用方式,但大多数的实践方式都落在两个极端。
使用现成的第三方客户端或者产品,无法快速的为AI提供上下文信息,要么需要频繁补充上下文信息,要么产出结果不符合预期。
使用OpenClaw这样的Agent集群工具,无法获得高可观测性,或者需要大量的工程成本。
之所以会出现这样的情况,主要是因为程序员这个职业比较特殊。
一方面,需要向AI提供足量的上下文来约束AI的行为和输出,另一方面他不能当老板(或者当皇帝,笑)。
他更像一个施工小队的队长,必须及时、快速的调整AI的行为和输出,以满足当前工作的规范。所以可观测性是非常重要的。
总而言之,在AI尚未成为真正的AI之前,程序员需要像一个Agent一样介入多个Agent的工作。

构思与实践

前提

使用IDE作为Agent协作的面板,本实践限定IDE为TRAE,因为他免费,功能做的也不错。
使用deepseek作为AI模型,因为它足够便宜,而且flash模型的产出就足够好。
笔者有一个使用单独git仓储作为日常工作区和知识库的习惯,所以这个仓储作为本实践的根目录。

核心实践

工具系统

使用.NET10的FBA作为工具构建基础,因为它足够轻量,而且有编译缓存。工具实现的时候尽量能够支持管道运算。
工具主要用来快速执行确定性的任务。为了符合AI的使用习惯,工具的参数不能设计的太死板。宁愿返回过量的内容,也不要增加参数来追求精确的输出。
举个例子,
比如我要写一个工具获取项目的连接字符串。那么我宁愿做一次扫描(模式匹配),返回所有的连接字符串,也不要添加一个–project参数,因为AI可能传递一个错误的参数。

核心的工具:

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐