新闻详情

新闻详情

首页 / 资讯中心 / 详情

Harness Engineering 在软件工程层面的理论与实践:用 AGENTS.md 与 Linter 搭建 AI Coding 质量门禁

发布时间:2026/9/29 10:31:27来源:尧图网络
Harness Engineering 在软件工程层面的理论与实践:用 AGENTS.md 与 Linter 搭建 AI Coding 质量门禁
1. 为什么 AI Coding 需要 Harness Engineering你可能已经习惯了让 AI 帮你补全函数、生成单测、甚至整段重构。但真正把 AI Coding 放进一个持续交付的团队项目里问题会立刻暴露Agent 今天写的代码能跑明天就绕过了分层这次生成的 import 没问题下次就把 UI 层直接连到了数据库。代码量越大这种“隐性腐化”越难靠人工 Review 拦住。Harness Engineering 要解决的就是这件事。它不是让模型更聪明而是给模型套上一副“马具”——用 AGENTS.md 定义行为边界用 Linter 把架构约束变成可执行的检查让 AI 在写代码之前就知道什么不能做在写完代码之后立刻收到可操作的反馈。这套思路在 OpenAI 的 Codex 实验里被验证过人类工程师不再逐行写代码而是设计环境、定义规则、搭建反馈回路。这篇文章面向正在把 AI Coding 引入日常开发的工程师。我会给出可直接复制的 AGENTS.md 骨架、Python 与 JavaScript 两套 Linter 配置片段、本地验证命令以及如何通过 TaoToken 统一 Key/API 通道接入 AI 工具完成端到端校验。你不需要先成为 AI 专家只要有一个能跑测试的项目就可以跟着做。2. TaoToken 前置统一 Key 与 API 通道在搭建 Harness 之前先解决一个现实问题你的 AI 工具可能不止一个。Codex CLI、Claude Code、Cursor、自建脚本每个都配一套 Key 和 Base URL管理成本高切换模型时还要改环境变量。TaoToken 的作用是把这些统一到一个入口。TaoToken 是一个 AI 模型 API 聚合服务提供兼容 OpenAI 风格的接口。你可以在官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后拿到 API Key然后在各个工具里把 Base URL 指向 https://taotoken.net/api。这样无论是跑 Codex 做代码审查还是用 Claude 做交叉评审都走同一个 Key计费和额度也集中管理。具体操作分三步。第一步登录后进入控制台创建 API Key建议按项目或按工具分别建 Key方便后续排查用量。第二步在本地环境变量里配置export TAOTOKEN_API_KEYsk-你的key export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEY$TAOTOKEN_API_KEY第三步验证通道是否通。用 curl 发一个最小请求curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: reply with ok}] }如果返回里有choices字段说明通道正常。这一步很关键因为后面 Agent 自动审查、Linter 报错修复都依赖这个通道。如果你更习惯用现成的对话界面先试模型可以直接打开模型对话页面如果准备长期跑编码 Agent建议了解 Coding Plan 的额度方案需要管理多个 Key 时API Keys 页面可以随时创建和吊销。3. 可复制配置AGENTS.md 骨架与 Linter 规则3.1 AGENTS.md 骨架AGENTS.md 是 Agent 每次会话开始时自动读取的文件。它的核心原则是“导航而非内容”——保持在一百行左右指向更深层的 docs/ 目录而不是把所有规则堆在一起。下面是一个可以直接改用的骨架# AGENTS.md ## 项目简介 前后端分离的订单管理系统前端 React后端 FastAPI数据库 MySQL。 ## 技术栈 - 前端JavaScript React 19 Vite 6 - 后端Python 3.12 FastAPI SQLAlchemy - 数据库MySQL 8.0 - 缓存Redis 7 ## 快速开始 ### 后端 cd backend uv sync uv run alembic upgrade head uv run uvicorn app.main:app --reload ### 前端 cd frontend pnpm install pnpm dev ## 测试 make test-backend # 覆盖率要求 80% make test-frontend make test-all ## 架构原则 - 后端依赖方向types - config - repo - service - api单向流动禁止反向 - 前端依赖方向types - config - services - hooks - pages单向流动 - 前后端只通过 REST API 通信前端不直接访问数据库 - 详见docs/architecture/dependency-rules.md ## 编码规范 - 后端RuffLint 格式化mypy类型检查 - 前端ESLint Prettier - 单文件不超过 200 行单函数不超过 30 行 ## 常见陷阱 - 不要在 repo 层写业务逻辑只做 CRUD - 不要在 api 层直接操作数据库必须经过 service 层 - 前端不要用 fetch 直接调 API统一走 services/ 层 - 数据库变更必须通过 alembic 迁移禁止手动改表结构 ## 深入阅读 - 架构详情docs/architecture/overview.md - 设计约束docs/design/constraints.md - 技术债追踪docs/plans/tech-debt.md这个文件的关键在于“常见陷阱”部分。每次 Agent 犯错你就把教训写进去下次它就不会再犯。这比反复在 Prompt 里提醒有效得多。3.2 后端 Linterimport-linter 强制分层Python 项目用 import-linter 把分层规则变成可执行检查。在 backend 目录下创建.importlinter[importlinter] root_packages app [importlinter:contract:backend-layers] name 后端分层架构约束 type layers layers api service repo config types containers app这条规则的含义是api 可以 import serviceservice 可以 import repo但 repo 不能反过来 import service。一旦违反lint-imports会直接报错并指出违规的 import 路径。配合 Ruff 做代码质量检查在pyproject.toml里配置[tool.ruff] line-length 100 [tool.ruff.lint] select [E, F, I, N, UP, B, SIM] ignore [E501] [tool.ruff.lint.per-file-ignores] __init__.py [F401]3.3 前端 Lintereslint-plugin-boundaries前端用 eslint-plugin-boundaries 做同样的约束。先安装依赖cd frontend pnpm add -D eslint eslint/js eslint-plugin-boundaries然后在eslint.config.js里定义元素类型和允许的依赖方向import boundaries from eslint-plugin-boundaries; export default [ { files: [src/**/*.{js,jsx}], plugins: { boundaries }, rules: { boundaries/element-types: [error, { default: disallow, rules: [ { from: types, allow: [] }, { from: config, allow: [types] }, { from: services, allow: [types, config] }, { from: hooks, allow: [types, config, services] }, { from: pages, allow: [types, config, services, hooks] }, { from: components, allow: [types, config, hooks] }, ], }], }, settings: { boundaries/elements: [ { type: types, pattern: src/types/** }, { type: config, pattern: src/config/** }, { type: services, pattern: src/services/** }, { type: hooks, pattern: src/hooks/** }, { type: pages, pattern: src/pages/** }, { type: components, pattern: src/components/** }, ], }, }, ];这样当 Agent 在 pages 层直接 import repo 或数据库相关模块时ESLint 会立刻报错而不是等到运行时才暴露问题。4. 验证请求与成功结果配置写完之后必须验证门禁真的能拦住违规代码。我建议用“故意写错再修复”的方式做端到端校验。4.1 后端验证先在后端制造一个反向依赖。在app/repo/order_repo.py里加一行from app.service.order_service import OrderService # 故意违规然后运行cd backend uv run lint-imports预期输出类似app.repo.order_repo - app.service.order_service (api - service - repo) LINTER ERROR: app.repo.order_repo - app.service.order_service violates contract 后端分层架构约束看到这个报错说明门禁生效。删掉违规 import再跑一次应该输出Contracts: 1 kept, 0 broken。4.2 前端验证在前端src/pages/OrderList.js里故意写import { getUserFromDB } from ../repo/userRepo; // 违规运行cd frontend pnpm lint预期报错error Dependency violation: pages cannot import from repo Allowed: types, config, services, hooks4.3 接入 AI 工具做自动修复门禁报错之后让 Agent 根据报错信息自动修复。用 TaoToken 通道跑 Codex CLInpx codex --approval-mode full-auto \ 运行 make lint根据报错信息修复所有架构违规不要改变业务逻辑Agent 会读取 AGENTS.md 里的架构原则结合 Linter 的具体报错把违规 import 改成通过 service 层调用。修复完成后再次运行make lint全部通过即表示闭环成立。如果你更想先手动确认模型输出质量可以在模型对话里贴上报错信息让它给出修复方案再落地。5. 本篇常见错排查5.1 lint-imports 报 “Could not find module”通常是root_packages配置和实际包名不一致。检查.importlinter里的root_packages app是否对应你项目里真实的 Python 包目录名。如果后端代码在src/app/下需要改成root_packages src.app或调整工作目录。5.2 ESLint 报 “boundaries/element-types rule not found”说明插件没装成功或配置里没注册。确认pnpm add -D eslint-plugin-boundaries执行成功并且eslint.config.js的plugins字段里有boundaries。如果用的是旧版.eslintrc配置方式不同建议统一升级到 flat config。5.3 Agent 不读 AGENTS.md不同工具读取规则文件的位置不同。Codex 默认读项目根目录的 AGENTS.mdClaude Code 读 CLAUDE.md部分工具读.cursorrules。如果你用的工具不识别 AGENTS.md可以在工具配置里显式指定或者建一个软链接ln -s AGENTS.md CLAUDE.md5.4 TaoToken 请求返回 401先确认环境变量TAOTOKEN_API_KEY是否在当前 shell 生效用echo $TAOTOKEN_API_KEY检查。如果 Key 正确但仍 401检查 Base URL 是否写成了https://taotoken.net/api而不是带/v1的完整路径——不同工具对 Base URL 的拼接方式不同OpenAI 兼容工具通常只需要到/api。需要重新生成 Key 时去 API Keys 页面操作。5.5 Linter 通过但运行时仍然出错Linter 只能检查静态的 import 关系不能覆盖运行时动态调用。比如通过字符串反射调用、事件总线跨层通信Linter 是拦不住的。这类问题需要在 AGENTS.md 的“常见陷阱”里明确写出禁止模式并配合集成测试覆盖关键路径。6. 把门禁接进 CI 与日常流程本地验证通过后把检查接进 CI让每次 PR 都自动跑一遍。后端质量门禁的 GitHub Actions 片段name: Backend Quality Gate on: [pull_request] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: astral-sh/setup-uvv4 - run: cd backend uv sync - run: cd backend uv run ruff check app/ tests/ - run: cd backend uv run mypy app/ - run: cd backend uv run lint-imports前端同理把pnpm lint和pnpm test串进 workflow。这样 Agent 提交的 PR 如果违反架构约束CI 会直接失败Agent 收到失败反馈后可以自动修复形成“违规 - 检测 - 修复”的闭环。最后分享一个实用技巧把 Linter 的报错信息格式改成对 Agent 友好的结构。普通报错只说“不允许”Agent 需要自己推断怎么改如果你在自定义规则里输出“违规文件、违规层级、允许的层级、修复建议”Agent 一次修复的成功率会明显提高。这个改动不大但能省下大量来回调试的时间。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

