端侧自主构建这件事我从去年下半年开始断断续续折腾了好几轮。最早的想法很简单能不能让一台普通笔记本在完全不依赖云端算力的前提下自己把一个中等复杂度的 Web 应用从一句自然语言需求一路做到可访问的交付状态。中间试过纯脚本编排、试过把大模型塞进本地推理框架、也试过让 agent 自己写测试自己跑踩的坑比想象中多得多。直到最近这一版跑通一个带用户体系、数据持久化、前后端分离的中等复杂度应用从需求输入到部署测试完成实测稳定在 12 分钟左右。这篇文章就把这套端侧自主构建的完整链路拆开讲清楚包括为什么这么设计、每一步在干什么、哪些地方最容易翻车以及怎么让后端部署不占用本地电脑空间这个很多人关心的问题。1. 端侧自主构建到底在解决什么问题1.1 从辅助写代码到自主交付的分界线大多数人现在用 AI 写代码模式还是对话式的你问一句它答一段你来复制粘贴、你来跑、你来修。这个模式的天花板很明显——它省的是打字时间不是工程时间。一个中等复杂度的应用真正耗时的从来不是敲代码而是需求拆解、技术选型、接口对齐、环境配置、部署调试这一整条链路。端侧自主构建要跨过的分界线就是让 agent 自己走完这条链路。你只给一句自然语言需求比如做一个带登录、能发帖、能评论的论坛数据要持久化剩下的需求结构化、技术栈选择、代码生成、依赖安装、本地起服务、自动化测试、部署上线全部由 agent 在本地闭环完成。这里的关键词是闭环——不是生成一堆代码让你自己跑而是它自己跑通、自己验证、自己交付一个能访问的地址。我一开始也怀疑端侧算力够不够。实测下来中等复杂度应用的代码生成量大概在几千行级别本地推理框架跑量化后的模型完全扛得住瓶颈不在生成而在编排和验证环节。这也是为什么端侧这两个字很重要数据不出本机构建过程不依赖网络往返延迟可控隐私可控。1.2 中等复杂度应用的界定标准什么叫中等复杂度这个必须说清楚否则 12 分钟这个数字没有意义。我自己的界定标准是三条同时满足有用户体系包含注册、登录、会话保持有至少两张核心业务表且存在关联关系前后端分离前端有至少三个页面后端有至少六个接口低于这个标准的算简单应用比如纯静态页、单表 CRUD那种几分钟就能搞定没有讨论价值。高于这个标准的算复杂应用涉及微服务、消息队列、分布式事务端侧单机跑起来会很吃力也不在本文范围内。我这次实测的样本是一个论坛类应用用户注册登录、发帖、评论、帖子列表分页、帖子详情。技术栈是前端 React Vite后端 Node.js Express数据库 SQLite端侧场景下 SQLite 比 MySQL 更合适后面会讲原因。整个应用从需求输入到部署测试完成12 分 07 秒。1.3 为什么端侧自主构建值得认真对待有人会问云端 agent 不是更强吗为什么要折腾端侧。我的理由有三个都是实操中体会出来的。第一是迭代速度。端侧没有网络往返agent 生成代码、跑测试、看报错、改代码这个循环可以压到秒级。云端方案每次调用都要等响应一个应用几十轮迭代下来光等待时间就够呛。第二是环境一致性。端侧构建出来的东西跑在你自己机器上依赖版本、系统环境都是确定的。云端构建完再拉回本地经常出现云端能跑本地跑不了的经典问题。第三是数据边界。需求描述、业务逻辑、甚至测试数据都在本机对于涉及内部业务的应用来说这个边界很重要。提示端侧自主构建不是要替代云端方案而是覆盖一个特定场景——快速把想法变成可运行、可验证的交付物。它的优势在速度和闭环不在极限能力。2. 12 分钟链路拆解每个阶段在干什么2.1 需求结构化把一句话变成可执行的规格自然语言需求最大的问题是模糊。做一个论坛这句话里藏着几十个未定义的决策点要不要登录、登录用什么方式、帖子要不要分类、评论要不要支持回复、分页每页几条。agent 第一步要做的不是写代码而是把这些决策点补全成一份结构化规格。我这一版用的是需求补全 确认两段式。agent 先根据需求生成一份规格草案包含数据模型、接口清单、页面清单然后自己检查有没有遗漏的必选项。这里有个经验不要让 agent 无限追问用户端侧自主构建的核心价值就是少打扰人。我的做法是给 agent 一套默认决策规则比如用户体系默认用邮箱加密码分页默认每页 10 条评论默认支持一级回复遇到规则覆盖不到的地方才标记为待确认。实测这一步耗时约 40 秒。规格草案大概长这样{ entities: [ {name: User, fields: [id, email, password_hash, created_at]}, {name: Post, fields: [id, user_id, title, content, created_at]}, {name: Comment, fields: [id, post_id, user_id, content, created_at]} ], apis: [ POST /api/auth/register, POST /api/auth/login, GET /api/posts?page1, POST /api/posts, GET /api/posts/:id, POST /api/posts/:id/comments ], pages: [登录页, 帖子列表页, 帖子详情页] }这份规格是整个构建的契约。后面所有代码生成、测试用例生成都基于它所以规格的质量直接决定最终交付的质量。我的经验是规格阶段多花 10 秒后面能省好几分钟的返工。2.2 技术栈决策为什么端侧场景偏爱轻量组合技术栈选择这一步agent 需要根据规格自动决策。我给它预设的决策逻辑是这样的维度端侧优选原因前端框架React Vite生态成熟agent 训练数据充分生成质量稳定后端框架Express轻量启动快依赖少端侧安装成本低数据库SQLite零配置单文件不占后台进程适合端侧测试框架Vitest Supertest与 Vite 同源配置简单接口测试友好这里重点说数据库为什么选 SQLite 而不是 MySQL 或 PostgreSQL。端侧场景下数据库要满足三个条件不需要独立服务进程、不需要额外配置、数据文件可迁移。SQLite 三条全中。MySQL 要起服务、要配用户权限、要占内存在端侧自主构建这个场景里是负担。有人担心 SQLite 并发能力但中等复杂度应用的测试阶段并发量极低完全够用。技术栈决策耗时约 15 秒基本是查表式的不需要复杂推理。2.3 代码生成分模块生成而不是一次性生成这是整个链路里最耗时也最容易出问题的环节。我试过让 agent 一次性生成整个应用结果经常是前面生成的接口和后面生成的前端对不上字段名不一致、路径不一致、返回结构不一致。后来改成分模块生成 接口契约校验稳定性大幅提升。具体做法是按依赖顺序生成先生成数据模型和数据库初始化脚本再生成后端接口每生成一个就对照规格校验路径、方法、字段然后生成前端页面每个页面调用的接口必须在已生成的后端接口列表里最后生成测试用例覆盖规格里的每个接口和每个页面这个顺序不能乱。数据模型是地基接口是骨架前端是皮肤测试是验收。跳过任何一步都会在后面付出代价。代码生成阶段耗时约 5 分钟是整个链路的大头。这里有个实操心得生成时让 agent 同时输出文件路径和文件内容而不是先规划目录再填内容。前者一次成型后者容易在目录结构上反复调整。2.4 依赖安装与本地起服务代码生成完agent 要自己装依赖、起服务。这一步看起来简单实际是坑最多的地方。依赖安装的坑主要在版本冲突。比如 React 18 和某些 UI 库的 peer dependency 冲突npm 会报错。我的处理方式是让 agent 在遇到安装错误时自动读取错误信息判断是版本问题还是网络问题版本问题就调整版本号重试网络问题就切换镜像源重试。这个重试逻辑我设了最多 3 次超过就标记失败让人介入。起服务的坑在端口占用和启动时序。后端要先于前端启动因为前端构建时可能需要访问后端接口做类型生成。我的做法是给后端固定端口 3001前端固定 5173启动前先检测端口是否被占用占用就杀掉旧进程。启动后轮询健康检查接口确认服务真的起来了再进入下一步。这一步耗时约 1 分 30 秒其中依赖安装占大头。2.5 自动化测试与部署交付测试环节是端侧自主构建区别于生成代码的关键。agent 要自己跑测试、自己看结果、自己修。我的测试策略分三层接口测试用 Supertest 跑每个后端接口验证状态码和返回结构集成测试模拟完整用户流程注册→登录→发帖→评论→查列表冒烟测试前端页面能否正常加载关键元素是否存在测试失败时agent 要能定位是哪个环节的问题。这里我给它加了一个约束每次只修一个问题修完重跑全部测试。因为多个问题一起修容易互相干扰而且无法判断哪个修改真正生效。测试通过后进入部署环节。端侧部署的目标是让应用可访问同时不占用本地电脑空间。这一步我单独用一节讲因为这是很多人关心的痛点。整个测试加部署耗时约 4 分钟。3. 后端部署不占本地空间的几种做法3.1 为什么不占本地空间是个真需求很多人做完一个 Web 应用测试也通过了卡在最后一步怎么让它在不占用自己电脑的情况下持续可访问。本地起个服务电脑一关就没了电脑开着内存和 CPU 一直被占着数据文件还在本地磁盘上堆着。这个需求在端侧自主构建场景下尤其突出因为构建过程本身就在本地如果交付物也赖在本地那交付两个字就名不副实。我梳理了几种做法各有适用场景下面逐个说。3.2 方案一构建产物打包部署到独立运行环境这是最正统的做法。agent 在本地完成构建和测试后把产物打包成一个可部署单元推送到一个独立的运行环境。这个运行环境可以是另一台机器、一个容器平台、或者一个托管服务。关键点是构建在本地运行在别处。本地只负责生成和验证不负责长期运行。这样本地空间只在构建期间被占用构建完清理掉临时文件即可。具体操作上agent 需要做几件事把后端代码和依赖清单打包生成一个可独立运行的目录把前端构建产物dist 目录打包生成部署脚本包含环境变量配置、启动命令、健康检查推送到目标环境并启动这个方案的优点是干净、可复现、本地零残留。缺点是需要一个目标环境不是所有人都现成有。3.3 方案二容器化后推送到镜像仓库如果目标环境支持容器容器化是更省心的做法。agent 生成 Dockerfile本地构建镜像推送到镜像仓库目标环境拉取运行。Dockerfile 的生成有几个要点FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --production COPY . . EXPOSE 3001 CMD [node, server.js]这里用npm ci而不是npm install因为 ci 严格按 lock 文件安装可复现性更好。用 alpine 基础镜像是因为体积小推送快。容器化的好处是环境完全隔离本地不需要装任何运行时依赖构建完把镜像推走本地镜像也可以删掉。数据持久化用挂载卷数据存在目标环境不占本地。3.4 方案三静态前端 托管后端接口如果应用的前端是纯静态的后端接口也不复杂可以拆开部署。前端构建产物是纯静态文件可以直接托管到静态托管服务几乎不占任何运行资源。后端接口部署到轻量运行环境。这个方案适合前端重、后端轻的应用。我实测的论坛应用就适合这种拆法前端三个页面全是静态资源后端六个接口逻辑简单拆开后前端托管成本几乎为零后端运行环境也很轻。拆开部署时要注意跨域配置。前端托管域名和后端接口域名不同需要在后端配置 CORS允许前端域名访问。这个配置 agent 要自动生成不能让人手动改。3.5 方案四构建完即清理按需重建如果应用只是阶段性验证不需要长期在线最省空间的做法是构建完验证通过后把产物归档本地清理需要时再重建。这个方案的关键是构建过程要可复现。只要规格和代码在版本控制里任何时候都能重建出一模一样的应用。归档时只存源码和规格不存依赖和构建产物空间占用极小。我自己的做法是每个项目构建完把源码和规格提交到本地 git 仓库然后删掉 node_modules 和构建产物。一个中等复杂度应用的源码加规格压缩后也就几百 KB。3.6 四种方案的对比与选择建议方案本地空间占用持续可访问适用场景打包部署到独立环境构建期占用之后为零是有目标环境需要长期运行容器化推送镜像构建期占用镜像可删是目标环境支持容器静态前端 托管后端几乎为零是前端重后端轻构建完清理按需重建仅源码否阶段性验证我的建议是如果只是验证想法用方案四如果要给别人访问用方案一或方案三如果目标环境是容器平台用方案二。端侧自主构建的 agent 应该能根据部署目标自动选择方案而不是固定一种。4. 实测中踩过的坑与排查链路4.1 接口字段不一致最隐蔽也最致命这个坑我踩了不止一次。表现是前端调接口报 400 或拿不到数据但后端日志看起来正常。排查了半天才发现前端传的是userName后端收的是username大小写差一个字母。根因是代码生成时前后端分开生成没有共享字段定义。修复方式是在规格里定义字段名生成时强制引用规格而不是各自命名。我后来加了一个校验步骤生成完前后端代码后自动扫描前端调用的接口字段和后端接收的字段做一致性比对不一致就报错。这个校验步骤加进去之后字段不一致的问题基本绝迹。排查链路是这样的前端报错看 Network 面板确认请求体和响应体对比请求体字段和后端接口定义不一致则定位到生成环节检查规格引用修复规格或生成逻辑重新生成4.2 依赖版本冲突npm 报错信息要会读依赖安装失败是高频问题。npm 的报错信息其实很详细但很多人不看直接换版本号瞎试。我的经验是npm 报错里会明确写peer dep missing还是version conflict前者是缺依赖后者是版本不兼容。处理逻辑peer dep missing安装缺失的 peer dependencyversion conflict找到冲突的两个包看哪个是直接依赖调整直接依赖的版本ETIMEDOUT或ECONNREFUSED网络问题切换镜像源我让 agent 按这个逻辑自动处理成功率大概八成。剩下两成是复杂冲突需要人工介入但这种情况不多。4.3 端口占用与启动时序服务没起来就测试这个坑的表现是测试全部失败报连接拒绝。排查发现是后端服务还没起来测试就开始了。根因是启动命令是异步的agent 发完启动命令就往下走了。修复方式是加健康检查轮询启动后每隔 500 毫秒请求一次健康检查接口连续三次成功才认为服务就绪最多等 30 秒。这个逻辑看起来简单但很关键。没有健康检查整个测试环节的结果都不可信。4.4 测试用例覆盖不全通过不等于正确有一次测试全绿我以为搞定了结果手动一测发现评论功能根本没生效。排查发现测试用例只测了接口返回 200没验证数据真的写进去了。根因是测试用例生成时只关注了接口能调通没关注业务逻辑正确。修复方式是让测试用例生成时每个写操作后面跟一个读操作验证。比如发帖接口测试发完帖要查列表确认帖子在里面。这个改动让测试用例数量翻倍但测试的可信度完全不同了。测试通过不等于功能正确这是端侧自主构建里最容易被忽视的一点。4.5 部署后环境变量丢失本地能跑线上不能跑部署到独立环境后应用起不来报数据库连接失败。排查发现是本地用的 SQLite 文件路径是相对路径部署后工作目录变了路径找不到。根因是环境相关的配置硬编码在代码里。修复方式是把所有环境相关配置抽到环境变量代码里只读环境变量不写死值。agent 生成代码时要自动识别哪些是环境相关配置抽出来。这个坑的教训是本地能跑不代表部署能跑环境差异要在构建阶段就消除。5. 让 12 分钟稳定复现的几个关键设计5.1 规格先行所有生成都引用同一份契约12 分钟能跑完核心原因是返工少。返工少的原因是规格先行。所有代码生成、测试生成都引用同一份规格字段名、接口路径、返回结构全部统一从源头消除了不一致。我的做法是规格生成后先做一次自检检查实体关系是否完整、接口是否覆盖所有页面需求、字段类型是否明确。自检通过才进入代码生成。这一步多花 20 秒能省后面几分钟的调试。5.2 分阶段验证每阶段结束就验证不攒到最后不要等所有代码生成完再测试那样出问题很难定位。我的做法是每个阶段结束就做一次轻量验证数据模型生成后跑一次建表脚本确认能建表后端接口生成后跑一次接口冒烟测试前端页面生成后跑一次构建确认能构建成功全部生成后跑完整测试分阶段验证的好处是问题早发现、早定位。数据模型的问题不会拖到前端才暴露。5.3 失败重试与人工介入的边界agent 自主构建不可能 100% 自动关键是定义好什么情况重试、什么情况找人。我的规则是网络类错误自动重试最多 3 次版本冲突自动调整版本重试最多 2 次测试失败自动修复重试最多 3 次超过重试次数暂停输出详细上下文等人介入这个边界很重要。没有边界agent 会陷入无限重试边界太窄一点小问题就找人失去自主的意义。5.4 时间预算分配把时间花在验证上12 分钟的时间分配大致是需求结构化 40 秒技术栈决策 15 秒代码生成 5 分钟依赖安装与起服务 1 分 30 秒测试与部署 4 分钟。可以看到验证相关的时间占了将近一半。这个分配是刻意的。生成快不代表交付快交付快靠的是验证充分、返工少。我试过压缩验证时间结果返工时间翻倍总时长反而更长。提示端侧自主构建的优化方向不是让生成更快而是让验证更准。验证准了一次通过总时长自然短。6. 这套方法还能往哪些方向延伸6.1 从 Web 应用延伸到其他交付形态目前跑通的是 Web 应用但同样的链路可以延伸到其他形态。比如命令行工具、数据处理脚本、简单的桌面应用。核心链路是一样的需求结构化、技术选型、代码生成、测试验证、交付。区别只在技术栈和验证方式。我下一步想试的是数据处理类应用输入是一份数据规格输出是一个能跑的数据处理管道。这类应用的验证更依赖数据正确性测试策略要调整。6.2 多应用批量构建的可能性单应用 12 分钟如果批量构建多个应用能不能并行。理论上可以因为每个应用的构建是独立的。但端侧资源有限并行会争抢 CPU 和内存实际提速可能不明显。我的想法是串行构建但把公共依赖缓存起来第二个应用开始依赖安装时间大幅缩短。6.3 构建产物的版本管理每个应用构建完产物怎么管理是个问题。我的做法是源码进 git构建产物不进。因为构建产物可复现没必要存。但规格要进 git因为规格是源头。这样每个应用的历史版本都能追溯也能随时重建。6.4 人工介入点的最小化现在还有大概两成的情况需要人工介入主要是复杂依赖冲突和测试修复失败。我的目标是把这个比例降到一成以下。方向是给 agent 更多的修复策略比如依赖冲突时尝试降级、测试失败时尝试回滚到上一个可用版本。这些策略需要慢慢积累不是一蹴而就的。我在实际使用中最大的体会是端侧自主构建的价值不在于全自动而在于闭环快。哪怕中间需要人工介入一两次只要整个链路是通的、可复现的效率提升就是实打实的。12 分钟这个数字不是终点随着验证策略和修复策略的积累它还会往下走。但比数字更重要的是这套方法让从想法到可验证交付这件事变得足够轻轻到你愿意为一个小想法真的动手去做而不是想想就算了。