专家进化
一句话定义
专家发布后不是静态的。系统会在后台读取真实对话轨迹与实测运行成本,重写专家的技能文档,用一套 10 维评分门禁验证「下一次运行更便宜且不更差」,通过门禁的才作为建议出现在你的进化面板里。采纳与否由你决定,系统从不自动改动你的专家。这是什么,不是什么
「AI 自我改进」这个词现在覆盖的范围很宽,所以先把边界划清楚。
Profy 做的是程序性记忆的定向优化:专家在一次次真实任务中积累了「哪些路走得通、哪些是死路」,进化把这些经验写回技能文档,让下一次不用重新趟一遍。模型权重、推理能力、平台代码都不在改动范围内。
之所以强调这个区分,是因为它决定了风险面:改的是一份人类可读、可 diff、可回滚的 Markdown 文档,不是一个不可解释的权重更新。你在面板上看到的就是完整的改动内容。
在「如何设计不被 reward hacking 的评测门禁」这个当下被反复讨论的问题上,Profy 的答案是下面这套双棘轮 + 代码托管维度。它的价值不在于有多复杂,而在于它把两条最容易被绕过的路都堵死了——具体见「为什么这样设计」一节。
目标函数:让下一次更便宜且不更差
进化的目标写在系统提示词的第一段,只有一句:让下一次运行更便宜且不更差。经验必须 替换 探索,而不是堆在探索之上。这句话排除了一整类看起来像改进的东西。加防御性步骤、加兜底、加更详尽的说明——都不算进步,除非它移除的成本大于它增加的成本。 这个取向是有代价的,也是刻意的:一份不断变厚的技能文档在直觉上像是「专家学到了更多」,但实际上它每一次运行都要被完整注入上下文,是一笔固定的、随文档增长而增长的成本。变厚往往意味着变贵。
评分表:10 个维度,两个组
每个维度 0–100 分。质量组 7 维权重合计 0.70,效率组 3 维合计 0.30,总分仍在 0–100 量纲上。质量组(0.70)
效率组(0.30)
context_footprint:唯一不由模型自评的维度
这一维的分数完全由代码从文档字符数算出,模型传什么值都会被忽略:
公式:
100 × (24000 − chars) / 21000,钳制在 0–100。
阈值不是拍脑袋定的。实测基线来自 Stage 4:种子技能 429 字符,进化后输出 12,109 字符。所以 3,000 字符被定义为「紧凑可注入的 SOP」(满分),24,000 字符约为 Stage 4 输出的两倍、已接近失控的固定单次成本(零分)。
拿不到当前技能内容时(比如查询失败),before 分回落到中性的 50.0 —— 既不奖励也不惩罚,保证门禁仍然可判定而不是直接报错。
双棘轮规则
一条建议被接受,两个条件必须同时成立:1
质量组不得下降
质量组加权分(after) ≥ 质量组加权分(before)2
效率组必须严格上升
效率组加权分(after) > 效率组加权分(before)双向禁止抵偿
这是整套设计的核心,也是它区别于「加权总分要提高」的地方。 违反第一条时,工具返回:为什么这样设计
单一加权总分的门禁有一个结构性漏洞:任何一维都可以被另一维买单。如果只要求总分上升,一次「质量 +15、效率 −10」的改动能轻松过关——而这正是最典型的退化形态:文档越写越厚、越写越”全面”,每次运行更贵,但每一项质量指标都在涨,总分看起来一路走高。 拆成两组并要求「一组不降 + 另一组严格升」,把这条路堵死了。同时反方向也被堵死:不能靠砍掉质量内容来换效率提升,因为质量组不允许下降。 第二个漏洞是自评。如果 10 个维度全由模型自己打分,那么门禁的判据和被判据的对象来自同一个来源——它想过就能过。context_footprint 由代码从字符数算出,是这条链上唯一一个模型无法自证的锚点。它权重只有 0.08,但因为效率组必须严格上升且只有三维,文档大幅变长时这一维的下跌通常足以让整个效率组无法上升。
这两个漏洞是同一类问题的两个面:门禁的判据不能由被守护的对象自己提供。第一个漏洞是维度之间互相提供借口,第二个是模型给自己出成绩单。
遗留 7 维评分表
设置EVOLUTION_RUBRIC=quality 会切回旧的 7 维(只有质量组,权重重新归一到 1.0),规则退化为「加权总分必须严格上升」。这只用于回滚,默认值是 quality_eff,所有环境都跑新表。
实测成本作为地面真值
进化不只看对话轨迹,还会收到一个<run_stats> 块——过去若干次运行的实测成本:
最多 20 条。判定规则写死在技能文档里:
- 技能变长之后 token 涨了 → 上一轮方向错了,这一轮必须压缩和删除,不能继续加内容
- token 降了且成功率没掉 → 方向对,继续编码捷径,但仍要盯文档体积
- 永远不要拿理论去反驳 run_stats,实测成本说了算
run_stats 是严格白名单结构且逐字段有上界,因为它会被逐字注入进化提示词。不做校验的话,未受控输入既会撑爆上下文,也可能被用来夹带指令。触发与调度
什么时候会跑一次进化
进化不是每轮对话都跑。计数器按 (用户, 专家) 累计,跨会话累加:
计数器按「用户×专家」而不是按会话累计是有原因的:同一个用户可能连开很多个只说一两句的短会话,按会话计数永远够不到阈值。TTL 7 天意味着一周不聊就重置——对这种提示性触发来说是可以接受的。
平台侧调度门槛
除了对话触发,平台还有一个周期调度器(默认关闭):EVOLUTION_PENDING_MAX = 5 这条直接决定你的体感:如果你积压了 5 条未处理建议,系统就不再为这个专家生成新的。所以定期清面板不只是整理习惯,它是让进化继续运转的前提。
进化模式的能力边界
进化跑在一个隔离的内部调用里,不是你正常对话的一部分。作用域是硬校验,不是约定
工具在提交前会核对目标技能确实是expert/*。不是的话直接拒绝:
builtin/*(平台内置)和 user/*(用户全局库)都在范围之外。前者改了就是改平台,后者不属于这个专家。同时 skill_name 必须是裸名(docx 而不是 expert/docx),带前缀会被拒。
可选的记忆整理
进化模式下还允许调memory(action="dream", scope="expert") 做记忆整理(合并重复、归档陈旧)。但它是可选且低优先级的,只在技能改进已提交或已跳过、且 token 预算有余时才做。技能评估永远优先。
采纳与忽略
采纳时发生什么
1
校验建议结构
结构不合法返回 400,不会写库。
2
定位目标技能
按
expertIdentifier + 共享作用域 + 技能名查。找不到返回 404(说明技能在生成建议后被删了)。3
事务内三件事一起做
更新技能内容 → 标记建议已采纳 → 专家的
evolutionCount 加一。三者同事务,不会出现「改了技能但没记数」。Only the expert creator can accept suggestions)。
忽略时发生什么
只改建议状态,绝不触碰技能内容。被忽略的建议不会重复出现。 如果你拿不准,忽略是安全的默认选择——若这个方向确实有价值,基于新的对话数据它还会以别的形式再来。你在面板上看到什么
提交成功后工具返回:
怎么读一条建议
先看效率组,再看质量组
先看效率组,再看质量组
效率组是必须严格上升的那一组,所以它的涨幅告诉你这次改动实际节省了多少。质量组只保证没退步。效率组只涨了 0.5 分的建议,价值多半有限。
看 context_footprint 是涨是跌
看 context_footprint 是涨是跌
这一维是唯一不可自评的。它涨了说明文档被压缩了——这通常是好信号,因为压缩比扩写难得多。它跌了但效率组仍上升,说明
step_economy 或 exploration_replacement 涨得足够多来抵消,这类改动值得仔细看看它到底删了什么、加了什么。通读改进后全文,不要只看摘要
通读改进后全文,不要只看摘要
面板给的是完整新版文档。技能文档是会被完整注入的东西,里面写错一句话,专家在往后每一次对话里都会照做。10 分钟通读的成本远低于事后排查。
产品定位由你把关
产品定位由你把关
评分表衡量的是「技能文档写得好不好、跑得贵不贵」,它不知道你的产品定位。一条技术上完全合理、但让专家的风格偏离你想要方向的建议,果断忽略。这是评分表结构性看不到的东西。
别让面板积压
别让面板积压
待处理建议达到 5 条就不再生成新的。积压等于停止进化。
边界与失败态
进化 vs 记忆
两个常被混淆的机制,作用对象完全不同:
记忆让专家了解具体的人和事,进化让专家整体的做事方法更省更准。两者独立运行、互不覆盖。
相关页面
进化机制原理
系统视角的进化管线
专家记忆
与进化正交的记忆机制
数据分析
用数据衡量进化效果
专家配置
进化不改动的那部分:prompt 分层
核对日期 2026-08-11。来源:
services/agent-runtime/src/plugins/builtin/evolution/tools/evolution_log.py、skills/evolution/SKILL.md、prompts/EVOLUTION.md、hooks/background_review.py、services/agent-runtime/src/models/evolution.py、services/core/src/db/service/expert-evolution.ts、services/core/src/config/env.ts。决策:knowledge/decisions/adr-0024-darwin-efficiency-objective.md、adr-0015-darwin-evolution-p0-boundary.md。
