尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Harness工程:AI编程规范驱动的核心基础设施与实战

Harness工程:AI编程规范驱动的核心基础设施与实战 1. 从“AI编程”到“规范驱动”为什么我们需要Harness最近和几个团队的技术负责人聊天发现一个挺有意思的现象大家或多或少都开始用上了AI编程助手比如GitHub Copilot、Cursor或者直接让Claude、GPT-4来写代码。初期效果确实惊艳生成速度飞快代码看起来也像模像样。但兴奋劲儿一过问题就来了——生成的代码质量参差不齐风格五花八门安全漏洞、性能问题、架构不一致性这些“暗坑”比比皆是。更头疼的是把这些AI生成的代码片段集成到现有的大型工程项目里就像把一堆形状各异的乐高积木硬塞进一个已经搭了一半的精密模型里要么塞不进去要么塞进去后整个结构都变得摇摇欲坠。这背后反映的正是当前“AI辅助编程”的一个核心痛点我们拥有了强大的“代码生成器”但严重缺乏一个可靠的“代码质检与装配流水线”。AI模型擅长根据自然语言描述生成代码但它不理解你项目的具体规范、架构约束、团队约定和业务上下文。它不知道你这个微服务里禁止使用某个过时的库不知道你的数据库操作必须统一走某个ORM层更不知道你的日志格式、错误处理、API响应体都有严格的定义。这就是“AI规范驱动编程”要解决的问题而Harness工程正是实现这一目标的关键基础设施。简单来说Harness不是另一个AI Agent也不是要取代现有的AI编码工具。你可以把它理解为一套“规则引擎”和“质量门禁”系统它包裹在AI核心的代码生成逻辑之外。当AI无论是大模型还是专用代码生成器产出一个代码片段、一个函数甚至一个模块时Harness会第一时间介入用你预先定义好的、机器可读的“工程规范”去校验、修正、重构甚至重写这段代码确保其产出物能无缝、安全、高质量地融入你的具体项目。它让AI的创造力被引导和约束在工程实践的轨道上从而实现从“有代码”到“有好代码”、“有可用的代码”的质变。2. 拆解Harness它到底是什么不是什么网络上关于Harness的讨论很多但概念容易混淆。结合最新的技术讨论和工程实践我们需要清晰地界定Harness的边界。2.1 Harness的核心定位AI Agent的“脚手架”与“质检员”首先必须明确一个关键区别Harness ≠ AI Agent。AI Agent是具备自主感知、规划、决策和执行能力的智能体。在编程场景下一个高级的AI编程Agent可以理解需求、拆解任务、选择工具、编写代码、运行测试、修复Bug甚至部署应用。它的核心是“推理”和“执行”。Harness则是一套基础设施层。它不负责代替Agent进行核心的推理和创意性工作。它的职责是提供结构化上下文为AI准备好当前项目的“地图”和“工具箱”包括代码库结构、依赖关系、API文档、架构图、已有的工具函数等。执行规范校验定义并强制执行代码风格如Prettier, ESLint、安全规则如Semgrep、架构约束如依赖注入检查、性能模式等。管理交互流程标准化AI与开发环境、版本控制系统、CI/CD流水线等的交互协议确保操作可预测、可回滚。反馈与学习收集AI生成结果的采纳率、人工修改点形成反馈闭环用于优化提示词Prompt或规范本身。用一个比喻AI Agent是才华横溢但天马行空的建筑设计师而Harness是严谨的工程监理和施工规范手册。设计师画出蓝图监理确保每一块砖都按标准砌筑钢筋水泥的标号符合要求最终建筑才能既美观又坚固。2.2 实战中的Harness构成要素一个完整的、用于规范驱动编程的Harness系统通常包含以下几个层次规范定义层Specification Layer形式这不仅仅是写在Confluence里的文档。它必须是机器可读、可执行的。常见形式包括配置文件.eslintrc.js,.prettierrc,pyproject.toml(用于Ruff/Black),checkstyle.xml等。领域特定语言DSL自定义的、用于描述架构规则如“ServiceA不能直接调用ServiceB的数据库”或业务逻辑约束的DSL。测试用例与契约API的OpenAPI Spec、数据模型的Pydantic/TypeScript接口、单元测试等它们本身就是一种“活”的规范。内容涵盖代码风格、安全策略、依赖管理、API设计、错误处理、日志规范、性能基线等。上下文管理层Context Management Layer作用解决AI的“健忘症”和“视野狭窄”问题。当AI为/src/services/payment.ts文件生成代码时Harness需要自动为它提供当前文件及相邻文件的代码。项目依赖图哪些模块依赖它它依赖哪些模块。相关的数据模型定义如Payment接口。类似的现有代码模式如其他Service是怎么写的。最近的Git提交历史和TODO注释。工具这通常通过增强的检索增强生成RAG系统实现从代码库、文档库中实时检索最相关的信息并结构化地注入到给AI的提示词中。执行与验证层Execution Validation Layer这是Harness的“肌肉”。它接收AI生成的原始代码或代码变更建议然后启动一个流水线进行处理静态分析调用配置好的linter、formatter、安全扫描工具。动态验证可选但强大在安全的沙箱环境中尝试编译、运行相关的单元测试甚至启动一个轻量级集成测试。规范匹配使用自定义的规则引擎检查代码是否违反DSL定义的架构规范。如果检查失败Harness不会直接让人工介入而是可以自动修复对于格式问题、简单的语法错误直接调用formatter修复。生成修正建议对于更复杂的问题将错误信息和上下文重新打包反馈给AI要求其重新生成或修正代码。这形成了一个“生成-校验-反馈-再生成”的闭环。集成与编排层Integration Orchestration Layer作用将上述能力无缝嵌入到开发者的工作流中。无论是IDE插件如VS Code Copilot Chat的增强插件、CLI工具还是作为CI/CD流水线中的一个自动审核步骤。关键接口与版本控制系统如Git的集成能够处理Pull Request的代码审查评论与项目管理工具如Jira的联动获取任务上下文。3. 构建你的第一个Harness一个Spring Boot API项目的实战理论说了这么多我们来点实际的。假设我们有一个基于Spring Boot的用户管理系统后端项目现在希望引入Harness来规范AI比如使用Cursor或ChatGPT生成的代码质量。我们的目标是AI生成的任何Controller、Service、Repository代码都必须符合我们的项目规范。3.1 第一步定义机器可读的规范这是最基础也最重要的一步。我们不能只靠口头约定。1. 代码风格与基础质量使用现有工具在项目根目录下我们强化已有的配置文件pom.xml/build.gradle: 明确定义Java版本、Spring Boot版本并加入关键插件。!-- 在pom.xml的build/plugins部分 -- plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-checkstyle-plugin/artifactId version3.3.0/version configuration configLocationgoogle_checks.xml/configLocation !-- 使用Google代码风格 -- /configuration executions executiongoalsgoalcheck/goal/goals/execution /executions /plugin plugin groupIdcom.github.spotbugs/groupId artifactIdspotbugs-maven-plugin/artifactId version4.8.3/version /plugin.editorconfig: 统一所有编辑器的基本设置。关键动作确保这些检查在本地mvn compile阶段和CI流水线中强制执行。这样Harness系统或你自己在拿到AI代码后第一件事就是运行mvn compile任何风格和基础bug都会暴露。2. 架构规范自定义规则我们在/docs/architecture-rules目录下创建一个简单的YAML文件layer-rules.yaml用DSL定义分层架构约束rules: - name: controller-depends-on-service description: Controller层只能依赖Service层接口不能依赖Repository或Mapper。 check: class: *Controller forbidden: imports: - *.repository.* - *.mapper.* - org.springframework.data.jpa.repository.* allowed: imports: - *.service.* - org.springframework.web.bind.annotation.* - jakarta.validation.* - name: service-transactional-readonly description: 执行只读操作的Service方法必须标注Transactional(readOnly true) check: method: *Service.* condition: method.name matches find|get|query|list required: annotations: - org.springframework.transaction.annotation.Transactional(readOnly true)这个YAML文件就是我们的“架构宪法”。我们需要编写一个简单的脚本可以用Python libcst或Java Parser来解析AI生成的代码并校验这些规则。3. API设计规范使用OpenAPI契约使用Spring Doc OpenAPI并严格要求Operation,ApiResponse等注解的完整性。在pom.xml中配置springdoc-openapi-ui并设定一个目标所有RestController下的公开端点都必须有完整的OpenAPI注解描述。我们可以把这个作为Harness校验的一部分扫描新的Controller类如果发现公开方法缺少Operation注解则视为不规范。3.2 第二步创建上下文检索器Context RetrieverAI需要知道我们的项目“长什么样”。我们创建一个简单的Python脚本作为Harness的一部分当需要为UserService添加方法时这个脚本能自动收集相关信息# harness/context_retriever.py import os from pathlib import Path import ast class CodebaseContextRetriever: def __init__(self, project_root): self.project_root Path(project_root) def get_context_for_file(self, file_path, context_lines50): 获取目标文件及其附近文件的代码 target_path self.project_root / file_path context {} # 1. 获取目标文件内容 context[target] target_path.read_text() # 2. 获取同目录下其他Java文件可能是相关类 sibling_files list(target_path.parent.glob(*.java)) context[siblings] {f.name: f.read_text() for f in sibling_files if f ! target_path} # 3. 获取可能相关的模型类根据命名约定推测 # 例如为UserService找User、UserDTO、UserRepository # ... 实现简单的命名推理和文件查找逻辑 return context def get_architectural_rules(self): 读取架构规则DSL rules_path self.project_root / docs / architecture-rules / layer-rules.yaml # 解析YAML并返回结构化规则 # ... # 使用示例 retriever CodebaseContextRetriever(/path/to/spring-boot-project) context retriever.get_context_for_file(src/main/java/com/example/service/UserService.java)这个检索器收集的信息将被格式化后作为“系统提示词”的一部分发送给AI模型极大地提升生成代码的上下文相关性。3.3 第三步实现校验与修正闭环这是Harness的“大脑”和“双手”。我们设计一个主流程# harness/validator_orchestrator.py import subprocess import tempfile from .context_retriever import CodebaseContextRetriever from .rule_engine import ArchitecturalRuleEngine # 假设我们实现了规则引擎 class HarnessOrchestrator: def __init__(self, project_root, ai_client): # ai_client可以是OpenAI、Claude等客户端 self.project_root project_root self.ai_client ai_client self.retriever CodebaseContextRetriever(project_root) self.rule_engine ArchitecturalRuleEngine(project_root) def process_ai_generated_code(self, original_prompt, ai_raw_code, target_file_path): 处理AI生成的原始代码。 1. 提供上下文 2. 生成代码 3. 校验并尝试修正 返回最终可用的代码或错误报告。 # 1. 获取丰富上下文 context self.retriever.get_context_for_file(target_file_path) enhanced_prompt self._build_enhanced_prompt(original_prompt, context) # 2. 可选如果ai_raw_code是初次生成的结果可以跳过。这里我们假设需要Harness驱动AI生成。 # generated_code self.ai_client.generate_code(enhanced_prompt) # 3. 将生成的代码写入临时文件进行静态检查 with tempfile.NamedTemporaryFile(modew, suffix.java, deleteFalse) as tmp: tmp.write(ai_raw_code) tmp_path tmp.name # 运行Maven编译检查包含Checkstyle, Spotbugs compile_result subprocess.run( [mvn, compile, -f, f{self.project_root}/pom.xml], capture_outputTrue, textTrue ) issues [] if compile_result.returncode ! 0: issues.append(f编译/静态检查失败\n{compile_result.stderr}) # 4. 运行自定义架构规则检查 rule_violations self.rule_engine.validate(ai_raw_code, target_file_path) if rule_violations: issues.append(f架构规则违反\n{rule_violations}) # 5. 判断并处理问题 if not issues: return {status: success, code: ai_raw_code} else: # 将问题反馈给AI要求其修正 feedback_prompt f 之前生成的代码存在以下问题 { .join(issues)} 请根据以上问题和原始需求重新生成代码。 原始需求{original_prompt} 项目上下文摘要{str(context)[:500]}... corrected_code self.ai_client.generate_code(feedback_prompt) # 可以递归调用process_ai_generated_code进行再次校验或设置最大重试次数 return {status: corrected, code: corrected_code, initial_issues: issues}这个流程实现了最基本的“生成-校验-反馈”循环。在实际项目中这个Orchestrator可以作为一个独立的服务或者集成到IDE插件中。4. 进阶将Harness融入CI/CD与团队协作个人使用的Harness能提升效率但Harness真正的威力在于团队协作和流程保障。4.1 作为PR的自动守门员在GitHub Actions或GitLab CI中添加一个Harness校验步骤# .github/workflows/harness-review.yml name: AI Code Harness Review on: [pull_request] jobs: harness-review: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Set up JDK uses: actions/setup-javav3 with: { java-version: 17, distribution: temurin } - name: Run Harness Validation run: | # 1. 识别PR中新增或修改的代码块特别是可能由AI生成的部分可通过提交信息或diff特征识别 # 2. 对每个识别出的代码块调用Harness Orchestrator服务进行规范校验 # 3. 将校验结果通过、需修正、失败以评论形式提交到PR python harness/pr_reviewer.py --pr-url ${{ github.event.pull_request.html_url }}这个步骤会自动检查PR中代码是否符合所有预定义的规范并给出具体的修改建议甚至能提供自动修复的代码片段。它把代码审查的“低级劳动”自动化让人类 reviewer 更专注于算法逻辑、业务正确性等高级层面。4.2 构建团队共享的“规范知识库”Harness的规则DSL应该被版本化并作为项目的一部分进行管理。团队可以像讨论业务逻辑一样讨论和修订这些规则当引入一个新的第三方库时在dependency-rules.yaml中更新白名单。当决定迁移到新的日志框架时更新logging-rules.yaml。新的安全团队要求所有REST端点必须进行输入校验更新security-rules.yaml并在Harness中增加相应的AST检查规则。这个知识库是活的随着项目演进。新成员加入时不是给他一本厚厚的、可能过时的开发手册而是让他运行一遍Harness校验所有规范立刻在实践中清晰起来。4.3 处理“灰色地带”与人工裁决并非所有规则都能被100%精确量化。比如“这个方法是否过于复杂”、“这个类是否违反了单一职责原则”。对于这些Harness可以做到标记与提示通过代码复杂度分析工具如Lizard计算圈复杂度如果超过阈值则在PR评论中提示“该方法圈复杂度为12建议重构以提高可读性”并附上重构建议可以由AI生成。学习人工决策当人类reviewer推翻Harness的某个建议时可以记录这个案例。积累足够多数据后可以用于微调规则或训练一个更精细的分类器。5. 避坑指南Harness工程化路上的常见挑战在实际引入Harness的过程中我踩过不少坑这里分享几个关键点。坑一规则过严扼杀生产力。最初我们设定了极其严格的规则比如“每个Service方法都必须有Javadoc”、“每个DTO字段都必须有Schema描述”。结果AI生成的代码大量被卡住或者生成的Javadoc全是废话反而增加了噪音。教训规则应该分层。将规则分为“阻断级”如安全漏洞、编译错误、“警告级”如代码风格、缺少文档和“建议级”如性能优化。Harness对“阻断级”规则必须失败对“警告级”可以自动修复或强烈建议对“建议级”仅做提示。坑二上下文检索效率低下。最初我们的检索器会把整个项目几十万行代码的摘要都塞进提示词导致AI响应慢、成本高且关键信息被淹没。优化方案分层检索先检索文件结构再根据导入关系、命名相似性定位最关键的几个文件。向量化检索将代码片段、文档块向量化存储。当需要为“用户支付功能”生成代码时检索与“支付”、“订单”、“交易”语义最相关的代码片段而不是目录最近的文件。缓存机制对项目的基础架构上下文如pom.xml、主要配置类进行缓存避免每次重复检索。坑三与现有工具链的集成冲突。团队原本就有完善的SonarQube、JaCoCo覆盖率检查。直接引入Harness后出现了重复检查、报告冲突。解决方案将Harness定位为“开发阶段”和“PR阶段”的快速反馈工具而SonarQube作为“合并后”的深度质量看板。让Harness运行那些更快、更针对AI生成代码问题的检查如架构分层而将代码覆盖率、重复率等重型分析留给SonarQube。两者可以通过共享质量门禁配置来保持标准一致。坑四忽视对AI提示词Prompt的工程化。Harness不仅管输出也要管输入。给AI的初始提示词质量直接决定了生成代码的起点。我们建立了一个“Prompt模板库”针对不同任务“生成CRUD Service”、“生成复杂业务逻辑”、“修复空指针异常”有结构化的提示词模板其中已经内置了部分规范要求如“请使用Project Lombok的Data注解”。Harness系统在调用AI前会先根据任务类型选择合适的模板并注入具体的上下文这比每次让开发者从头写提示词要高效、稳定得多。Harness工程不是一个一蹴而就的“银弹”项目而是一个需要持续迭代的基础设施。从定义最关键的一两条规则开始从一个小的试点项目入手让团队感受到它带来的代码一致性提升和审查负担减轻再逐步推广和丰富规则库。它的最终目标是让AI生成的代码从“可用”变成“好用”从“需要大量修改”变成“几乎可以直接提交”从而真正释放开发者的创造力去解决更复杂的业务和架构难题。
返回列表