AAIPROS

AIPROS · Static Essay Page

非技术人员,5天从零构建全栈AI平台——我的AI Coding实战复盘

Agent治理 公众号文章 2026-05-04 15 min

4月29号晚上11点半,我第一次用 git init 初始化了 skill-platform 这个项目。

4月29号晚上11点半,我第一次用 git init 初始化了 skill-platform 这个项目。

5月3号下午,92次提交之后,项目正式上线。前端部署在 Cloudflare Pages,后端跑在 Railway,Python Agent Runtime 跑在 Docker 容器里。140个源文件,24000行代码。Dashboard、Skill 市场、智能体对话、知识库、权限管理——一个完整的 AI 技能管理平台。

我是一个产品经理,不是程序员。不会写 TypeScript,不会写 Python,不会配 Docker。五年前的工作是画流程图和写 PRD。

但这五天里,我经历了从零到上线的完整软件工程周期:需求定义、技术选型、架构设计、前后端开发、联调、部署、502 崩溃排查、权限重构、移动端适配。每一个环节都是 AI 在写代码,但每一个决策都是我在做。

这篇文章,我想把整个过程拆开来讲。不是讲感受,是讲方法。讲一个非技术人员怎么用 AI coding 完成一个全栈项目,讲中间踩了哪些坑、省了哪些钱、做对了什么、做错了什么。如果你也想试,希望你能从这篇文章里找到一条可复制的路径。

一、先交代背景:为什么是我在做这件事

我的职业背景是 AI 产品经理 + 流程管理专家。日常做的是产品规划、需求分析、业务流程设计。写代码这件事,从来不在我的工作范围里。

但我一直有个执念:一个做 AI 产品的人,如果自己不会用 AI 把想法变成产品,那对 AI 的理解永远是二手的。你评审过再多技术方案,面试过再多工程师,自己没下过场,很多东西就是理解不了。

所以 skill-platform 这个项目,本质上是一次"下场验证"。验证的核心命题是: 一个非技术人员,借助 AI coding 工具,能不能独立完成一个专业级的全栈产品?

答案是能。但过程远比想象中曲折。

二、产品定义:我想做一个什么东西

Skill Platform(中文名:詹老师的智能体平台)是一个 AI 技能管理与智能体运行平台。简单说,它解决的问题是: 怎么让 AI 从"能聊天"变成"能干活"。

核心功能模块:

1. Skill 管理 —— AI 技能的创建、版本管理、市场分发。每个 Skill 可以理解为一个"AI 能力包",包含提示词、执行配置、API 对接方式等。

2. 智能体(Agent)管理 —— 创建对话式 AI 智能体,绑定不同的 Skill,用户通过聊天的方式调用技能。

3. Deep Agent 运行时 —— 一个 Python 写的 Agent Runtime,内置 8 类工具:文档生成(Word/Excel/PPT)、代码执行、互联网搜索、数据分析、图表生成等。这是让 AI "能干活"的核心引擎。

4. 知识库 —— 上传文档、自动解析,为智能体提供领域知识。

5. 权限体系 —— 访客/注册用户/管理员三层角色,登录弹窗而非独立页面,降低使用门槛。

三、技术架构:三层分离,各司其职

这是我做的第一个关键决策。作为一个产品经理,我本能地选择了"分层架构"——因为这就是业务流程设计的思路:每一层做好自己的事,层与层之间通过标准接口通信。

整个系统分三层:

前端层(Frontend)

技术栈:React 18 + Vite 5 + Ant Design 5 + Zustand(状态管理)+ React Router v6

部署:Cloudflare Pages(全球 CDN,免费额度充足)

代码量:约 40 个文件,涵盖 Dashboard、Skill 市场、智能体对话、知识库、用户管理等页面

后端层(Backend)

技术栈:NestJS 10 + TypeORM + better-sqlite3 + JWT 认证

部署:Railway(支持 Docker 构建,自动 HTTPS)

代码量:约 80 个文件,包含 13 个 Entity、完整的 REST API、Swagger 文档

Agent 运行时层(Agent Runtime)

技术栈:Python FastAPI + LangChain + LangGraph + 阿里云百炼 SDK

