演化器是一个与生产链路物理隔离的后台子系统。它从历史决策日志里学习,生成发送阈值与提示词的改进候选,在「影子」里用历史对话重放重判,只有统计上显著变好、且通过零容忍的安全回归门,再经管理员二次确认,才会真正发布到生产。回滚永远由人手动触发——没有自动回滚。
The evolver is a background subsystem physically isolated from the production path. It learns from past decision logs, generates improvement candidates for send thresholds and prompts, replays them against real history in a "shadow", and only ships to production after a statistically significant gain that passes a zero-tolerance safety-regression gate — confirmed by an admin. Rollback is always a manual human action; there is no auto-rollback.
整个 src/evolution/ 模块严禁引用统一网关、发件箱、MCP 客户端、任务循环与 Webhook。它读历史日志、写实验与候选记录,但永远没有一条通往「给客户发消息」的代码路径。这条隔离红线不是靠自觉——scripts/check-evolution-isolation.sh 在 CI 里静态扫描该目录强制执行,一旦出现被禁的依赖,构建直接失败。
The entire src/evolution/ module is forbidden from referencing the unified gateway, outbox, MCP client, task loop or webhooks. It reads history and writes experiment and proposal records, but there is never a code path that reaches "send a message to a customer". This line is not a matter of discipline — scripts/check-evolution-isolation.sh statically scans the directory in CI and fails the build the moment a forbidden dependency appears.
agent::gateway统一发送网关send gateway
agent::outbox持久化发件箱persistent outbox
mcp::*微信发送工具WeChat send tools
tasks · webhooks任务循环 / 回调task loop / webhooks
后台 worker 每隔一个周期(默认 6 小时)触发一次 tick。单次 tick 失败不影响下一次,异常会被捕获并写入 evolution_tick_failed 事件——worker 的存活永远优先。
A background worker fires one tick per interval (6 hours by default). A failed tick never affects the next; exceptions are caught and recorded as an evolution_tick_failed event — worker survival always comes first.
每个 tick 开一条 experiments 记录,唯一索引,初始状态 collecting。
Each tick opens one experiments record with a unique index, initial status collecting.
insert_experiment_envelope从最近 72 小时已完成的决策日志取样,按联系人哈希分桶灰度,同联系人去重。
Samples completed run logs from the last 72h, buckets by contact hash for rollout, dedupes per contact.
select_cohorts_filtered纯统计路径:对比闸门命中率与目标区间,提出阈值微调。不调 LLM、不消预算。
Pure-stats path: compares gate hit rates to target bands and proposes threshold nudges. No LLM, no budget.
threshold::generate 纯统计 · 零成本pure stats · no cost把失败案例分桶喂给 Critic LLM,产出提示词修订草案。唯一消耗演化预算的阶段。
Feeds bucketed failures to a critic LLM to draft prompt revisions. The only stage that spends the evolution budget.
prompt_critic::generate Critic LLM · 计预算critic LLM · budgeted把本次 tick 消耗的 token 与调用数写回信封。预算耗尽不报错,静默跳过剩余候选。
Writes tokens and calls spent back to the envelope. Budget exhaustion never errors — it silently skips remaining work.
budget_used_tokens · _calls对每条候选在历史样本上重放重判,聚合指标,按显著性与安全回归门分级。
Replays each candidate over history, aggregates metrics, then grades by significance and the safety-regression gate.
replay::eval_all · significance 影子 · 零副作用shadow · no side effects实验状态推进到 awaiting_admin。通过显著性的候选标为 eligible_for_release,等管理员裁决。
Experiment status advances to awaiting_admin. Passing candidates become eligible_for_release, pending an admin's call.
status = awaiting_admin扫一遍到期的发布后复盘(发布 +24h),对比前后窗口的真实指标。仅观测,绝不自动回滚。
Sweeps due post-release reviews (release +24h), comparing real metrics before and after. Observe only — never auto-rollback.
post_release::run_due_reviews仅阈值候选、且双重开关开启时,对仍未回正的信号闭环放量。提示词永远要人确认。默认关闭。
Only for threshold candidates, only when a double switch is on, closing the loop for signals that haven't self-corrected. Prompts always need a human. Off by default.
auto_release_eligible_thresholds纯统计驱动:统计每道发送闸门在近期决策里的命中率,和经过校准的目标区间对比。命中率偏低说明闸门过严,往松调;偏高说明过松,往紧调。每步固定 0.5,永远不超出 1–10 的硬边界。
Purely statistical: measures each send gate's recent hit rate against a calibrated target band. Too low means the gate is too strict — loosen it; too high means too loose — tighten it. Each step is a fixed 0.5 and never crosses the hard 1–10 bounds.
不调用 LLM · 不消耗预算No LLM · no budget spentfact_risk_block事实风险拦截fact-risk blockpressure_risk_block压迫感拦截pressure-risk blockproduct_accuracy_score_block产品准确性拦截product-accuracy blockhuman_like_score_rewrite拟人度重写human-likeness rewriteemotional_value_rewrite情绪价值重写emotional-value rewriteplanner_block_rate_threshold规划器拦截率planner block rate由独立的 Critic LLM 驱动:把失败案例按最终评审状态分桶,让 Critic 针对某个提示词分段提出修订草案,并声明它预期改善哪些指标。产出经三道安全闸校验——字段超长、命中禁词、或试图修改演化器自己的提示词,整批丢弃。
Driven by a separate critic LLM: buckets failures by final review status and asks the critic to draft a revision to a specific prompt section, declaring which metrics it expects to improve. Output passes three safety checks — over-length fields, forbidden words, or any attempt to edit the evolver's own prompt drops the whole batch.
调用 Critic LLM · 计入演化预算Calls a critic LLM · counts against budgetsoul人格灵魂层soul layersystem_contract系统契约层system contractpolicy策略层policy layeroperator_instruction运营指令层operator instruction影子回放是演化器最关键的安全设计:候选不会作用于任何在线对话,而是在历史样本上「假装」自己已经生效,看结果会怎样。它不调网关、不入发件箱、不调 MCP、不写出站消息,也不写决策日志——纯粹只读、纯粹评估。
Shadow replay is the evolver's key safety design: a candidate never acts on a live conversation. Instead it "pretends" to already be in effect over historical samples and observes the outcome. It calls no gateway, no outbox, no MCP, writes no outbound message and no run log — strictly read-only, strictly evaluation.
每条历史决策都记录了当时的五维评分(事实风险、压迫感、拟人度、情绪价值、产品准确性)。阈值候选不需要重新生成回复——它直接拿这些已记录的评分,套上新阈值重新判定每道闸门是否命中,得出一个「如果当时用新阈值会怎样」的最终评审状态,再和旧结果逐条对比。
Every past decision recorded its five-dimension scores (fact-risk, pressure, human-likeness, emotional value, product accuracy). A threshold candidate needs no regeneration — it takes those recorded scores, re-applies the new threshold to each gate, derives a "what if the new threshold had been used" final review status, and compares it against the old result, case by case.
诚实地说:提示词候选的完整影子重放(用新提示词在历史对话上真实重跑 LLM)尚在分期建设中,当前阶段记为 prompt_replay_not_implemented_w3。这意味着提示词改动当前必须走管理员人工确认这条更保守的路径——而不会被自动放量。我们选择把现状写清楚,而不是夸大能力。
To be honest: full shadow replay for prompt candidates (actually re-running the LLM with the new prompt over real history) is still being built in stages, currently recorded as prompt_replay_not_implemented_w3. This means prompt edits today must take the more conservative admin-confirmation path — they are never auto-released. We state the status plainly rather than overstate the capability.
显著性判定是一组确定性的阈值门,不是统计假设检验——没有 p 值,只有「改进幅度是否达到下限、回归幅度是否超过上限」的硬比较,结果只有通过或拒绝两档。一条候选要发布,必须同时满足最小样本量、失败率上限、改进幅度下限、闸门命中涨幅上限四项;如果它放松的是安全闸,还要额外通过零容忍的安全回归门。
Significance is a set of deterministic threshold gates, not a hypothesis test — no p-values, just hard comparisons of whether the gain clears a floor and the regression stays under a ceiling. The verdict is binary: pass or reject. To ship, a candidate must clear minimum sample size, a fail-rate ceiling, an improvement floor and a gate-hit-increase ceiling — and if it loosens a safety gate, it must also pass the zero-tolerance safety-regression gate.
低于 30 条完成重放,直接判样本不足,不予发布。
Below 30 completed replays, it's ruled insufficient and not shipped.
阈值候选的发送成功率至少要提升 5 个百分点。
A threshold candidate must lift send-success by at least 5 points.
重放失败率超过 30%,结果不可信,拒绝。
Above a 30% replay fail rate the result is untrustworthy — rejected.
零容忍:哪怕一条曾被安全闸拦下的消息被放行,就否决。
Zero tolerance: even one once-blocked message now allowed vetoes it.
三道安全闸(事实风险、压迫感、产品准确性)被特殊保护。任何放松它们的候选,只要在影子重判里出现「原本被拦下、现在被放行」的样本——哪怕只有一条——安全回归率就超过 0.0 上限,直接否决。重写类闸门和规划器不属于安全闸,放松它们不构成漏过风险。
Three safety gates (fact-risk, pressure, product-accuracy) get special protection. Any candidate loosening them is vetoed the moment a shadow re-grade shows a "was blocked, now allowed" sample — even one — because the safety-regression rate then exceeds the 0.0 ceiling. Rewrite gates and the planner are not safety gates; loosening them lets no risk through.
管理员对 eligible 候选确认后发布。阈值写入 threshold_overrides,提示词写入新版本,两者各用一个 Mongo 事务把「生效写入」和「状态推进」绑成原子操作——要么都成,要么都不成。
An admin confirms an eligible candidate. Thresholds write to threshold_overrides, prompts write a new version; each uses a Mongo transaction to bind "apply" and "state advance" atomically — all or nothing.
仅阈值候选可走闭环自动放量,且需要环境总开关与工作区子开关「双闸」同时开启(默认都关)。还要满足:回看窗口里信号仍未自然回正、且窗口内的负反应率未超过上限。提示词永远不自动放量。
Only threshold candidates can auto-release, and only when both an env switch and a per-workspace switch are on (both off by default). The signal must still be off-band in the look-back window, and the window's negative-reaction rate must stay under the cap. Prompts never auto-release.
回滚永远只能由管理员手动触发——这条铁律在三处代码注释里明确写着,对应需求 9.7。发布后复盘只观测、只记录前后窗口的真实指标差,绝不据此自动回滚。前置校验要求状态必须是 released,否则拒绝。
Rollback can only ever be triggered manually by an admin — a rule spelled out in three code comments, mapping to Requirement 9.7. Post-release review only observes and records the real before/after metric deltas; it never auto-rolls-back. A precondition requires the status to be released, else it's refused.
演化器从不静默运行。每个 tick 的完成、预算耗尽、发布、回滚、自动放量决策、发布后复盘,都写一条带工作区与账号边界的事件。前端的演化中心据此呈现完整的演化历史。
The evolver never runs silently. Every tick completion, budget exhaustion, release, rollback, auto-release decision and post-release review writes an event scoped to workspace and account. The admin's evolution center renders the full history from these.
一次 tick 正常收尾,汇总队列大小、候选数、合格数、放量数。
A tick finished cleanly, summarizing cohort sizes, candidates, eligible and released counts.
ok单次 tick 抛错被捕获,记录错误摘要,不影响下一次。
A tick threw and was caught, recording an error summary without affecting the next.
error演化预算耗尽,记录已用 token 与调用数,静默跳过剩余候选。
The evolution budget ran out, logging tokens and calls used, silently skipping the rest.
warning一条阈值候选发布生效(无论手动还是自动放量)。
A threshold candidate went live (whether by manual or auto-release).
ok一条提示词候选发布为新版本,提示词缓存随之失效。
A prompt candidate shipped as a new version, invalidating the prompt cache.
ok管理员手动回滚完成,阈值或提示词恢复到上一档。
An admin's manual rollback finished, restoring the prior threshold or prompt.
ok自动放量判定结果(放量 / 跳过),含命中率与负反应率依据。
An auto-release verdict (release / skip) with hit-rate and negative-reaction basis.
release · skip发布 +24h 的复盘完成,落前后窗口的真实指标差。
A release +24h review completed, recording real before/after metric deltas.
ok演化器有独立错误类型,预算耗尽绝不映射成 webhook 的 5xx。
The evolver has its own error type; budget exhaustion never maps to a webhook 5xx.
与主链路解耦decoupled物理隔离、影子回放、零容忍安全回归门、管理员确认、永远手动的回滚、默认全部关闭——自我演化的每一道约束,都和它的能力一样,是写进代码、被 CI 守住的工程事实。
Physical isolation, shadow replay, a zero-tolerance safety gate, admin confirmation, always-manual rollback, off by default — every constraint on self-evolution is, like its capability, an engineering fact written into code and held by CI.