# CY-02｜Cindy 的 Agent 使用与开发过程

核验日期：2026-10-10；源码基线 `5888d140db4f58af77f154f745ac2a047cb5da69`。本章追踪产品任务和开发修复两条线。运行链来自当前源码；修复案例来自仓库历史取证记录。本次没有调用模型、真实插件或 Windows 打包，也没有重跑该历史任务的测试。

![Cindy 的 Agent 任务与开发过程逻辑架构图](<../../图表/CY-02_架构.svg>)

## 1. 两条线有不同的目标

产品运行关注“用户任务是否在正确环境执行，结果是否完整反馈”；开发过程关注“发现的缺陷是否被准确定位，改动是否满足验收”。前者的参与者是用户、宿主、Agent、工具和环境，产物是任务结果与状态；后者的参与者是需求提出者、开发者／开发 Agent、评审者和 CI，产物是代码、验证和交接。

| 分析线 | 输入 | 成功依据 | 本章材料 |
|---|---|---|---|
| 产品 Agent 运行 | 原始目标、工作目录、能力与历史 | 工具结果和任务完成条件 | 发送事务、Session、Ghost、事件管道 |
| 使用 Agent 开发 Cindy | 症状、范围、复现与规则 | 有效修复、对照、评审与验收 | Pi 生命周期研究、工作流 |

产品支持多执行器，并不能证明一次修复由多个 Agent 完成；开发文档出现 AI 工具，也不能证明全部代码都由 AI 生成。案例只陈述材料直接支持的工作，不推算人机贡献比例。

## 2. 一次任务怎样进入执行

沿当前常见 Desktop 输入入口，可以用下列顺序解释任务。它是源码调用关系，没有本次实发日志：

```text
Renderer 形成输入队列项
  → preload 的 input.enqueue
  → Main 的输入协调器接受、排队或派发
  → makerSendTransaction.sendToAgentAccepted
  → 必要时创建／恢复 Session
  → Session.send 与执行器派发
  → Session 事件回到宿主
```