部署:Docker 容器(与后端合并部署,共用一个 Railway 服务)

代码量:约 20 个文件,包含 8 类内置工具(共 11 个工具文件)

为什么选这个架构?三个原因:

第一,前后端分离是现在的主流范式,教程多、资料全,AI 写代码的时候不容易犯架构级错误。第二,SQLite 作为数据库不需要额外部署数据库服务,省掉了一大块运维成本。第三,Python Agent Runtime 独立部署,和 Node.js 后端通过 HTTP 通信,语言栈不耦合,后续可以独立升级。

这些决策不是我当时就能想清楚的。是 AI 在我描述需求的时候,给出了这个方案,我根据自己的产品经验判断它合理,就采纳了。

四、Token 成本策略:该省省,该花花

这是我觉得最值得分享的经验之一。

很多人觉得用 AI coding 做项目,Token 费用是个无底洞。但实际上,只要你掌握一个原则—— 用对的模型做对的事 ——成本完全可以控制。

4.1 前端开发阶段:用便宜模型就够了

前端页面的开发,大部分工作是"把设计稿变成代码"。React 组件、Ant Design 样式、路由配置——这些任务的复杂度是相对固定的,不需要最强的推理能力。

我在构建前端页面的时候,用的是相对便宜的模型(比如 GPT-4o-mini 级别或 Claude Sonnet 级别)。一个 Dashboard 页面,一轮对话就能出来 80% 的骨架。然后微调样式、调整布局,几轮交互就完成了。

这个阶段的 Token 消耗特点是:单次对话不长(几百行代码),但对话轮次多(每个页面 5-10 轮)。所以便宜的模型在成本上优势很大——大概是一个零头的价格。

4.2 后端架构和 Agent 设计:该用贵的就用贵的

真正需要强模型的是后端架构设计和 Agent Runtime 的实现。这些涉及:

数据库 Schema 设计(13 个 Entity,关联关系复杂)

TypeORM 的 synchronize 机制和 migration 策略

JWT 认证 + Passport 守卫的完整实现

流式响应(SSE)的前后端联调

这些任务的共同特点是:逻辑链长、边界条件多、一个错误会导致整个系统崩溃。用强模型(Claude Opus / GPT-4 级别),虽然单次 Token 成本是便宜模型的 5-10 倍,但减少的调试轮次远超这个差价。

我做过一个对比:后端的 AI Service(核心对话逻辑),用便宜模型写了三版,每版都有不同的 bug——第一版返回格式不对,第二版流式输出断开,第三版 Function Calling 的 JSON 解析失败。换成强模型,一版通过。

4.3 调试排障阶段:强模型是刚需

项目上线后遇到 502 崩溃。后端日志显示 TypeORM 在 synchronize 时因为 phone 字段的 NOT NULL 约束报错。这种问题的根因分析,需要 AI 理解 TypeORM 的 synchronize 机制、SQLite 的 ALTER TABLE 限制、以及 Entity 定义和数据库实际表结构之间的差异。这不是便宜模型能搞定的事。

用强模型,一轮对话就定位到了问题:phone 字段在 Entity 里没有标记 nullable,但数据库里已有的记录 phone 为空。解决方案是在 Entity 里加一行 @Column({ nullable: true })。一个字的修改,但需要理解整个上下文才能找到。

4.4 我的 Token 成本估算

整个项目下来,Token 费用大约在 200-400 元人民币。其中:

前端开发(占代码量 40%):约 50 元,大部分用便宜模型

后端开发(占代码量 35%):约 150 元,大部分用贵模型

Agent Runtime(占代码量 15%):约 80 元,全部用贵模型

调试排障(占时间 30%):约 70 元,全部用贵模型

部署和配置(占时间 15%):约 50 元,混合使用

如果全程用最贵的模型,成本会翻 3-4 倍。如果全程用最便宜的模型,开发周期可能要翻 2 倍(因为调试轮次暴增)。所以 核心策略就是:前端用便宜模型快速出活,后端和调试用强模型一次搞定。

五、开发时间线:92 次提交的真实节奏

整个项目从初始化到上线,Git 记录了 92 次提交。我把关键节点梳理出来:

