AI全栈开发工程化实践:Harness+SDD+多仓模式破解复杂交付难题
1. 项目概述当AI全栈开发遇上现代工程化最近在得物技术团队内部我们完成了一次很有意思的工程实践核心是把Harness、SDD和多仓管理模式这三样东西揉进了一个AI全栈开发的项目里。听起来有点“缝合怪”的意思但实际跑下来这套组合拳的效果远超预期尤其是在应对AI应用那种“需求变化快、技术栈杂、部署运维烦”的特性时显得格外顺手。今天就来聊聊我们是怎么做的以及踩过哪些坑。简单来说这个项目就是一个典型的AI驱动型业务应用前端有复杂的交互后端需要集成多个大模型和传统服务数据流和模型版本管理都是头疼事。传统的单体仓库手动部署松散的项目管理方式在快速迭代的AI项目面前很快就捉襟见肘。我们的目标很明确建立一个既能支撑AI应用快速实验、又能保证工程质量和交付效率的现代化开发体系。最终Harness作为CI/CD和GitOps的核心SDDStory-Driven Development作为需求管理和开发协作的框架多仓模式作为代码和模块的组织形式三者协同构成了这次实践的主线。如果你也在做AI应用或者任何技术栈复杂、需要快速迭代的全栈项目觉得从需求到上线的链路总是磕磕绊绊那接下来的内容或许能给你一些直接的参考。我们不仅会讲清楚每部分怎么用更会重点分享为什么这么选以及实际配合时那些“教科书上不会写”的细节。2. 核心架构与选型逻辑为什么是HarnessSDD多仓在启动项目前我们评估过不少方案。最终锁定“Harness SDD 多仓”这个组合不是拍脑袋而是基于AI全栈开发的几个核心痛点做的针对性选择。2.1 剖析AI全栈开发的典型痛点AI项目尤其是全栈应用和传统Web开发有很大不同技术栈异构且迭代快前端可能是React/Vue后端是PythonFastAPI/Flask或JavaSpring Boot中间还夹着PyTorch/TensorFlow的模型训练代码、各种向量数据库的接入。每个部分的技术选型和版本都可能独立、快速地变化。环境依赖复杂CUDA版本、Python包、系统库……模型推理服务的环境配置堪称“玄学”复现困难。“在我机器上能跑”是常态。交付物多样不止是应用二进制包还包括训练好的模型文件.pt, .h5、向量化后的数据索引、配置文件等。这些都需要版本化管理并纳入交付流水线。需求不确定性高AI功能的效果往往需要快速试错。产品经理可能基于一个初步的模型效果提出需求但实际开发中模型可能需要反复调优甚至更换导致后端接口、前端展示逻辑随之频繁变动。传统的单仓分支策略所有代码混在一起一个模型训练脚本的改动可能会触发整个前后端的CI构建慢、依赖混乱。而松散的手工部署则完全无法应对模型版本回滚、A/B测试等复杂场景。2.2 多仓管理模式解耦与自治的基石首先我们采用了多仓库Multi-Repo模式。这不是什么新概念但在AI场景下价值被放大。前端仓库包含所有UI组件、状态管理和与后端的API交互逻辑。后端服务仓库核心业务逻辑、传统微服务、数据库操作等。AI模型服务仓库独立存放模型推理服务代码、模型加载逻辑、Prompt工程模板等。这里可能是Python项目。基础设施即代码IaC仓库存放Kubernetes的YAML文件、Helm Charts、Harness Pipeline配置等。为什么选多仓核心是解耦和自治。AI模型团队可以独立地迭代他们的模型和服务遵循自己的发布节奏而不必担心影响前端或核心后端。每个仓库都可以有自己独立的CI流程比如模型仓库需要跑单元测试和简单的推理验证构建速度更快。权限管理也更清晰前端工程师无需关心模型仓库的代码。注意多仓最大的挑战是依赖管理和版本协调。比如前端需要调用后端v1.2的API而后端v1.2又依赖AI模型服务的v0.5。我们通过清晰的接口约定Protobuf/OpenAPI和Harness的“服务”概念来管理这些依赖后面会详细说。2.3 SDD在快速变化中锚定需求面对AI需求的多变我们引入了SDDStory-Driven Development。它不同于传统的“接到PRD就开干”更强调以用户故事User Story为驱动和协作中心。流程每个功能点都从一个清晰的用户故事卡片开始格式是“作为一个[角色]我希望[达成某个目标]以便于[获得某种价值]”。这张卡片会关联到具体的验收条件Acceptance Criteria并成为开发、测试、产品讨论的唯一依据。在AI项目中的价值对于“智能商品推荐”这类功能故事可能是“作为一名用户我希望在浏览鞋类商品时页面能根据我最近的浏览记录展示我可能感兴趣的其他款式以便更快找到心仪商品”。这个故事明确了场景浏览鞋类、输入浏览记录、输出推荐款式和价值提升效率。当模型效果不理想需要调整推荐算法时我们依然围绕这个故事进行讨论和验收避免了需求范围的蔓延。SDD确保了无论后端模型怎么变前端交互怎么调我们始终知道为什么要做这个功能以及怎样才算做完。它为多团队协作提供了稳定的“需求锚点”。2.4 Harness串联一切的自动化引擎最后是Harness它扮演了“胶水”和“自动化引擎”的角色。我们主要用到了它的几个模块CI模块为每个仓库配置自动化的构建、测试流程。CD模块实现基于GitOps的自动化部署。这是关键。Feature Flags用于灰度发布和A/B测试这对验证AI功能效果至关重要。Cloud Cost Management监控模型推理服务等资源消耗。为什么是Harness而不是Jenkins或GitLab CI对于复杂的AI全栈交付我们需要一个能原生理解“服务”、“环境”、“基础设施”概念的平台。Harness将每一次部署都抽象为一个“服务”的一个“版本”在某个“环境”中的发布。这完美契合了多仓模式我们可以定义一个“智能推荐服务”它的源码关联到后端仓库和AI模型仓库。当这两个仓库任一有新的合格镜像构建出来Harness能自动或手动触发这个“服务”的新版本部署。它帮我们解决了多仓下版本同步和协同发布的核心难题。3. 实战搭建从代码提交到服务上线的完整流水线理论说再多不如看实操。下面我以一次“优化商品标题生成AI模型”的需求为例拆解整个流程。3.1 故事驱动下的开发启程假设我们收到一个用户故事“作为商家我希望在上架新商品时系统能根据我输入的关键属性如品牌、款式、颜色自动生成一段吸引人的商品标题以便提升商品点击率。”故事拆解与任务创建前端需要优化商品发布页增加一个“AI生成标题”的按钮和展示区域。后端需要提供一个新API接收商品属性调用AI服务返回生成的标题。AI模型服务需要优化或训练一个新的文本生成模型比如基于T5或GPT-2微调并暴露一个推理接口。验收条件生成的标题需通顺、包含关键属性、符合电商文案风格点击按钮后3秒内返回结果。分支策略每个团队在自己的仓库中从主分支拉取一个以故事ID命名的特性分支例如feature/STORY-123-ai-title-generation。这保证了所有代码变更都能追溯到具体的故事。3.2 多仓协同开发与独立CI各个团队在各自分支上并行开发。AI模型仓库数据科学家在feature/STORY-123-ai-title-generation分支上调整模型架构和训练数据。他们提交代码后触发Harness CI流水线# 简化版Harness CI Pipeline配置示例 pipeline: name: ai-model-service-ci stages: - stage: name: 构建与测试 steps: - step: type: BuildAndPush name: 训练镜像构建 spec: connectorRef: docker-hub-connector # 连接器 repo: our-org/ai-title-model tags: pipeline.sequenceId # 使用流水线执行ID作为标签 - step: type: Run name: 运行单元测试与简易推理测试 spec: shell: Bash command: | python -m pytest tests/ -v python scripts/quick_inference_test.py # 一个快速验证脚本这条流水线会构建一个包含训练/推理代码的Docker镜像并推送到镜像仓库标签为流水线ID。后端服务仓库后端工程师在同一个故事分支下开发新的API端点。他们的CI流水线会运行单元测试、集成测试并构建后端应用镜像。前端仓库前端工程师开发UI组件。他们的CI流水线会运行Lint检查、单元测试并构建静态资源。关键点每个仓库的CI都是独立、快速的。AI模型仓库的CI不需要安装Node.js前端仓库的CI也不需要GPU环境。3.3 基于Harness GitOps的协同部署当三个仓库的特性分支都开发完成并通过各自的CI后就进入集成和部署阶段。这是Harness发挥核心作用的地方。创建Harness服务我们在Harness中定义一个叫product-title-ai-service的服务。这个服务并不直接对应一个代码仓库而是一个逻辑上的应用。在它的“配置”里我们关联两个“制品源”后端服务镜像指向后端仓库CI产出的最新镜像。AI模型服务镜像指向AI模型仓库CI产出的最新镜像。环境与基础设施定义我们有一个“开发”环境关联到Kubernetes集群的一个命名空间。基础设施通过IaC仓库如存放K8s YAML的Git仓库定义。GitOps工作流当AI模型团队觉得模型ready了他们将特性分支合并回主分支。这会触发主分支的CI构建一个“稳定版”镜像标签为latest或v1.2.3。与此同时后端团队也合并了他们的分支。部署的触发我们配置Harness CD Pipeline监听这两个“制品源”。当检测到product-title-ai-service所依赖的后端镜像或AI模型镜像有新版本被推送到镜像仓库时可以自动或手动触发部署。部署过程Harness会从IaC仓库拉取最新的Kubernetes部署清单Deployment YAML并将清单中镜像的标签替换为刚刚构建出来的新版本标签然后自动kubectl apply到“开发”环境的K8s集群中。前端部署前端静态资源通常部署到CDN或Ingress。我们可以配置另一个独立的Harness CD Pipeline监听前端仓库的镜像或代码变更触发前端部署。这样一来无论哪个组件更新Harness都能确保将所有相关服务的最新正确版本协同部署到目标环境。这解决了多仓下“部署谁、部署哪个版本、怎么一起部署”的混乱问题。3.4 利用Feature Flags进行AI功能验证服务部署到开发环境后我们并不急于全量开放。因为AI效果需要验证。 我们在前端代码和后端API中集成Harness的Feature FlagsFFSDK。后端在调用AI模型服务前检查一个叫enable_ai_title_generation的标志。前端“AI生成标题”按钮的显示和调用也受这个标志控制。在Harness控制台我们可以针对这个标志做精细化的规则设置对内部测试人员规则设置为100%开启让他们充分测试。对线上1%的随机用户开启进行小流量灰度收集真实用户反馈和效果数据如点击率。根据效果决策如果灰度数据表现好逐步放量到10%、50%、100%。如果效果不好直接在控制台将标志关闭功能瞬间对所有用户下线而无需回滚代码或重新部署。这为AI功能的试错提供了极大的灵活性和安全性。4. 核心配置详解与避坑指南光有流程不够细节决定成败。下面分享几个关键配置和踩过的坑。4.1 Harness Pipeline中的“服务”与“环境”抽象这是Harness理念的核心也是新手最容易配置不当的地方。服务Service不要把它简单理解为一个代码仓库或一个Docker容器。它应该代表一个可独立部署、具有版本概念的逻辑单元。在我们的例子里product-title-ai-service就是一个服务它由后端和AI模型两个“制品”共同构成。在Harness中一个服务可以关联多个“制品源”。环境Environment代表部署的目标如“开发”、“预发”、“生产”。每个环境关联具体的基础设施如K8s集群、命名空间。关键技巧为不同环境配置不同的“配置覆盖”Configuration Overrides。例如开发环境的模型可能用CPU推理生产环境用GPU不同环境的数据库连接串、API密钥通过Harness的“密文”管理功能注入。避坑指南初期我们曾为后端和AI模型分别创建了两个Harness服务。结果部署时无法保证它们版本的一致性常出现后端调用了不兼容的老版本模型API的错误。后来才纠正为“一个逻辑服务多个物理制品”的模式。4.2 多仓下的版本号与依赖管理我们采用语义化版本SemVer但并非每个仓库都严格遵循。前端/后端仓库严格遵循主版本.次版本.修订号变动在CHANGELOG中记录。AI模型仓库由于迭代极快我们采用“日历化版本”CalVer如模型名称-2024.05.01-1表示2024年5月1日的第一次构建。这更符合数据科学的工作习惯。依赖管理策略接口契约优先前后端、后端与AI服务之间严格使用OpenAPISwagger或gRPC Proto文件定义接口。这些接口定义文件可以放在一个独立的“契约仓库”或者作为某个主导仓库的一部分通过Git Submodule或包管理如将Proto文件发布到私有仓库被其他仓库引用。在Harness中建立依赖关系在product-title-ai-service的部署流程中我们可以设定步骤顺序例如“先更新AI模型服务Pod等待其健康检查通过再更新后端服务Pod”。这保证了服务启动的依赖顺序。数据库/缓存等中间件变更通过独立的“数据库迁移脚本仓库”管理并在Harness CD Pipeline中增加“执行数据库迁移”的步骤该步骤在应用部署前运行。4.3 SDD故事卡的颗粒度与完成标准SDD要落地故事卡写得好不好是关键。避免过于庞大的故事例如“重构智能推荐系统”这种故事太大无法在一个迭代内完成。应该拆解成“优化推荐结果多样性”、“增加实时行为反馈”等多个小故事。验收条件必须可测试像“生成标题要吸引人”这种是主观的。要将其转化为客观条件如“生成的标题必须包含所有用户输入的关键属性词”、“标题长度在15-30字之间”、“通过一个预训练的文本质量模型打分高于X分”。这样开发、测试、产品才有统一的验收标准。关联技术任务在故事卡下可以创建技术子任务如“[后端] 提供标题生成API”、“[AI] 微调T5模型并部署”。这些子任务直接关联到代码仓库的Issue或分支实现需求到代码的双向追溯。5. 效能提升与问题排查实录这套体系运行一段时间后我们观察到了一些明显的效能变化也积累了一批典型问题的排查方法。5.1 关键效能指标对比指标传统模式单仓手动HarnessSDD多仓模式从需求到开发启动约2-3天PRD评审、技术方案设计约0.5-1天故事卡研讨与拆分特性分支平均构建时间15-20分钟全栈构建前端3分钟后端5分钟AI模型8分钟并行独立构建集成部署频率每周1-2次大包合并风险高每天多次小批次自动化线上问题定位平均时间较长需排查代码、配置、部署记录大幅缩短Harness提供完整的部署时间线、版本差异对比AI功能灰度与回滚困难需重新部署分钟级通过Feature Flags切换最直观的感受是团队间的等待和耦合减少了。AI团队可以一天内发布多次模型迭代而不必催促前端或后端配合发布。产品经理可以通过调整Feature Flags的规则快速验证不同AI策略的效果。5.2 常见问题与排查技巧问题Harness部署失败报错“镜像拉取失败”。排查首先检查Harness中“服务”配置的制品源确认镜像标签是否正确。其次检查部署目标K8s集群的节点是否配置了正确的镜像仓库拉取密钥ImagePullSecrets。一个技巧在Harness CD Pipeline中在部署步骤前增加一个“Shell Script”步骤用kubectl run test-pod --image你的镜像 --restartNever --command -- sleep 5命令预先测试一下镜像能否拉取。问题前端调用新API失败但后端日志显示API已正常部署。排查这通常是多仓版本不一致的典型问题。首先通过Harness的部署历史确认前端服务当前运行的版本以及后端服务当前运行的版本。然后检查这两个版本对应的代码分支是否在接口契约OpenAPI上匹配。我们养成的习惯在每次跨团队的故事卡开发启动时会先一起更新并确认接口契约文件并将其合并到主分支各团队基于此契约开发。问题AI模型服务更新后响应时间变慢或准确率下降。排查利用Harness的“部署后验证”功能。我们配置了一个验证步骤在模型部署后自动发送一批预设的测试用例到新部署的模型端点并断言响应时间和结果准确性。如果验证失败Pipeline会自动将部署标记为失败并触发回滚Rollback。更进一步我们将生产环境模型推理的延迟和错误率指标接入监控系统如Prometheus并在Harness中配置这些指标作为“持续验证”的条件实现长期监控。问题Feature Flags不生效。排查首先检查Harness控制台该标志是否已开启规则是否正确。其次检查应用内SDK的初始化是否正确特别是SDK Key和环境是否匹配。在K8s环境中常见的一个坑应用Pod可能缓存了旧的标志规则。确保SDK配置了合理的轮询间隔并在Harness中更改规则后允许一定的传播时间。对于紧急情况可以重启应用Pod来强制刷新。6. 进阶实践安全、成本与未来展望当基础流程跑顺后我们开始关注更进阶的话题。6.1 安全与合规性集成AI应用涉及数据安全。秘密管理所有API Key如OpenAI、向量数据库、数据库密码等均使用Harness内置的秘密管理器可集成Vault、AWS Secrets Manager等存储。在Pipeline中通过变量引用绝不硬编码在代码或配置文件中。镜像安全扫描在CI流水线的“构建与推送”步骤后我们集成了Trivy镜像漏洞扫描步骤。只有扫描通过无高危漏洞的镜像才会被推送到生产镜像仓库并触发后续的CD流程。模型文件安全训练好的模型文件作为重要资产我们将其存储在企业级的对象存储如S3中并通过Harness Pipeline在部署时使用临时凭证安全地下载到Pod内。6.2 AI资源成本管控GPU资源昂贵成本管控是AI项目的必修课。资源请求与限制在K8s的Deployment YAML中为AI模型服务容器精确设置resources.requests和resources.limits。避免资源浪费。利用Harness CCM我们将集群的计量数据与Harness的Cloud Cost Management模块对接。它可以清晰地展示每个命名空间、每个部署对应我们的Harness服务的资源消耗和成本甚至能下钻到Pod级别。这让我们能快速发现“哪个模型服务这个月特别耗钱”从而进行优化或预算调整。自动伸缩HPA为AI推理服务配置基于CPU/内存或自定义指标如QPS的Horizontal Pod Autoscaler在流量低谷时自动缩容以减少成本。6.3 面向AI Agent的开发流程演进当前的热点是AI Agent。我们的流程也在为此做准备。将Agent视为特殊服务一个具备自主推理和工具调用能力的Agent可以封装成一个独立的服务进行部署。它的版本管理、CI/CD流程与其他服务无异。Prompt即代码纳入版本控制Agent的核心之一是其Prompt模板。我们将这些Prompt模板文件放在代码仓库中与业务逻辑一起进行版本管理、代码审查和CI测试例如运行简单的断言确保Prompt格式正确。测试挑战Agent的非确定性输出是测试难点。我们正在探索的实践是在CI中为Agent服务增加一个“集成测试”阶段使用一批固定的测试用例和模拟工具调用环境对Agent的输出进行“合理性”评估如检查是否包含关键信息、是否符合安全规范而非精确匹配。回头看Harness SDD 多仓这套模式本质上是通过工程化手段为高不确定性的AI应用开发注入确定性的协作和交付流程。它没有魔法只是把软件工程中已验证的最佳实践针对AI项目的特性做了适配和整合。最大的收获不是工具本身多厉害而是它强制团队形成了清晰的责任边界、契约化的协作接口和自动化的质量关卡。对于正在探索AI落地的团队不妨从一个小项目开始尝试引入这三者中的一两个点比如先用SDD管好需求或者用Harness自动化一个模型的部署流程感受一下工程化带来的秩序和效率提升可能比一开始就追求大而全的体系要更实际。