18. 工程质量、测试与可迁移结论
Craft Agents 0.11.2 已经不是原型规模:约 1,496 个 TypeScript/TSX 文件、34.1 万行、373 个 TypeScript 测试入口(含5个独立进程测试),跨 Electron、headless server、WebUI、Viewer、CLI、两套 Agent backend、三种消息平台和多个子进程。
这一章不再按功能走链,而是回答三个问题:哪些工程选择支撑了这种复杂度,哪些地方已经成为结构债,以及如果在另一个项目复用思想,应该保留什么、舍弃什么。
18.1 定量地图
Section titled “18.1 定量地图”以下为 0.11.2 快照中 packages/ 与 apps/ 的 TS/TSX 统计,不含依赖和生成产物:
| 包/应用 | TS/TSX 文件 | 约行数 | 测试文件 |
|---|---|---|---|
apps/electron |
617 | 131,287 | 90 |
packages/shared |
434 | 115,553 | 162 |
packages/ui |
171 | 30,059 | 33 |
packages/server-core |
105 | 27,488 | 30 |
packages/messaging-gateway |
47 | 14,028 | 25 |
packages/session-tools-core |
51 | 8,575 | 16 |
packages/pi-agent-server |
26 | 5,033 | 10 |
apps/cli |
6 | 3,703 | 3 |
packages/messaging-whatsapp-worker |
8 | 1,788 | 3 |
packages/core |
10 | 966 | 0 |
apps/webui |
11 | 878 | 0 |
apps/viewer |
7 | 650 | 0 |
packages/session-mcp-server |
1 | 576 | 0 |
packages/server |
2 | 542 | 1 |
| 合计 | 1,496 | 341,126 | 373 |
这张表揭示两个事实:
shared + electron占约72%的代码,是主要维护面;- 测试数量不少,但分布很不均匀,WebUI/Viewer/core/session-mcp-server几乎依赖间接覆盖。
18.2 代码规模热点
Section titled “18.2 代码规模热点”| 文件 | 约行数 | 为什么会大 |
|---|---|---|
SessionManager.ts |
9,005 | 会话生命周期、运行时、队列、持久化、工作流、browser wiring |
AppShell.tsx |
3,911 | 桌面导航、布局、筛选、panel、settings入口 |
browser-pane-manager.ts |
3,613 | WebContentsView与整套浏览器自动化 |
TurnCard.tsx |
3,279 | 多类消息/tool/activity渲染 |
claude-agent.ts |
3,180 | SDK适配、permission、event、恢复、工具 |
config/storage.ts |
3,044 | 跨版本配置/迁移/路径 |
pi-agent.ts |
2,691 | 子进程桥、协议、event adapter |
FreeFormInput.tsx |
2,537 | composer完整状态机 |
ChatDisplay.tsx |
2,383 | turn组织、滚动、搜索与交互 |
unified-network-interceptor.ts |
2,265 | 多 transport网络策略 |
热点并不都应立即拆分。browser-pane-manager 大但围绕一个真实资源 owner;SessionManager 则横跨多个可独立变化的子领域,更值得优先解耦。
18.3 测试重点是行为边界,不只是纯函数
Section titled “18.3 测试重点是行为边界,不只是纯函数”测试集中在最容易分叉的状态机与失败窗口:
- permission mode与 pre-tool safety矩阵;
- Claude/Pi event parity与 tool name normalization;
- session分支、SDK id更新、fork cwd失效回退;
- 用户消息先落盘、发送失败耐久性;
- mid-stream queue/steer与 replay timestamp;
- JSONL anchor/compaction/branch rollback;
- Source config watcher、credential/OAuth;
- RemoteBrowser capability与 screenshot wire conversion;
- Task DAG、引用、budget、repair;
- Automation condition/security;
- Messaging binding/access/button幂等;
- Electron browser permission、notification routing;
- renderer纯 event handlers和 race regression。
这是成熟 Agent产品应有的测试形状:最危险的 bug通常不是“函数算错”,而是“中断发生在落盘之后、广播之前”“第二次点击落到已结束 runtime”“重连只恢复一半状态”。
18.4 测试缝来自端口,而不是全局 mock
Section titled “18.4 测试缝来自端口,而不是全局 mock”代码中反复使用小接口/callback:
AgentBackendISessionManagerConductorSessionHostIBrowserPaneManagerPlatformAdapterEventSinkFnCredentialManagersession self-management callbacks因此测试可用内存 host/adapter/event sink验证调度与状态,不必启动 Electron、真实模型或 Telegram。
几个好例子:
TaskRunner只依赖 create/send/status/completion等 host方法;RemoteBrowserPaneManager用假的 capability invoker验证 wire;Renderer用带 capability的 fake adapter测试三种响应模式;processEvent()是无副作用纯函数;evaluateBindingAccess()直接穷举安全矩阵。
可迁移原则:测试友好性通常是架构端口清晰的副产品,不是后置 mock技巧。
18.5 为什么存在 .isolated.ts
Section titled “18.5 为什么存在 .isolated.ts”根 test 脚本先运行 bun test,再单独查找所有 *.isolated.ts逐个执行。当前隔离测试覆盖:
- Electron notification routing;
- branch rollback;
- session annotations;
- pre-tool checks;
- prerequisite manager。
这些测试通常会改 module/global/env/mock状态,放进同一 Bun进程可能互相污染。独立进程是务实隔离,但也提示对应代码对进程级单例或 import-time状态依赖较重。长期可把可变全局收进显式 runtime container,减少必须隔离的测试。
18.6 CI 实际执行面比测试仓库小
Section titled “18.6 CI 实际执行面比测试仓库小”根 package.json 定义:
test → bun test + isolated testsvalidate:dev → typecheck:all + selective shared tests + Python doc-tool smokevalidate:ci → validate:dev + i18n parity/sorted/coverage但 .github/workflows/validate.yml 只运行 bun run validate:ci,其中没有根 bun test,也没有根 lint。因此当前 OSS快照中的373个 TypeScript测试入口并未由这个必跑 workflow完整执行。
另一个手动 workflow validate-server.yml 在 Linux/macOS/Windows跑真实 CLI server validation,但只在 workflow_dispatch 触发。
建议最少改为:
required PR jobs├── typecheck all workspaces├── unit/integration tests + isolated tests├── lint + protocol/i18n guards├── build electron/webui/viewer/server workers└── platform smoke matrix (可按 nightly/label分层)18.7 typecheck:all 也并非真正 all
Section titled “18.7 typecheck:all 也并非真正 all”当前脚本包含 core/shared/server-core/server/session-tools/pi-agent-server/electron/ui,但未包含:
messaging-gateway;messaging-whatsapp-worker;apps/cli;apps/webui;apps/viewer;session-mcp-server。
这些 package大多有自己的 typecheck script,但没有被根验证串起来。命名为 typecheck:all 会给维护者错误信心,建议从 workspace清单自动发现 script,或显式补齐并加测试保证新 workspace不会漏掉。
18.8 OSS 快照中的 lint 打包缺口
Section titled “18.8 OSS 快照中的 lint 打包缺口”根 lint 引用了:
scripts/check-raw-sends.shscripts/check-task-tool-checks.sh但这两个文件不在当前 craft-agents-oss-0.11.2 快照中;.husky 也未随快照提供,而 prepare仍指向 husky。因此直接运行完整 lint会先因脚本缺失失败。
这可能是 OSS同步/发布过滤导致,不一定代表内部仓库缺失,但对开源消费者而言就是可复现性问题。发布过程应在净导出目录执行:
bun install --frozen-lockfilebun run typecheck:allbun testbun run lintbun run build任何内部才存在的路径都应在发布前暴露。
18.9 类型系统使用得最好的地方
Section titled “18.9 类型系统使用得最好的地方”Discriminated unions
Section titled “Discriminated unions”大量状态使用 tag:
AgentEvent.type;- message/content block;
- permission/credential request;
- automation action/condition;
- Task node/run state;
- messaging runtime/access verdict;
- Pi subprocess command/event。
配合 exhaustive switch,新增事件能在多个 adapter/UI handler编译时报漏分支。
Ports 与 DTO
Section titled “Ports 与 DTO”server-core接口、RPC DTO与 UI domain类型基本分开;remote wire还会把 Buffer显式转 Uint8Array。这比把 SDK对象直接穿过 IPC/WS稳健。
Normalization at boundaries
Section titled “Normalization at boundaries”旧 binding config、legacy messages、provider tool input、路径与来源配置会先 normalize再进入主链。兼容逻辑集中在入口,内部代码不必每处判断版本。
18.10 类型不能替代协议版本
Section titled “18.10 类型不能替代协议版本”TypeScript只在同一构建时成立,跨子进程/网络后输入是 unknown。Craft已经在部分 wire上加入 v: 1 和 runtime validation,但仍有可加强处:
- parent Pi adapter与 subprocess各自维护协议相关类型;
- Electron channel map/API类型跨多个包同步;
- shared session JSONL演进主要靠宽松 parser;
- Task schema接受的节点多于 executor能力;
- Viewer对 Claude/Pi tool字段做本地 fallback。
建议从单一 schema生成:
runtime validatorTypeScript typesJSON Schema/docsprotocol compatibility tests并在 handshake中明确 min/max protocol version与capability,而不是只假设 client/server来自同一版本。
18.11 持久化工程做得好的部分
Section titled “18.11 持久化工程做得好的部分”Session主链有明确耐久性纪律:
accept user intent→ assign stable id/timestamp→ persist user message→ update in-memory state→ broadcast/reply→ run provider分支/迁移失败有 rollback;JSONL anchor保留 provider恢复语义;queued message在 interruption/restart后有可识别状态;分享上传只读 snapshot而非暴露工作目录。
文件系统事实源还带来:
- 可检查/可复制/可版本迁移;
- headless与Electron共享;
- 不需要内嵌数据库服务;
- Task/Source/Automation可用普通 YAML/JSON。
18.12 文件存储的不一致
Section titled “18.12 文件存储的不一致”不同子系统各自实现 JSON/YAML读写:
- session JSONL与metadata;
- config/storage/migration;
- Sources/credentials;
- messaging config/bindings/pending/topics;
- Task spec/run;
- Automation config/history。
有些使用 temp+rename/队列,有些直接覆盖;有些失败抛出,有些重置为空;有些先写后 event,有些 callback时序不同。
应抽一个小而严格的 storage toolkit:
readVersioned<T>(path, schema, migrations)writeJsonAtomic(path, value)appendJsonlDurable(path, record)withFileLock/serialQueue(key, fn)quarantineCorrupt(path)目标不是建 ORM,而是统一 crash窗口、corruption策略和 observability。
18.13 并发控制的成熟模式
Section titled “18.13 并发控制的成熟模式”代码中多处有“按资源串行”:
- SessionManager per-session send queue;
- Source runtime refresh coalescing;
- TopicRegistry同 name find-or-create序列化;
- WhatsApp pending command id;
- plan/permission token一次 claim;
- TaskRunner max parallel + node状态;
- event replay buffer sequence;
- atom transaction更新 metadata。
共同点是没有用一个全局 mutex,而是选择正确 key:session、source、topic、request、binding、run。这是高并发 Agent应用中最值得迁移的模式之一。
18.14 Observability
Section titled “18.14 Observability”优点:
- messaging logger支持 child context和结构字段;
- transport connection保留 attempt、close code、last error;
- Agent错误以 exception上报Sentry;
- provider/subprocess stderr与机器 stdout分开; -许多关键日志带 workspace/session/binding/event;
- Task run、automation history和session JSONL本身就是审计记录。
仍需统一:
- trace/run/turn/tool/request id贯穿 UI→RPC→SessionManager→backend→subprocess;
- log字段 schema与敏感字段 redaction;
- model/API/MCP/browser/消息平台的耗时与失败分类;
- dropped event、replay gap、queue depth、outbox lag等指标;
- 用户可导出的诊断包与隐私预览。
当前许多 console.* 与结构 logger并存,跨进程关联一次失败仍较费力。
18.15 构建矩阵本身就是架构成本
Section titled “18.15 构建矩阵本身就是架构成本”产物包括:
- Electron main/preload/renderer/resources;
- macOS/Windows/Linux安装包;
- headless server多平台二进制;
- Pi agent server;
- session MCP server;
- WhatsApp worker;
- WebUI;
- Viewer;
- Python document tools与资源;
- browser/native依赖。
因此“本地 TypeScript能跑”远远不够。子进程 entry、resources path、Electron ASAR unpack、native module ABI、Python env和平台文件名都可能只在打包后失败。
建议把构建 smoke当测试维度:每个产物至少启动、握手、执行一个无网络命令再退出。
18.16 架构最强的十个点
Section titled “18.16 架构最强的十个点”- Session Actor:运行资源、队列、持久状态、事件出口以 session为一致性边界。
- Backend abstraction:共享外壳但保留 provider-native session/branch/compaction语义。
- 统一 RPC:本地 Electron与远程 server使用同一 channel contract。
- Reverse capability:远端 Agent可借用在线客户端浏览器,而不把 GUI塞进 server。
- Durable-first message:用户输入先落盘,降低确认后丢失。
- Pure event projection:流式协议到 UI状态有单一、可测试转移。
- Central pre-tool gate:provider变化不绕过权限、安全与prerequisite。
- File-native domain:workspace/session/source/task可搬运、可诊断。
- Workflow reuse:Task/Automation/Messaging都复用 SessionManager,不复制执行器。
- Capability-aware degradation:Web/Viewer/platform adapter明确能力不足时的降级。
18.17 最大的结构债:SessionManager
Section titled “18.17 最大的结构债:SessionManager”SessionManager 同时是:
- repository;
- actor registry;
- backend factory;
- turn coordinator;
- permission broker;
- browser host resolver;
- source refresher;
- task/automation host;
- branch/share/transfer service;
- event publisher。
问题不是9,000行本身,而是这些职责的变化原因不同。新增 provider、修改 persistence、改 browser host选择都碰同一类,回归半径过大。
建议拆分,不改变外部接口
Section titled “建议拆分,不改变外部接口”flowchart TD F["SessionFacade / ISessionManager"] R["SessionRepository"] A["ManagedSessionRegistry"] T["TurnCoordinator"] B["BackendRuntimeFactory"] P["PermissionBroker"] C["ContextAndSourceController"] E["SessionEventPublisher"] W["WorkflowHost"]
F --> R F --> A F --> T T --> B T --> P T --> C T --> E F --> W推荐顺序:
- 先抽纯 repository与event publisher;
- 再抽 backend runtime factory;
- 把 send/queue/steer/abort变成
TurnCoordinator状态机; - 最后把 Task/Automation callbacks移到独立 host adapter;
- 外部仍保留
ISessionManagerfacade,避免大爆炸迁移。
18.18 第二大债:shared 已变成平台内核
Section titled “18.18 第二大债:shared 已变成平台内核”packages/shared 约11.6万行,包含:
- Agent实现;
- config/storage/credentials;
- prompts/tools/modes;
- sources/MCP/API;
- sessions JSONL;
- tasks/automations;
- protocol/i18n;
- browser runtime;
- network interceptor。
它不是普通“shared utils”,而是多个内聚域的合集。包名掩盖依赖方向,任何 consumer很容易从内部任意路径import。
可逐步形成:
agent-runtimeagent-protocolsession-domainworkspace-configsource-runtimeworkflow-domainsecurity-policy不必一次拆 npm package;先建立 public barrel与eslint boundary,再按编译/部署需求物理拆包。
18.19 Provider abstraction 的下一步
Section titled “18.19 Provider abstraction 的下一步”当前 AgentBackend 隔离得不错,但 provider差异仍渗到:
- stored metadata与branch anchors;
- Viewer tool payload字段;
- model/thinking配置;
- context/compaction行为;
- permission event细节。
不要追求把所有 provider压成最低公分母。更好的模型是:
interface AgentBackend { common lifecycle... capabilities: { nativeFork, nativeResume, nativeCompaction, thinkingLevels, toolProtocolVersion }}上层以 capability选择语义;持久层保存 provider-neutral transcript + provider-specific resume envelope,两者边界明确。
18.20 Remote Browser 的同步接口债
Section titled “18.20 Remote Browser 的同步接口债”本地 IBrowserPaneManager 历史上有同步查询,远程 WS调用天然异步,于是 RemoteBrowserPaneManager 对部分 sync方法只能返回空/降级,并另加 async版本。
这说明接口抽象建立在“本地对象”假设上。既然产品已支持远端,跨边界端口应全部 Promise化;本地实现立即 resolve即可。否则调用者可能在本地正确、远端静默得到空列表。
18.21 Schema 领先 executor 的债
Section titled “18.21 Schema 领先 executor 的债”Task schema能 round-trip route/map/loop/approval/...,当前 Runner只执行 session DAG子集。这有利于前向兼容,但会产生“解析成功=支持执行”的错觉。
应在 schema之外显式发布 capability/version:
{ taskSchemaVersion: 1, executorVersion: 1, supportedNodeKinds: ['session'], supportedFeatures: ['depends_on','inputs','retry','verify']}Editor保存/运行前根据 executor capability校验,而不是只看 parser。
18.22 UI 结构债
Section titled “18.22 UI 结构债”第16章列出多个2,000–4,000行组件。最需要避免的是“为了减行数把 JSX搬到子文件”,但状态/副作用仍集中在 parent。
真正应抽的是应用层控制器:
- event subscription + reconcile;
- route/filter projection;
- composer intent state machine;
- panel/navigation model;
- overlay resolver;
- platform capability service。
纯 UI组件应拿明确 view model与commands,减少直接访问 window.electronAPI 的位置。
18.23 安全优先级
Section titled “18.23 安全优先级”若按风险而非易改程度排:
- 远程 TLS信任:移除默认
tlsRejectUnauthorized:false,支持证书 pin/trust UI; - Browser权限细分:Safe模式不应把 click/fill与snapshot一概视作只读;
- Shell/path validator跨 macOS/Linux/Windows一致性与fuzz;
- Source OAuth/API credential日志与错误 redaction;
- Messaging所有 callback/附件/pairing端到端攻击测试;
- HTML/Markdown/URL artifact跨 Electron/Web/Viewer同一 sanitization policy;
- Remote client capability invocation绑定 workspace/session/host身份;
- 分享 snapshot脱敏与撤销后的缓存策略;
- 自动化默认 allow-all的可见风险与 sandbox profile;
- 文件写入atomic/corruption quarantine。
安全策略应按“动作效果”分类,而不是按工具名或 provider名分类。一个 browser_tool click、MCP send_email 与 shell curl -X POST 都可能产生外部副作用。
18.24 下一阶段最有价值的测试
Section titled “18.24 下一阶段最有价值的测试”Crash/restart invariant
Section titled “Crash/restart invariant”对关键时间点注入崩溃:
after user-message persistafter runtime createmid text streamafter tool side effect before result persistmid compactionmid branch copymid source credential refresh重启后验证无用户消息丢失、无重复 tool执行、状态可解释。
Protocol contract
Section titled “Protocol contract”- client/server版本差一档;
- Pi/WhatsApp JSONL随机分块、粘包、坏帧、超大帧;
- event sequence gap/replay overflow;
- unknown event/tool content兼容;
- capability消失/host切换。
Property/fuzz
Section titled “Property/fuzz”- shell/PowerShell validator;
- path boundary/symlink;
- browser command tokenizer;
- task引用与DAG cycle;
- Markdown/Lark/Telegram formatter;
- session JSONL migration parser。
Multi-client
Section titled “Multi-client”- 两窗口同时看/改 session;
- 一个窗口离线后回放;
- split view未读;
- permission在桌面与Telegram竞争;
- remote browser host断线重选。
18.25 建议的偿债顺序
Section titled “18.25 建议的偿债顺序”flowchart TD A["1. 修 CI: full tests/typecheck/lint/build"] B["2. 固化 protocol schemas + compatibility tests"] C["3. 统一 atomic storage toolkit"] D["4. 抽 SessionRepository/EventPublisher"] E["5. 抽 TurnCoordinator/RuntimeFactory"] F["6. UI application controllers"] G["7. 拆 shared public domains"]
A --> B --> C --> D --> E --> F --> G先修验证网,再重构核心。否则拆分只会把现有隐含行为变成无法发现的回归。
18.26 二次开发检查表
Section titled “18.26 二次开发检查表”新增 backend
Section titled “新增 backend”- 实现
AgentBackendlifecycle与event mapping; - 声明 native resume/fork/compact/thinking capability;
- 复用统一 pre-tool permission pipeline;
- 定义 provider resume envelope与失效回退;
- 测 message/tool/permission/error/usage parity;
- 验证中断、queue、branch、restart。
新增 Source/MCP/API
Section titled “新增 Source/MCP/API”- config schema与 migration;
- credential storage,不把 secret写普通文件;
- OAuth callback/relay与state校验;
- tool naming/description normalization;
- runtime refresh串行与在途 turn策略;
- request/response大小、重试、redaction;
- source mutation如何影响 active session。
新增 session字段
Section titled “新增 session字段”- canonical type与默认值;
- metadata/full session是否都需要;
- JSONL/legacy migration;
- RPC DTO与event;
- atom/event processor/UI projection;
- branch/transfer/share是否携带;
- 多窗口与重连测试。
新增 tool
Section titled “新增 tool”- provider schema/alias;
- canonical name;
- mode分类与风险等级;
- pre-tool path/command/network/source checks;
- permission描述是否可理解;
- output truncation/artifact;
- UI parser与generic fallback;
- background/cancel/restart语义。
18.27 如果重做一个最小 Craft
Section titled “18.27 如果重做一个最小 Craft”不要从 34万行开始。保留骨架即可:
1. Workspace + file-backed SessionRepository2. SessionActor(send/abort/queue)3. 单一 AgentBackend4. canonical event protocol5. WebSocket RPC6. pure UI event reducer7. central pre-tool policy8. one Source/MCP path9. crash/reconnect tests等这些不变量稳定后,再依次加:
second backend→ branch/compaction→ remote client capability→ Tasks/Automations→ Messaging→ share/viewerCraft最复杂的地方都来自功能组合,不来自单功能本身。增量顺序决定架构是否仍可理解。
18.28 最值得直接复用的模式
Section titled “18.28 最值得直接复用的模式”模式 A:Actor + durable log + event projection
Section titled “模式 A:Actor + durable log + event projection”command → actor serializes → durable state → canonical event → UI projection适合任何长运行、可中断、可恢复 Agent。
模式 B:Provider-neutral core + provider resume envelope
Section titled “模式 B:Provider-neutral core + provider resume envelope”共享产品语义,但不伪造完全统一的底层会话能力。
模式 C:Callback port 打破包环
Section titled “模式 C:Callback port 打破包环”SessionManager提供 host接口,Task/Messaging/Browser实现方从外部注入;比 service locator或互相 import清晰。
模式 D:Replay优先,snapshot修复
Section titled “模式 D:Replay优先,snapshot修复”短断线靠 event buffer低成本追平,长断线按 active/processing范围拉 snapshot。
模式 E:Capability-driven degradation
Section titled “模式 E:Capability-driven degradation”同一 UI/renderer面对 Electron、Web、Viewer、Telegram、WhatsApp时,明确声明 edit/file/browser/approval等能力。
模式 F:稳定上下文与易变上下文分层
Section titled “模式 F:稳定上下文与易变上下文分层”System prompt缓存稳定语义,turn context承载时间、workspace、sources、协作状态,降低缓存失效。
18.29 不应照搬的模式
Section titled “18.29 不应照搬的模式”- 把所有领域都堆进一个
shared包; - 让单一 manager成为 repository、runtime、workflow和transport总入口;
- 直接覆盖小 JSON文件而没有统一 atomic writer;
- 用“schema可解析”代表“executor可运行”;
- 为本地对象设计同步接口,再勉强远程代理;
- 让 Web adapter假装所有 Electron方法都存在却 no-op;
- 把 browser整类工具在 Safe模式一概自动允许;
- 依赖非必跑/手动 CI验证关键集成;
- 在 OSS导出中保留指向未发布脚本的命令;
- 在每个 UI surface重复 provider-specific tool字段 fallback。
18.30 用十条不变量概括系统
Section titled “18.30 用十条不变量概括系统”理解或修改 Craft时,可以用这十条做回归审查:
- 用户确认已发送的消息最终必须可从磁盘恢复。
- 同一 session同时只有一个协调者决定 turn/queue/abort顺序。
- Provider差异不能绕过统一权限和安全检查。
- 所有客户端消费同一 canonical session event语义。
- Event丢失时必须有权威 snapshot修复路径。
- Secret只进入 credential boundary,不进入普通 config/prompt/log。
- Workspace/session/source/browser/message binding都必须有明确 ownership key。
- 任何跨进程消息都按不可信
unknown验证。 - 外部副作用的批准要绑定精确 request并且一次生效。
- Schema、runtime capability与 UI承诺必须描述同一个版本边界。
18.31 最终评价
Section titled “18.31 最终评价”Craft Agents 0.11.2 最有价值的地方,是它已经把“Agent聊天”推到了真实个人工作系统的复杂边界:多模型、长会话、文件事实源、工具安全、OAuth/MCP、远程客户端、浏览器、工作流、外部消息和跨端 UI。
它证明了一条可行路线:
Session 是核心 Actor文件系统是可恢复事实源Backend 是模型运行端口Event 是所有表面的共同语言RPC/capability 是部署边界Policy 是所有工具的共同门卫同时,0.11.2 也显示了平台成长后的典型压力:中心类和 shared包膨胀、UI应用层过厚、协议同步成本、文件存储策略不一、构建/CI覆盖落后于功能面。
如果只取一个结论:不要从“支持多少模型和工具”衡量 Agent架构,而要从中断、失败、重连、迁移和多入口同时发生时,系统是否仍只有一个可解释事实来衡量。 Craft已经在很多关键链路上做到了这一点;下一阶段的工程重点,是把这些正确不变量从大文件里的经验,提炼成更小、更明确、可自动验证的边界。