Day 0 · 4月29日 · 深夜

git init。项目初始化,第一次提交。前端骨架搭建(React + Vite + Ant Design)。

Day 1 · 4月30日

前端核心页面开发:Dashboard、Skill List、Skill 创建、Skill 详情页。后端初始化:NestJS + TypeORM + SQLite,13 个 Entity 定义。第一次 Railway 部署尝试。

Day 2 · 5月1日

功能裁剪:移除组织架构、架构管理、评审管理、租户管理等非核心模块。登录功能降级——移除强制登录,实现免登录访问。前后端首次联调成功。

Day 3 · 5月2日

Agent Runtime 开发:Python FastAPI 服务,8 类工具实现。Dockerfile 编写和调试。Railway 部署——502 崩溃排查。phone 字段 nullable 修复。

Day 4 · 5月3日

权限系统重构:三层角色模型(访客/用户/管理员)。Agent Runtime 独立部署配置。Chat streaming 502 异常修复。Skill 三级级联筛选。最终上线验证。

六、踩过的坑:每个都是一整个下午换来的

坑 1:环境变量编译成字面量

前端用的是 Vite,环境变量通过 import.meta.env.VITE_API_URL 注入。问题在于,Vite 在 build 时会把环境变量直接替换成字符串字面量。如果构建时没有正确设置环境变量,线上代码里就会写着 http://localhost:3000。

第一次部署后,前端所有的 API 请求都打到了 localhost。解决方案:删除 .env.production 文件,改为在构建命令中注入: VITE_API_URL=https://xxx.railway.app vite build。

这个坑的教训是: Vite 的环境变量不是"运行时读取"的,而是"构建时替换"的。理解这个机制,就能避免一整类部署问题。

坑 2:TypeORM synchronize 导致 502 崩溃

这是最让人崩溃的一个 bug。现象是:后端服务启动后,一切正常。过一会儿,所有 API 返回 502。

排查了半天,发现是 TypeORM 的 synchronize: true 配置。每次服务启动,TypeORM 会自动对比 Entity 定义和数据库表结构,如果有差异就执行 ALTER TABLE。但 SQLite 对 ALTER TABLE 的支持有限——它不能直接给已有列添加 NOT NULL 约束。而 phone 字段在 Entity 里没有标记 nullable: true,TypeORM 尝试同步时就崩了。

修复方式:在 Entity 里加 @Column({ nullable: true })。一行代码。但找到这一行代码,花了整个下午。

坑 3:Docker 基础镜像选错

后端用了 better-sqlite3,这是一个需要编译原生模块的库。最初用的 Docker 基础镜像是 node:20-alpine,Alpine Linux 缺少编译工具链,导致 npm install 失败。

中间试过在 Alpine 里手动安装 build-base python3,但编译出来的二进制文件在 Alpine 的 musl libc 下又和 better-sqlite3 不兼容。

最终方案:换成 node:20-slim (基于 Debian),天然支持原生模块编译。Dockerfile 从 30 行简化到 15 行。

教训: 如果你的 Node.js 项目依赖原生模块,不要用 Alpine 镜像。slim 镜像虽然大一点,但省去了无数编译问题。

坑 4:Chat Streaming 的 502 异常

AI 对话功能用的是 Server-Sent Events(SSE)实现流式输出。问题是:当 AI 回复过程中出现错误(比如 API 超时),后端会 throw 异常。但此时 HTTP header 已经发送了(SSE 的特性),throw 会导致连接异常中断,前端收到的是 502 而不是正常的错误消息。

修复方式:在 catch 块里,用 SSE 的 event: error 格式发送错误消息,然后正常结束连接。这样前端能收到完整的错误信息,用户体验不会中断。

坑 5:前端 TypeScript 编译的未定义变量

AI 生成的组件代码里,偶尔会引用一些还没有定义的变量或类型。本地开发时因为 Vite 的 HMR(热更新),可能看不出来。但 build 的时候,TypeScript 编译器会严格检查,直接报错。

最典型的一次是 SkillList.tsx 组件里引用了 mockData,但这个变量只在开发时用过,后来删了忘了清理。解决方式是全局搜索引用,逐个修复。

