


















理论是地图,实战是航行。一张再精确的地图,也无法替代一次在真实风浪中的航行体验。本章,我们将共同“驾驶”AI这条巨轮,完成一次完整的项目航行。
我们将从一个空白的文件夹开始,严格遵循我们在本书中建立的所有约束原则,一步一步地,构建一个功能完备、质量可靠的应用程序。
在这个过程中,你将看到:
准备好了吗?扬帆,起航。
为了让这次演练具有足够的普适性和挑战性,我精心设计了一个涵盖了多种常见技术难题的案例:一个安全的、跨平台的、支持离线使用的笔记应用——“Guardian Notes”。
核心需求(来自“产品经理”的原始需求):
“我们要做一款笔记应用,用户可以在上面写私密的日记、备忘录。我们最大的卖点是‘安全’和‘随处可用’。具体来说:
- 绝对安全:用户的笔记内容,必须在他们自己的设备上加密。就算我们的服务器被黑了,黑客也拿不到任何有意义的内容。
- 跨平台:它必须能在Web浏览器、桌面应用(Windows, macOS)上使用。
- 离线优先:就算没网,用户也应该能查看、创建和编辑笔记。等有网了,再自动同步到云端。
- 基本功能:支持Markdown语法,可以按文件夹组织笔记。”
这个案例的“魔鬼之处”在于:
Web + Desktop):这意味着我们需要处理不同运行环境的差异,是“环境约束”的绝佳演练场。Offline-First):这要求我们必须在本地持久化数据,并处理复杂的数据同步和冲突解决逻辑,对“架构约束”和“流程约束”提出了高要求。E2EE):这是一个极其严肃的安全需求。“加密”逻辑一旦出错,后果是灾难性的。这为我们的“质量约束”(尤其是测试)提供了最严苛的考验。我们将使用一个常见的技术栈来构建它:
Dexie.js)libsodium-wrappers目标:在编写任何一行应用代码之前,先用文档,为AI和我们自己,构建起坚不可摧的“思想护栏”。这是架构约束的集中体现。
行动:我们在项目根目录,创建三个核心的Markdown文件。
AGENTS.md我们首先定义与我们协作的AI的角色和行事准则。
# AI Agent Directives: Project "Guardian Notes"
This document defines your persona and core principles for this project.
## Persona: Senior Security-Focused Engineer
You are to act as a Senior Software Engineer with a specialization in security and cross-platform application development. You are paranoid, meticulous, and pragmatic.
## Core Principles:
1. Security First, Always: Every line of code that handles user data must be viewed through a security lens. When in doubt, choose the more secure option.
2. Offline-First is Non-Negotiable: All features must be designed to work offline first. Cloud sync is an enhancement, not a dependency.
3. Simplicity over Complexity: Given the security-critical nature, prefer simple, well-understood algorithms and architectures over complex, "clever" ones.
4. Zero Trust for the Server: The server is considered a dumb, untrusted storage bucket. It should never see unencrypted user data or have access to decryption keys.
5. Strictly Typed: All code must be written in TypeScript with `strict` mode enabled. The `any` type is forbidden.
ARCHITECTURE.md这是项目的“宪法”。我们在这里,做出最关键的、高阶的技术决策,并划定“负空间”。
# "Guardian Notes" - Architecture Document (v0.1)
This is the Single Source of Truth for our architecture.
## 1. Core Principles (Reiteration)
- End-to-End Encrypted (E2EE)
- Offline-First
- Cross-Platform (Web, Desktop)
## 2. High-Level Architecture
The application is divided into three layers:
1. Core Logic (Platform-Agnostic): A pure TypeScript module responsible for encryption, data management (CRUD), and sync logic. It has ZERO dependencies on any UI framework or platform-specific API.
2. Platform Adapters: Thin layers that connect the Core Logic to specific platforms (e.g., a React hooks-based adapter for the Web/Desktop UI, a REST API adapter for cloud sync).
3. UI Layer: The React components that consume the platform adapters.
## 3. The "Forbidden Zone" (Negative Constraints)
To enforce our principles, the following are STRICTLY FORBIDDEN:
- No Unencrypted Data on the Wire: Any data sent to the server API MUST be a pre-encrypted binary blob or ciphertext string.
- No Private Keys on the Server: The user's master decryption key must NEVER leave the client device. It may be stored, wrapped (encrypted with a password), in the client's local storage.
- Core Logic Cannot Access `window` or `document`: The Core Logic module is forbidden from importing or accessing any browser-specific or Electron-specific global objects. This ensures its platform-agnostic purity.
- UI Components Cannot Perform Direct Data-Access: All data operations (reading from/writing to the database, encryption) MUST go through the Core Logic via the adapter layer. UI components should be "dumb".
## 4. Key Decisions
- Encryption: We will use `libsodium-wrappers` for all cryptographic operations. The chosen algorithm will be `XChaCha20-Poly1305-IETF` for symmetric encryption.
- Local Storage: We will use `Dexie.js` as a wrapper around IndexedDB for robust local data persistence.
- Data Sync: The sync protocol will be state-based. The client sends its full encrypted data blob to the server, and the server replaces its old version. (Note: This is a simplification for the case study; a real app would use a more granular, operational-transform-based sync).
CHANGELOG.md我们初始化我们的“航行日志”,为即将开始的开发工作,写下第一个条目。
# Changelog
## Unreleased
- Decision: Established the initial project structure and core architectural constraints. Defined AI agent persona.
- Next Step: Begin implementation of the "Core Logic" layer, starting with the encryption module.
阶段复盘: 我们花了大约一个小时,没有写任何一行应用代码,但我们取得的成果,是决定性的。我们:
AGENTS.md,我们让AI知道,这是一个严肃的、安全优先的项目,而不是一个普通的CRUD应用。ARCHITECTURE.md,我们做出了最重要、影响最深远的技术决策,并建立了物理隔离(分层),防止不同关注点的代码“污染”彼此。CHANGELLOG.md,我们清晰地知道,下一步,我们该做什么。现在,我们有了一个坚固的“容器”。是时候往里面填充逻辑了。
目标:实现项目的核心功能——笔记的本地加密、存储和读取。在这个过程中,严格执行“调研 -> 谋局 -> 落地”的流程约束,强制进行“慢思考”。
场景:我们要实现EncryptionService,它需要负责生成密钥、加密和解密文本。
我们不能直接让AI写代码。我们要先让它当我们的“研究助理”。
你的提问(在一个新的、干净的会话中,首先投喂三份文档):
[粘贴 AGENTS.md, ARCHITECTURE.md, CHANGELOG.md 的内容]
Acknowledge and internalize. Our next step is to implement the encryption module.
Your Role: Act as the Senior Security-Focused Engineer defined in the agent directives.
Task: We have decided to use
libsodium-wrappers. Before we write code, conduct a brief research on the best practices for using this library for our specific use case (encrypting user text with a master key derived from a password).
salt, ops-limit, mem-limit) are involved, and what are sane defaults?
- Encryption/Decryption: What is the specific function for symmetric encryption using
XChaCha20-Poly1305-IETF? What are the inputs (key, nonce, plaintext) and outputs? How should the nonce be generated and stored?Constraint: Do not provide a full implementation yet. Your focus is on providing the necessary background information and function signatures.
AI会返回一份关于crypto_pwhash(密钥派生)和crypto_aead_xchacha20poly1305_ietf_encrypt(加密)的、详尽的、带有安全警告的技术备忘录。它会解释“盐”(salt)和“随机数”(nonce)的重要性。
基于研究结果,我们要求AI设计出EncryptionService的“蓝图”。
你的提问:
Excellent research. Now, let's design the API for our
EncryptionService.tsmodule.Task:
- Define the Interface: Propose a TypeScript interface named
IEncryptionServicethat exposes the necessary methods. These should include methods for:
- Generating a new master key.
- Deriving a key from a password (for login).
- Encrypting a string.
- Decrypting a ciphertext.
- Plan the Implementation: For each method in the interface, write a short, 1-2 sentence comment describing its implementation strategy based on your previous research (e.g., "This will use
crypto_pwhashto derive the key...").- Task Breakdown: Create a sequential task list for implementing this service.
Constraint: Again, provide only the interface, comments, and task list. No method bodies yet.
AI会返回清晰的接口定义和开发计划。这个“谋局”的过程,迫使我们思考了模块的“公共契约”,而不是过早地陷入实现细节。
现在,所有的思考和设计工作都已完成。我们进入了“高速编码”阶段。我们逐一地,将任务清单里的任务,交给AI去完成。
你的提问:
I approve the design. Let's start with Task 1: "Implement the
generateMasterKeymethod".Task: Write the full implementation for the
generateMasterKeymethod within a classEncryptionServicethat implementsIEncryptionService.Constraints:
- The key must be generated using
randombytes_buf.- The key should be returned in a secure, URL-safe base64 encoding.
- Adhere to all principles in
AGENTS.mdandARCHITECTURE.md.
AI会返回一小段、高度聚焦的、符合我们所有约束的代码。我们会重复这个过程,逐一完成encrypt、decrypt等其他方法。在这个过程中,我们还会让AI为每个方法,编写全面的单元测试,并确保测试覆盖率达标(质量约束的初步介入)。
阶段复盘:
目标:我们将核心逻辑,集成到Web和Electron两个不同的平台中,并解决在此过程中,必然会出现的“环境依赖型”问题。这是环境约束的实战。
场景:我们在Electron桌面端,发现笔记的保存速度,偶尔会变得极慢,甚至导致应用卡死。但在Web端,同样的操作,却非常流畅。
这是一个典型的“环境依赖型”Bug。代码是同一份(我们的Core Logic),但在不同环境下,表现却天差地别。
错误的流程: 对AI说:“我的Electron应用很卡,Web上却不卡,为什么?” 这是一个无法回答的问题,AI只能靠猜。
正确的流程(遥测驱动):
你的提问(对AI说):
"We need to add detailed performance logging to our
saveNotefunction inNoteService.ts. Act as a Senior SRE. Modify the function to log structured events at key stages. The logs must includetrace_id, timestamps, and relevant context likenote_id."The stages to log are:
SAVE_NOTE_STARTEDENCRYPTION_STARTEDENCRYPTION_FINISHED(log duration)LOCAL_DB_WRITE_STARTEDLOCAL_DB_WRITE_FINISHED(log duration)SAVE_NOTE_FINISHED(log total duration)
在真实环境中取证:我们在Electron应用中,打开开发者工具,执行几次缓慢的“保存”操作,然后,从控制台,复制出完整的、JSON格式的结构化日志流。
逆向投喂日志:
你的提问(对AI说):
Context: We are debugging a performance issue in our Electron app. Here is the full log stream from a single, slow
saveNoteoperation.Your Role: Act as a Performance Engineer specializing in Electron and browser storage.
Log Data:
[ {"event": "SAVE_NOTE_STARTED", "trace_id": "xyz", ...}, {"event": "ENCRYPTION_STARTED", ...}, {"event": "ENCRYPTION_FINISHED", "duration_ms": 50, ...}, {"event": "LOCAL_DB_WRITE_STARTED", ...}, {"event": "LOCAL_DB_WRITE_FINISHED", "duration_ms": 8500, ...}, {"event": "SAVE_NOTE_FINISHED", "total_duration_ms": 8550, ...} ]Analysis Request:
- Based on the log data, what is the exact bottleneck?
- The same operation in the Chrome browser takes only 100ms for the DB write. Why would an IndexedDB write be over 80 times slower in Electron compared to Chrome, given they use the same V8 engine?
- Propose a specific solution for this Electron-specific issue.
AI的精准诊断: AI在接收到这份量化的、无可辩驳的数据后,它的“思考”过程会是这样的:
定位瓶颈:日志清晰地显示,8.5秒的耗时,99%都花在了LOCAL_DB_WRITE上。加密很快。
激活专业知识:AI的知识库中,包含了大量关于Electron和Web性能差异的知识。它知道,Electron的主进程和渲染进程,虽然都用V8,但其底层的I/O模型和磁盘交互方式,与沙箱化的浏览器环境,有本质区别。
提出假设:它会提出一个极具洞见的假设:“在Electron中,频繁地、小批量地向IndexedDB(底层是文件系统)写入数据,可能会受到主进程I/O瓶颈或杀毒软件实时扫描的影响,导致性能急剧下降。Chrome浏览器对此有更深度的优化。一个常见的解决方案,是将多次小的写入,批处理为一次大的写入。”
修复与验证:根据AI的建议,我们修改了代码,使用Dexie.js的bulkPut() API,将多个保存操作,缓存起来,一次性写入数据库。再次运行,Electron端的保存速度,恢复到了和Web端一样的毫秒级。
阶段复盘:
目标:项目核心功能已完成,现在我们需要对其进行“净化”,移除开发过程中产生的技术债务,并优化结构,同时确保没有破坏任何现有功能。这是质量约束和定期垃圾回收的实践。
场景:我们的NoteService.ts模块,在多次迭代后,变得有些臃肿。里面混杂了数据操作、加密调用和一些初步的同步逻辑。我们想让AI来重构它,将其拆分成更内聚的多个模块。
行动:
NoteService.ts建立起坚固的防线。NoteService.ts的所有公共方法,编写了100%分支覆盖率的单元测试。我们运行了一遍,所有测试都通过。这是我们的“功能正确性基线”。saveNote和loadNotes函数,编写了基准测试,并记录下它们在当前实现下的平均执行时间。这是我们的“性能基线”。你的提问(对AI说):
Context: We need to refactor our
NoteService.tsmodule. It has grown too large.Your Role: Act as a Senior Software Architect, obsessed with the Single Responsibility Principle (SRP).
Task:
- Propose a Refactoring Plan: Analyze the current
NoteService.tsand propose a plan to split it into smaller, more cohesive modules (e.g.,NoteRepository.tsfor data access,SyncService.tsfor sync logic, etc.).- Execute the Refactoring: Once I approve the plan, provide the code for the new modules and the refactored
NoteService.ts.ANTI-REGRESSION CONTRACT (ABSOLUTE & NON-NEGOTIABLE):
- No Functional Regression: The refactored code must pass all existing unit tests for
NoteService.tswithout any modification to the test files themselves.- No Performance Regression: The performance of the key operations must remain within 5% of our established baselines.
- Clean Up: After the refactoring, run
ts-pruneto identify and remove any now-unused helper functions or imports from the old module.
当AI完成重构后,我们进行验收:
ts-prune和depcheck,将AI重构后产生的“死代码”和“孤儿依赖”,清理得一干二净。阶段复盘:
回顾我们这次从零到一的完整航行,我们可以总结出在每个阶段,最重要的“心法”和“决策点”。
| 阶段 | 核心任务 | 关键决策点 / 心法 | 约束体系 |
|---|---|---|---|
| 一: 文档先行 | 建立共识,划定边界 | “慢就是快”:花在文档上的1小时,能为你节省后续10小时的返工时间。 “先想好不做什么”:负空间约束,比正面描述功能,更能体现架构的智慧。 | 架构约束 |
| 二: 核心开发 | 将设计转化为代码 | “抵制‘一步到位’的诱惑”:强制执行“三步走”,将AI的算力,从“快速编码”引导到“深度思考”上。 | 流程约束 |
| 三: 环境调试 | 解决平台差异与“黑盒”问题 | “别跟AI‘聊’问题,给它‘喂’数据”:任何口头描述,都不如一份原始的、结构化的遥测日志有说服力。 | 环境约束 |
| 四: 重构优化 | 对抗熵增,提升质量 | “信任,但要验证”:授权AI进行大胆重构,但必须用自动化的、刚性的测试基线,来无情地验证其结果。 “代码库是花园,不是仓库”:定期修剪和净化,比不断堆砌新功能,更能体现一个高级工程师的价值。 | 质量约束 |
最终的感悟: “有效约束”,不是要去限制AI的创造力。恰恰相反,它是为了最安全、最高效地释放AI的创造力。
就像一条湍急的河流,如果没有河岸的约束,它只会肆意泛滥,最终变成一片毫无生机的沼泽。而有了坚固的河岸(我们的约束体系),它的万顷伟力,才能被引导、被聚焦,最终汇入大海,或者,驱动水轮发电机,点亮一整个世界。
你,就是那个“河流的治理者”。掌握了“约束”的艺术,你就掌握了与这个时代最强大的生产力,共舞的秘诀。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。