不辞职也能读硕士?同等学力申硕这条路怎么走 2026/9/29 11:31:56

不辞职也能读硕士?同等学力申硕这条路怎么走

有人问我,上班了还想拿个硕士,是不是只能辞职去考全日制。不是。除了全国统考的非全日制研究生,还有一条叫“同等学力人员申请硕士学位”的路,不用脱产、先入学后考试,适合一边上班一边提升的人。今天把它走一遍。 一、…

阅读更多 →
vibecoding黑盒代码改造:从“能跑”到“敢接手”的渐进重构指南 2026/9/29 11:31:50

vibecoding黑盒代码改造:从“能跑”到“敢接手”的渐进重构指南

上个月,公司让我接管一个vibecoding落地的订单发货系统。功能都跑着,线上也有业务在走,但没人敢碰——这是一个典型的黑盒:12张表、4000多行代码挤在几个大而全的函数里、零测试、变量从a1排到a9。我花了差不多两周,把…

阅读更多 →
v1.0 正式版发布:全流程经验复盘 2026/9/29 11:31:31

v1.0 正式版发布:全流程经验复盘

v1.0 正式版发布:全流程经验复盘历经整整一个月的高强度迭代与打磨,我们的开源 AI 命令行工具 Star-CLI 迎来了里程碑式的 v1.0 正式版全网发布! 从九月初 v0.3 版本时那个臃肿笨重、启动耗时近 30ms、代码充斥着过度设计的初版原型&#xff…