教训: 每次 AI 生成代码后,立即跑一遍 build,不要积攒到最后一起解决。

坑 6:Railway 环境变量覆盖 Dockerfile ENV

在 Dockerfile 里设置了 ENV AGENT_RUNTIME_URL=http://agent-runtime:8001,但 Railway 的环境变量配置里有一个旧的值,Railway 会用环境变量覆盖 Dockerfile 的 ENV,导致后端找不到 Agent Runtime。

解决方案:在 Railway 的环境变量配置里,把 AGENT_RUNTIME_URL 设置为 http://localhost:8001 (因为 Agent Runtime 和后端在同一个 Docker 容器里运行)。

教训: Docker ENV 和 Railway 环境变量的优先级关系要搞清楚。平台的环境变量永远优先于 Dockerfile 的 ENV。

七、架构决策回顾:做对了什么,做错了什么

做对了的

1. 先做减法,再做加法。

最初的产品规划里,有组织架构管理、架构树编辑、流程画布、评审系统、租户管理——非常完整。但到了第二天,我果断砍掉了这些模块,只保留 Skill 管理、智能体对话、知识库、Dashboard 这四个核心。

原因很简单:作为一个验证项目,砍掉非核心功能,意味着减少 50% 的代码量和 70% 的联调复杂度。上线比完美重要。

2. 登录降级策略。

最初设计了完整的登录系统(JWT + Passport 守卫),但上线后发现:没有用户基础的时候,强制登录只会劝退访客。所以我做了降级——移除强制登录,改为弹窗提示。访客可以浏览所有功能,只有创建和编辑操作需要登录。

这个决策来自产品经验:先让人用起来,再设计门槛。

3. SQLite 而不是 PostgreSQL。

作为一个验证项目,SQLite 是最优选择。零配置、零运维、文件级存储、数据随代码走。Railway 部署时只需要一个 volume 挂载,不需要额外的数据库服务。

如果后续需要迁移到 PostgreSQL,TypeORM 的抽象层让迁移成本很低——改一下连接配置就行。

4. 三层角色模型。

访客(可浏览)、注册用户(可创建)、管理员(全权限)。这个设计刚好覆盖了平台的运营需求,又不会过度设计。

做错了的

1. Dockerfile.combined 的反复折腾。

最初想用一个 Dockerfile 同时部署后端和 Agent Runtime(supervisor 管理两个进程)。但 Docker 里跑多进程是个坑——日志管理、进程崩溃恢复、端口冲突,每一个都是问题。

最后回退到简单方案:后端和 Agent Runtime 各自独立部署。虽然多了一个服务,但稳定性和可维护性都好很多。

2. 前端移动端适配做得太晚。

最初所有页面都按桌面端设计,到上线前一天才做移动端适配。如果一开始就用移动优先(Mobile First)的设计思路,很多布局问题就不会出现。

八、Deep Agent 工具链:AI 从"聊天"到"干活"的关键

这是整个项目里最有技术含量的部分。

普通的 AI 聊天,就是一问一答。但 Skill Platform 的目标是让 AI 真正"干活"——生成文档、搜索互联网、执行代码、分析数据。这就需要一个工具调用机制:Function Calling。

8.1 工具架构

Agent Runtime 内置了 8 类工具:

文档生成工具(document_generator.py)

支持生成 Word、Excel、PowerPoint 文档。用 python-docx、openpyxl、python-pptx 实现。用户说"帮我生成一份项目报告",AI 就能生成一份 .docx 文件并提供下载链接。

代码执行工具(code_exec.py)

在沙箱中执行 Python 代码。用 subprocess 隔离运行,限制执行时间,防止恶意代码。

互联网搜索工具(web_search.py)

用 DuckDuckGo Search API 搜索互联网。AI 可以实时获取信息,而不是只依赖训练数据。

数据分析工具(data_tools.py)

用 Pandas 处理结构化数据,支持统计分析、数据清洗。

图表生成工具(media_tools.py)

用 Matplotlib 生成各类图表,输出为 PNG 图片。

文件操作工具(file_ops.py)

读写文件、管理临时文件、处理上传下载。

知识库工具(knowledge_tools.py)

检索知识库中的相关文档,为 AI 提供领域知识。

