NAVIGATION SYS
首页折腾手记造点东西投资笔记做点音乐想点事情

NCC-1701-D // SYSTEM ONLINE

Deep Space Viewport
造点东西

AI开发配置系统(二):我与AI的72小时:从零打造ConfigBridge

舸扬
造点东西
发布: 2025-11-11
更新: 2026-02-02
标签configbridge系列配置管理
AI开发配置系统(二):我与AI的72小时:从零打造ConfigBridge
本文字数:5577预计阅读:14 分钟

📖 本文是「AI开发配置系统」系列第二篇。上一篇:AI开发配置系统(一):告别手动Lucky配置:我为什么要自己造一个ConfigBridge

TL;DR(太长不看版)

  • 背景:在上一篇文章中,我介绍了 ConfigBridge 的功能和使用场景
  • 本文焦点:从 0 到 1 的真实开发过程,以及 AI 结对编程的体验
  • 时间线:72 小时完成 MVP → 一个月打磨成完整产品
  • 技术栈:FastAPI + Vue 3 + SQLAlchemy + Jinja2 模板引擎
  • 核心收获:AI 不是替代,而是杠杆——让个人开发者也能突破技术边界

开篇:关于"72 小时"的真相

先说实话:标题里的"72 小时"有点标题党了

严格来说,72 小时只够我完成一个勉强能跑的 MVP(Minimum Viable Product,最小可行产品)。这个 MVP 能做什么呢?

  • ✅ 创建服务、服务器、模板的基本增删改查(CRUD)
  • ✅ 变量系统的雏形(但只有两层优先级)
  • ✅ 最基础的配置生成(但没有批量,没有远程部署)
  • ✅ 一个"能用但丑陋"的前端界面

但这离"完整产品"还差得远。

从 MVP 到你在上一篇文章里看到的那个功能完善、界面美观的 ConfigBridge,我又花了将近一个月的时间:

  • 🔧 变量系统从两层扩展到四层
  • 🔧 加入远程部署、自动备份功能
  • 🔧 加入配置版本控制
  • 🔧 前端界面推翻重做了两次
  • 🔧 无数的 Bug 修复和边界情况处理

所以更准确的说法是:72 小时从 0 到 MVP,一个月从 MVP 到产品

但这恰恰是 AI 结对编程的价值所在——如果没有 AI,72 小时我可能连 MVP 都搞不定。

第一章:凌晨一点的决定

故事要从那个失眠的夜晚说起。

凌晨一点,我盯着散落在三台服务器上的几十个配置文件,做了一个决定:

自己造一个配置管理工具。

问题的背景我在上一篇文章中已经详细描述过了:IPv6 服务器、FRP(一种内网穿透工具)、多机 Nginx 配置……每新增一个服务,就要手写 4 份配置文件,分布在 2 台机器上。10 个服务意味着 40+ 份配置,任何一个拼写错误都可能导致服务不可用。

这不是技术问题,是效率问题。而效率问题,正是工具应该解决的。

我躺在床上,脑子里开始构思这个工具的雏形:

  • 需要一个中心化的管理界面,所有服务、服务器、配置都在一个地方
  • 需要模板系统,写一次模板,复用 N 次
  • 需要变量系统,同一套模板在不同环境下生成不同配置
  • 需要一键生成,点一下按钮,所有配置文件自动生成

想着想着,突然来了精神——我爬起来,打开电脑,开始和 AI 聊这个项目。

第二章:与 AI 结对——72 小时冲刺 MVP

我打开 Cursor,开始和 AI 讨论这个需求。

2.1 需求梳理:5 分钟定义核心概念

我告诉 AI:

"我需要一个配置管理系统。用户输入服务名、子域名、端口,系统自动生成 Nginx 配置、FRP 配置等。不同服务器需要不同的配置模板。"

AI 很快帮我梳理出几个核心概念:

概念
说明
示例
服务 (Service)Web 服务的抽象名称、子域名、端口
服务器 (Server)物理/虚拟服务器IP、SSH 凭证、是否 IPv6
配置模板 (Template)Jinja2 格式模板Nginx 模板、FRP 模板
变量 (Variable)可自定义的配置项监听端口、后端地址

2.2 核心设计:变量覆盖系统

这是我和 AI 花了最多时间讨论的部分。

问题:同一个模板,在不同服务器上生成的配置可能有细微差别。比如服务器 A 需要监听 IPv6,服务器 B 的端口要改成 FRP 转发端口……如果为每个场景单独写模板,模板数量会爆炸。

