驾驭工程:用规范和约束赋能AI,实现高质量输出
Harness Engineering 驾驭工程,是一种方法论、工作/思维模式,让人类通过约束、linter等方式,在规定的自由空间内,让AI发挥自己的能力,做到更高质量的输出成果。
再说简单点,Harness是一种思维方式,让人知道在哪里进行一些规则的设定,让AI在偏离业务需求时,可以拽回来,重新回到预定的轨道前进。
就像互联网软件开发一样,程序员有自己的代码规范、git提交规范、业务逻辑规范、测试用例等,这样可以更高效的产出结果。
本章是讲Harness的入门到精通,咱们就从Harness的诞生开始讲起,这样渐进式的讲解,能让大家更明白什么是Harness思维。
AI时代的软件开发 —— 从SDD 到 TDD
SDD:规格驱动开发
SDD(Specification-Driven Development) :规格驱动开发,写规格文档(Spec),让规格 = 一等公民,代码只是规格的可执行表达。
在 AI 编程时代,这份 Spec 既是给人看的需求文档,也是给 AI Agent 看的任务说明书。
| 传统开发 | SDD开发 |
|---|---|
| 口头说需求/PRD文档 --> 直接写代码 --> 事后补文档 | 写SPEC文档 --> 从SPEC提取测试代码 --> 按测试代码写开发代码 |
| 问题:需求在脑子里,AI看不到/无法理解/理解会有偏差 | 优势:规格是可版本化,人与AI都看得懂,可被AI读取 |
SPEC文档格式:
# Stock Deep Research with AkShare -- 规格文档 (Specification)> 本文档是项目的"一等公民"。所有实现代码都是本规格的可执行表达。> 修改本文档时必须同步更新对应的测试和实现。## 功能目标输入一个股票代码(如 "600519"),自动从多个维度联网搜索信息,通过 Qwen 大模型进行分析,生成结构化深度研究报告。使用 AkShare 库获取金融数据,增强数据采集能力。## 系统架构```<br><br>用户输入(股票代码)<br><br> |<br><br> v<br><br> QwenClient -- API 客户端层:封装 Qwen 联网搜索能力<br><br> |<br><br> v<br><br> Collector -- 数据采集层:按维度并行采集<br><br> / \<br><br> / \<br><br>AkShare 网络搜索<br><br>(金融数据) (新闻、分析)<br><br> |<br><br> v<br><br> Analyzer -- 分析层:汇总评分 + 风险识别<br><br> |<br><br> v<br><br> Reporter -- 报告层:生成结构化报告 + 校验<br><br> |<br><br> v<br><br> 结构化 JSON 报告<br><br>```## 数据采集维度| 维度 | 英文标识 | 采集内容 | AkShare 数据源 ||------|---------|---------|---------------|| 基本面 | fundamental | 公司简介、主营业务、近期财报摘要 | stock_zh_a_spot, stock_financial_analysis_indicator || 市场面 | market | 近期股价走势、成交量变化、技术指标信号 | stock_zh_a_daily, stock_zh_a_index_daily, stock_zh_a_tech_indicator || 消息面 | news | 近期重大新闻、公告、行业动态 | stock_news_em, stock_info_em || 分析师观点 | analyst | 机构评级、目标价、投资建议汇总 | stock_analyst_grade_em |## 输出格式报告必须严格遵循以下 JSON 结构:```json<br><br>{<br><br> "stock_code": "600519",<br><br> "stock_name": "贵州茅台",<br><br> "report_date": "2026-04-20",<br><br> "dimensions": {<br><br> "fundamental": {<br><br> "summary": "不少于100字的基本面分析...",<br><br> "confidence": 0.85,<br><br> "akshare_data": true<br><br> },<br><br> "market": {<br><br> "summary": "不少于100字的市场面分析...",<br><br> "confidence": 0.78,<br><br> "akshare_data": true<br><br> },<br><br> "news": {<br><br> "summary": "不少于100字的消息面分析...",<br><br> "confidence": 0.72,<br><br> "akshare_data": true<br><br> },<br><br> "analyst": {<br><br> "summary": "不少于100字的分析师观点...",<br><br> "confidence": 0.80,<br><br> "akshare_data": true<br><br> }<br><br> },<br><br> "overall_rating": "buy",<br><br> "risk_factors": ["风险因素1", "风险因素2"],<br><br> "sources": ["https://...", "https://...", "https://..."],<br><br> "akshare_version": "1.10.60"<br><br>}<br><br>```## 约束条件(Constraints)以下约束条件将直接转化为测试用例和 linter 规则:### C1: 维度完整性- 报告必须包含全部 4 个维度:fundamental, market, news, analyst- 缺少任何一个维度视为报告不合格### C2: 摘要最小长度- 每个维度的 summary 字段不少于 100 个字符- 空摘要或过短摘要说明数据采集不充分### C3: 置信度范围- 每个维度的 confidence 必须在 [0.0, 1.0] 闭区间内- 超出范围说明评分逻辑有误### C4: 评级有效值- overall_rating 只能取 "buy"、"hold"、"sell" 三个值之一- 其他值(如 "strong_buy"、"outperform")不被接受### C5: 来源数量- sources 列表必须包含至少 3 个来源 URL- 来源过少说明研究深度不够### C6: 风险因素- risk_factors 列表不能为空- 任何投资都有风险,空列表说明分析不完整### C7: 必填字段- stock_code, stock_name, report_date 为必填字段- 缺少任何一个视为报告结构不完整### C8: AkShare 数据使用- 每个维度必须标记是否使用了 AkShare 数据 (akshare_data 字段)- akshare_version 字段必须包含当前使用的 AkShare 版本## API 依赖- 模型:通过 DashScope 调用 Qwen 系列模型- 联网搜索:enable_search=True, search_strategy="agent"- 认证:通过 DASHSCOPE_API_KEY 环境变量- 金融数据:AkShare 库 (版本 >= 1.10.60)
Spec 中的每一条约束(C1~C7),都可以直接翻译为一个测试用例。每个约束也是SDD与TDD的天然连接点,即规格文档写完,测试用例也就有了。
TDD:测试驱动开发
TDD(Test-Driven Development): 测试驱动开发,V模型,有测试单元 对应 开发单元。没有先失败的测试,就没有生产代码。先有测试用例,第一次是无代码状态,肯定都是失败,然后再根据测试用例编写程序,再进行验证。
核心:红-绿-重构循环
| 阶段 | 做什么 | 验证 |
|---|---|---|
| RED 红灯 | 写一个最小的失败测试 | 运行测试,看到 FAILED |
| GREEN 绿灯 | 写最少的代码让测试通过 | 运行测试,看到 PASSED |
| REFACTOR 重构 | 在测试保持绿灯的前提下优化代码 | 运行测试,仍然 PASSED |
没有先失败的测试,就没有生产代码:
TDD 的红-绿-重构(Red-Green-Refactor)循环中的硬性顺序:
-
Red(红):
先写一个测试,运行它,确保它失败。这一步证明:
测试本身是有效的(不是 永远通过的假测试)
当前确实没有实现这个功能
你清楚知道"完成"的标准是什么(测试代码就是需求规格) -
Green(绿):
编写刚好够让测试通过的最少代码,不做多余设计;
-
Refactor(重构):
在不破坏测试的前提下优化代码结构。
简而言之,在看到一个失败的测试之前,你不能写任何生产代码。这个失败是扳机,确认你正在解决一个真实存在的问题,而不是臆想。
如何理解先写了代码再补测试?删掉代码,重新开始?
为了防止自欺欺人的心理陷阱:
-
如果先写代码:
你潜意识里会写 刚好能让这段代码通过的测试 => 测试变成了验证代码正确性的工具,而不是定义需求的规格。
-
测试失去防护价值:
当需求变更或重构时,这些后补的测试往往过于宽松,或者测试的是实现细节而非行为,无法保护代码。
删掉重来是为了强制你回到正确的思维轨道:让需求(测试)驱动设计,而不是让设计(实现)扭曲需求。
TDD的错误理解:
-
太简单不需要测试
=> 简单代码也会坏。写测试只要 30 秒。
-
我先写代码,之后补测试
=> 后补的测试立刻通过,证明不了任何东西。
-
TDD 太教条了,我更务实
=> TDD 就是务实:先找 bug 比事后 debug 快 10 倍。
-
已经手动测过了
=> 手动测试无法重复、无法回归、无法证明覆盖面。
-
删掉 X 小时的代码太浪费
=> 沉没成本谬误。留着你无法信任的代码才是浪费。
案例:AI投研工具
我这里以AI投研工具案例,来讲解下SDD --> TDD 怎么使用。
在写案例之前,这里正好聊到古法编程(目前流行将近20年的代码编程) ,现在AI进化越来越快,很多人在使用各类AI coding 工具(Trae、Cursor、Claude code、lingma等) 进行编程,也叫Vibe coding(氛围编程),古法编程变得越来越少。
从以前TDD指导开发,到现在的SDD指导开发,或者是2者的结合:
- 方法一:SDD => vibe coding => TDD
- 方法二:SDD => TDD => vibe coding
其实SDD、TDD 都是一种思维方式,更好的让AI去高质量、高效率输出我们想要的结果。
| 传统编程模式 | AI编程模式 |
|---|---|
| 先写代码,关注怎么写逻辑判断,有出现2个问题: 1、容易过度设计(考虑性能、通用性); 2、测试变成 验证我对了 | 先写测试,关注用户输入什么,我应该返回什么。 只关注业务需求,测试变成 定义什么叫对 等高效的AI约束,让AI知道怎么做是错的,要回到正轨上来。 |
我们聊回案例:需求是我们要做一个股票深度研究工具,输入一个股票代码(如 600519贵州茅台),系统自动通过 akshare 获取真实的财务数据、新闻、机构评级等信息,再结合 Qwen 大模型联网搜索分析,最终生成一份结构化的多维度研究报告。
step1: 撰写一个SPEC,通过Trae Idea来编写:
我想撰写一个软件SPEC,需求是:输入一个股票代码(如“600519”),自动从多个维度联网搜索信息,通过Qwen大模型进行分析,生成结构化深度研究报告。使用到akshare方便后续进行测试和代码生成,给我SPEC即可,写入到spec文件夹中。
``````plaintext
# Stock Deep Research with AkShare -- 规格文档 (Specification)> 本文档是项目的"一等公民"。所有实现代码都是本规格的可执行表达。> 修改本文档时必须同步更新对应的测试和实现。## 功能目标输入一个股票代码(如 "600519"),自动从多个维度联网搜索信息,通过 Qwen 大模型进行分析,生成结构化深度研究报告。使用 AkShare 库获取金融数据,增强数据采集能力。## 系统架构```<br><br>用户输入(股票代码)<br><br> |<br><br> v<br><br> QwenClient -- API 客户端层:封装 Qwen 联网搜索能力<br><br> |<br><br> v<br><br> Collector -- 数据采集层:按维度并行采集<br><br> / \<br><br> / \<br><br>AkShare 网络搜索<br><br>(金融数据) (新闻、分析)<br><br> |<br><br> v<br><br> Analyzer -- 分析层:汇总评分 + 风险识别<br><br> |<br><br> v<br><br> Reporter -- 报告层:生成结构化报告 + 校验<br><br> |<br><br> v<br><br> 结构化 JSON 报告<br><br>```## 数据采集维度| 维度 | 英文标识 | 采集内容 | AkShare 数据源 ||------|---------|---------|---------------|| 基本面 | fundamental | 公司简介、主营业务、近期财报摘要 | stock_zh_a_spot, stock_financial_analysis_indicator || 市场面 | market | 近期股价走势、成交量变化、技术指标信号 | stock_zh_a_daily, stock_zh_a_index_daily, stock_zh_a_tech_indicator || 消息面 | news | 近期重大新闻、公告、行业动态 | stock_news_em, stock_info_em || 分析师观点 | analyst | 机构评级、目标价、投资建议汇总 | stock_analyst_grade_em |## 输出格式报告必须严格遵循以下 JSON 结构:```json<br><br>{<br><br> "stock_code": "600519",<br><br> "stock_name": "贵州茅台",<br><br> "report_date": "2026-04-20",<br><br> "dimensions": {<br><br> "fundamental": {<br><br> "summary": "不少于100字的基本面分析...",<br><br> "confidence": 0.85,<br><br> "akshare_data": true<br><br> },<br><br> "market": {<br><br> "summary": "不少于100字的市场面分析...",<br><br> "confidence": 0.78,<br><br> "akshare_data": true<br><br> },<br><br> "news": {<br><br> "summary": "不少于100字的消息面分析...",<br><br> "confidence": 0.72,<br><br> "akshare_data": true<br><br> },<br><br> "analyst": {<br><br> "summary": "不少于100字的分析师观点...",<br><br> "confidence": 0.80,<br><br> "akshare_data": true<br><br> }<br><br> },<br><br> "overall_rating": "buy",<br><br> "risk_factors": ["风险因素1", "风险因素2"],<br><br> "sources": ["https://...", "https://...", "https://..."],<br><br> "akshare_version": "1.10.60"<br><br>}<br><br>```## 约束条件(Constraints)以下约束条件将直接转化为测试用例和 linter 规则:### C1: 维度完整性- 报告必须包含全部 4 个维度:fundamental, market, news, analyst- 缺少任何一个维度视为报告不合格### C2: 摘要最小长度- 每个维度的 summary 字段不少于 100 个字符- 空摘要或过短摘要说明数据采集不充分### C3: 置信度范围- 每个维度的 confidence 必须在 [0.0, 1.0] 闭区间内- 超出范围说明评分逻辑有误### C4: 评级有效值- overall_rating 只能取 "buy"、"hold"、"sell" 三个值之一- 其他值(如 "strong_buy"、"outperform")不被接受### C5: 来源数量- sources 列表必须包含至少 3 个来源 URL- 来源过少说明研究深度不够### C6: 风险因素- risk_factors 列表不能为空- 任何投资都有风险,空列表说明分析不完整### C7: 必填字段- stock_code, stock_name, report_date 为必填字段- 缺少任何一个视为报告结构不完整### C8: AkShare 数据使用- 每个维度必须标记是否使用了 AkShare 数据 (akshare_data 字段)- akshare_version 字段必须包含当前使用的 AkShare 版本## API 依赖- 模型:通过 DashScope 调用 Qwen 系列模型- 联网搜索:enable_search=True, search_strategy="agent"- 认证:通过 DASHSCOPE_API_KEY 环境变量- 金融数据:AkShare 库 (版本 >= 1.10.60)
step2: 撰写测试用例,@stock_research_with_akshare_spec.md 这个是SPEC,这里有 C1 - C8的约束,帮我先撰写测试代码(我打算用TDD的模式驱动开发,先不用开发);
测试代码放到 tests 文件夹中,到时候实际代码会放到 src 文件夹中。

