Harness Engineering 完整实践指南:用 Python 打造 Agent 友好型代码库

📌 先纠一个常见误解
“Harness Engineering” 不是搭建评测框架,也不是跑 benchmark 打分。
OpenAI 这篇文章讲的是:如何构建一套让 AI agent 能高效完成工程工作的环境系统。
Harness = 驾驭 AI 的"缰绳与鞍具"——是工程基础设施,不是测试工具。
先感受一下这件事的规模
2025年8月,OpenAI 一个工程团队启动实验:从空仓库开始,构建真实产品,全程不写一行人工代码。
| 100万 行代码 | 3人 工程师团队 | 5个月 完成周期 | 1/10 传统开发时间 |
1500个PR · 零人工编码 · 人均每天3.5个PR · 有真实日活用户
“人类掌舵,智能体执行。当团队扩展到7人,吞吐量反而还在增加。” — OpenAI 工程博客
一、工程师的角色彻底变了
在这套模式下,工程师几乎完全通过提示词与系统交互——描述任务,运行 agent,让它开 PR。
工程师的时间分配,从"写代码"变成了三件事:
| ① 设计系统环境 | 搭建工具链、目录结构、抽象层、约束规则——让 agent 能在其中有效工作的"操场" |
| ② 明确意图 | 把大目标拆成小任务,写清楚验收标准,输出的是"提示词+计划"而不是代码 |
| ③ 构建反馈回路 | 当 agent 卡住,不是"再换个提示",而是追问:它缺什么工具?缺什么文档?把缺的东西补进仓库 |
Codex 卡住时,正确的响应
❌ “换个角度再提示一遍”
✅ 它缺少什么工具?→ 写一个脚本放进 scripts/
✅ 它缺少什么文档?→ 写一篇 ADR 提交进 docs/design/
✅ 它缺少什么约束?→ 写一条 lint 规则,错误信息里附上修复方法
关键洞见:修复 agent 的方式,是改善环境,而不是改善提示词本身。
二、仓库是 Agent 的全部世界
Agent 在运行时看不到的东西,对它来说不存在
| 🚫 Agent 看不到 Slack / 飞书讨论记录 Google Docs 设计文档 会议纪要 工程师脑子里的隐性知识 口头约定的架构规范 | ✅ Agent 能看到 仓库里的 .md 文档 AGENTS.md / ARCHITECTURE.md 版本化的执行计划 linter 的错误信息(含修复指令) 代码注释和类型签名 |
→ 每一个技术决策,都必须以 Markdown 形式落进仓库
他们踩过一个大坑:写了一个超大的 AGENTS.md,列满所有规则。结果:
| ❌ 大而全的 AGENTS.md • 挤掉任务和代码的上下文空间 • 规则太多,agent 全部失效 • 文件腐烂成规则坟场 • 无法机械化验证有效性 • 人类也不会去维护它 | ✅ 100行以内的目录式 • 作为地图,指向深层文档 • 渐进式披露,按需展开 • 核心约束精简可执行 • 专用 linter 验证更新状态 • doc-gardening agent 自动维护 |
推荐的 Python 项目知识库结构
project/
├──
AGENTS.md
# 地图,100行以内,不是手册
├──
ARCHITECTURE.md
# 层级约束,依赖方向
├──
docs/
│ ├──
design/
# ADR 架构决策记录
│ ├──
specs/
# 功能规格文档
│ ├──
plans/
│ │ ├── active/
# 进行中的任务计划
│ │ └── done/
# 已完成(留作历史)
│ └──
references/
# 外部库的 llms.txt
├──
src/myapp/
│ ├── types/
# Pydantic models,无依赖
│ ├── config/
# 配置加载
│ ├── repo/
# 数据访问,只管 CRUD
│ ├── service/
# 业务逻辑
│ ├── api/
# FastAPI 路由
│ └── utils/
# 纯函数工具
├──
tests/
├──
scripts/
│ ├── check_imports.py
│ └── health_check.py
└──
Makefile
AGENTS.md 完整模板
# 项目名称
一句话描述项目功能。
## 快速导航
- 整体架构和层级约束 → ARCHITECTURE.md
- 当前进行中的任务 → docs/plans/active/
- 架构决策记录 (ADR) → docs/design/
- 数据模型定义 → src/myapp/types/
- 产品规格 → docs/specs/
## 开发命令
make dev # 启动开发服务器 (port 8000)
make test # 运行全部测试
make check # lint + typecheck + 层级检查(提交前必跑)
make clean-check # 代码库健康检查,输出清洁报告
## 核心约束(违反则 CI 失败)
1. 边界处必须用 Pydantic 验证,禁止裸 dict 传递数据
2. 禁止跨层导入(api→repo 等,详见 ARCHITECTURE.md)
3. 所有日志用 structlog,禁止裸 print() 和 logging.info(str)
4. service 层新方法必须有对应的单元测试
5. 单文件不超过 300 行(超出请拆分模块)
## 技术栈
- Web框架: FastAPI + uvicorn
- 数据验证: Pydantic v2
- 数据库: PostgreSQL + SQLAlchemy 2.0 (async)
- 日志: structlog (JSON 格式)
- 测试: pytest + pytest-asyncio
- Lint: ruff + mypy (strict)
三、Python 分层架构:约束即倍增器
严格的分层架构,在传统工程里要等公司规模扩展到数百人才引入。在 agent 工程里,这是早期必要条件——有了约束,速度才不会随规模下降。
Python 分层架构(依赖只能向下单向流动)
api/
FastAPI 路由 · 只管 HTTP · Pydantic 验证入口 · 不含业务逻辑
↓ 只能向下
service/
业务逻辑 · 编排 repo · 不知道 HTTP 的存在 · 所有业务规则在此
↓ 只能向下
repo/
数据访问 · 只管 CRUD · 无业务逻辑 · 返回 ORM model
↓ 只能向下
types/
Pydantic models · 无任何依赖 · 所有层都可以导入
❌ 禁止:api→repo(跳层)· repo→service(反向)· types→任何层(循环)
各层代码示例——以"创建用户"为例完整走一遍:
types/ — 只定义数据形状
# src/myapp/types/user.py
from
pydantic
import
BaseModel, EmailStr, field_validator
from
datetime
import
datetime
class
UserCreate
(BaseModel):
email: EmailStr
name: str
@field_validator
(
"name"
)
@classmethod
def
name_not_empty
(cls, v: str) -> str:
if not
v.strip():
raise
ValueError(
"name cannot be empty"
)
return
v.strip()
class
UserRead
(BaseModel):
id: int
email: str
name: str
created_at: datetime
model_config = {
"from_attributes"
: True}
repo/ — 只管 CRUD,无业务判断
# src/myapp/repo/user_repo.py
class
UserRepo
:
def
__init__
(self, session: AsyncSession):
self.session = session
async def
create
(self, data: UserCreate) -> UserModel:
user = UserModel(email=data.email, name=data.name)
self.session.add(user)
await
self.session.flush()
return
user
async def
get_by_email
(self, email: str) -> UserModel | None:
result =
await
self.session.execute(
select(UserModel).where(UserModel.email == email)
)
return
result.scalar_one_or_none()
service/ — 业务逻辑全在这里
# src/myapp/service/user_service.py
import
structlog
logger = structlog.get_logger()
class
UserService
:
def
__init__
(self, repo: UserRepo):
self.repo = repo
async def
create_user
(self, data: UserCreate) -> UserRead:
log = logger.bind(email=data.email)
existing =
await
self.repo.get_by_email(data.email)
if
existing:
log.warning(
"user.create.duplicate_email"
)
raise
ValueError(
f"Email already registered: {data.email}"
)
user =
await
self.repo.create(data)
log.info(
"user.created"
, user_id=user.id)
return
UserRead.model_validate(user)
api/ — 只处理 HTTP,不含业务判断
# src/myapp/api/user_router.py
router = APIRouter(prefix=
"/users"
, tags=[
"users"
])
@router.post
(
"/"
, response_model=UserRead, status_code=
201
)
async def
create_user
(
data: UserCreate,
# Pydantic 自动验证请求体
service: UserService = Depends(get_user_service),
):
try
:
return await
service.create_user(data)
except
ValueError
as
e:
raise
HTTPException(status_code=
409
, detail=str(e))
用脚本机械化执行约束(接入 CI)
linter 的错误信息里要内嵌修复指令,因为这条报错会出现在 Codex 的上下文里:
# scripts/check_imports.py
FORBIDDEN = {
"api"
: [
"repo"
],
"repo"
: [
"service"
,
"api"
],
"types"
: [
"repo"
,
"service"
,
"api"
],
}
def
violation_message
(layer, forbidden, file, line):
return
(
f"❌ {file}:{line}
"
f" {layer}层 不能导入 {forbidden}层
"
f" ✅ 修复:在 service/ 新增方法,通过 service 访问数据
"
f" 📖 参考:ARCHITECTURE.md#层级约束"
)
四、结构化日志:让 Agent 能查询运行时信号
OpenAI 把完整的可观测性栈(日志/指标/追踪)暴露给 Codex,让它能用 LogQL、PromQL 自己查问题。Python 项目里,最基础的做法是结构化日志。
⚠️ 为什么裸 print 是大问题
Codex 无法对 print(f"用户 {uid} 创建了") 做精确查询。它只能靠 grep,容易误匹配。结构化 JSON 日志才能做到:grep '"event":"user.created"' 精准定位。
# src/myapp/config/logging.py
import
structlog
def
setup_logging
():
structlog.configure(
processors=[
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.TimeStamper(fmt=
"iso"
),
structlog.processors.JSONRenderer(),
],
)
# 使用方式
logger = structlog.get_logger()
❌ print(f"用户 {user_id} 创建成功")
❌ logging.info("user created: " + str(user_id))
✅ logger.info("user.created", user_id=user_id, duration_ms=42)
✅ logger.error("payment.failed", order_id=oid, reason="insufficient")
✅ logger.warning("rate_limit.hit", endpoint="/api/users", ip=ip)
在 AGENTS.md 里补充查询命令,让 Codex 知道怎么查日志:
## 查看日志(在 AGENTS.md 里写清楚)
# 实时日志
tail -f logs/app.log | python -m json.tool
# 查所有错误
cat logs/app.log | grep '"level":"error"'
# 查特定事件
cat logs/app.log | grep '"event":"user.created"'
# 查某个用户的所有日志
cat logs/app.log | grep '"user_id":456'
# 统计今天的错误数量
cat logs/app.log | grep '"level":"error"' | wc -l
五、执行计划:管住复杂任务不跑偏
超过两个文件的变更,必须先写执行计划。计划提交进仓库,Codex 按计划执行,出问题时知道在哪一步。
标准两步提示流程
第一轮:“分析代码库,为「添加用户权限系统」写执行计划,存到 docs/plans/active/user-auth.md”
→ 你 review 计划,修改不合理处
第二轮:“按照 docs/plans/active/user-auth.md 执行 Step 1-2,完成后更新进度标记”
<!-- docs/plans/active/user-auth.md -->
# 执行计划:用户认证系统
## 目标
为 API 添加 JWT 认证,保护需要登录的接口。
## 步骤
- [x] Step 1: types/auth.py 定义 LoginRequest, TokenResponse
- [x] Step 2: 实现 AuthService.login(),返回 JWT token
- [ ] Step 3: 实现 get_current_user dependency,验证 JWT
- [ ] Step 4: 在需要认证的路由加 Depends(get_current_user)
- [ ] Step 5: 补充集成测试(含过期 token、无效 token 场景)
## 决策日志
2025-03-20: 选 python-jose 而非 PyJWT,RS256 支持更完整
2025-03-21: Token 有效期 24h,refresh token 暂不实现,记入技术债
## 风险点
- JWT secret 必须从环境变量读取,禁止硬编码
- 过期 token 必须返回 401,不能 500
六、给 Codex 的标准提示模板
好的提示词不是让 Codex"更努力",而是给它清晰的输入、约束和验收标准。
| 场景 | 提示模板 |
|---|---|
| 新功能 | 按照 docs/plans/active/xxx.md 实现 Step N。完成后:① run make check ② run make test ③ 更新计划进度 ④ 开 PR 说明做了什么 |
| 修 Bug | ① 先写能复现此问题的测试(确认失败) ② 修复代码 ③ 确认测试通过 ④ run make check ⑤ 开 PR |
| 重构 | xxx.py 已 450 行,按 ARCHITECTURE.md 拆分:认证逻辑→auth_service.py,权限→permission_service.py。保证所有现有测试继续通过。 |
| 调查问题 | 查看 logs/app.log 中最近 1 小时的 error 事件,分析根因,在 docs/design/ 写一个 ADR 说明问题和修复方案,然后实施修复。 |
七、熵与垃圾回收:让代码库不漂移
全 agent 生成的代码会自然漂移——Codex 会复制仓库里已有的模式,包括坏的。OpenAI 团队把清洁工作本身也 agent 化,定期扫描偏差、自动发 PR。
# scripts/health_check.py — 每周运行,输出喂给 Codex
from
pathlib
import
Path
import
re
def
check_large_files
(src: Path, max_lines=
300
):
return
[
f" {f} ({len(f.read_text().splitlines())}行,建议拆分)"
for
f
in
src.rglob(
"*.py"
)
if
len(f.read_text().splitlines()) > max_lines
]
def
check_bare_print
(src: Path):
results = []
for
f
in
src.rglob(
"*.py"
):
for
i, line
in
enumerate(f.read_text().splitlines(),
1
):
if
re.match(
r"\s*print\("
, line):
results.append(
f" {f}:{i} — 改用 structlog"
)
return
results
def
check_missing_tests
(src: Path, tests: Path):
return
[
f" {f} 缺少测试"
for
f
in
(src/
"service"
).rglob(
"*.py"
)
if not
f.name.startswith(
"_"
)
and not
(tests/
"unit"
/f
f"test_{f.name}"
).exists()
]
def
check_todos
(src: Path):
results = []
for
f
in
src.rglob(
"*.py"
):
for
i, line
in
enumerate(f.read_text().splitlines(),
1
):
if any
(kw
in
line
for
kw
in
[
"TODO"
,
"FIXME"
,
"HACK"
]):
results.append(
f" {f}:{i} — {line.strip()}"
)
return
results
跑完后把报告喂给 Codex:
“以下是本周健康检查报告:[粘贴输出]
请按优先级处理,每个问题单独开一个 PR,标题格式:chore: [描述]”
八、工具配置:让一切可以一键执行
AGENTS.md 里只写 make check,Codex 就知道该跑什么。
# Makefile
dev
:
uvicorn myapp.main:app --reload --port 8000
test
:
pytest tests/ -v --tb=short --asyncio-mode=auto
lint
:
ruff check src/ tests/
ruff format --check src/ tests/
typecheck
:
mypy src/ --strict
check
: lint typecheck
python scripts/check_imports.py
@echo "✅ All checks passed"
clean-check
:
python scripts/health_check.py
# pyproject.toml
[tool.ruff]
line-length =
100
target-version =
"py311"
[tool.ruff.lint]
select = [
"E"
,
"F"
,
"I"
,
"N"
,
"UP"
,
"B"
,
"RUF"
]
[tool.mypy]
strict =
true
python_version =
"3.11"
[tool.pytest.ini_options]
asyncio_mode =
"auto"
testpaths = [
"tests"
]
九、落地路线图
| 阶段 | 行动 | 耗时 |
|---|---|---|
| 今天 | 写 AGENTS.md(100行以内,含导航/约束/命令) | 30 min |
| 今天 | 建 docs/plans/active/,把当前任务写成计划文件 | 20 min |
| 今天 | 写 ARCHITECTURE.md,定清层级约束和禁止依赖 | 30 min |
| 本周 | 配置 ruff + mypy,写 check_imports.py 接入 CI | 2 h |
| 本周 | 引入 structlog,统一替换 print / logging.info(str) | 半天 |
| 本周 | 把最近 3 个技术决策写成 ADR 提交 docs/design/ | 1 h |
| 本月 | 写 health_check.py 清洁脚本,设置每周定期执行 | 半天 |
| 本月 | worktree 隔离 + 应用可观测性接入,完整闭环 | 2 天 |
核心一句话
当 agent 负责写代码,工程师的价值在于设计让 agent 能高效工作的环境。
每次 Codex 卡住,不要手动修——追问:仓库里缺了什么?把它补进去。这才是新时代的工程师核心技能。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)