网络抓取工具(web_scrape.py)

用 BeautifulSoup 抓取网页内容,提取正文。

8.2 Function Calling 循环

核心机制是"循环调用":

第 1 步:用户发消息。

第 2 步:AI 分析意图,决定是否需要调用工具。

第 3 步:如果需要,生成工具调用参数(JSON 格式),后端执行工具。

第 4 步:把工具执行结果返回给 AI。

第 5 步:AI 继续分析,决定是继续调工具还是直接回答。

第 6 步:循环直到 AI 给出最终回复。

这个循环最多跑 10 轮,防止无限循环。

九、部署实战:从本地到线上

9.1 部署架构

前端 → Cloudflare Pages

Cloudflare Pages 的优势:免费额度大、全球 CDN、自动 HTTPS、支持 GitHub 仓库自动构建。前端 build 出来的静态文件,推到 GitHub 后自动触发部署。

后端 → Railway

Railway 支持 Docker 构建、自动 HTTPS、环境变量管理。后端代码推到 GitHub 后,Railway 自动拉取、构建、部署。

Agent Runtime → Docker 容器(与后端合并)

最初想独立部署,但两个服务之间的网络配置比较麻烦(Railway 的内部网络需要额外配置)。最终选择合并部署——在一个 Dockerfile 里同时启动 Node.js 后端和 Python Agent Runtime。

9.2 部署踩坑清单

Cloudflare Pages 的坑:

首次部署前需要先在 Cloudflare 上创建项目,否则 CLI 部署会报错

构建命令要写对: npm run build,输出目录是 dist

环境变量要在 Cloudflare 的项目设置里配置,不能只写在本地 .env 文件里

Railway 的坑:

Railway 不需要安装 CLI,直接通过 GitHub 集成部署

环境变量的优先级:Railway 设置的 > Dockerfile ENV 的

构建日志要认真看——很多部署失败的原因藏在日志中间,不是最后一行

Alpine 镜像的原生模块编译问题,前面已经讲过

十、AI Coding 的方法论:给后来者的建议

五天下来,我总结了七条方法论。这些不是理论,是每一次报错、每一次崩溃、每一次"为什么又不工作了"之后提炼出来的。

1. 先想清楚产品,再让 AI 写代码

AI coding 最常见的失败模式是:没有产品定义,上来就让 AI 写代码。结果写了一堆功能,但拼不成一个产品。

我的做法是:先花半天时间把功能树画出来。哪些是核心功能,哪些是锦上添花,哪些是以后再说。这个功能树不需要很专业——我用的是 XMind 格式,但纸笔画也行。

有了功能树,AI 就有了边界。它知道哪些功能该做、哪些不该做。这比"你帮我做一个智能体平台"这种模糊描述,效率高 10 倍。

2. 分阶段交付,每个阶段都要能跑

不要一口气让 AI 把所有功能都写完。我的节奏是:

Day 0:项目骨架 + 首页能跑

Day 1:核心 CRUD 功能能跑

Day 2:联调通过 + 功能裁剪

Day 3:高级功能(Agent Runtime)能跑

Day 4:部署上线 + 修复

每个阶段结束时,项目都是"可运行"的状态。这样即使后续出问题,也可以回退到上一个稳定状态。

3. 描述需求时,用"给实习生讲需求"的方式

AI coding 的核心能力是理解自然语言。但"理解"不等于"猜对"。你说"做一个好看的登录页",AI 能做出来,但大概率不是你想要的。

更好的方式是像给实习生讲需求一样:具体、有参照、有边界。"做一个登录页,左边是品牌 Logo 和标语,右边是登录表单,支持 和密码登录。风格参考 Notion 的登录页——简洁、留白多、黑白灰为主色。"

描述越具体,AI 的输出越接近预期。修改轮次越少,Token 费用越低。

4. 代码审查:你不需要看懂每一行,但要看懂每一块

非技术人员做 AI coding,最大的心理障碍是"代码看不懂"。

实际上,你不需要看懂每一行代码。你需要看懂的是"每一块代码在做什么"。方法很简单:让 AI 给你解释。每次它写完一个模块,你说"解释一下这段代码的思路",它会用自然语言给你讲。

