
最近把一个移动端全栈项目完整跑了下来工具链核心是 Codex设计源头用的是 Relay。整个过程从设计师给的原型图开始到后端接口、移动端前端、联调优化、打包交付一条链路全部打通。这篇文章就把这条链路怎么搭、中间踩了哪些坑、哪些地方最值得注意原原本本写出来给同样打算用 AI 做全栈开发的人一个可直接抄作业的参考。先说结论用 Codex 做移动端全栈开发真正值钱的地方不是让 AI 一次性生成一堆代码而是学会把设计稿、业务逻辑、验收标准拆成 AI 能理解的任务再通过一段段小步验证把项目稳定地推到可交付状态。这不是“写个需求就能躺着收代码”的事反而对开发者的架构能力和排错能力要求更高。1. 为什么选 Codex Relay 这条链路做移动端全栈1.1 整体工作流从原型图到可交付项目这个项目的起点是一套完整的产品原型图用 Relay 产出。Relay 在做 UI 设计交付时非常方便它能把设计稿里的颜色、字号、间距、组件状态、交互逻辑这些信息一键导出成结构化说明设计师不用额外写文档开发者也不用对着设计稿反复量像素。传统的开发流程是设计稿出来前端对着切图标注重写页面后端对着接口文档单独开发再约联调。这个流程的问题在于信息损耗很大设计稿里的细节传到开发者手里往往已经丢了三四成。我们的链路变成了这样Relay 负责把设计稿转成结构化的设计规格说明包括页面布局、组件状态、交互行为、设计 token。Codex 负责读取这些说明结合项目上下文直接生成后端接口、数据模型和移动端页面。开发者在中间做的事情是拆解任务、组织上下文、验证产出、修复 AI 犯的错。这套流程跑通的标志不是我写代码的量变少了而是“从设计到可演示版本”的周期被压缩得非常明显。过去一个中等复杂度的移动端 H5 项目从设计稿到能演示顺利的话需要三到五天这次在一天半左右就拿到了包含真实数据的可运行版本。1.2 选型背后的三个理由和一次翻车教训选 Codex 而不是别的 AI 编程工具原因有几个。第一Codex 不是单纯的代码补全工具它是一个跑在终端里的 AI 智能体底层通过 Codex harness 在沙箱环境里执行任务。它能看到整个项目的文件结构可以自己跑命令、运行测试、检查代码输出发现问题还能自己修。这种能力非常适合全栈项目因为全栈开发里大量时间花在“写完代码——启动服务——看报错——修复——再试”的循环上而这个过程恰恰是 Codex 最擅长的。第二Codex 对多文件改动和跨层调用的理解比较靠谱。移动端全栈项目涉及前端页面、状态管理、API 请求、后端路由、数据库模型同一个功能要改动多个文件。让 Codex 理解这些文件之间的依赖关系比让它在单个文件里写函数要难得多这也是我一开始比较担心的地方。第三Codex 的任务模式适合小步验证。它每完成一个子任务就会停下来让我确认不会一股脑把所有代码都甩出来。这种工作方式对开发质量来说是安全的我可以随时打断、纠正方向。当然也有翻车的时候。我第一次尝试的时候把整个项目需求一次性抛给 Codex让它“把整个应用做完”。结果它生成了一堆看起来像模像样、实际完全跑不起来的代码各个模块之间的接口对不上数据库字段和前端表单字段命名也完全不一致。后来我总结出教训用 Codex 不能一上来就让它做整个项目必须把项目拆成一颗颗小任务每个任务都能独立验证验证通过后再进入下一步。这个思路贯穿了整个项目的后续开发。2. 环境准备把 Codex 调到能干活的状态2.1 Codex 安装、登录和项目级配置Codex 的安装不复杂官方提供了命令行工具安装后会有一个 codex 命令第一次使用需要登录授权。我选的是 CLI 方式因为它在自动化脚本和 CI 场景里更友好。安装完成后首先是项目级配置。Codex 会在项目根目录维护一个配置文件里面可以指定使用的模型、是否开启实验特性等。我建议不要全局装完就直接用而是在每个项目里都建一个独立的配置因为不同项目的代码风格、检查命令、构建方式差距很大。更关键的是一个叫 AGENTS.md 的项目说明文件。这个文件是给 Codex 看的项目说明书里面写清楚这四类信息项目是什么解决什么问题技术栈是什么。项目目录结构每个目录放什么。常用命令如何安装依赖、如何启动开发服务、如何跑测试、如何构建。代码规范命名习惯、组件组织方式、接口返回格式等。这个文件写得好不好直接决定了 Codex 出活的水平。我见过很多人拿了 Codex 就直接让写代码完全跳过项目上下文输入结果 AI 全靠猜。AGENTS.md 就是把 AI 从“啥都不懂的新人”变成“看过项目文档的实习生”的关键一步。2.2 一次真实的代理报错cc switch local proxy failed环境配置阶段我遇到一个非常闹心的问题。Codex 启动后任何一次请求都报错错误信息类似 cc switch local proxy failed while handling codex endpoint /responses。最开始以为是 Codex 本身的问题重装了两次也没解决。后来排查下来问题出在本地代理环境上。机器上装了代理转发工具系统级环境变量里设置了 HTTP 代理指向本地端口而 Codex 的请求走了这个代理但代理进程当前没有正常工作端口没监听或者握手失败导致所有 /responses 请求全部失败。解决办法分两步。第一步检查本机代理工具是不是正常启动端口是不是真的在监听。如果代理本身只是偶尔挂掉重启代理服务就能解决。第二步把 Codex 的直连域名加进 no_proxy 环境变量让 Codex 的 API 请求不走本地代理直接走原始连接。这个问题给我一个提醒用 Codex 之前最好先确认终端里的代理环境是否干净尤其是那些常年开着代理工具的人。Codex 对网络环境比较敏感代理配置稍有不对就会报这种看起来很玄学、实际和代码完全无关的错误。2.3 把 Relay 原型整理成 Codex 能消费的设计文档Relay 导出的设计规格说明虽然结构清晰但它不是直接给 Codex 用的。Codex 真正需要的是“设计规格 业务规则 技术约束”三者合并后的任务描述文档。我的做法是在项目里建一个 docs 目录把 Relay 导出的原始说明放进去一份然后写一份设计交付说明按照模块拆开。比如用户登录模块我会把 Relay 里的页面结构和组件状态提炼成一段文字页面包含手机号输入框、验证码输入框、登录按钮、协议勾选输入框有不同状态登录按钮有加载态、禁用态登录成功后跳转到首页接口字段是 phone 和 code返回 token 和用户信息。这一步是整条链路里最反直觉但最重要的一步。很多人以为有了 Relay 导出的设计稿就能让 Codex 直接读实际上 Relay 导出的信息偏视觉层而 Codex 写代码需要的是逻辑层信息。设计交付说明就是填补这层鸿沟的桥梁。这份文档不需要很长但必须准确因为后面生成的所有代码都以它为准。3. 从 Relay 原型生成前后端核心实操全记录3.1 后端服务生成接口先行后端我选的技术栈是 FastAPI 加 SQLite。选 FastAPI 是因为它自带接口文档方便用 Codex 协作也方便后面移动端联调。SQLite 做原型阶段的数据库足够了文件即库迁移成本低。任务是拆分后交给 Codex 的第一批任务是数据模型设计。我把 Relay 设计稿里涉及的所有实体列出来用户、项目、任务、评论、附件然后让 Codex 设计表结构和字段类型同时要求它生成数据库迁移脚本。这里要让 Codex 输出建表 SQL 而不是直接在代码里塞建表逻辑方便后面审查。第二批任务是接口开发。我习惯先约接口文档再写实现所以直接让 Codex 在 FastAPI 项目里按设计交付说明生成 REST 接口包括请求参数校验、鉴权逻辑、错误码规范。每个接口生成完后我会要求 Codex 写一段简单的自测代码用 httpx 把接口跑一遍确保返回结构符合预期。这里有个很实用的指令让 Codex 在每个接口的文档字符串里写清楚请求示例和响应示例。这样后面移动端联调时直接看接口文档就能确定字段不用再去翻代码。实测下来这比让 Codex 单独维护一份接口文档更可靠因为代码和文档由同一个任务生成不容易出现两边不一致。3.2 移动端前端生成组件化落地前端我选的是 Vue 3 加 Vant 组件库构建工具用 Vite。选择这个组合是因为 Vant 对移动端场景覆盖比较全日期选择、弹出层、表单校验这些基础组件都有可以减少 Codex 从头写 UI 组件的概率让它的精力集中在业务逻辑上。前端任务拆得更细。每个页面单独一个任务任务描述里包含四样东西页面功能描述、涉及的设计规格片段、后端接口地址和字段说明、验收标准。验收标准很关键比如登录页的验收标准是“手机号不合法时点登录按钮要提示错误”“验证码格式不对要前端拦截”“登录成功后路由跳转到首页”。Codex 生成页面代码后我让它做三件事给 API 请求层统一封装好 loading 和错误提示给每个列表接口做空态和异常态处理给路由加懒加载。这三个要求是移动端应用的基本功如果不在任务描述里显式提出来AI 生成的页面往往是能跑但没有异常处理的裸状态。3.3 联调细节字段对齐与错误处理前后端联调是 AI 开发最容易翻车的环节因为没有哪个工具能自动理解你的业务字段。Codex 生成的后端接口字段和前端表单字段一旦不一致页面上就会各种取不到数据。规避方案是在任务拆分时就做统一约束。我在设计交付说明里维护了一张字段对照表前端用户名这个字段叫什么后端接口参数叫什么数据库列名叫什么三条全部对齐。每次让 Codex 写代码时都把这张表粘进任务描述让它严格按表执行。联调阶段我还让 Codex 在本地起了一个 mock 模式前端开发时不依赖真实后端用本地 mock 数据先把交互流程跑通。等后端接口稳定了再通过环境变量切换成真实接口。这样前后端可以并行开发不会互相阻塞。错误处理也要提前设计。我让 Codex 在 API 请求层统一拦截三种错误网络错误、业务错误、鉴权过期。网络错误提示“连接失败”业务错误直接把后端返回的错误信息展示给用户鉴权过期统一跳登录页并清理本地存储。这些逻辑如果不在需求里写清楚AI 生成的代码就会处理得七零八落。4. 移动端适配、性能优化与几个印象深刻的坑4.1 多端适配方案从 px 到 rem/vw 再到安全区移动端适配是所有 H5 项目绕不开的问题。这次项目的适配方案用了三层策略。第一层是布局单位的处理。项目采用 rem 为主、vw 为辅的混合方案根字号由设计稿宽度和当前视口宽度动态计算组件库 Vant 内部用 px通过 postcss 插件按函数转换。这样设计稿标注多少代码里就写多少不用手动换算。第二层是尺寸适配。移动端设备屏幕宽度差异很大iPhone 和 Android 的刘海屏、挖孔屏也必须处理页面顶部和底部要留出安全区。这个直接用 env(safe-area-inset-bottom) 和 constant() 在 CSS 里处理配合 viewport-fitcover 的 viewport 配置。第三层是横屏和分屏。移动端偶发小窗、分屏场景我让 Codex 处理了 resize 事件导致的计算更新避免 rem 基准变了但页面没重算的问题。这类边角问题通常不在需求文档里但到了用户手里肯定会遇到提前处理比事后挨骂强。4.2 video 层级问题被移动端浏览器抬到顶层的视频这个坑在开发过程中真实出现过而且非常有代表性。项目中有一个短视频预览功能在大多数浏览器里表现正常但在部分安卓浏览器上视频元素会被强制提升到一个独立的顶层视图导致页面上的弹窗、底部导航、返回按钮全部被视频盖住点都点不到。这个问题源头不在业务代码而在浏览器内核的渲染策略。部分移动端浏览器遇到 video 标签时会启用系统播放器级别的渲染把视频从页面文档流中抽出来单独显示。网上讨论得很多的一句话是“video 自动置顶、层级提高”就是这类浏览器的固有行为。解决方案分几步走。第一步给 video 标签加上 playsinline 和 webkit-playsinline 属性让视频在页面内播放不触发全屏播放器。第二步针对部分安卓浏览器加 x5-video-player-typeh5 这类同层播放标记让视频回到普通文档流。第三步是业务上的妥协方案如果某些场景实在无法做到同层就用封面图加播放按钮模拟视频入口用户点击后才真正创建 video 元素。实测下来第三种方案最稳因为它从源头上绕开了视频元素常驻页面的问题。4.3 性能优化首屏、列表、图片三条线移动端性能优化我分成三条主线来做首屏加载时间、长列表滚动流畅度、图片体积管理。首屏优化的核心是减少加载体积。项目用 Vite 构建配合路由懒加载每个页面单独拆包。首页只加载首页需要的资源其他页面的 JS 全部按需加载。再给静态资源开了 gzip 压缩首屏体积降下来很多。长列表处理用了虚拟滚动思路。列表项非常多的时候如果全部渲染进 DOM滚动起来会非常卡。我让 Codex 封装了一个虚拟滚动组件只渲染可视区域附近的列表项上下各留一些缓冲区。这个组件在数据量达到四五百条时效果明显滚动帧率稳定很多。图片是移动端页面体积的大头。Relay 导出的设计稿里大量图片都是 PNG 甚至原图我在交付说明里要求前端统一把位图压缩成 WebP 格式并配合懒加载库实现滚动到可视区域才加载。这一项优化下来首屏图片请求数和体积都下降明显。4.4 vue2 移动端树选择器的实现思路项目里有一个模块需要多级区域选择本来想让 Codex 直接用现成的树选择器组件项目维护的旧版本里还有一块是基于 Vue 2 的业务需要兼容。Vant 自带的 TreeSelect 组件只支持两级联动但我们这需要四级区域选择所以只能自己实现。实现思路是递归组件加扁平化数据结构。树形数据传到递归组件里组件自己管理展开收起状态选中的节点路径通过事件回传给父页面。为了性能数据在进入组件前先做一次扁平化用父节点 ID 建立索引展开时只从索引里取子节点避免每次展开都遍历整个树。这部分的经验是如果树的数据量不大直接用递归组件渲染最简单如果数据量到了几千个节点就必须做虚拟滚动或者懒加载子树。我们项目里区域数据全量加载也就几百条所以选择的方案是递归组件加一次性渲染简单可靠不引入额外依赖。5. 测试、评审与交付链路5.1 让 Codex 生成的代码过一遍人工评审AI 生成的代码不是不能信但不能全信。我在交付前留了一整个环节做人工评审重点是四类问题。第一类是安全问题。接口有没有校验用户身份密码有没有明文存储敏感信息有没有硬编码在代码里这类问题 AI 很容易出现默认不设防的状态。第二类是边界条件。列表分页最后一页有没有重复数据提交按钮被连点会不会产生重复请求时间格式化在时区不匹配时会不会崩第三类是状态管理。页面退出后异步请求的回调还会不会更新视图全局状态有没有异常残留第四类是兼容性。低版本 WebView 上 CSS 新特性能不能正常渲染这一步不能省。Codex 生成代码的效率越高人工评审的价值反而越大因为生成速度快意味着低级错误也会被快速复制到多个文件。我会特别要求 Codex 在多个地方重复用到同一个逻辑时抽取公共函数而不是到处复制粘贴这样评审时只需要看一个函数就够了。5.2 自动化测试 人工回归清单自动化测试这次主要做了接口级和端到端两条线。接口测试用 pytest 直接调接口断言返回结构端到端测试用 Playwright 把核心用户流程跑一遍包括注册登录、创建任务、编辑资料、查看列表这些高频路径。Codex 生成代码时我要求它同步写测试用例然后由它自己跑测试、看失败原因、修到通过为止。人工回归清单是给 Codex 自动化测试兜底的。很多体验层面的问题自动化很难覆盖比如弹窗动画是否卡顿、键盘弹起会不会遮挡输入框、返回手势是否正常。这些我整理成了一份固定的回归清单每次交付前手动过一遍大概花二十分钟但能挡掉八成以上用户可感知的体验问题。5.3 打包、部署与交付记录部署走的是常规方案前端构建产物部署到静态资源服务器后端接口用容器方式部署。Codex 环境准备时我在 AGENTS.md 里写了构建命令和部署步骤后续每次让它改代码它都会在最后跑一遍构建确保改完的代码能正常打包这一步能提前暴露很多只在构建期才会出现的问题。交付链路里最有用的一个习惯是让 Codex 每次完成一个任务后都写一条简短的变更说明内容包括改了哪些文件、改了什么东西、为什么这么改。这个记录在排障时特别管用出了问题可以快速定位是哪次变更引入的不用对着 git 历史一个个猜。6. 常见问题与排查速查表6.1 高频问题速查这一节把项目过程中遇到的高频问题和解决办法整理成表格方便后面直接查阅。现象可能原因解决办法Codex 请求一直报 endpoint /responses 失败本地代理环境变量异常或代理进程挂掉检查代理端口监听把 Codex 域名加入 no_proxy 后重试Codex 生成的代码改了但页面没变化构建缓存未清理清掉构建缓存目录重新执行完整构建移动端页面在部分浏览器布局错乱未处理安全区、未统一 rem 基准补充 safe-area 样式确认根字号计算逻辑video 元素遮挡页面操作浏览器把 video 提升到顶层渲染加 playsinline 和同层播放标记必要时用封面替代长列表滚动卡顿DOM 节点过多改用虚拟滚动组件接口能通但页面取不到数据前端字段与后端返回字段不一致用字段映射表统一约束联调时逐个核对构建产物体积过大未做路由懒加载和按需引入检查路由拆分组件库按需引入6.2 两个值得展开的排障过程第一个是接口联调时出现的字段丢失问题。前端页面里列表展示正常但详情页一直拿不到部分字段。排查下来发现是后端序列化器把空值字段过滤掉了数据库里明明有值但响应里就是没有这个 key。解决方案是在后端序列化配置里显式声明保留空值字段并让前端对缺失字段做默认值兜底。这类问题如果在需求阶段就约定好“空值必须返回 null 而不是不返回”两边都会省很多事。第二个是某次 Codex 连续修改代码后页面从一个入口进入时白屏。先看控制台报错发现是运行时异常导致组件树整个挂掉进一步定位是某个接口返回的数据结构变了组件拿到新结构后取不到嵌套属性。这个问题暴露了 AI 开发的一个风险Codex 可能只改了后端返回结构忘记同步修改前端的解析逻辑或者反过来。所以后来我要求所有跨端字段调整必须同时生成前后端两份改动清单Codex 改完之后我人工检查清单是否两边都覆盖了。还有一个经验值得单独说用 Codex 做开发任务描述里一定要写清楚“不要擅自变更需求”。有一次我只让它改某个按钮的样式结果它顺手把按钮的点击事件逻辑也改掉了原因是它觉得原逻辑有性能问题。这种“好心办坏事”在 AI 编程里非常常见所以在任务描述里加上“仅修改指定部分不要调整无关逻辑”这句话能省去大量返工时间。整个项目跑下来我个人最深的体感是Codex 这类 AI 编程工具的真正价值不是让开发者变成一个只会提需求的“甩手掌柜”而是把大量重复性、确定性高的编码工作接管过去让开发者能把精力放在更值得人来做的事情上——比如判断设计意图、梳理业务边界、识别潜在风险。如果你决定把这套链路用到自己的项目里我的建议是先在一个小项目上完整跑通一遍把任务拆分的节奏、设计文档的写法都调顺了再上复杂项目。踩过几次坑之后你会对“哪些活可以交给 AI、哪些活必须自己来”有非常清晰的感觉。