阅读更多 →
【大数据毕设项目】基于大数据的药品批准信息分析与风险预警可视化 面向智慧监管的药品批准信息大数据分析与可视化研究 2026/9/29 11:31:31

【大数据毕设项目】基于大数据的药品批准信息分析与风险预警可视化 面向智慧监管的药品批准信息大数据分析与可视化研究

💕💕作者:计算机源码社 💕💕个人简介:本人八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Spark、hadoop、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题…

阅读更多 →
九月份技术选型台账与取舍手记 2026/9/29 11:31:31

九月份技术选型台账与取舍手记

九月份技术选型台账与取舍手记技术选型是一门权衡的艺术。在做每一个技术抉择时,我们不仅要看“得到了什么”,更要清醒地知道“放弃了什么、承担了什么隐形代价”。 在整个九月的项目推进中,我们记录了一本详尽的技术选型台账(Tec…

阅读更多 →
ZeroLaunch-rs文件通配符:正则表达式添加程序技巧 2026/9/29 11:31:31

ZeroLaunch-rs文件通配符:正则表达式添加程序技巧

ZeroLaunch-rs文件通配符:正则表达式添加程序技巧 🎯 痛点场景:为什么需要高级文件匹配? 你是否曾经遇到过这样的困扰: 自定义安装的软件无法被启动器识别特定类型的文档文件想要快速启动批量添加某个文件夹下的特定模…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