Skip to main content

自进化系统

传统 AI 应用发布后就固定了,除非开发者手动更新。Profy 的专家不同:它们从真实使用中提出改进,经过一道代码强制的评分门禁,再由创作者决定是否采纳。 这一页讲的是系统怎么运转。如果你是创作者、关心的是「我该怎么读一条建议」,请看 专家进化

先划边界:这不是 RSI

「递归自我改进」(RSI)指的是系统改进造模型的过程本身,从而递归地提升自身能力。Profy 做的不是这件事。 Profy 改的是「专家用什么方法做事」这份文档,不是「专家用什么大脑思考」。这个限制是设计选择而不是能力不足——它把改动限制在一个可以被完整审阅的对象上。

三层进化

系统里有三条独立的后台链路,名字容易混,实际管的事完全不同:
这三个阈值默认值都是「5」但含义完全不同:记忆是会话内消息数、技能自创是单轮工具调用次数、技能进化是跨会话的用户×专家交互数。看到「5」不要以为是同一个计数器。
本页后续只讲第三层。

计数器的存储决策

三层用了两种不同的存储,原因值得说明: 进程内字典有 _COUNTER_CAP = 10,000 的上限,超出时淘汰最旧会话以限制内存。Redis 不可用时进化计数器降级到进程内字典——尽力而为,重启清零。

一次进化调用的完整链路

1

Core 侧筛选候选

调度器按冷却期(EVOLUTION_COOLDOWN_HOURS,默认 24h)、失败退避(EVOLUTION_FAILURE_BACKOFF_HOURS,默认 6h)、批量上限(EVOLUTION_BATCH_SIZE,默认 10)筛出可进化的专家。
2

积压检查

待处理建议数达到 EVOLUTION_PENDING_MAX(默认 5)的专家直接跳过,不发起调用。这是最常见的「为什么没有新建议」的原因。
3

组装载荷

取最近 EVOLUTION_RECENT_SESSION_LIMIT(默认 5)个会话的 EVOLUTION_RECENT_MESSAGE_LIMIT(默认 40)条消息,加上专家的技能列表、persona / soul / agent 内容,以及 run_stats技能列表里每一项的 scope必填的:runtime 的 inject_user_skills 会静默跳过 scope 不是 user / expert 的条目(只留一条警告日志)。
4

内部调用 agent-runtime

POST /api/agent/evolutionX-Internal-Secret 鉴权,is_internal_invoke 恒为 true(调用方不可配置)。超时 EVOLUTION_TIMEOUT_SEC,默认 900 秒,由 asyncio.timeout 实际强制。
5

进化模式运行

profy-evolution 插件被激活且 exclusive: true——其他插件全部不加载。只有三个工具可用。
6

提交建议

模型调 evolution_log,通过双棘轮门禁后写入 expert_evolution_log,状态为待处理。每次调用最多一条
7

创作者决策

建议出现在 Studio 进化面板。采纳走事务,忽略只改状态。

900 秒超时不是随手定的

默认值对齐实测:Stage 4 的进化运行耗时 721–1003 秒。取 900 秒意味着大部分运行能跑完,而失控的会被切断。可配置范围 30–1800 秒。

进化模式的隔离

这是安全边界的核心。进化跑在一个排他的内部调用里:
exclusive: true 的效果是:进化模式下其他所有插件都不加载。这不是靠提示词请求模型「不要用别的工具」,而是那些工具根本不在工具列表里。

唯一写入点

evolution_log 是进化模式下唯一能改变外部状态的工具,而它能做的只有一件事:写一条待审核的建议。它不能直接改技能——改技能发生在创作者点「采纳」之后的 Core 侧事务里。 这个结构让「模型能做什么」和「什么会真的生效」被一道人工闸门彻底分开。

递归守卫

进化模式不产生任何面向用户的输出,也不会触发新的后台复盘——否则一次进化会引发下一次进化。is_internal_invoke 既是激活条件,也是这条守卫的判据。

