从 IDEA 到 App 的 AI Native 项目流程
目标
在之前发布的的博客中,我已经介绍了我的脚手架(Java) + Docs 文档体系,今天这篇长文,我会详细介绍我用 Coding Agent ,通过使用我的 AI Native Project Template,管理需求、统一语言、文档、计划、测试,把 IDEA 落地成一个应用,本文不包含商业验证和变现相关内容。
前置条件
- 已经有一个相对明确的产品 idea,不需要非常完整,但是至少能说清楚核心功能
- 已经安装或准备使用 AI Native Project Template:
- GitHub 地址:
https://github.com/ryan-alexander-zhang/ai-native-project-template - CLI 地址:
https://github.com/ryan-alexander-zhang/ainpt - 本文使用
english-copilot作为 demo:一个英语学习助手 Web 应用。
AI Native Project Template 是我搞得一个模板项目,不是一个完整应用脚手架。没有预设前端框架、后端框架、部署平台,是一套 docs-first 的项目工作模板,安装
ainpt 并创建项目 ainpt create english-copilot 。整体链路
这套流程的核心是:
从 IDEA 到 App 的 AI Native 项目流程 (text)
idea -> prd -> spec(link user story) -> design -> decision(optional) -> plan -> coding -> verifyidea:还没有完全产品化的想法,记录问题、初始能力、边界和早期判断。prd:产品需求,说明为什么做、给谁用、做什么、不做什么。spec:系统视角的规格,说明系统到底应该做什么。us:User Story,核心,挂在 spec 下面,承载用户价值视角的需求描述,含EARS 需求和 GWT 验收。design:跨功能或者结构性的技术设计,比如领域模型、数据模型、状态机等decision:有取舍的产品、技术、架构决策(ADR)plan:具体如何实现,拆任务、列文件、列验收
项目模板要求每个主要文档都有 front matter,通过 front matter 管理类型、状态和 Link,唯一 ID 可全局检索,
从 IDEA 到 App 的 AI Native 项目流程 (yaml)
---
id: <type>-<five-digit-number>-<slug>
type: idea|prd|spec|us|design|decision|plan|issue|...
role: main
status: draft
parent: <upstream-id>
---parent 很关键,用来串联上下游文档从 IDEA 到 App 的 AI Native 项目流程 (text)
idea-00001-english-learning-copilot
-> prd-00001-english-learning-copilot
-> spec-00001-auth-accounts
-> us-00001-register-email-password
-> plan-00001-auth-accounts这样做的好处是,后面 review、补需求、修 bug 的时候,Agent 能顺着文档链找到“当初为什么这么做”,而不是只看当前代码猜。
步骤一:先得有个 IDEA
先得有一个 IDEA,本文会以一个英语学习的 Web 应用举例
从 IDEA 到 App 的 AI Native 项目流程 (markdown)
我有一个idea,做一个英语学习的助手
1. 预设系统级别单词本,比如预设CET4、CET6,单词本可以设置 include 和 exclude,与后文有关
2. 用户可以创建用户级别单词本,然后可以添加单词,添加单词时可以输入一个或多个例句,每个例句可以对应一个 URL。每个用户初始化都有一个默认的单词本,相关操作如果没有选择单词本都会添加到这个默认单词本中。
3. 用户可以在设置页面配置多个外部词典的 template url,比如有道词典的https://www.youdao.com/result?word={argument name="word"}&lang=en,这样每一个单词可以跳转到外部的词典中
4. 可以通过浏览器插件 Clip 网页为 Markdown 成为一份系统内部的学习材料,这份材料中的单词,如果命中了include,则高亮显示,如果命中了 exclude 则不高亮显示,同一个单词如果同时在include 又在exclude,exclude 优先级更高
5. 在查看学习材料详情页,用户可在文章中选中句子添加注解,注解可以设置描述和颜色,注解可以单独查看,注解也可以编辑和删除
6. 在查看学习材料详情页,用户可以在文章中选择单词,添加到单词本中,单词本可选择,没有选择则添加到默认用户级别单词本
7. 用户可以分享学习材料,包括添加的标注,分享后会有一个只读链接,可以Public 访问
8. 登录认证,可以注册、登录,也可以用 Google 登录认证步骤二:创建项目
使用 AI Native Project Template 创建项目:
从 IDEA 到 App 的 AI Native 项目流程 (shell)
ainpt new english-copilot文件大概说明:
ARCHITECTURE.md:当前系统形态、技术栈、模块结构、边界。AGENTS.md:Agent 在这个 repo 里工作的规则。CONTEXT.md:从CONTEXT_TEMPLATE.md创建出来的项目统一语言。DEVELOPMENT.md:开发阶段、命令、Definition of Done,微调TESTING.md/UNIT_TESTING.md/INTEGRATION_TESTING.md/API_TESTING.md/E2E_TESTING.md:测试分层和命令,其中API_TESTING我固定为 Bruno,其他都需要进行调整。DOCUMENT.md:文档管理规则。THIRDPARTY.md:外部依赖、参考资料、第三方代码来源。docs/README.md:docs/目录分类和 front matter 规则。
步骤三:先统一语言
为什么要做这件事?举个例子,比如单词本语义,在语言表述中,我们可能会用单词本、WordBook、WordsBook、Vocabulary、单词数据库等等各种各样的词汇都可能会使用,如果不约束 AI,有可能就会出现各种各样的表达。等 Agent 用
grep|rg 去检索词的时候,如果模型没有把这些词汇罗列,就漏掉了。CONTEXT.md 作为 Agent 后续写 idea、prd、spec、代码、测试时的词汇事实源,新词需要注册,语言一统一,就能减少后续因为关键词检索导致的上下文丢失的问题。项目初期保留的
CONTEXT.md 内容:从 IDEA 到 App 的 AI Native 项目流程 (markdown)
# English Learning Copilot Context
The shared glossary for the app that turns clipped web pages into personalized
English study material. One canonical term per concept; use these exactly.
## Language
### Vocabulary
**Wordbook**:
A named collection of word entries. A **system wordbook** is preset and shared
(e.g. CET4, CET6) and is read-only to learners; a **user wordbook** is created
and owned by a learner. Each learner has exactly one **default wordbook** that
receives word-adds when none is chosen.
_Avoid_: word list, vocabulary book, deck, set.
**Word entry**:
One word inside a wordbook, optionally carrying example sentences.
_Avoid_: word item, vocab, term, lemma (a lemma is the matching result, not the entry).
**Example sentence**:
A sentence attached to a word entry, with an optional source URL.
_Avoid_: usage, sample, quote.
**Highlight mode**:
A per-learner setting on a wordbook that drives highlighting: **HIGHLIGHT**
(highlight its words), **EXCLUDE** (never highlight them; wins over HIGHLIGHT),
or **NORMAL** (no effect, e.g. the default wordbook). Set per learner, so a
shared system wordbook can be HIGHLIGHT for one learner and NORMAL for another.
_Avoid_: include/exclude sets, whitelist/blacklist, allow/deny list.
### Reading
**Learning material**:
A web page clipped into Markdown and stored in the app. It is a one-time
snapshot, never re-clipped from the source.
_Avoid_: material, article, document, doc, page, clip (the noun).
**Clip**:
The act of capturing a web page as a learning material via the browser
extension. Verb only.
_Avoid_: import, scrape, save, capture.
**Highlight**:
The visual marking of a word in a learning material because its lemma is in a
HIGHLIGHT-mode wordbook and not in any EXCLUDE-mode one. Matching is lemma-based
and case-insensitive (`Running` matches `run`).
_Avoid_: mark, flag, emphasize.
**Annotation**:
A learner's note on a selected sentence in a learning material, with a
description and a color. Editable and deletable; not auto-re-anchored when the
material text changes.
_Avoid_: note, comment, highlight (highlight is vocabulary marking, not a note),
markup.
### Sharing & Config
**Share link**:
A read-only, public, no-login URL to a learning material and its annotations. A
live view that reflects later edits.
_Avoid_: public link, share URL, permalink, snapshot link.
**External dictionary template**:
A learner-configured dictionary URL with a `{word}` placeholder, used to open a
word in a third-party dictionary.
_Avoid_: dictionary URL, lookup template, dict link.
## Flagged ambiguities
- **Highlight** vs **Annotation**: both are visual on a material. "Highlight" is
only the automatic vocabulary marking driven by wordbook highlight modes. A
learner's colored note on a sentence is always an "annotation", never a
"highlight".
- **Clip** (verb, the action) vs **Learning material** (noun, the result). Never
call the stored material a "clip".步骤四:把 IDEA 落盘到 docs/idea/
把 idea 让 AI 落盘到
docs/idea/ 下:这里的
README.md 中有对 idea 类型简单说明和模板,所以 Agent 会格式化文档,这就是整个业务的开始。步骤五:从 IDEA 到写 PRD
让 AI 根据:
从 IDEA 到 App 的 AI Native 项目流程 (text)
docs/idea/idea-00001-english-learning-copilot.md写 PRD 并:
从 IDEA 到 App 的 AI Native 项目流程 (text)
docs/prd/prd-00001-english-learning-copilot.mdPRD 的 front matter 里,
parent 指向上游 idea:从 IDEA 到 App 的 AI Native 项目流程 (yaml)
---
id: prd-00001-english-learning-copilot
type: prd
role: main
status: active
parent: idea-00001-english-learning-copilot
---步骤六:确定技术栈和项目形态
有了 Idea 和 PRD 后,就需要考虑技术栈了。这部分需要一定的技术沉淀、调研能力和判断力。
针对本文中这种工具向应用,能有可用的框架复用的就复用。用框架的好处就是有参考、可组合,劣势就是认知负担会重一些,需要学习框架。但是在 AI 时代,获取知识和学习比以前要容易很多。所以第一时间不考虑任何造轮子的事情,重要的是把东西做出来、用起来,后续迭代过程中,再考虑 enhance、replace 等,并且可以在已用框架的基础上借鉴一些实现方案,后续可以瘦身。我的经验是,先做加法再做减法。
本次选用的技术栈:
Area | Choice |
|---|---|
Runtime / package manager | Bun |
Framework | Next.js (App Router, TypeScript) — React Server Components, Server Actions, and Route Handlers |
UI | Tailwind CSS + shadcn/ui, lucide-react icons, GSAP for landing-page and complex animations |
Auth | Auth.js v5 (NextAuth) + @auth/prisma-adapter; Google provider + Credentials provider; bcryptjs for password hashing |
ORM / Database | Prisma + PostgreSQL |
Validation / forms | Zod + React Hook Form ( @hookform/resolvers) |
Web clipping | Defuddle (content extraction + HTML→Markdown), studied from Obsidian Web Clipper — see THIRDPARTY.md |
Material rendering | react-markdown + remark-gfm + rehype-sanitize |
Highlight matching | wink-lemmatizer (lemma-based, case-insensitive) |
Browser extension | WXT (planned; separate build target, deferred until the web app lands) |
Testing | Vitest + @testing-library/react (unit/component), Playwright (E2E), Testcontainers PostgreSQL (integration) |
Lint | ESLint |
步骤七:项目根目录工作流和规格文件适配当前项目
AI Native Project Template 的
README.md 里有根据模板创建项目后需要自定义的说明,这些需要自定义的还是要改一下,需要根据实际项目、语言、框架等做出调整。最后封装成 Makefile make 调用,目的是可以在本地随时让 Agent 启停中间件、运行测试、运行项目等。比如 make dev 启动,make test 跑测试,make e2e 跑端到端测试等。在
english-copilot 里,Makefile 的入口:步骤八:写 Spec 和 User Story
按照 AI Native Project Template 定义的 Doc 模型:
从 IDEA 到 App 的 AI Native 项目流程 (text)
spec:us = 1:nSpec 文件说明 Do What 和 Design,内联或者挂载
docs/design 文件。模板中,使用 EARS 描述系统视角需求项,使用 GWT 编写验收细则,最后让 Agent 生成 plan,后续根据这个 plan 开始 coding。在
english-copilot 里的 DemoUser Story 的一个 Demo:
可以看到,需求和验收都结构化且具有唯一 ID,这样可以在任何地方进行 Link。
步骤九:Design Doc
小 spec 可以 inline design,但如果涉及跨多个功能或者比较大,就应该单独写一个 Design,另外,Design 甚至可以单独编写,后续再挂载,比如一些系统切面功能(限流、熔断、高并发、优化方案等)的预 Design。
比如 parent 指向 PRD/SPEC 等需要 Design 的地方
从 IDEA 到 App 的 AI Native 项目流程 (yaml)
---
id: design-00001-data-model
type: design
role: main
status: active
parent: prd-00001-english-learning-copilot
---步骤十:让 Agent 生成 Plan,再开始 Coding
编写代码之前根据 spec 生成 plan,如果 plan 太大可以拆分成单独的 task 文件,实践过程中觉得过度涉及了,没有拆过。
在这个 demo 里:
从 IDEA 到 App 的 AI Native 项目流程 (text)
docs/plan/plan-00001-auth-accounts.md
docs/plan/plan-00002-wordbooks.md
docs/plan/plan-00003-materials.md以
plan-00002-wordbooks.md 为例,内容如下:步骤十一:实现、测试、验收、记录
有了 plan 之后,可以根据 plan 进行 coding ,通过测试门禁后更新结果。在 demo 里,
plan-00002-wordbooks.md 最后的结果记录 是:从 IDEA 到 App 的 AI Native 项目流程 (text)
All tasks done. Domain lib (T1–T6) + server actions (T7) + UI (T8: `/wordbooks`,
`/wordbooks/[id]`, `/settings`) + E2E (T9). Verified: `make build` + `make lint`
clean; 34 unit/integration tests at 100% `src/lib` coverage; 4 E2E specs pass
(auth + wordbooks: create → set mode → add word, and the `{word}` rejection).另外,关于验收,除了必须的人工验收,可以使用 Sub Agent 从文档出发去验证代码,去读 spec 的 EARS 和 GWT 去做验证,是否真的完成了,是否有对应的测试且测试通过了。
步骤十二:Issue Fix
如果出现 Issue,先落盘 Issue 文件,使用第一性原理 Debug 落盘现象、复现流程以及 Fix 方案后进行 Fix,这样可以做到 Issue 可观测、可跟踪、可审计。
比如一个简单的 Issue Demo:
demo 的文档结构
贴一个过程中的文档结构:
总结
CONTEXT.md里有项目统一语言,并且 spec / design / code 使用的是同一套词。docs/idea/里有最初产品想法,状态不是随便留在draft。docs/prd/里有 PRD,并且parent指向 idea。docs/spec/里有可实现的功能规格,并且parent指向 PRD。docs/us/里有挂到 spec 下的 User Story,EARS 和 GWT 能互相对应。- 有跨功能设计时,放到
docs/design/,不要散在多个 spec 里。 - 有真实取舍时,写
docs/decision/,不要只把选择写成结论。 docs/plan/里有实现计划,能看到任务、文件、需求映射和验收路径。Makefile能启动、测试、构建、迁移数据库。- plan 结束后记录实际做完了什么、跑了什么验证。
另外这个 Demo 是在一个 Session 中完成的,让 AI 总结了一下 Session 中的人机分工如下图:
常见坑
- 先写代码,后补文档:这样 Agent 一开始没有稳定上下文,后面补的文档也容易变成事后说明。
- 不写 `CONTEXT.md`:短期看省时间,长期会让概念发散,尤其是中英文混用时,检索会漏。
- PRD 和 spec 混在一起:PRD 说产品要什么,spec 说系统做什么,plan 说怎么做。混在一起后,Agent 很难判断自己该执行哪一层,所以 PRD 给人看,用来产出 spec,下游尽量不依赖 PRD。
- 有取舍但不写 decision:可能就不记得当时为什么要这么做了,只剩个 pr 或者 commit。比如过几天就忘了为什么选 Auth.js、不选 Clerk;为什么先做 web app、不先做 extension。
- Makefile 没有稳定入口:每次都重新告诉 Agent 怎么启动、怎么测,会浪费上下文,也容易跑错命令。
- Plan 没有验收路径:Agent 写完了,但不知道要跑哪些测试,也不知道失败后该回到哪个需求。
- Outcome 不记录:实现完成后没有证据沉淀,后续 review 和 debug 都要重新考古。
后续
- 继续完善文档模板和工作流
- 后续打算多探索下关于验证的方法,目前通过覆盖率、变异测试可以提高单元测试的质量,但是在符合业务语义的测试用例生成中依然是不如意,还是需要大量的人力去写测试用例,另外涉及浏览器的
E2E测试的成本、环境等都是需要考虑的角度。总而言之,在 AI 时代,写代码去实现需求这件事变得成本不高了,工程上更多聚焦于怎么验收、怎么 Review、怎么提高效能和质量上了。 - 这个英语学习助手 Demo 的 UI Design,按照经验,Claude Design 还是香,也可以使用 Open Design 但要用 Claude 模型,Codex 可以使用
image2生成图后转 UI 或者直接落地代码,但可修改性上不太够。