step3: 运行测试用例:
运行测试用例,使用TDD 红 - 绿 - 重构循环

step4: 用 akshare 获取真实股票数据,输出报告 这个项目 @stock_research_with_akshare_spec.md 基于这个SPEC文档完成,
然后完成相应的测试(基于TDD 红-绿-重构循环),你刚才已经写了测试用例

step5: @stock_research_with_akshare_spec.md 基于这个文档完成 完整的项目,这里会用到 akshare 和 qwen大模型(可以使用DevAGI平台,apikey可以使用环境变量中的 DEV_AGI_API_KEY,你可以参考 @example03.py 文件,看下怎么调用大模型)

Harness Engineering(驾驭工程)
2026年最火的技术是什么?我想大家第一时间想到的就是Harness Engineering(驾驭工程),把AI比喻成马,Harness就是马的缰绳,由我们人类通过Harness来驾驭AI(马),让AI输出人类想要的结果。
前段时间,我在抖音看到的一则新闻:
一个 3 人团队,用 5 个月时间,从空仓库开始,完全不手写代码,所有代码都由 AI(Codex)生成。最终产出了一个真正的产品,超过 100 万行代码,提交了约 1500 个 PR。后来团队扩展到 7 人,吞吐量仍然在增长。
他们人均每天合并 3.5 个 PR。单次 Codex 运行可以持续 6 小时以上,通常在人类下班睡觉的时间自动工作。
他们是怎么做到的?答案就是 Harness Engineering。
其实 上面的案例:AI投研工具 用的也是Harness思维进行编写项目的。
Harness 是模型之外的一切,即:约束系统、反馈回路、工具环境、验证机制。
裸模型不是 Agent,只有给它装上缰绳,它才能可靠工作。

