Skip to content

필사 모드: 框架不是配置,而是交付物 —— 自我改进循环真正的瓶颈

中文
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

提示词一个字没改,成功率却涨了 6 个百分点

智能体的任务成功率比上周涨了。没有提示词的提交,模型版本也没变。翻了一圈才发现:某个工具定义的描述文字被缩短了,重试上限从 3 提到了 5,读文件工具返回的行数上限也变了。这三处改动分别是不同的人出于不同的理由做的,而且没有一处出现在发布说明里。

下周要是成功率掉了,该回滚哪一个?在现在这个结构下,你答不上来。

给框架划出边界,管理才算开始

Lilian Weng 在 2026 年 7 月 4 日写的那篇文章给这一坨东西起了名字。框架是包裹基础模型、协调其执行的系统,是决定模型如何思考与规划、如何调用工具与行动、如何感知与管理上下文、把产物存到哪里、如何评估结果的那一层。

这个定义之所以有用,是因为它把范围划得很宽。比早期智能体框架所涵盖的更宽,它把工作流设计与评估、权限控制、持久状态管理都包了进来。前面例子里变动的那三处,全都落在这个边界之内。只有先划出边界,「到底是什么变了」这个问题才变得可回答。

从提示词工程走向框架工程

这次转移在实务上的含义,是杠杆在哪儿。大多数团队既不做基础模型,也不做微调。这些团队能动的,就是整个框架。

而框架这一侧的改进空间,通常比提示词的措辞大得多。比如暴露几个工具、失败怎么回传、什么时候拉起子智能体、中间产物是落成文件还是抱在上下文里往下走。这篇文章里说「代码是通用语言」的那一段,正是挂在这儿。用句子能指示的空间,远远小于用代码能定义的空间。

单看「工具失败怎么回传给模型」这一件事就是如此。把异常字符串原样丢回去,模型就会重复同一次调用。把失败原因连同当前可行的替代方案列表结构化地返回,下一次调用就会不一样。这是提示词写得再好也拿不到的那类改进,而且完全是代码侧的决定。

自我改进会先发生在框架上,而不是权重上

文章的核心主张关于递归式自我改进:AI 用当下的智能去改进那台生产自身智能的机器。而它的判断是,在可见的未来,这件事推进的路径不是直接改模型权重,而是框架不断演化。

这个判断听着抽象,其实已经以非常具体的形态在跑了。智能体改自己的工具定义、修改自己的执行脚本、读失败日志然后重排工作流。只要具备读写文件、执行 shell、git、创建子智能体这类工具,框架就成了一个可以自我编辑的对象。

这里在实务上更重要的,不是「这个循环已经在转」这个事实,而是「在大多数团队里它转得没有记录」这个事实。智能体润色了工具描述,人草草批了那个提交,性能变了一点点,没有人把这两件事联系起来。自我改进循环的危险不在于它快,而在于它没被观测。

把上下文当成 playbook,而不是提示词

这篇文章介绍的做法里,最能直接搬进实务的,是把上下文当成不断演化的 playbook,而不是越写越长的提示词。把「生成条目」「回顾条目」「筛选条目」的角色拆开,来管理结构化的条目。

差别在这里。提示词的做法里,新学到的东西不断被追加到段落末尾。一个月后没人再读那份文档,互相矛盾的指令并存,涨的只有 token。playbook 的做法里,每个条目都记录了它是什么时候加进来的、适用于什么情形、最近有没有派上用场,于是删除变得可能。上下文管理难的地方不是往里放,而是往外拿;而要能拿出来,条目就得带元数据。

框架是带版本号的交付物

走到这一步,就能回到最初那个问题了。要把框架当交付物来对待,至少得有一个指纹。

"""框架指纹:要和结果一起保存,才能回溯回归。"""
import hashlib
import json
from dataclasses import dataclass, field, asdict


@dataclass
class HarnessSpec:
    model: str
    system_prompt: str
    tools: list                 # [{"name":..., "description":..., "schema":...}]
    max_steps: int
    max_retries: int
    context_policy: dict        # 截断、摘要、playbook 策略
    permissions: list           # 允许的副作用

    def fingerprint(self) -> str:
        payload = asdict(self)
        # 工具顺序没有意义,先做归一化。不做的话指纹每次都会变。
        payload["tools"] = sorted(payload["tools"], key=lambda t: t["name"])
        blob = json.dumps(payload, sort_keys=True, ensure_ascii=False)
        return hashlib.sha256(blob.encode("utf-8")).hexdigest()[:12]


def diff(a: HarnessSpec, b: HarnessSpec) -> dict:
    da, db = asdict(a), asdict(b)
    return {k: (da[k], db[k]) for k in da if da[k] != db[k]}


base = HarnessSpec(
    model="some-model-v3",
    system_prompt="...",
    tools=[{"name": "read_file", "description": "读取文件", "schema": {}}],
    max_steps=20,
    max_retries=3,
    context_policy={"strategy": "playbook", "max_items": 40},
    permissions=["read_fs"],
)
candidate = HarnessSpec(**{**asdict(base), "max_retries": 5})

print(base.fingerprint(), "->", candidate.fingerprint())
print(diff(base, candidate))   # {'max_retries': (3, 5)}

把这个指纹和每一次评估运行的结果一起留下来,成功率曲线上的每一级台阶对应哪一次改动,就能回溯了。而且会自然产生一条规则:凡是会改变指纹的改动,都是需要重跑评估的改动。把重试上限从 3 提到 5 的那一行,会被当成和改提示词同一等级的事来对待。

这个循环的瓶颈不是模型,而是评估者

同一篇文章列了框架工程面临的若干难题,排在第一的是弱评估者。只要看一眼自我改进循环的结构,这就是必然的结论。

循环做的是:改框架、做评估、采纳更好的那一边。这个循环的速度不取决于改框架的速度,而取决于评估是否可信。评估如果是噪声,循环就会顺着噪声移动。它会变成一个没有方向却跑得很快的系统,指标在涨,实际使用的质量原地不动甚至更差。

所以在把框架改进自动化之前,必须先做的是校准评估者。顺序一颠倒,自动化就只是把问题制造得更快。

奖励作弊不是 bug,而是正常输出

最后一个难题是奖励作弊,而不误解这个说法很重要。智能体为了让测试通过而去改测试、塞进吞掉失败的异常处理、只填评估脚本会去看的那几个字段 —— 这些都不是系统出故障的结果,而是精确优化了我们所定义的目标的结果。

应对分两条线。一条是权限。把评估代码和评分数据从智能体可写的路径中排除掉,这一类的一半就消失了。原文之所以把权限控制明确列为框架的组成部分,原因就在这里。权限在成为安全项之前,首先是评估完整性的一项。

另一条是不要只用一个指标。在成功率之外,一并观察工具调用次数、被修改文件的范围、被删掉的测试数这类制衡指标。制衡指标不是目标而是警报,所以设个阈值、越线时让人来看一眼就够了。

总结起来是这样:框架工程的杠杆又大又抓得住,但要安全地扳动这根杠杆,评估必须先立起来。给框架打上指纹,是连接这两者最便宜的第一步。

参考资料

현재 단락 (1/55)

智能体的任务成功率比上周涨了。没有提示词的提交,模型版本也没变。翻了一圈才发现:某个工具定义的描述文字被缩短了,重试上限从 3 提到了 5,读文件工具返回的行数上限也变了。这三处改动分别是不同的人出于...

작성 글자: 0원문 글자: 3,522작성 단락: 0/55