你能理解的部分,验证它是否符合你的需求。你不能理解的部分,跑一遍看效果。效果对了就过,效果不对就说清楚哪里不对。

5. 遇到报错,把完整错误信息给 AI

这是最省 Token 的调试方式。不要自己翻译错误信息,不要只截一段报错给 AI。把完整的错误日志(包括 stack trace)直接贴过去,让 AI 自己分析。

AI 从完整日志中定位问题的能力,远强于从你转述的片段中猜测。这不是偷懒,是效率最大化。

6. 一个问题的修改可能引发另一个问题

在 AI coding 过程中,最危险的不是单个 bug,而是连锁反应。你修复了一个 TypeScript 编译错误,结果引入了一个运行时类型不匹配。你修改了 Entity 定义,结果 TypeORM 的 synchronize 又出问题了。

应对方式: 每次修改后,立即跑 build + 冒烟测试。不要攒着一起改。每改一处,验证一处。这比一口气改 10 处然后花一整天排查要高效得多。

7. 部署不是最后一步,是贯穿全程的事

很多人的做法是:本地开发完成 → 部署。但部署本身就是一个复杂的工程环节。我的建议是:第一天就尝试部署,哪怕只部署一个空壳。部署成功了,后续每次提交都有线上验证。

如果最后才部署,你会发现一堆环境问题(环境变量、Docker 配置、网络、数据库),解决这些问题可能比开发本身还耗时。

十一、一些数字

代码量: 140 个源文件,24000 行代码(不含 node_modules 和 dist)

Git 提交: 92 次

开发周期: 5 天(4月29日 — 5月3日)

技术栈: React + NestJS + Python FastAPI + SQLite + Docker

部署服务: Railway(后端)+ Cloudflare Pages(前端)

Token 成本: 约 200-400 元人民币

截图数量: 288 张(开发过程中的每个关键节点都有截图记录)

核心模块: 5 个(Skill 管理、智能体管理、Agent Runtime、知识库、权限系统)

Agent 工具: 8 类(文档生成、代码执行、互联网搜索、数据分析、图表生成、文件操作、知识库检索、网页抓取)

十二、写在最后:AI Coding 改变的是什么

Anthropic 在 2026 年的 Agentic Coding 趋势报告里写了一句话:"编程能力正在民主化,非技术人员开始构建自己的工具。"我不是看了这份报告才开始的,但做完项目再看这段话,感受完全不同。

因为"民主化"不是一个抽象概念——它是实实在在的。一个产品经理,5 天时间,24000 行代码,一个上线运行的全栈平台。这在两年前是不可能的。

但我想说的是另一面。

AI coding 改变的不是"谁会写代码",而是 "谁有能力定义问题"。

在传统开发模式里,产品经理和程序员之间有一条清晰的边界:产品经理负责"做什么",程序员负责"怎么做"。这条边界的存在,是因为"怎么做"的门槛很高——你需要学编程语言、学框架、学部署、学调试。

AI coding 降低了"怎么做"的门槛,但它没有降低"做什么"的门槛。恰恰相反——当"怎么做"不再是瓶颈的时候,"做什么"变成了唯一的瓶颈。

你需要知道做出来的东西用户会不会用。你需要知道哪些功能该砍、哪些该留。你需要在 502 崩溃的时候判断是数据库的问题还是网络的问题。你需要在 Token 预算有限的时候决定哪里用便宜模型、哪里用贵模型。

这些判断力,不是 AI 能给你的。它来自你的产品经验、你的业务理解、你对用户需求的洞察。

所以,如果你也是一个非技术人员,想尝试 AI coding,我的建议是: 从一个你真正理解的问题开始。

不需要是一个宏大的 idea。一个你自己工作中的痛点、一个你每天重复的操作、一个你觉得"应该有工具但就是没有"的场景——这些就是最好的起点。因为你对问题的理解越深,AI 的输出质量就越高。

AI coding 不是一个让非技术人员变成程序员的技术。它是一个让每个人都能把自己的专业能力"代码化"的技术。你不需要学编程,你只需要知道自己想做什么。

剩下的,AI 会帮你。

— 全文完 —