我如何与AI结对编程:五个项目的深度复盘与思考
AI能做 70% 的编码,但决定成败的,是人类工程师那 30% 的智慧
大家好,作为一名软件工程师。在这近一年里,我独自主导了五个不同项目的构建,从零到一,覆盖了数据平台、智能客服、RAG 知识库、文档解析服务,甚至一个公司级的后端框架。我的经历有些特殊,我的核心“搭档”一直是 AI。
这篇文章,是我对这段人机协作旅程的一次复盘。我想通过真实的案例,与大家分享一个正在发生的核心转变:AI 正在从一个“听话的程序员”,进化为一个能力超群的“执行伙伴”。 它能帮你完成大约 70% 的编码工作,但决定项目成败、架构优劣、业务成败的,永远是人类工程师凭借经验和智慧做出的那关键的 30% 的决策。
第一章:数据采集平台 —— 在规则的“灰色地带”与 AI 共同探路
启动任何数据项目,第一步大概率是数据采集。这往往意味着要与目标网站的反爬虫机制斗智斗勇,而这正是最考验人类经验的地方。
坦白说,在开始这个项目之前,我对爬虫几乎没有任何经验。正因为如此,我和 AI 的关系更像是“两个新手一起上路”:它可以帮我快速写出请求、解析页面的代码,而我则需要不断学习、验证,并在踩坑之后总结经验。很多时候,AI 给我的答案并不完美,甚至会因为忽略反爬策略而失败。但正是这种“我补它的盲点,它带我快速试错”的过程,让我在短时间里摸清了整个采集流程。对了,这个项目一定是我是选用 Python 快速试错,验证可行性,然后采用个人和团队中都更熟悉、更有技术积累的 Go 语言进行正式的开发工作。
场景一:当 API 返回“高质量的垃圾数据”
项目初期,我的目标是从一个行业数据网站获取公开的榜单信息。我向 AI 下达了指令:“分析这个API接口,编写 Go 代码进行采集”。AI 不负众望,迅速交付了基于http.Client的采集代码。然而,灾难随之而来:我们采集到的数据,要么是空的,要么是看似格式正确但内容完全错误的“假数据”。
这是一个典型的反爬虫陷阱。我没有问 AI “如何修复这段 Go 代码?”,而是向它提出了一个需要经验判断的战略问题:“我们正面临一个设计精良的反爬虫机制,其根源是什么?为什么简单的‘打补丁’是死路一条?”。
AI 伙伴的回应是一份深刻的《关于解决第三方数据源采集困境的专题报告》。它精准地剖析了我们被识别的技术根源:HTTP请求头指纹、TLS 握手指纹,以及最关键的——JavaScript 执行环境的缺失。报告一针见血地指出,任何试图“模仿”浏览器的行为都将陷入永无休止的“猫鼠游戏”。
这 30% 的人类智慧:战略决策与风险评估。 AI可以分析技术细节,但它无法替我做出生死攸关的战略决策。而我基于对项目长期稳定性的考量,否决了继续在 HTTP 层面“打补丁”的短视方案,并采纳了 AI 报告中提出的、更复杂但更稳健的无头浏览器方案。AI 提供了地图,但我必须选择前进的方向并承担后果。
场景二:“金钥匙”的发现与“机会主义”采集策略的确立
转向无头浏览器并非一帆风顺。我们发现,直接访问目标页面无法获取数据,因为 URL 需要一个动态的、我们无法生成的签名参数。项目一度陷入“鸡生蛋、蛋生鸡”的困境。
正是在与 AI 反复的探索和日志分析中,我取得了决定性突破:我偶然发现,一个我早已在稳定采集的“榜单 API ”返回的 JSON 中,包含了一个名为AwemeDetailUrl的字段。这是一个由服务器为我们预先生成好的、包含了合法签名的 URL!我们称之为“金钥匙”。
这个发现彻底改变了战局。AI 迅速将这个线索方案化,设计并验证了一套全新的“两步走”方案:先用“金钥匙”URL在浏览器中完成“授权”,再用同一个会话去访问不带签名的原始API,从而获取真实数据。
然而,新的问题接踵而至:我敏锐地意识到,这个“金钥匙”是有有效期的。AI 不会主动思考这个业务细节,它只会执行“拿到钥匙,打开门”的指令。如果我们将钥匙存入数据库,等几个小时后再用,它很可能已经“生锈”了。
这 30% 的人类智慧:洞察业务规则的隐性约束。 AI不懂“时效性”这个业务概念。而我基于对 API 签名的经验判断,提出了“金钥匙”可能过期的风险。基于这个判断,我们共同设计了“采集与下钻一体化”的混合动力架构,确保“金钥匙”的获取和使用在一个紧密耦合的任务流中完成,从而规避了签名过期的风险。是我,进一步推断出,一旦某个条目下榜,我们将永久失去获取其“金钥匙”的能力,从而将整个数据战略从“全量历史回溯”调整为“机会主义的即时快照”。这些基于对业务深刻理解的战略调整,是 AI 无法独立完成的。
场景三:ETL流程中的“并发依赖”与“脏数据”难题
当数据采集进入 ETL 阶段,我又遇到了两个 AI 无法自行解决的典型业务场景问题。
第一个问题是并发依赖。我们有两个并发执行的任务,一个处理视频的概览数据(summary),一个处理趋势数据(trend)。我最初的设计是,trend 的处理依赖 summary 先写入数据库的点赞数字段。AI 忠实地执行了我的设计。但很快我们发现,由于并发执行的顺序无法保证,trend 任务经常因为读不到最新的点赞数而失败或使用了错误数据。
第二个问题是上游脏数据。我们发现上游 API 有时会在一次请求的 JSON 响应中,返回日期重复的趋势数据。这导致我们使用“(视频 ID, 日期)”作为唯一索引进行 Upsert 时,数据库直接报错。AI 最初的建议是在代码里去重,但它没能理解这是一个“死锁”:唯一索引不允许脏数据入库,但我们需要唯一索引来实现 Upsert。
这 30% 的人类智慧:处理非理想状态下的业务逻辑。 作为架构师,我意识到并发任务间的依赖是脆弱的,并决策彻底解耦这两个处理函数。我指令 AI 重构代码,让 trend 处理器独立地、主动地去查询原始数据,不再依赖任何其他进程的状态。 对于脏数据问题,是我否决了 AI 的初步方案,并设计了更健壮的单表“事务性删除并插入”方案:我们大胆地移除了唯一索引,允许数据库存储最原始、可能包含重复的数据以备审计,然后在代码层面通过一个数据库事务,原子性地完成“先删除旧数据,再插入新数据”的操作,从而在逻辑上完美实现了 Upsert 的业务需求,同时又规避了唯一索引的限制。这种在“理想数据模型”与“肮脏现实”之间做出权衡和创新,是纯粹的技术逻辑无法替代的。
第二章:智能客服系统 —— 在复杂状态与模糊需求中构建“神经中枢”
智能客服系统是一个状态极其复杂的应用。它不仅仅是技术问题,更是产品逻辑、用户体验和业务流程的集合体。
场景一:从“自动化”到“智能化”的范式革命
我们最初基于一个工作流引擎构建客服系统,用户可以在画布上拖拽节点(如问题分类、知识库查询、发送消息)来定义流程。AI 可以完美地帮我实现这些节点的功能。但我很快意识到,这本质上是一个高级的“自动化”引擎,而非“智能化”引擎。它在处理需要动态决策、多轮澄清的复杂场景时显得力不从心。
我向 AI 提出了一个更高层次的构想:我们能否融合 Agent 的灵活性与工作流的稳定性?具体来说,就是在画布上引入一个全新的“智能助理”节点。当流程走到这里时,一个拥有自主思考能力的 Agent 被激活,而画布上的其他业务节点,则动态地成为该 Agent 可用的“工具(Tool)”。
这 30% 的人类智慧:产品架构的顶层设计与创新。 AI 无法凭空创造一个全新的产品范式。我基于对客服业务和AI技术趋势的理解,提出了“宏观流程(工作流)”与“微观智能(Agent)”相结合的核心理念。AI 随后将这个理念转化为具体的技术实现路径,例如设计“动态工具注册”机制、规划如何将现有节点重构为“双重身份”(既是图节点也是 Agent 工具)。这种从 0 到 1 的产品架构创新,源于人类的洞察力和创造力。
场景二:精确驱动 AI 完成复杂的“外科手术式”重构
将旧系统升级到新的 Agent 模式,是一项涉及多个服务的庞大系统工程。如果我只是简单地告诉 AI:“帮我实现这个功能”,结果将是灾难性的。
为此,我和 AI 共同建立了一套指令范式。我作为项目经理/架构师,负责定义每个阶段的战略目标,而 AI 则将这些目标拆解成原子化、可执行、上下文明确的开发指令,供“ AI 代码编辑器”执行。
例如,在改造消息网关服务时,我下达的战略意图是:“彻底剥离AI逻辑,回归‘通信网关’的本质”。AI 则生成了一份极其详尽的三阶段执行方案。其中一个关键指令是:“移除旧 AI 逻辑判断与触发,引入新 Agent 模式触发条件判断”。它没有虚构一个不存在的函数名,而是清晰地描述了“做什么”和“为什么”,把“如何做”的权力完全交给了拥有完整代码上下文的AI代码编辑器。
这 30% 的人类智慧:定义清晰的“契约”与验收标准。 我与 AI 的协作模式是:我负责提出“做什么 (What)”和“为什么 (Why)”,AI 负责设计技术方案和生成“目标导向”的开发指令。在“ AI 转人工”功能的实现中,我明确了 12 个具体的业务步骤,包括更新会话状态、处理分配记录、插入系统消息和推送 WebSocket 通知等。AI 则将这些业务需求,翻译成了精确到代码级别的指令。“指令的质量决定了输出的质量”,而高质量的指令,源于人类对业务流程的深刻理解。
场景三:处理“配置失效”引发的分布式状态同步难题
一个典型的、AI 无法独立思考的场景出现了:当运营人员在后台禁用了某个 AI 工作流,或者移除了某个机器人时,那些成百上千个正处于“ AI 接待中”的用户会话应该怎么办?
AI 无法主动预见这个问题,因为它不懂“后台配置变更”对“前端用户状态”的连锁反应。它只会执行“禁用工作流”这个原子操作。
是我,预见了这个问题,并向AI提出了挑战。我们共同设计了一个精巧的方案:
ai 应用计算差异:在配置变更时,由ai服务计算出被新增和移除的机器人列表。MQ广播差异:ai将这个包含“差异”的精确消息发布到 MQ。IM响应:IM服务消费这个消息,一方面向前端广播一个携带“差异”的 WebSocket 事件,让前端可以智能地刷新 UI;另一方面,如果“移除列表”不为空,则启动一个异步、分批的后台任务,安全地将会话从 AI 接待迁移到人工接待,避免了同时操作上千个会话可能导致的数据库雪崩。
这 30% 的人类智慧:预见分布式系统中的“副作用”与设计优雅的降级方案。 这个场景完美体现了人类工程师的系统思维能力。我们预见了一个操作在分布式系统中可能引发的“状态不一致”问题,并设计了一套异步、解耦、最终一致的解决方案。从提出问题,到设计包含“差异计算”、“ MQ 通知”、“后台批量任务”、“前端智能刷新”的完整闭环,这整个过程充满了对业务细节、系统性能和用户体验的综合权衡,这正是人类经验的价值所在。
第三章:企业知识库 —— 在“可用”与“卓越”之间进行架构权衡
构建一个企业级的 RAG 知识库,不仅仅是调用几个 API 那么简单。它充满了关于数据模型、处理流程和性能优化的架构决策。
场景一:定义微服务的职责边界
项目初期,我们有两个微服务:一个 Go 服务负责业务逻辑,一个 Python 服务负责将任意格式文件转为 Markdown。最大的架构决策点在于,文本分块(Chunking)、FAQ 生成这些 NLP 密集型任务,应该放在哪一端?
AI 可以为我实现任何一种方案。但它无法替我直接做出最符合客户场景的、“高内聚、低耦合”原则的架构决策。
我基于对两种语言技术生态的理解,采纳了 AI 的强烈建议:让 Python 服务负责所有文档内容的深度处理,Go 服务只负责业务流程的编排和存储。Python 在 NLP 领域的生态优势是 Go 无法比拟的,让专业的人(或服务)做专业的事,是最高效的选择。
这 30% 的人类智慧:基于技术生态和团队专长的架构决策。 AI 的知识是广博的,但人类架构师的智慧在于,能够结合项目目标、团队技术栈、语言生态优势等非功能性因素,做出最优的权衡。这个决策,确保了两个服务都可以独立迭代,技术栈都用在了自己最擅长的地方,从源头上保证了系统的可维护性。
场景二:从“一刀切”到“自适应分块”的智能化升级
系统上线后,我们发现对所有文档采用固定的分块大小效果不佳。例如,一篇长篇大论的 PDF 和一份结构稀疏的 PPT,它们生成的 Markdown 结构完全不同,用同样的方式切割,会严重破坏语义。
AI 可以帮我调整参数,但它不会主动提出:“我们应该让系统自己学会调整参数”。
我向 AI 提出了实现“自适应分块(Adaptive Chunking)”的设想。AI 迅速将这个设想具象化为一个可行的技术方案:在分块前,先对 Markdown 文档进行一次“文体扫描”,分析其内容密度、标题密度、平均章节长度等特征,然后动态地决定最合适的ChunkSize和ChunkOverlap。AI 甚至设计了前端 UI,允许用户在“自动(推荐)”和“手动设置”之间切换。
这 30% 的人类智慧:提出超越当前需求的“智能化”策略。 从“让用户配置”到“让系统自适应”,这是一个从“功能”到“智能”的质变。这种产品层面的进化思考,来源于人类对“更好体验”的追求。AI 是实现这个目标的强大工具,但点燃这个创新火花的角色,往往是人类。
场景三:解决检索性能瓶颈的“预计算”重构
随着知识库数量的增长,我们遇到了一个严重的性能问题:RAG 的“知识库路由”(即判断用户问题应该查询哪个知识库)非常缓慢。原因在于,我们之前的实现是“实时计算”的:每次查询,系统都会从数据库捞取所有知识库的描述文本,进行向量化,然后与问题向量进行比较。当知识库成千上万时,这个过程的延迟是不可接受的。
AI 可以帮我优化 SQL 查询,但它无法跳出“实时计算”这个思维定式。
我基于对向量检索原理的理解,提出了一个全新的、基于“预计算”的路由方案。我指令 AI 进行如下重构:
- 创建专用的路由向量集合:在向量数据库中创建一个新的、专门用于路由的集合。
- 预计算与存储:当一个知识库被创建或其描述被更新时,系统需要立即将其描述向量化,并将这个向量与对应的知识库 ID 存入上述的路由集合中。
- 重构检索逻辑:路由逻辑不再从数据库捞取所有描述,而是直接将用户问题向量化,然后向路由集合发起一次高效的相似性搜索,瞬间找出最相关的知识库 ID。
这 30% 的人类智慧:应用核心原理进行架构级的性能优化。 从“实时计算”到“预计算”,这是一个典型的用空间换时间的架构优化模式。AI 拥有实现这两种模式的知识,但它缺乏识别“何时应该进行这种模式转换”的经验和判断力。这种基于对系统瓶颈的深刻洞察而进行的架构重构,是高级工程师的核心价值体现。
第四章:文档解析与通用脚手架 —— 在理念与哲学层面与AI共舞
除了具体的业务项目,我与AI的合作还延伸到了更底层的工具和架构哲学层面。
场景一:文档解析服务的“双引擎混合动力”构想
我们有一个基于 Python 的文档解析服务,它使用传统库将文档转为 Markdown,速度快、成本低。但我们发现,它在处理视觉元素极其丰富的文档时能力有限。
我向 AI 提出了一个战略升级构想:引入视觉大语言模型(VLM),构建一个“双引擎混合动力”系统。
- 引擎A (高效解析管线):默认引擎,处理常规文档,快且便宜。
- 引擎B (深度理解引擎):基于 VLM,处理视觉密集型文档,慢但理解能力强。 系统内部会有一个“智能路由”,自动为文件选择最优引擎,同时提供专家模式供手动指定。这份构想被AI整理成了一份正式的项目备忘录,作为项目未来的战略指引。
这 30% 的人类智慧:定义项目的长远技术愿景。 在这个场景中,我不再是解决一个具体的技术问题,而是在定义一个项目的灵魂和未来发展路径。我负责提出这种富有前瞻性的、融合多种技术优势的混合架构理念。AI 则扮演了出色的“技术书记”角色,帮助我将模糊的思考和权衡,固化为清晰的备忘录和设计原则。
场景二:Go 服务脚手架的“工具箱哲学”
在启动公司级的 Go 服务脚手架项目时,我们最初的目标是构建一个技术上“完美”的、基于依赖注入和接口化的纯粹分层架构。
但在团队沟通中,我们遇到了现实的挑战:“小项目有必要搞这么复杂吗?”、“团队现在不做单元测试,这套架构的收益在哪?”。这让我意识到,一个脱离团队现状的“完美”架构,本身就是一种“过度设计”。
基于此,我与 AI 共同确立了脚手架全新的核心理念——“赋能而非限制”的工具箱哲学。
- 提供选项,而非统一标准:脚手架将同时支持“简单模式”(全局
GetDB())和“结构化模式”(依赖注入)。 - 文档即是最终解释权:README 以及各类文档将成为一份详尽的“决策指南”,阐述两种模式的适用场景、优缺点和背后的工程权衡,目的是教育和引导开发者。
- 支持渐进式演进:项目可以用简单模式启动,并在未来根据文档指引平滑重构。
这 30% 的人类智慧:在“最佳实践”与“团队现实”之间寻找务实的平衡点。 AI 可以告诉我什么是业界“最好”的架构,但它不懂我的团队,不懂组织文化,不懂在特定情境下“最合适”的架构可能并非“最好”的。而我作为人类领导者,需要在技术的纯粹性与团队的接受度、项目的实际需求之间做出艰难但必要的权衡。这种充满“人情味”和现实考量的决策,是 AI 无法替代的。
结论:重新定义“我”与“AI”的角色
回顾至今,我与 AI 的协作模式经历了一次深刻的演进。它不再是我单向地向一个工具索取代码片段,而是一种深度共创的伙伴关系。
AI 的角色,从一个积极但缺乏远见的“初级程序员”,成长为一个能力覆盖全栈的“架构师伙伴”。它能将我的战略意图转化为详尽的技术蓝图,能在我需要时提供多种备选方案,甚至能在我思考技术哲学时,成为我的“思想碰撞的伙伴”。
而我的身份,也从单纯亲力亲为的开发者,逐渐转变为一名真正的 “AI 团队的领导者”。即便团队里只有我和它,我们依然像一个完整的团队在协作。我的核心工作已不再是亲自敲下每一个 for 循环或 if-else 判断,而是:
- 提出正确的问题和定义清晰的战略意图。
- 在AI提供的多个方案中,进行充满智慧和经验权衡的关键性架构决策。
- 洞察AI无法理解的业务细节、隐性规则和非功能性需求,并将其转化为精确的指令。
- 评估最终的交付成果,确保其不仅功能正确,而且在性能、可维护性和健壮性上都达到了人类工程师的高标准。
AI 帮我减轻了 70% 的重复性编码负担,却让我更深刻地意识到:工程师的真正价值,永远藏在那无法被AI轻易取代的、充满对业务的深刻洞察、对架构的精妙权衡、对团队的务实考量,以及对产品未来的无限创造力的 30% 里。
这是一种全新的、令人兴奋的工作范式。它没有削弱我的价值,反而将我从繁琐的实现细节中解放出来,让我能专注于最具创造力和战略性的工作。未来,AI 也许会变得更强大,甚至在某一天取代程序员,但至少当下,它为我打开了一种新的可能——一种值得持续学习、关注并与之共同成长的可能。毕竟,它尚无法真正理解业务逻辑,更无法平衡计算机之外的利益考量;它需要一个能够统筹全局、做出判断的人来领导。而这个角色,正是我。