MateClaw 2.3.0 于 2026 年 9 月 20 日发布。这次更新瞄准了企业智能体中一个很现实的问题:Agent 说“任务完成了”,并不代表交付物真的满足要求。新版为 Persistent Goal 引入用户配置的托管 JSON 验收机制,将完成判定从智能体的自然语言声明,转变为服务端可复核的结构化检查。
核心变化不只是增加一个 JSON 文件,而是把需求、产物版本、执行证据和验收结果绑定在同一条可追踪链路上。只有当前要求对应的所有绑定都有效,目标才可以进入完成状态。
从“我做完了”转向服务端验收
长任务经常跨越多轮执行,期间可能发生文件更新、测试重跑、需求调整或人工介入。如果系统只检查 Agent 最后一条回复,就会出现几类典型问题:
- Agent 汇报测试通过,但引用的是旧版本代码的测试结果。
- 交付文件后来被覆盖,验收记录却仍然指向旧内容。
- 用户已经修改要求,Agent 仍按上一版要求宣布完成。
- 某些子任务失败或缺少证据,但总体状态被提前标记为完成。
MateClaw 2.3.0 的 Persistent Goal 验收模型强调三个约束:
- Agent 发布不可变的产物版本:验收针对一个确定版本,而不是随时可能变化的工作目录。
- 检查结果绑定当前要求和具体 generation:旧 generation 的成功结果不能自动替代新一轮执行。
- 全部当前绑定有效后才能完成:只要有一项缺失、失效或指向旧 generation,服务端就不应放行。
这里的 generation 可以理解为一次明确的目标执行代次。它让系统能够区分“第 6 次执行通过”与“第 7 次修改后尚未验证”,避免复用过期证据。
不可变 JSON 解决的是验收竞态
结构化验收的价值不仅是方便机器读取,更重要的是固定验收对象。一个合理的验收记录至少需要表达:
- 当前目标与 generation;
- 产物的唯一版本或摘要;
- 当前生效的要求集合;
- 每项要求对应的证据;
- 检查结果及其生成时间;
- 是否存在受控人工干预。
如果产物可被原地修改,就可能发生验收竞态:服务端检查时文件符合要求,随后文件被覆盖,但目标仍显示已完成。实践中可以用内容摘要、对象存储版本号、只追加存储或签名清单实现不可变性。来源摘要没有说明 MateClaw 内部采用哪一种存储技术,因此这些属于可选的工程实现,而不是对产品内部机制的推断。
观察模式执行证据也补上了关键一环。它让验收系统不仅看到最终声明,还能保留执行过程中的可观察证据。对于部署、数据迁移、批量修改等高风险任务,证据通常比一句总结更有价值。
可以这样实践:实现一个最小验收门禁
下面是一个可直接运行的 Python 示例,用来模拟 generation 绑定、产物摘要和全量要求检查。它不是 MateClaw 的官方 API,而是一种可改造成内部验收服务的参考实现。
将以下内容保存为 acceptance_gate.py:
from __future__ import annotations
import hashlib
import json
from pathlib import Path
CURRENT_GENERATION = 7
CURRENT_REQUIREMENTS = {
'report-produced': 'file_sha256',
'tests-passed': 'check_passed',
}
def sha256_file(path: str) -> str:
digest = hashlib.sha256()
with open(path, 'rb') as stream:
for chunk in iter(lambda: stream.read(65536), b''):
digest.update(chunk)
return digest.hexdigest()
def validate_acceptance(document: dict) -> list[str]:
errors: list[str] = []
if document.get('generation') != CURRENT_GENERATION:
errors.append('acceptance document belongs to a stale generation')
artifact = document.get('artifact', {})
if artifact.get('immutable') is not True:
errors.append('artifact is not marked immutable')
bindings = document.get('bindings', [])
indexed = {item.get('requirement_id'): item for item in bindings}
if set(indexed) != set(CURRENT_REQUIREMENTS):
errors.append('bindings do not exactly match current requirements')
return errors
for requirement_id, check_type in CURRENT_REQUIREMENTS.items():
binding = indexed[requirement_id]
if binding.get('generation') != CURRENT_GENERATION:
errors.append(f'{requirement_id}: stale generation binding')
continue
if binding.get('valid') is not True:
errors.append(f'{requirement_id}: binding is not valid')
continue
evidence = binding.get('evidence', {})
if check_type == 'file_sha256':
path = evidence.get('path')
expected = evidence.get('sha256')
if not path or not Path(path).is_file():
errors.append(f'{requirement_id}: evidence file is missing')
elif sha256_file(path) != expected:
errors.append(f'{requirement_id}: artifact hash changed')
if check_type == 'check_passed':
if evidence.get('status') != 'passed':
errors.append(f'{requirement_id}: check did not pass')
return errors
def main() -> None:
Path('report.txt').write_text(
'Persistent Goal delivery for generation 7\n',
encoding='utf-8',
)
document = {
'goal_id': 'goal-quarterly-report',
'generation': 7,
'artifact': {
'version': 'artifact-v7',
'immutable': True,
},
'bindings': [
{
'requirement_id': 'report-produced',
'generation': 7,
'valid': True,
'evidence': {
'path': 'report.txt',
'sha256': sha256_file('report.txt'),
},
},
{
'requirement_id': 'tests-passed',
'generation': 7,
'valid': True,
'evidence': {
'status': 'passed',
'command': 'python -m unittest',
},
},
],
}
errors = validate_acceptance(document)
print(json.dumps(document, ensure_ascii=False, indent=2))
if errors:
print('\nREJECTED')
for error in errors:
print(f'- {error}')
raise SystemExit(1)
print('\nACCEPTED: every current requirement is valid')
if __name__ == '__main__':
main()
运行:
python acceptance_gate.py
正常情况下程序会输出 ACCEPTED。随后修改 report.txt 并单独调用验收函数,摘要检查就会失败。在真实系统里,还应把 artifact-v7 放入不可覆盖的存储位置,并让服务端而不是 Agent 自己决定 immutable 和 valid 字段是否可信。
这个例子还揭示了一条重要边界:JSON 只是声明载体,不天然等于可信证据。生产环境至少应考虑以下强化措施:
- 由服务端生成或签名 generation、产物版本和验收结果;
- 使用对象版本、内容哈希或签名校验实际产物;
- 禁止 Agent 直接把自己的检查结果标记为可信;
- 需求发生变化时,使旧绑定自动失效;
- 将观察证据和人工干预记录写入审计日志。
Team Worker 干预与上传能力意味着什么
本次版本还包括 Team Worker 受控干预,以及 Skill 文档和文件夹上传。它们与验收机制放在一起看更有意义。
受控干预意味着操作者可以在必要时修正执行过程,但干预不能成为绕过验收的后门。比较稳妥的做法是记录干预者、时间、原因、影响的 generation,以及干预后是否触发重新检查。如果人工修改了产物,原有摘要和绑定通常应该失效。
Skill 文档及文件夹上传则有助于把操作手册、模板、脚本和项目上下文整体交给智能体。与此同时,上传范围扩大也带来新的治理问题:敏感文件、隐藏目录、密钥、超大二进制文件和符号链接都需要明确处理策略。企业接入时不应只检查上传是否成功,还应建立文件过滤、权限隔离和内容扫描机制。
上线前值得确认的清单
要把 2.3.0 的验收能力真正用于企业长任务,可以从以下检查开始:
- 每项要求是否拥有稳定且唯一的标识,而不是只靠自然语言描述?
- generation 在需求修改、人工干预和任务重试时是否会正确推进?
- 产物是否具备真正的不可变版本,而不只是 JSON 中的布尔标记?
- 服务端是否拒绝缺失绑定、额外绑定和旧 generation 的结果?
- 观察模式证据是否有保留期限、访问控制和脱敏规则?
- Team Worker 的人工干预是否进入审计链,并触发必要的重新验收?
- Skill 文件夹上传是否排除了密钥、构建缓存和无关的大文件?
MateClaw 2.3.0 最值得关注的变化,是把“完成”从对 Agent 的信任问题,变成一个可以由服务端执行的状态转换。不可变产物、generation 绑定和全量要求校验结合后,长任务才有机会从“看起来做完了”升级为“有证据证明这一版确实满足当前要求”。