LLM 工程范式的演进
2023年的Prompt Engineering 提示词工程 :
-
关注:
说什么(单次指令);
-
解决:
让 AI 听懂单次指令;
也是驱动大模型唯一的语言(prompt)
2025年的Context Engineering 上下文工程:
-
关注:
知道什么(上下文管理);
-
解决:
让 AI 获得所需信息;
从而兴起了RAG知识库,一个Agent配备了RAG知识库的话,RAG会先执行,它类似数据库一样,基于用户query,先去知识库内检索相关信息,再拼接好新的prompt,给到LLM模型。想详细了解的可以去看下我之前写的文章 # 浅聊Prompt、向量知识库、RAG。
2026年的Harness Engineering 驾驭工程:
-
关注:
在什么环境做事(系统构建)
-
解决:
让 Agent 可靠自主完成复杂任务
它是方法论、工作/思维模式,不是代码也不是工具,让约束好AI,并且让AI高效、高质量输出结果。
随着AI进化越来越快,它能解决越来越多的复杂事务,单一个提示词,或者上下文是没办法满足需求,所以就衍生了Harness,甚至我个人猜测后面还会其他的AI工程出现,这也是一种必然的趋势。
Harness的三大支柱
告知!!!约束!!!验证!!!
Inform(告知):
AGENTS.md 导航文件、上下文工程 => AGENTS.md 项目导航入口
让AI知道,你的角色是什么,如果你想要找某些技能,找某些内容,从哪里去看,这就是我们的告知支柱。
# Stock Deep Research - AGENTS.md> 本文件是项目导航入口(给 AI Agent 和开发者看的目录页)。> 遵循 Harness Engineering "地图而非手册" 原则:~50 行入口,指向更深层文档。## 项目定位AI 驱动的股票深度研究工具,通过 Qwen 大模型联网搜索生成多维度结构化研报。同时作为 TDD + SDD + Harness Engineering 的教学案例。## 关键文件导航| 文件 | 用途 ||------|------|| `spec/stock_research_with_akshare_spec.md` | 规格文档(一等公民) -- 所有约束条件的权威来源 || `src/qwen_client.py` | Qwen API 客户端封装 || `src/collector.py` | 多维度数据采集 || `src/analyzer.py` | 数据汇总分析 + 评分 || `src/reporter.py` | 报告生成 + 结构校验 || `src/validator.py` | 报告验证器(C1-C8 约束条件) || `tests/test_validator.py` | 测试用例(31 个测试) |## 开发约定1. **TDD 强制**:所有新功能必须先写失败的测试,再写实现2. **Spec 同步**:修改报告结构时必须同步更新 `spec/stock_research_with_akshare_spec.md`3. **测试隔离**:单元测试禁止调用真实 API,使用 Mock4. **结构对称**:`src/` 下每个模块对应 `tests/` 下的 `test_` 同名文件## 测试命令```bash<br><br>pytest tests/ -q # 全部单元测试<br><br>pytest tests/test_validator.py -v # 单个模块<br><br>python src/main.py 600519 # 生成股票研究报告<br><br>```## 架构约束- 依赖方向:`client -> collector -> analyzer -> reporter`- 禁止反向依赖(reporter 不能 import collector)- API 调用只发生在 `qwen_client.py` 中,其他模块不直接调用外部 API- 所有核心代码放置在 `src/` 文件夹内
Constrain(约束):
架构边界、权限控制、自定义 Linter(代码检查器) => lint_structure.py
我到底要做哪些事情,有哪些权限,我到底怎么去做检测,这就是约束支柱。
#!/usr/bin/env python3"""项目结构校验工具遵循 Harness Engineering 核心理念:文档会腐烂,lint 规则不会"""import osimport sysimport jsonimport refrom typing import List, Dict, OptionalclassProjectStructureLinter:"""项目结构校验器"""def__init__(self): self.required_files ={"src":["__init__.py","validator.py","collector.py","analyzer.py","reporter.py","qwen_client.py","main.py"],"tests":["__init__.py","test_validator.py"],"spec":["stock_research_with_akshare_spec.md"]} self.errors: List[str]=[]defcheck_directory(self, directory:str, required_files: List[str])->None:"""检查目录是否包含所有必需的文件"""ifnot os.path.exists(directory): self.errors.append(f"ERROR: 目录 {directory} 不存在。请创建该目录。")return existing_files = os.listdir(directory)forfilein required_files:iffilenotin existing_files: self.errors.append(f"ERROR: 目录 {directory} 中缺少必需文件 {file}。请创建该文件。")...defrun(self)->bool:"""运行所有校验"""print("正在进行项目结构校验...")# 检查目录结构for directory, files in self.required_files.items(): self.check_directory(directory, files)# 检查导入规则 src_files =["src/main.py","src/reporter.py","src/analyzer.py"]...else:print("\n项目结构校验通过!")returnTrueif __name__ =="__main__": linter = ProjectStructureLinter() success = linter.run() sys.exit(0if success else1)
Verify(验证):
其实约束就会给你写个验证,它会通过测试的方式,给你完成一个验证。拿自动化测试去完成。
"""股票深度研究报告验证器测试用例基于 TDD 模式,针对 SPEC 文档中的约束条件 C1-C8"""import pytestimport sysimport os# 添加项目根目录到 Python 路径sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))from src.validator import StockReportValidatorclassTestC1_DimensionCompleteness:"""C1: 维度完整性测试"""deftest_all_dimensions_present(self):"""测试:报告包含全部 4 个维度""" report ={"stock_code":"600519","stock_name":"贵州茅台","report_date":"2026-04-20","dimensions":{"fundamental":{"summary":"测试基本面分析"*15,"confidence":0.85,"akshare_data":True},"market":{"summary":"测试市场面分析"*15,"confidence":0.78,"akshare_data":True},"news":{"summary":"测试消息面分析"*15,"confidence":0.72,"akshare_data":True},"analyst":{"summary":"测试分析师观点"*15,"confidence":0.80,"akshare_data":True}},"overall_rating":"buy","risk_factors":["风险因素1","风险因素2"],"sources":["https://example1.com","https://example2.com","https://example3.com"],"akshare_version":"1.10.60"} validator = StockReportValidator(report)assert validator.validate()isTrueassertlen(validator.get_errors())==0classTestC2_SummaryMinLength:"""C2: 摘要最小长度测试"""deftest_all_summaries_meet_min_length(self):"""测试:所有维度的摘要都满足最小长度要求""" report ={"stock_code":"600519","stock_name":"贵州茅台","report_date":"2026-04-20","dimensions":{"fundamental":{"summary":"测试基本面分析"*15,"confidence":0.85,"akshare_data":True},"market":{"summary":"测试市场面分析"*15,"confidence":0.78,"akshare_data":True},"news":{"summary":"测试消息面分析"*15,"confidence":0.72,"akshare_data":True},"analyst":{"summary":"测试分析师观点"*15,"confidence":0.80,"akshare_data":True}},"overall_rating":"buy","risk_factors":["风险因素1","风险因素2"],"sources":["https://example1.com","https://example2.com","https://example3.com"],"akshare_version":"1.10.60"} validator = StockReportValidator(report)assert validator.validate()isTrueclassTestC3_ConfidenceRange:"""C3: 置信度范围测试"""deftest_all_confidences_in_valid_range(self):"""测试:所有置信度都在有效范围内""" report ={"stock_code":"600519","stock_name":"贵州茅台","report_date":"2026-04-20","dimensions":{"fundamental":{"summary":"测试基本面分析"*15,"confidence":0.85,"akshare_data":True},"market":{"summary":"测试市场面分析"*15,"confidence":0.78,"akshare_data":True},"news":{"summary":"测试消息面分析"*15,"confidence":0.72,"akshare_data":True},"analyst":{"summary":"测试分析师观点"*15,"confidence":0.80,"akshare_data":True}},"overall_rating":"buy","risk_factors":["风险因素1","风险因素2"],"sources":["https://example1.com","https://example2.com","https://example3.com"],"akshare_version":"1.10.60"} validator = StockReportValidator(report)assert validator.validate()isTrue
Inform 告知:Agent 该做什么 => Constrain 约束:Agent 不能做什么 => Verify 验证:Agent 做得对不对!!!
Harness组件
仓库(记忆系统)
为什么仓库是记录系统?
在传统团队中,很多重要信息散落在 微信、飞书、钉钉等聊天群内(聊天记录)、飞书文档、会议纪要、甚至团队成员的脑子里。
对于人类是可以的,但对 AI Agent 来说——这些信息等于不存在。
| 信息存放位置 | 人类能否访问 | AI Agent 能否访问 |
|---|---|---|
| 飞书/禅道/gitee 中的需求文档 | 能 | 不能 |
| Slack/微信群里的技术讨论 | 能 | 不能 |
| 老刘脑子里的架构决策 | 能(问老刘) | 不能 |
| 仓库里的 Markdown 文档 | 能 | 能 |
| 代码 + 注释 | 能 | 能 |
| Lint 规则 | 间接能 | 能(强制执行) |
一切决策、规范、计划都必须以版本化的文件提交到仓库。在我们的 stock-research 中,Spec 文档(spec/stock_research_with_akshare_spec.md)就是这个记录系统的体现。报告的输出格式、约束条件 C1-C8、API 依赖——全部写在仓库里,而不是在脑子里
AGENTS.md:地图而非手册
既然所有信息都要进仓库,那把所有规则写成一个巨大的说明文件行不行?
不行!HumanLayer 团队的实践表明:AGENTS.md 超过 60 行,效果反而会下降。
巨型指令文件有三个死因:挤占上下文窗口、无法维护、无法被机械验证。
AGENTS.md是地图,是导航。就像我们去图书馆看一本书(python入门秘籍),图书管有上十万本书,我们不可能一本一本的去翻,这样效率极其低下,并且耗时太长,所以图书馆内有会把同类型的书籍放在一个类目区域内,并且在图书馆大门口有目录指引。
我们的AGENTS.md也是这个道理,它是一个大目录,告诉AI你想要的东西在哪里可以找到,类似渐进式披露。
我们上面聊到的案例:AI投研工具进行撰写AGENTS.md。
prompt:
你查看整个项目,写一个AGENTS.md,AGENTS.md 不能超过 60 行,AGENTS.md只有关键路标,不写具体规则(具体规则在 Spec 和 Linter 里)。
生成后的文件:
# Stock Deep Research - AGENTS.md> 本文件是项目导航入口(给 AI Agent 和开发者看的目录页)。> 遵循 Harness Engineering "地图而非手册" 原则:~50 行入口,指向更深层文档。## 项目定位AI 驱动的股票深度研究工具,通过 Qwen 大模型联网搜索生成多维度结构化研报。同时作为 TDD + SDD + Harness Engineering 的教学案例。## 关键文件导航| 文件 | 用途 ||------|------|| `spec/stock_research_with_akshare_spec.md` | 规格文档(一等公民) -- 所有约束条件的权威来源 || `src/qwen_client.py` | Qwen API 客户端封装 || `src/collector.py` | 多维度数据采集 || `src/analyzer.py` | 数据汇总分析 + 评分 || `src/reporter.py` | 报告生成 + 结构校验 || `src/validator.py` | 报告验证器(C1-C8 约束条件) || `tests/test_validator.py` | 测试用例(31 个测试) |## 开发约定1. **TDD 强制**:所有新功能必须先写失败的测试,再写实现2. **Spec 同步**:修改报告结构时必须同步更新 `spec/stock_research_with_akshare_spec.md`3. **测试隔离**:单元测试禁止调用真实 API,使用 Mock4. **结构对称**:`src/` 下每个模块对应 `tests/` 下的 `test_` 同名文件## 测试命令```bash<br><br>pytest tests/ -q # 全部单元测试<br><br>pytest tests/test_validator.py -v # 单个模块<br><br>python src/main.py 600519 # 生成股票研究报告<br><br>```## 架构约束- 依赖方向:`client -> collector -> analyzer -> reporter`- 禁止反向依赖(reporter 不能 import collector)- API 调用只发生在 `qwen_client.py` 中,其他模块不直接调用外部 API- 所有核心代码放置在 `src/` 文件夹内
Lint代码级规则
Harness内的Lint规则,其实类似于 程序员通过Idea编写代码,都会设置一个静态代码检查lint,确保代码的规范性,违反我们的规范/约束的话,就会失败,报错,警告等。
Lint规则的重要性如何?
OpenAI 团队在实践中发现一个规律:写在文档里的规范,Agent 经常忘记或忽略。
但写成 Lint 规则的约束,Agent 每次都会遵守——因为违反规则会导致 CI 失败,Agent 无法跳过。
更关键的洞察是:Lint 错误信息里可以嵌入修复指令。
普通的错误信息只告诉你错了,但 Agent 不知道怎么修。如果错误信息里直接给出修复步骤,Agent 就能自我纠正,形成闭环。
Lint(或Linter) 是一种静态代码分析工具,它在不运行代码的情况下扫描源代码,自动检测潜在错误。
机械化执行:文档会腐烂,Lint 规则不会
| 普通错误 | Harness 错误 |
|---|---|
| Error: File exceeds 500 lines. | Error: File exceeds 500 lines. # Agent 看到后:知道怎么修,可以自己执行 Fix: Split into domain-specific modules following docs/ARCHITECTURE.md. Consider extracting types to types/ and service logic to service/. |
在案例:AI投研工具内,validator.py的每个错误都嵌入了修复指令。当 Agent 生成的报告不合格时,它可以读取错误信息,按指令自动修复。
def_validate_c1_dimension_completeness(self)->None:""" C1: 维度完整性 报告必须包含全部 4 个维度:fundamental, market, news, analyst """if"dimensions"notin self.report: self.errors.append("C1: 报告缺少 'dimensions' 字段")return dimensions = self.report["dimensions"] missing_dimensions =[dim for dim in self.REQUIRED_DIMENSIONS if dim notin dimensions]if missing_dimensions: self.errors.append(f"C1: 报告缺少以下维度: {', '.join(missing_dimensions)}")...
自定义结构 Linter项目级规则
除了代码层面的校验,还需要编写项目级的结构检查器。
检查项目有没有按照约定组织,比如 reporter.py 里是不是有validate_report 函数、REQUIRED_DIMENSIONS
常量是不是包含了全部 4 个维度。
defcheck_validate_report_exists(reporter_path):"""检查 reporter.py 必须包含 validate_report 函数"""source = reporter_path.read_text(encoding="utf-8")tree = ast.parse(source)func_names =[node.name for node in ast.walk(tree)ifisinstance(node, ast.FunctionDef)]if"validate_report"notin func_names:return["ERROR: src/reporter.py 缺少 validate_report() 函数。\n""FIX: 添加 def validate_report(report: dict) -> list[dict],\n"" 逐条检查 spec/research_spec.md 中的约束条件 C1-C7。\n"]return[]
Guides x Sensors 矩阵
Harness 有很多组件,但这些零件是如何协同工作的?
Martin Fowler 团队用一个 2 x 2 矩阵做了分类:

只有引导器(只告诉 Agent 怎么做,不检查结果)= 不知道规则是否生效,可能一直犯同样的错;
只有传感器(只检查结果,不提前引导)= Agent 反复试错,效率低下;
两者结合 = 先引导提高首次成功率,再检测兜底,形成闭环。
在 AI投研工具 案例中:
-
引导器:
AGENTS.md 告诉 Agent 项目结构、Spec.md 定义约束、Prompt提示词模板引导 Qwen 按格式分析。
-
传感器:
代码级Lint 检查报告结构、Linter 检查项目结构、pytest 运行所有测试。
CI/CD 质量门禁
代码提交后,CI/CD 流水线 会自动运行三道质量检查。
门禁从快到慢分层排列,越早发现问题,修复成本越低。

# .github/workflows/quality_gate.ymlname: Quality Gateon:push:branches:[main]pull_request:branches:[main]concurrency:group: quality-${{ github.ref }}cancel-in-progress:truejobs:# 第一道门:结构检查(Harness Engineering 的机械化执行)structure-lint:runs-on: ubuntu-latesttimeout-minutes:2steps:-uses: actions/checkout@v4-uses: actions/setup-python@v5with:python-version:"3.11"-name: Structure Lintrun: python linters/check_report_structure.py# 第二道门:单元测试(TDD 的验证)unit-tests:runs-on: ubuntu-latesttimeout-minutes:5needs: structure-lintsteps:-uses: actions/checkout@v4-uses: actions/setup-python@v5with:python-version:"3.11"-name: Install dependenciesrun: pip install -r requirements.txt-name: Run unit testsrun: pytest tests/ -v --tb=short -m "not integration"env:DASHSCOPE_API_KEY:""# 第三道门:集成测试(仅 main 分支,需要真实 API Key)integration-tests:runs-on: ubuntu-latesttimeout-minutes:10needs: unit-testsif: github.ref == 'refs/heads/main'steps:-uses: actions/checkout@v4-uses: actions/setup-python@v5with:python-version:"3.11"-name: Install dependenciesrun: pip install -r requirements.txt-name: Run integration testsrun: pytest tests/test_integration.py -v -m integrationenv:DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
最后
对于正在迷茫择业、想转行提升,或是刚入门的程序员、编程小白来说,有一个问题几乎人人都在问:未来10年,什么领域的职业发展潜力最大?
答案只有一个:人工智能(尤其是大模型方向)
当下,人工智能行业正处于爆发式增长期,其中大模型相关岗位更是供不应求,薪资待遇直接拉满——字节跳动作为AI领域的头部玩家,给硕士毕业的优质AI人才(含大模型相关方向)开出的月基础工资高达5万—6万元;即便是非“人才计划”的普通应聘者,月基础工资也能稳定在4万元左右。
再看阿里、腾讯两大互联网大厂,非“人才计划”的AI相关岗位应聘者,月基础工资也约有3万元,远超其他行业同资历岗位的薪资水平,对于程序员、小白来说,无疑是绝佳的转型和提升赛道。
如果你还不知道从何开始,我自己整理一套全网最全最细的大模型零基础教程,我也是一路自学走过来的,很清楚小白前期学习的痛楚,你要是没有方向还没有好的资源,根本学不到东西!
下面是我整理的大模型学习资源,希望能帮到你。

👇👇扫码免费领取全部内容👇👇

最后
1、大模型学习路线

2、从0到进阶大模型学习视频教程
从入门到进阶这里都有,跟着老师学习事半功倍。

3、 入门必看大模型学习书籍&文档.pdf(书面上的技术书籍确实太多了,这些是我精选出来的,还有很多不在图里)

4、 AI大模型最新行业报告
2026最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

5、面试试题/经验

【大厂 AI 岗位面经分享(107 道)】

【AI 大模型面试真题(102 道)】

【LLMs 面试真题(97 道)】

6、大模型项目实战&配套源码

适用人群

四阶段学习规划(共90天,可落地执行)
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
-
硬件选型
-
带你了解全球大模型
-
使用国产大模型服务
-
搭建 OpenAI 代理
-
热身:基于阿里云 PAI 部署 Stable Diffusion
-
在本地计算机运行大模型
-
大模型的私有化部署
-
基于 vLLM 部署大模型
-
案例:如何优雅地在阿里云私有部署开源大模型
-
部署一套开源 LLM 项目
-
内容安全
-
互联网信息服务算法备案
-
…
👇👇扫码免费领取全部内容👇👇

3、这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

更多推荐

所有评论(0)