双棘轮门禁

10 个维度分两组,质量组权重合计 0.70、效率组 0.30。 接受条件(必须同时成立)
  1. 质量组加权分 不下降(after ≥ before)
  2. 效率组加权分 严格上升(after > before)
双向禁止抵偿:效率涨不能为质量跌买单,质量涨也不能为效率持平买单。 各维度的权重、0/50/100 分锚点、以及 context_footprint 的打分曲线,完整写在 专家进化 页。这里只讲设计动机。

为什么不是「总分要涨」

单一加权总分的门禁存在结构性漏洞:任何一维都能被另一维买单。「质量 +15、效率 −10」这样的改动在总分口径下轻松通过,而这恰恰是最典型的退化形态——文档越写越厚越”全面”,每次运行更贵,但每项质量指标都在涨。 分组 + 双条件把这条路堵死。

为什么必须有一维由代码算

如果 10 维全由模型自评,那么门禁的判据与被判据的对象同源,它想过就能过。 context_footprint 从技能文档字符数直接算出(≤3,000 → 100,≥24,000 → 0,线性),模型传什么值都被丢弃。它是这条链上唯一模型无法自证的锚点。权重虽只有 0.08,但因为效率组只有三维且必须严格上升,文档大幅膨胀时这一维的下跌通常足以让整组无法上升。 阈值有实测依据:Stage 4 种子技能 429 字符,进化后 12,109 字符;24,000 约为其两倍。
这两条设计回应的是同一个问题:门禁的判据不能由它守护的对象提供。第一条防的是维度之间互相提供借口,第二条防的是模型给自己出成绩单。当前关于「如何设计不被 reward hacking 的评测」的讨论里,大多数方案在这两点上至少缺一条。

run_stats:实测成本作为地面真值

评分表本身仍然依赖模型判断(除 context_footprint 外的 9 维)。为了让判断不悬空,进化提示词里会带一个 <run_stats> 块,列出过去最多 20 次运行的实测成本:token 数、LLM 轮次、工具调用次数、当时的技能文档长度、是否成功。 判定规则是硬性的:
  • 技能变长后 token 涨了 → 上一轮方向错了,这一轮必须压缩
  • token 降了且成功率保持 → 方向对,继续
  • 永远不要拿理论反驳 run_stats
run_stats 是严格白名单 Pydantic 模型且逐字段有上界(total_tokens ≤ 10,000,000tool_calls ≤ 500skill_version_note ≤ 120 字符等),因为它会被逐字注入提示词——不校验的话既撑上下文,也给了夹带指令的口子。

采纳的事务性

创作者点「采纳」后,Core 侧:
1

结构校验

validateSkillImprovementContent 不通过返回 400。
2

归属校验

非创作者返回 403。
3

定位技能

expertIdentifier + 共享作用域 user id + 技能名查 expert_skill。找不到返回 404——说明建议生成后技能被删了。
4

单事务三写

更新 skillMdContent → 标记建议 accepted → expert.evolutionCount + 1。三者同事务,杜绝「技能改了但计数没动」的半成品状态。
skill_improvement 类型(如 knowledge_update)走「仅改状态 + 计数」路径,不写技能 「忽略」只改建议状态,永远不碰 expert_skills

与传统 ML 的对比

关键差别不在效果而在可审查性:你能读到将要生效的每一个字,并在它生效前否决。

相关页面

专家进化(创作者视角)

完整评分表、阈值表与怎么读一条建议

时态记忆

与进化正交的记忆管线

Agent Runtime

进化调用运行在什么之上

技能

技能三路归属:builtin / user / expert
核对日期 2026-08-11。来源:services/agent-runtime/src/plugins/builtin/evolution/{plugin.json,tools/evolution_log.py,skills/evolution/SKILL.md,prompts/EVOLUTION.md,hooks/background_review.py}services/agent-runtime/src/models/evolution.pyservices/core/src/db/service/expert-evolution.tsservices/core/src/config/env.ts