第五章:垃圾收集 —— 与熵的持久战
即使有了完善的上下文工程和严格的架构约束,熵增仍然是不可避免的。驾驭工程的第三根支柱,是一套持续对抗熵增的机制。
熵增是不可避免的
漂移的本质
Agent 会复现代码库中已存在的模式。随着代码量增长:
时间 → 代码量 → 模式多样度 → 不一致性 → 熵
每个模式单独看都是合理的
但它们的组合可能产生不一致
再加上 Agent 偶尔引入的不理想模式
代码库逐渐漂移,偏离预期架构和风格
手动清理无法扩展
OpenAI 团队的惨痛教训:
他们最初安排每周五(20% 时间)手动清理 Agent 引入的不一致。
结果: ├── 你清理的速度 << Agent 引入偏差的速度 ├── 清理期间 Agent 还在继续产出 └── 最终 → 清理只是杯水车薪
在 Agent 的高吞吐量下(每人每天 3.5 个 PR), 手动清理完全无法扩展 [1]。
用 Agent 对抗 Agent 的熵
自动化对抗自动化
解决方案是用自动化对抗自动化:
graph TB
subgraph "熵增循环"
A1[编码 Agent] -->|产出代码| A2[代码库]
A2 -->|积累偏差| A3[熵增]
end
subgraph "垃圾收集循环"
B1[后台扫描 Agent] -->|检测偏差| A2
B1 -->|发起重构 PR| B2[小而聚焦的 PR]
B2 -->|快速审查| B3[自动合并]
B3 -->|清理偏差| A2
end
A3 -.->|触发| B1
垃圾收集循环
OpenAI 团队建立的"垃圾收集"循环 [1]:
定期运行后台 Codex 任务
↓
扫描代码库中的偏差
├── 不一致的错误处理模式
├── 重复代码
├── 过时的文档
└── 违反编码规范的地方
↓
更新质量等级
↓
发起有针对性的重构 Pull Request
↓
快速审查(通常 1 分钟内)
↓
自动合并
文档花园
垃圾收集也覆盖文档维护:
文档花园维护系统:
├── 专职 linter 验证知识库更新状况
├── CI 作业检查交叉链接和结构正确性
└── "doc-gardening" Agent 定期扫描过时文档并自动发起修复 PR
技术债务如同高息贷款
两种偿还策略
策略 A:持续小额偿还
├── 每天发现并解决不良模式
├── 在它们传播之前消灭
└── 成本:低,持续
策略 B:债务累积后痛苦偿还
├── 等到问题大到不可忽视
├── 批量处理
└── 成本:极高,阵痛期长
在低吞吐量环境中,策略 B 可能勉强可行。
但在高 Agent 吞吐量环境中(每人每天 3.5 个 PR), 让债务累积意味着灾难。
债务的复利会迅速吞噬你从 Agent 获得的所有效率增益。
合并策略的转变
吞吐量改变了合并的理念:
| 维度 | 低吞吐量(传统) | 高吞吐量(Agent) |
|---|---|---|
| 等待成本 | 低 | 极高(阻塞大量后续 PR) |
| 纠错成本 | 高 | 低(Agent 可快速修复) |
| 合并策略 | 确保万无一失再合并 | 最小化合并阻塞 |
| 修复方式 | 人工审查后合并 | 快速合并 + 后台修复 |
传统:最小化测试失败
Agent:最小化合并阻塞
实现垃圾收集系统
质量扫描器
# tools/quality_scanner.py
class QualityScanner:
"""代码库质量扫描器"""
def __init__(self, config: Dict):
self.rules = self._load_rules(config["rules_path"])
self.thresholds = config["thresholds"]
async def scan(self) -> ScanReport:
"""
扫描代码库,检测偏差
"""
findings = []
# 1. 一致性检查
consistency = await self._check_consistency()
findings.extend(consistency)
# 2. 模式偏差检测
pattern_drift = await self._detect_pattern_drift()
findings.extend(pattern_drift)
# 3. 文档新鲜度
doc_freshness = await self._check_documentation()
findings.extend(doc_freshness)
# 4. 死代码检测
dead_code = await self._detect_dead_code()
findings.extend(dead_code)
return ScanReport(
findings=findings,
quality_score=self._compute_score(findings),
auto_fixable=[f for f in findings if f.auto_fix],
)
async def _check_consistency(self) -> List[Finding]:
"""检查代码一致性"""
findings = []
# 检查错误处理风格是否统一
error_styles = await self._detect_error_handling_styles()
if len(error_styles) > 2:
findings.append(Finding(
type="consistency",
severity="warning",
message=f"发现 {len(error_styles)} 种错误处理风格",
auto_fix=True,
fix_description="统一为推荐的错误处理风格",
))
return findings
async def _detect_pattern_drift(self) -> List[Finding]:
"""检测模式漂移"""
findings = []
# 检查是否偏离了推荐的实现模式
patterns = await self._analyze_patterns()
for pattern in patterns:
if pattern.drift_score > self.thresholds["drift"]:
findings.append(Finding(
type="drift",
severity="info",
message=f"模式 '{pattern.name}' 出现漂移",
affected_files=pattern.files,
))
return findings
自动重构 PR 生成
# tools/auto_refactor.py
class AutoRefactor:
"""自动重构 PR 生成器"""
async def generate_refactor_pr(self, finding: Finding) -> PR:
"""
根据发现的问题生成重构 PR
"""
if not finding.auto_fix:
return None
# 生成修复代码
fix = await self._generate_fix(finding)
# 创建分支
branch = f"gc/{finding.type}/{finding.id}"
# 应用修复
for file_path, changes in fix.changes.items():
await self._apply_changes(file_path, changes)
# 创建 PR
pr = await self._create_pr(
branch=branch,
title=f"[GC] {finding.message}",
body=self._generate_pr_description(finding, fix),
labels=["auto-generated", "garbage-collection"],
)
return pr
def _generate_pr_description(self, finding: Finding, fix: Fix) -> str:
return f"""
## 垃圾收集自动修复
### 问题
{finding.message}
### 影响范围
{', '.join(finding.affected_files)}
### 修复方案
{fix.description}
### 变更
{fix.diff_summary}
---
此 PR 由垃圾收集系统自动生成。通常可在 1 分钟内完成审查。
"""
质量等级系统
# tools/quality_score.py
class QualityScorer:
"""代码库质量评分"""
DIMENSIONS = {
"consistency": {
"weight": 0.3,
"checks": ["error_handling_style", "naming_convention", "log_format"]
},
"architecture": {
"weight": 0.3,
"checks": ["dependency_direction", "module_boundary", "layer_separation"]
},
"documentation": {
"weight": 0.2,
"checks": ["doc_coverage", "doc_freshness", "cross_reference"]
},
"test_coverage": {
"weight": 0.2,
"checks": ["unit_coverage", "integration_coverage", "critical_path"]
}
}
def compute_overall_score(self, scan_result: ScanReport) -> QualityReport:
scores = {}
for dim, config in self.DIMENSIONS.items():
dim_findings = [f for f in scan_result.findings
if any(c in f.type for c in config["checks"])]
scores[dim] = self._score_dimension(dim_findings)
overall = sum(
scores[dim] * config["weight"]
for dim, config in self.DIMENSIONS.items()
)
return QualityReport(
overall=overall,
dimensions=scores,
trend=self._compute_trend(),
recommendation=self._generate_recommendation(scores),
)
监控熵的趋势
行业案例:Harness 迭代的必然性
垃圾收集不仅是代码层面的维护,更涉及整个 Harness 体系的持续迭代。以下案例说明了这一点:
Manus:6 个月,5 次 Harness 重写
├── 第 1 版:基础 Prompt → 迅速发现不够用
├── 第 2 版:加入 RAG → 上下文管理失控
├── 第 3 版:引入工具系统 → 工具间交互混乱
├── 第 4 版:分层架构 → 约束执行不够自动化
├── 第 5 版:完整的 Harness 体系 → 终于稳定
└── 启示:Harness 本身也会积累技术债务
LangChain:1 年,3 次架构重构
├── v1:单链式 Agent → 复杂任务无法处理
├── v2:Multi-Agent → Agent 间协调困难
├── v3:Harness + 规范化接口 → 走向成熟
└── 启示:不重构的 Harness 会成为新的瓶颈
一个健康的 Harness 应该被设计为可删除的。
这不是说你会删除它,而是说: ├── 每个约束都有明确的存活条件 ├── 当约束不再需要时,应该能干净地移除 ├── Harness 自身也在被垃圾收集的范围内
如果你不敢删除某个约束,说明它还没有被正确编码。 如果你永远不删除约束,Harness 本身就会变成技术债务。
质量趋势追踪
质量得分趋势:
Week 1: ████████████████████ 0.95 (初始)
Week 2: ██████████████████░░ 0.88 (开始漂移)
Week 3: █████████████████░░░ 0.85 (GC 启动)
Week 4: ███████████████████░ 0.91 (GC 生效)
Week 5: ████████████████████ 0.94 (恢复)
Week 6: ████████████████████ 0.95 (稳定)
关键信号:
├── 连续 2 周下降 → 触发 GC 扫描
├── 单周下降 > 5% → 紧急扫描
└── 恢复后稳定 → GC 频率降低
告警规则
# 告警配置
alerts:
- name: quality_drop
condition: "quality_score < prev_week_score - 0.03"
action: "trigger_gc_scan"
- name: drift_accumulation
condition: "drift_findings > 20"
action: "schedule_refactor_batch"
- name: doc_stale
condition: "doc_freshness_score < 0.7"
action: "trigger_doc_gardening"
实践指南
垃圾收集策略选择
| 项目阶段 | 推荐策略 | 频率 |
|---|---|---|
| 初始阶段 | 手动清理 + 基础 linter | 每周 |
| 成长阶段 | 半自动扫描 + 人工审查 PR | 每日 |
| 成熟阶段 | 全自动扫描 + 自动 PR + 自动合并 | 持续 |
关键指标
✅ 代码库质量得分趋势(目标:持续 > 0.85)
✅ GC 扫描发现的问题数(目标:持续下降)
✅ 自动修复 PR 的合并率(目标:> 90%)
✅ 文档新鲜度得分(目标:> 0.8)
✅ 模式一致性得分(目标:> 0.9)
快速检查清单
✅ 是否有自动化的代码库质量扫描?
✅ 是否有后台 Agent 定期扫描偏差?
✅ 扫描发现是否能自动生成修复 PR?
✅ 文档是否有自动新鲜度检查?
✅ 质量趋势是否有监控和告警?
✅ 合并策略是否适应高吞吐量?
小结
✅ 熵增不可避免,但可以控制 ✅ 用自动化对抗自动化 ✅ 技术债务持续小额偿还 ✅ 合并策略:最小化阻塞,而非最小化失败 ✅ 质量趋势监控 + 自动告警 ✅ 文档花园需要持续维护
参考文献:
- [1] Ryan Lopopolo, "Harness engineering: leveraging Codex in an agent-first world", OpenAI, 2026
- [2] Birgitta Böckeler, "Harness Engineering", martinfowler.com, 2026
- [3] "模型不是关键,Harness 才是", 微信公众号, 2026
下一章,我们将进入方法论篇,深入探讨评估体系设计。