阅读位置依次为 [makerChatStore.ts](<../../sources.html#ref-6a8e22c24fac78>)、[preload.ts](<../../sources.html#ref-8486ab5d6fa7a7>)、[register.ts](<../../sources.html#ref-dad802d99d7e18>) 和 [makerSendTransaction.ts](<../../sources.html#ref-38135b8d13e5a4>)。直接发送兼容路径通过 [sessionSendHandler.ts](<../../sources.html#ref-b2890a80e09245>) 委托同一事务。

事务不只是把字符串交给模型，还涉及待应用执行器选择、工作目录检查、Session 健康与恢复、持久消息和派发前边界。`accepted` 说明输入跨过对应的接受／派发契约，不能翻译成“用户任务已经完成”。已接受之后的辅助记录失败，也不能随意回退成“消息从未发出”，否则用户重试可能重复执行。

任务输入应保留目标、目录、附件、约束与已有进展。工作目录恢复说明在消息被接受后才消费，失败则留待下一次。这样的状态安排体现了“交接信息也有消费时机”，避免一次失败把必要解释提前丢掉。

## 3. 模型接入与上下文的边界

[BaseAgent](<../../sources.html#ref-debd299af146f2>) 描述执行器能力和启动接口，[Maker](<../../sources.html#ref-01bc9befe9e78d>) 将会话参数交给 `agent.startSession`，再建立 [Session](<../../sources.html#ref-01b2959f287d7e>)。模型选择、推理设置、权限、工作目录、MCP 与宿主回调是不同信息，不能合并成一条模糊“系统提示”。

工具的可用性应来自真实接口；历史摘要保存进展；稳定产品段提供长期行为；临时请求提供当前目标。供应商的上下文压缩、原生事件和恢复能力不必相同。共享抽象负责建立产品可消费的契约，具体差异仍须由适配器处理。

[maker-core 规则](<../../sources.html#ref-b35bfce00f1f89>) 要求关注缓存、热路径性能、事件准确性与模型路由。本次只是学习规则与调用代码，未做真实模型缓存率或吞吐测量，不能把“未新增模型调用”写成“性能完全不变”。

## 4. 能力发现与工具调用

Skill 是可按需读取的工作方法，MCP 是工具接入接口，插件可以包含工具、手册与配置，宿主则提供执行和权限机制。这些名称对应不同层次，不应作为互斥产品标签或能力强弱排名。

[Ghost 渐进发现文档](<../../sources.html#ref-ef515727bbe420>) 解释了按需取得信息的路径：常驻花名册保留身份和召回场景；已知 `ghost_id` 时调用 `ghost_info` 精确查询，需要实时全量回查时调用 `ghost_list`。两者返回信息完整度相同，是并列入口，没有固定的 `list → info` 顺序。

拿到信息后，可读取 `ghost_manual`，也可通过 `ghost_call` 调用插件声明的 `list_tools(category)`。两条路径可以交叉，信息足够时才执行具体工具。manual-only 插件可以提供手册，但不因此具备工具执行能力。

下面是只读资产检查的教学调用设计，参数和工具名为示意，不冒充 Cindy 内置工具或实测：

```text
目标：读取本次给定 CSV，返回问题行，不修改输入。
发现：由召回线索或已知 ID 查询插件信息。
阅读：取得检查器的真实 schema、目录要求与失败协议。
执行：传入被控机器上的合法文件引用和所需参数。
核验：对照问题行、输入哈希和完成条件。
```

花名册、手册和工具说明都是能力信息，不能代替用户意图或授权。当前 [ghostVisibility.ts](<../../sources.html#ref-a4a42155ea1d1d>) 依次检查存在、账号可用、下线、目录停用和启用；[ghost.ts](<../../sources.html#ref-2973838b2a65f9>) 是宿主调用入口。异步准备后仍需按当前状态复查，不能凭旧发现结果持续放行。

## 5. 状态怎样反馈给用户

[事件管道](<../../sources.html#ref-ae00b7053526c2>) 从 Session 消费事件，准备归属与展示数据，再处理流记录、交付、终态、快照和用量。[sessionEventDelivery.ts](<../../sources.html#ref-9ea690995fc44d>) 负责交付环节。进度、正文、工具结果和终态是不同事件，不能拿正文一句“结束了”替代终态协议。

| 观察 | 能证明什么 | 仍需什么 |
|---|---|---|
| 输入接受 | 当前输入被对应入口受理 | 派发、执行与结果 |
| 工具开始 | 一项动作已经进入执行流程 | 工具返回或确认失败 |
| 工具结果 | 对应调用有观察值 | 目标要求的完整检查 |
| 供应商 turn 结束 | 原生轮次到达结束事件 | 产品续段／等待是否收口 |
| 界面收到事件 | 展示链收到数据 | 持久化和完整任务验收 |

长任务静默、执行器退出、通信 EOF、用户 Stop 和结果丢失应分别处理。恢复需要说明哪些事实仍存在，哪些结果未知。产品若有显式续段或人工等待，供应商轮次结束不一定意味着产品任务结束；重发原请求则可能重跑已经执行的动作。

## 6. 开发任务从症状到复现

真实案例取自 [Pi 长工具生命周期：#3916 受控取证](<../../sources.html#ref-73fa23b0a5e810>)。用户原报告描述 Windows、Pi 的长 exe 打包停在“已工作”。报告缺少同轮 PID、退出码与 RPC 时间线，不能直接确认根因。

开发记录把问题缩成可检验假设：Pi 已退出，但工具后代继承 stdout／stderr，Node 的 child `close` 仍等待管道 EOF，Cindy 没收到退出通知。受控 fixture 替换 transport 可执行程序，其余使用生产 `PiAgent → PiRpcProcess → translator → AsyncQueue → Session` 链路；它不调用模型、不做真实打包。

fixture 确认 prompt，发工具开始事件，启动继承管道的后代，然后以 23 退出。测试同时检查 Pi PID 消失、后代仍活着。历史记录的最初四个用例中三个对照通过，该用例在两秒内没有 terminal error；修复后约 0.3 秒收到含退出码 23 的失败终态。它证明这条缺陷，不证明原 Windows 用户故障一定同源。

## 7. 验证、评审与交接

当前 [transport.ts](<../../sources.html#ref-1b03bfd8dbd588>) 在 child `exit` 后禁止继续写入，最多给尾帧 250ms 排空；若正常 `close` 更早到达，则沿原路径通知。250ms 从确认进程退出起算，不是正常工具或整个任务的期限。修复没有自动重放请求，也没有据此杀掉构建进程树。

对照覆盖正常工具长时间静默、普通退出、丢失不同事件、EOF 与 Stop。缺结果就保持缺结果；取消只取消当前意图，不增加新 prompt。评审进一步检查“关闭失败不能冒充退出”，保留退出码、通知一次和竞态断言。

历史记录中的六个定向文件 134 用例、根级 511 通过与 1 跳过，是该任务当时的结果。本次没有重跑。额外类型检查存在已由基线复现的 `TS2322`；没有脚本而跳过也不能写成类型检查通过。

Windows 补充记录同样要定界：旧 fixture 的后代受 Job 生命周期影响，不能建立所需前提，于是仅对测试后代设置 detached，生产策略不变。后续运行已通过行为断言，却在删除临时目录时遇到 EBUSY；清理改为确认 PID 退出后有界异步重试，效果仍以对应新 CI 为准。这些记录不能被概括成“Windows 实机打包已通过”。

[开发工作流](<../../sources.html#ref-fe7e6901ae6eb1>) 要求按影响面验证并如实交接。交接应写最终行为、实际检查、基线失败、未覆盖环境和下一步证据；旧测试数量不能挪到新版本验收栏。

## 8. 从两类重复问题形成方法

第一类是“系统没有结束”被笼统归因于模型。Pi 案例把它拆为进程、管道、事件和产品状态，找到可由确定性代码修复的边界。迁移到 TA 工具时，同样区分外部执行器退出、UE 子任务仍运行和结果文件缺失。

第二类是“说明已经读到，却不能调用”被当作能力不存在。Ghost 案例把召回、实时信息、手册和运行时可见性分开；已安装、已发现、已登录、已授权和调用成功不能互相替代。迁移时先写清真实接口与可用状态，再让 Agent 决定步骤。

两者共通的方法是保留关键状态和证据来源，而不是增加笼统重试。使用 [调用与开发交接模板](<../../模板/Cindy调用与开发交接.md>) 分别记录运行调用和开发修复，交接就能服务下一位开发者。

## 练习与验收

画一张从 `input.enqueue` 到 Session 事件回界面的时序图，标出普通入队与兼容直发分支。再为 Pi 案例填写“原症状、假设、受控前提、对照、改动、历史结果、仍需取证”。

验收要求：每个关键步骤有可回查文件；250ms 的起点解释正确；明确原 Windows 根因未证明；不把说明文本当授权；交接能说明哪些检查是历史记录、哪些是本次执行。

![本章思维导图](<../../图表/CY-02_思维导图.svg>)

## 来源与衔接

当前结构见 [CY-01](<CY-01_文档与软件结构.md>)。本章主要来源为链接中的核心、宿主、Ghost 与 Pi 研究文件；工程原则见 [CY-03](<CY-03_工程原则与迁移.md>)，一般任务验证方法见 [CC-03](<../ClaudeCode/CC-03_调试测试与评审.md>)。