我向 AI 描述了这个问题,它几乎立刻给出了解决方案:

AI:"你需要一个变量覆盖系统。从全局到服务级别,层层覆盖。就像 CSS 的优先级规则一样。"

这个类比让我茅塞顿开!

这就好比公司的规章制度:

  • 公司级规定(全局变量):全公司早上 9 点上班。
  • 部门级规定(服务变量):开发部比较特殊,早上 10 点上班。
  • 部门级自动覆盖了公司级

72 小时内,我们快速实现了一个简单的两层变量系统

TERMINAL
服务变量(高优先级) 全局变量(低优先级)

当时的设计逻辑很简单:全局变量定义默认值,服务变量覆盖特定服务的配置。这对于 MVP 来说已经够用了。

但我心里隐隐觉得这还不够——如果同一个服务在不同服务器上需要不同的配置呢?这个问题我先记下了,留待后续解决。

2.3 模板语法:Jinja2 的魔力

ConfigBridge 的模板使用 Jinja2 语法。这是一个可行的 Nginx 模板:

jinja2
server { listen {{vars.listen_port}} ssl; server_name {{service.name}}.{{global.base_domain}}; ssl_certificate {{vars.ssl_pem_path}}; ssl_certificate_key {{vars.ssl_key_path}}; error_page 497 =301 https://$host:{{vars.listen_port}}$request_uri; {% if vars.is_nginx_webdav_config is defined and vars.is_nginx_webdav_config %} include conf.d/webdav_params; {% endif %} location / { proxy_pass http://127.0.0.1:{{service.port}}; include proxy_params; } }

变量来源解读

  • {{ service.xxx }}:来自服务数据(名称、端口等)
  • {{ server.xxx }}:来自服务器数据(IP、是否 IPv6 等)
  • {{ vars.xxx }}:来自变量系统(自动合并后的结果)
  • {{ global.xxx }}:来自全局配置

2.4 技术栈:为什么选择它们

层级
技术选型
选择理由
后端框架FastAPI异步、自带 OpenAPI 文档、类型提示友好
ORMSQLAlchemy 2.0成熟稳定、支持异步
模板引擎Jinja2功能强大、语法优雅、与 Python 生态无缝集成
前端框架Vue 3响应式、组合式 API 开发体验佳
UI 组件库Element Plus组件丰富、文档完善
部署Docker容器化、环境一致性

第三章:72 小时后的 MVP

经过 72 小时的密集开发,ConfigBridge 的第一个可运行版本诞生了。

说是"可运行",其实还很粗糙:

MVP 能做什么

  • ✅ 服务管理:创建、编辑、删除服务,关联到服务器
  • ✅ 服务器管理:记录服务器信息(名称、IP)
  • ✅ 模板管理:创建 Jinja2 模板
  • ✅ 变量系统(两层):全局变量 + 服务变量
  • ✅ 配置生成:选择服务和服务器,生成配置文件

MVP 不能做什么

  • ❌ 没有"服务-服务器变量"(四层变量的关键一层)
  • ❌ 没有远程部署,只能手动 SCP
  • ❌ 没有配置版本控制
  • ❌ 没有批量操作
  • ❌ 前端界面……一言难尽

第一次用自己的工具

尽管如此,我还是用这个 MVP 给自己的一个新服务生成了配置。

那种感觉就像——你造了一辆自行车,它歪歪扭扭的,刹车有点不灵,但它真的能骑

从输入服务信息到生成 2 台服务器的 4 份配置文件,只用了不到 1 分钟。而以前,这个过程需要 30 分钟的复制粘贴和反复检查。

从 30 分钟到 1 分钟——这就是 MVP 的价值。

它证明了这个方向是对的。接下来要做的,是把它打磨成一个真正好用的产品。

第四章:从 MVP 到产品——一个月的打磨

72 小时的冲刺之后,是一个月的持续迭代。

4.1 阵痛与推倒重来:那次惨痛的“删库”

MVP 虽然跑通了,但随着我开始往里面塞更多的功能,代码开始失控了。

由于最初 72 小时冲刺时为了快,很多逻辑都写得极其随意,变量命名混乱,数据库关联也设计得一塌糊涂。当我试图修复一个“变量覆盖”的 Bug 时,往往会触发另外三个关于“模板渲染”的 Bug。

那是一个周三的深夜,我看着满屏的 TODO 和打了无数补丁的 service.py,意识到这已经不是在修补代码,而是在往屎山上盖别墅。

我做了一个决定:删除代码,推倒重来。

我没有在原有的代码上继续修补,而是直接新建了一个 v2 分支,执行了原代码删除。我把过去 72 小时积累的经验(以及踩过的坑)重新梳理,用更严谨的 OOP(面向对象编程)设计模式和更清晰的数据库结构(Schema)重新构建了核心引擎。

这里我有一个很深的感触:在 AI 时代,“推倒重来”不再是一个沉重的决定。

AI 写代码的速度极快,这使得重构甚至重写的“物理成本”被大大压缩了,剩下的仅仅是“心理负担”。既然代码实现变得如此廉价,我们完全可以将“推倒重来”作为一个并不昂贵的可选项。

前期多花点心思做好设计,远比在错误的架构上缝缝补补要划算得多。

虽然这让进度看起来倒退了三天,但正是这次“归零”,才有了后来能够稳定承载复杂配置的架构。

4.2 变量系统升级:从两层到四层

还记得 72 小时冲刺时留下的那个问题吗?——"如果同一个服务在不同服务器上需要不同的配置怎么办?"

在实际使用中,这个问题很快暴露出来了。

问题:同一个服务(比如 Nextcloud),在服务器 A 上的 backend_port 是 8080(直连),在服务器 B 上却是 8081(FRP 转发端口)。两层变量系统没法表达这种"服务 + 服务器"的组合关系。

我又跟 AI 进行了一轮深入讨论:

AI 的扩展方案

我为您设计了一个扩展方案:

  • 服务级变量:当 server_id 为 NULL 时,视为该服务的全局默认值
  • 服务器级变量:当 server_id 指定了具体 ID 时,覆盖服务级变量
  • 全局变量:新增一个专门的 GlobalVariable

:你这个设计有个小问题——这里面没有属于某个服务器而不绑定任何服务的变量

AI:你说得对!💯 我的设计确实遗漏了仅与服务器关联而不绑定特定服务的变量。这是一个很重要的场景,比如服务器的通用路径、特定于服务器的 API Key 等。感谢你的指正!让我把这个层级加进去...

这就是真实的结对编程——AI 给出了一个 80 分的方案,但那漏掉的 20 分正是需要我来补充的。如果没有我对实际使用场景的理解(某些变量确实只和服务器相关,与服务无关),AI 不会主动发现这个问题。

最终我们敲定了四层变量优先级

TERMINAL
服务-服务器变量(最高优先级) 服务器变量 服务变量 全局变量(最低优先级)

这个设计的关键洞见是:优先级越高,适用范围越窄。服务-服务器变量只对特定服务在特定服务器上生效,全局变量则对所有服务的所有服务器生效。

这个升级涉及到数据库 Schema 改动、后端 API 改动、前端表单改动……前后花了一周

4.3 远程部署:告别手动 SCP

MVP 只能把配置文件生成到本地目录,然后我还得手动 scp 到服务器上。这太蠢了。

第二周,我加入了远程部署功能

  • 通过 SSH 连接到目标服务器
  • 自动备份原配置文件
  • 将新配置写入目标路径
  • 可选执行重载命令(如 nginx -s reload

这个功能用到了 Python 的 paramiko 库。说实话,SSH 连接、密钥认证这些我之前没怎么写过,全靠 AI 帮我搞定。

4.4 前端界面:推翻重做两次

作为后端程序员,我的前端水平可以用"惨不忍睹"来形容。

MVP 的界面是什么样的呢?想象一下:默认的 Element Plus 组件,没有任何样式调整,布局全靠运气……

第一次重做:我让 AI 帮我"美化"界面。结果就是在原来的基础上加了一些 CSS,稍微好看了一点,但还是很"程序员审美"。

第二次重做:我换了个思路,不再说"帮我美化",而是说"参考 xxx(某个我觉得好看的后台管理系统),帮我重新设计"。这次终于像样了。

教训:让 AI 做设计时,给它具体的参考,比给它抽象的描述有效得多。

4.5 边界情况和 Bug 修复

剩下的两周,主要在处理各种边界情况:

  • 如果用户删除了一个正在被服务引用的模板怎么办?
  • 如果远程部署时 SSH 连接超时怎么办?
  • 如果生成的配置文件语法有错误怎么办?
  • 如果两个服务用了相同的子域名怎么办?

这些问题 AI 帮不了太多忙——它不知道我的业务逻辑应该怎么处理。这是需要我自己思考和决策的部分。

4.6 一个月后的成果

一个月后,ConfigBridge 的功能基本完善:

  • ✅ 四层变量优先级系统
  • ✅ 远程部署 + 自动备份
  • ✅ 配置版本控制
  • ✅ 批量生成和部署
  • ✅ 看得过去的前端界面

从新增一个服务需要 30 分钟手动配置,到 3 秒钟一键生成——这就是 ConfigBridge 的价值。

核心功能的详细介绍可以参考上一篇文章,这里不再赘述。

第五章:AI 的高光与低谷

开发过程中,AI 既有让我惊艳的高光时刻,也有让我无奈的低谷时刻。

🌟 高光时刻:SSH 连接代码一气呵成

做远程部署功能时,我对 Python 的 paramiko 库完全陌生。

我只跟 AI 说了需求:"我需要通过 SSH 连接到远程服务器,上传文件,执行命令",它就给我生成了一段完整的代码,包括:

  • 密钥认证和密码认证两种方式
  • 连接超时处理
  • 文件上传(用 SFTP)
  • 命令执行和输出捕获
  • 异常处理和资源清理

我几乎没改什么就直接用了。这相当于帮我省了至少半天的学习时间。

🔧 实战案例:前后端联调 Bug 排查

这里分享一个真实的 Bug 修复过程。某天我在调试服务详情页面时,控制台突然报了一堆 422 Unprocessable Entity 错误:

TERMINAL
Failed to load resource: the server responded with a status of 422 请求失败: services/.../variable-status, 状态码: 422

我把日志丢给 AI,对话是这样的:

AI:让我分析一下这个错误。422 通常意味着 FastAPI 在处理请求时数据验证失败。我找到了处理这个路由的代码...问题出在 template_ids: List[UUID] = Body(...) 这一行——GET 请求不应该包含请求体,参数应该通过 Query Parameters(就是 URL 里问号后面那一串参数)传递。

:(AI 修改了后端代码后)还是没解决,我把前端报错贴过来...

AI:原来如此!虽然后端改成了接收 Query 参数,但前端代码仍然把 template_ids 放在了请求体里。让我查看前端的 API 调用...

接下来 AI 定位到了前端 services.js 文件中的问题:

javascript
// 问题代码:函数根本没有接收 template_ids 参数! export function checkVariableStatus(serviceId, serverId) { return request.get(`${baseURL}${serviceId}/servers/${serverId}/variable-status`); } // 修复后:正确传递查询参数 export function checkVariableStatus(serviceId, serverId, paramsData) { const config = { params: { template_ids: paramsData.template_ids } }; return request.get(`...variable-status`, config); }

这个 Bug 修复过程展示了 AI 的真正价值:它能快速理解错误日志,定位代码位置,分析问题原因。但也暴露了它的局限——前后端代码分散在不同文件,AI 第一次只修了一半,需要我追问才发现另一半的问题。

低谷时刻:业务逻辑经常失智

但 AI 也有无能为力的时候。

比如:"如果用户删除了一个正在被多个服务引用的模板,应该怎么办?"

我问 AI,它给了我三个选项:

  1. 禁止删除,提示用户先取消关联
  2. 级联删除所有关联的服务
  3. 允许删除,但保留一个"模板已删除"的占位符

这三个选项都是技术上可行的,但哪个是业务上正确的?AI 不知道,因为这取决于我的产品定位和用户预期。

最终我选了第一个:禁止删除,让用户自己决定怎么处理关联的服务。这个决策只能由我来做。

另一个教训:"臆想"出来的方案

还有一次,我让 AI 帮我设计一个新功能的技术方案。结果它写了一整套设计文档,看起来头头是道。

直到我发现——它根本没仔细看现有代码。

它设计的方案里说"需要新增 server_path 字段",但这个字段项目里早就有了。它说"需要修改数据库模型",但现有模型已经支持这个场景。整个方案有一半是在重复造轮子。

我不得不提醒它:"你这个 story 文件完全就是臆想出来的,完全没根据当前项目的情况去设计。"

这件事教会我:AI 需要被"喂"足够的上下文。如果你不主动让它阅读相关代码,它就会基于通用模式去猜测,然后输出一个"看起来正确但脱离实际"的方案。

💡 我的体会

AI 擅长的是:

  • 技术问题:报错信息诊断、API 用法查询、代码实现
  • 重复劳动:生成样板代码、写 CRUD、调整样式
  • 知识检索:它见过无数个类似的问题和解决方案

AI 不擅长的是:

  • 业务决策:产品逻辑应该怎么设计
  • 架构权衡:这个方案的长期代价是什么
  • 上下文理解:它不会主动去了解你的项目现状

最高效的协作方式:我负责思考"做什么"和"为什么",AI 负责帮我"怎么做"。但我也要负责给它足够的上下文,否则它就会"臆想"。

第六章:下一步计划

一个月的开发后,ConfigBridge 的核心功能已经可用。但作为一个自己用的工具,我还有一些想法:

🔮 还想做的功能

功能
说明
优先级
配置语法验证部署前验证 Nginx/FRP 配置语法,避免写错
Webhook 通知配置变更后自动触发 CI/CD
多用户支持如果要给团队用的话
配置 Diff 对比部署前预览本次变更内容

第六章:关于 AI 结对编程的深度思考

一个月的开发经历让我对 AI 编程有了更深的理解。这里分享几个思考。

🧠 AI 是放大器,不是替代品

很多人问我:"AI 这么厉害,程序员是不是要失业了?"

我的答案是:AI 是放大器,10 倍放大你的能力——但如果你的能力是 0,10 倍之后还是 0。

举个例子:在四层变量设计的讨论中,AI 一开始只给了三层的方案。是我根据实际使用场景发现了遗漏,才最终完善成四层。如果我对配置管理没有任何理解,我根本不会发现这个问题,AI 的"80 分方案"就会直接变成最终方案——然后在实际使用中掉进坑里。

真正的价值在于

  • 你对问题域的理解
  • 你对边界情况的敏感度
  • 你对用户需求的把握

AI 可以帮你更快地实现想法,但想法本身还得你来。

🔄 "对话"比"指令"更有效

我发现,和 AI 合作最高效的方式不是"下指令",而是"对话"。

低效的方式:"帮我写一个配置管理系统的后端。"

高效的方式

  1. "我想做一个配置管理系统,核心问题是...你觉得应该怎么设计?"
  2. (看 AI 的方案)"这里有个问题...能不能这样改?"
  3. (继续迭代)"现在开始实现这个模块,但要注意...。"

对话的意义在于:它让 AI 有机会暴露自己的思路,也让你有机会纠正它的错误假设。一开始就全权委托,往往会得到一个"正确但不适合"的结果。

🎯 "上下文工程"是新技能

在这一个月里,我逐渐意识到一个被低估的技能:如何给 AI 提供正确的上下文

AI 不会主动去读你的所有代码。它读取到的只是你当前对话中提供的信息。如果你想让它给出一个贴合项目现状的方案,你需要主动告诉它:"先看看这几个文件...",或者把关键代码片段直接贴给它。

我把这叫做"上下文工程"(Context Engineering):

  • 太少的上下文:AI 会基于通用模式去臆想
  • 太多的上下文:AI 会被无关信息干扰
  • 恰到好处的上下文:AI 能给出精准贴合的方案

这是一门需要时间摸索的技能。

结语:AI 让我成为"超级个体"

回顾这一个月,我最大的感触是:

AI 没有抢走我的饭碗,反而让我成为了"超级个体"。

如果没有 AI:

  • 架构设计可能要花一周时间反复推敲
  • 遇到 Alembic(数据库版本工具)这种冷门问题,可能要耗费半天
  • 前端 Vue 组件的 CSS 布局,作为后端程序员的我可能要抓瞎
  • SSH 远程部署功能,光学 paramiko 库就要花一天

但有了 AI:

  • 我负责:提出需求、做出决策、把控质量、提供上下文
  • AI 负责:快速实现、填充细节、解决技术卡点、跨越知识壁垒

这不是替代,而是协作。这不是依赖,而是杠杆

ConfigBridge 只是一个开始。在 AI 编程时代,每个开发者都可以突破自己的技术边界,去实现以前想都不敢想的项目。

你准备好成为"超级个体"了吗?

📌 项目信息

项目
详情
项目名称ConfigBridge 配置管理系统
解决问题IPv6/IPv4 混合环境下的服务配置集中管理
技术栈FastAPI + Vue 3 + SQLAlchemy + Jinja2
开发周期72 小时 MVP + 一个月迭代

📚 AI开发配置系统系列导航

下一篇:AI开发配置系统(三):AI懂个锤子架构?ConfigBridge后端演进实录

END OF LOG_
ID: CONFIGBR