一个 Rust(Axum)进程托管管理后台、对外 API、微信回调与后台任务循环。无论是回调自动回复还是主动跟进,每一次发送都流经同一个发送网关:重载上下文 → 多重前置检查 → 知识路由 → 分层决策 → 独立评审 → 至多一次改写 → 幂等发件箱 → MCP 发送。绕过网关,就是 bug。
A single Rust (Axum) process hosts the admin SPA, the public API, WeChat callbacks and the background task loop. Whether an auto-reply or a proactive follow-up, every send flows through one gateway: reload context → prechecks → knowledge route → tiered decision → independent review → at most one rewrite → idempotent outbox → MCP send. Bypassing it is a bug.
用户运营 Agent 不是一个巨型函数,而是一组各司其职的子模块。决策、评审、知识路由、预算、守卫、记忆彼此隔离,可单独理解与测试——外部调用方只通过统一入口访问。
The user-ops agent isn't one giant function but a set of single-purpose submodules. Decision, review, knowledge routing, budget, guards and memory are isolated — callers reach them only through unified entrypoints.
Reply Agent 主决策与初始画像生成,产出结构化决策 JSON。
The Reply Agent's main decision and initial profile generation, emitting structured decision JSON.
独立评审 Agent 与本地评审、改写流,只看事实不看推理。
The independent reviewer plus local review and rewrite flow — sees facts, not reasoning.
catalog → list_chunks → open_slice 的工具调用式规划,渐进披露知识。
A catalog → list_chunks → open_slice tool-calling planner that discloses knowledge progressively.
统一编排整条链路,所有发送的唯一出口,绕过即 bug。
Orchestrates the whole path — the single exit for all sends. Bypassing it is a bug.
状态机转移、字符串级 fact-risk 与知识支撑校验。
State-machine transitions, string-level fact-risk and knowledge-grounding checks.
task-local 的 token / 调用计数,超额触发降级而非报错。
A task-local token/call counter; exceeding it degrades gracefully rather than erroring.
长期 memoryCard 整理与合并,沉淀对每个人的认知。
Consolidates long-term memory cards, accruing understanding of each person.
带幂等键的发件箱,二次安全闸与重试,异步派发到 MCP。
An idempotency-keyed outbox with a second safety gate and retries, dispatched async to MCP.
上线前对单人模拟对话,验证表现后再放行真实运营。
Simulates dialogue for one person before go-live, validating behavior ahead of real operations.
所有 LLM JSON 调用都经唯一入口 generate_agent_json:它持有 LRU 提示词缓存、写入 llm_call_logs(状态 success / cache_hit / failed / json_error),并把 token 用量累加进运行预算。
Every LLM JSON call goes through one entrypoint, generate_agent_json: it owns the LRU prompt cache, writes llm_call_logs (status success / cache_hit / failed / json_error) and accumulates token usage into the run budget.
下面是真实代码里 run_user_operation_gateway 的执行顺序。每一步都可能改变结果,每一步都留痕。前置检查通不过就不发,发出前还要再查一次。
This is the real execution order inside run_user_operation_gateway. Each step can change the outcome and each is recorded. If prechecks fail, nothing is sent — and they run again right before send.
逐项核对是否允许发送。任一不通过即停下,写跳过事件与运行日志,并按原因取消或重排任务。
Checks every condition for sending. Any failure stops here, logs a skip event and run log, then cancels or reschedules the task by reason.
每次都从头取:最近消息、激活的行业画像、运行参数、待办任务、运营方法论、运营记忆与长期记忆卡。不靠内存里的旧状态。
Everything is fetched fresh: recent messages, the active domain profile, run params, pending tasks, playbooks, operating memory and the long-term memory card. No stale in-memory state.
先决定要不要查知识、查什么、引用哪些切片。预算超额时退化为空路由并标记降级——绝不假装有据。
First decides whether and what knowledge to consult and which slices to cite. If over budget, it degrades to an empty route and marks the run degraded — never faking grounding.
先用最省的 Lean 档自评,按充分性判定 Enough / 升档 / 需澄清。命中知识缺口会当场升到 Full 档重新生成。
Starts on the lean tier and self-assesses: Enough / escalate / clarify. A knowledge gap forces an immediate escalation to the Full tier and regenerates.
另一个评审 Agent 只拿到事实面投影,看不到 Reply Agent 的自我推理,独立打分。预算超额时退化为本地评审。
A separate reviewer gets only a facts projection — never the Reply Agent's self-reasoning — and scores independently. Over budget, it falls back to local review.
评审要求改写时,按改写指令在 Full 档重生成一次并复审一次——single-shot,不无限循环。预算超额则跳过。
If review asks for a rewrite, it regenerates once on the Full tier and re-reviews once — single-shot, never an infinite loop. Skipped if over budget.
汇总最终评审状态,运营状态按状态机校验合法转移(非法则保留旧状态、记审计,不阻断已定稿的回复)。
Finalizes the review status; the operation state is validated against the state machine (illegal transitions keep the old state and log an audit, never blocking a finalized reply).
发出前再查一遍前置条件;若期间客户又来了新消息,则中止本次、标记被新入站取代,避免抢话。
Re-runs prechecks just before sending; if the customer sent a new message meanwhile, it aborts and marks itself superseded — no talking over them.
仅当评审为 approved / 改写后通过、应当回复且文本非空,才入发件箱。多段回复逐段入队,各带幂等键。转述类还要再过两道红线。
Only enqueues when review is approved / approved-after-rewrite, should reply and text is non-empty. Multi-segment replies enqueue per segment with idempotency keys; relays pass two more hard lines.
独立的派发 worker 原子抢占待发条目(租约 + worker 标记),调 MCP 工具发出。超时由回收器收回租约重试,不重复发送。
A separate dispatcher atomically claims pending entries (lease + worker tag) and calls the MCP tool. Expired leases are reclaimed and retried — never double-sent.
不是每一句话都需要把知识库、完整 SOP、长期记忆全塞进上下文。大多数寒暄、确认、闲聊,用最精简的一档就能答好。系统先用最省的 Lean 档生成并自评「信息够不够」,不够才按缺口逐档加料——把算力花在真正复杂的那一轮。
Not every message needs the whole knowledge base, full SOP and long-term memory stuffed into context. Most greetings, confirmations and small talk are handled well by the leanest tier. The system generates on the lean tier first, self-assesses whether it has enough, and only adds layers by the actual gap — spending compute on the turns that truly need it.
只带人格、各提示词层、当前对话与客户基础身份。日常寒暄、确认、轻量闲聊够用。
Carries only the persona, prompt layers, the current conversation and basic identity. Enough for greetings, confirmations and light chat.
在 Lean 之上接入完整长期记忆、记忆卡片与意图轨迹——需要「记得这个人」时才升上来。
Adds the full long-term memory, memory card and intent trajectory on top of Lean — escalated when it needs to "remember this person".
missing_tier = relational 时升到这一档重新生成。missing_tier = relational.再叠加知识库切片、产品目录、运营方法、状态机、名片引荐等全部业务组——报价、产品主张、复杂推进走这一档。
Layers on knowledge slices, the product catalog, playbooks, the state machine, referral cards and the rest of the business group — quotes, product claims and complex moves run here.
本轮信息充足,不升档,直接进入五道闸门评审。
Context is sufficient; no escalation — straight into the five gates.
按缺口升到 Relational 或 Full 重新生成。需产品知识却连弱证据都没有时,当场强制升 Full。
Escalates to Relational or Full and regenerates. If it needs product knowledge but has no evidence at all, it is forced to Full on the spot.
客户表述本身不明确时,不硬猜,先反问一句把需求问清。
When the customer's request itself is ambiguous, it asks one clarifying question instead of guessing.
「禁止做的事」与「已对客户承诺的事」属于安全/身份铁律——任何一档都注入。降档若丢了这两项,AI 可能违背承诺或踩禁止项,是不可恢复的事故。所以即便是最省的 Lean 档,也会单独补一份精简安全子片:doNotDo 与 commitments 一字不漏。
"Things never to do" and "promises already made to the customer" are safety/identity hard lines — injected at every tier. Dropping them on a lower tier could make the AI break a promise or cross a forbidden line — an unrecoverable failure. So even the leanest tier injects a compact safety subset: doNotDo and commitments are kept verbatim.
如果评审 Agent 能看到 Reply Agent 的内心独白,它很容易被说服、变成「追认」。所以评审拿到的是一份事实投影:回复文本、引用了哪些知识、检测到的异议、客户阶段——而 user_understanding、self_critique、why_should_reply 等九个自我推理字段被刻意剥离。
If the reviewer could read the Reply Agent's inner monologue, it would be easily persuaded into rubber-stamping. So it gets a facts projection — reply text, cited knowledge, detected objections, customer stage — while nine self-reasoning fields (user_understanding, self_critique, why_should_reply…) are deliberately stripped.
可选地,第二个评审者(不同模型)并行评审,分歧会触发改写——双脑交叉,不偏听一面。 Optionally a second reviewer (a different model) reviews in parallel; disagreement triggers a rewrite — two heads cross-checking, not one voice.
知识支撑、事实风险、运行预算三道闸共同决定一条回复能否发出。关键设计是 fail-soft:闸门触发或预算耗尽时降级处理(本地评审、跳过改写、暂缓发送),webhook 调用方永远拿到正常响应,不会收到 5xx。
Grounding, fact-risk and run-budget gates together decide whether a reply ships. The key design is fail-soft: when a gate fires or budget runs out, it degrades (local review, skip rewrite, hold the send) — callers never get a 5xx.
产品声明必须有已核验知识支撑。支撑分过低则拦;若需要产品知识却没有已验证切片,直接判定为未验证产品声明。
Product claims must rest on verified knowledge. Too low a grounding score blocks; if product knowledge is required but no verified slice exists, it's an unverified claim.
对幻觉 / 编造事实打分,达到阈值即硬拦。压力风险过高同样拦截,避免逼单与越界承诺。
Scores hallucination / fabrication; at threshold it hard-blocks. Excessive pressure risk is blocked too — no hard-selling or out-of-bounds promises.
每次运行有 token / 调用 / 工具调用上限。超额不报错而是降级:跳过知识路由、退化本地评审、跳过改写;仅当还需评审时才暂缓。
Each run has token / call / tool-call caps. Exceeding them degrades rather than errors: skip routing, fall back to local review, skip rewrite; only holds when review is still required.
| 评分维度 | Score | 判定 | Condition | 动作 | Action |
|---|---|---|---|---|---|
| 事实风险 FactRisk | FactRisk | ≥ 6 | 拦截Block | ||
| 压力风险 PressureRisk | PressureRisk | ≥ 7 | 拦截Block | ||
| 产品准确度 ProductAccuracy | ProductAccuracy | < 7 | 拦截Block | ||
| 拟人度 HumanLikeScore | HumanLikeScore | < 6 | 改写一次Rewrite once | ||
| 情绪价值 EmotionalValue | EmotionalValue | < 6 | 改写一次Rewrite once |
以上为默认阈值,管理员可在画像中覆盖并自动夹紧到 1–10 区间。阈值是行业画像的一部分,不是写死的魔法数。 These are defaults; admins can override them in the profile, clamped to 1–10. Thresholds live in the domain profile, not as hardcoded magic numbers.
运营方法论以人类可读的文本表达式存在行业画像里,作为 LLM 自评打分的锚点注入提示词——代码侧只渲染字符串、保存 AI 的自报结果,没有任何数值求值器。这让方法论能随行业自由替换,而不必改一行 Rust。
Playbook methodology lives as human-readable text expressions in the domain profile, injected into prompts as anchors for the LLM's self-scoring. Rust only renders strings and stores the AI's self-reported result — there is no numeric evaluator. Methodology swaps per industry without touching a line of Rust.
信任随一致性、可靠度、亲密度上升,随自我中心下降。
Trust rises with consistency, reliability and intimacy; falls with self-orientation.
动机、契合、时机、信任共同推动,阻力拉低。
Motivation, fit, timing and trust drive it; friction holds it back.
共情、鼓励、认可累加,压力扣减。
Empathy, encouragement and recognition add up; pressure subtracts.
相关性、时机、预期价值越高越该做,打扰感越低越好。
Higher relevance, timing and expected value favor acting; lower intrusiveness is better.
下面四项把心理学与认知科学里被验证的方法落进了引擎。我们把每一项的真实机制讲清楚——它做了什么、用什么数据结构、以及刻意不做什么。技术买家值得这份坦诚。
These four bring validated methods from psychology and cognitive science into the engine. We spell out the real mechanism of each — what it does, on what data structures, and what it deliberately does not do. Technical buyers deserve that candor.
短期是当轮上下文包,长期是一张分三层(核心 / 近期 / 已弃)的记忆卡。新观察先写入候选池,由整理 Agent 周期性固化为记忆卡,并做容量压缩与冲突作废,用乐观锁版本号保证并发安全。
Short-term is the per-turn context pack; long-term is a memory card in three layers (core / recent / deprecated). New observations land in a candidate pool, a consolidator periodically promotes them into the card, compacts by capacity and deprecates on conflict — guarded by an optimistic version lock.
是完整的「候选 → 固化 → 压缩 → 作废」流水线,不是把历史对话整段塞回提示词。压缩时保留上一版未丢弃的核心事实,防止新近事件挤掉关键认知。
A full candidate → consolidate → compact → deprecate pipeline, not stuffing raw history back into the prompt. Compaction preserves last version's undiscarded core facts so recency can't crowd out key knowledge.
AI 自由发现至多 6 个客户维度,每个维度维护一条置信走势(最多 100 点)。占槽门槛是:跨 ≥3 轮反复命中,且代码侧客观统计到 ≥2 次强证据(锚定客户真实 Inbound 发言)。
The AI freely discovers up to 6 customer dimensions, each with a confidence trajectory (up to 100 points). Promotion requires hits across ≥3 rounds plus ≥2 strong-evidence counts objectively tallied in code (anchored to the customer's own inbound messages).
这里走的是多轮证据累积 + 客观强证据计数的置信追踪,不是先验/后验的概率推断;强证据由代码统计,不采信大模型自报的置信数字。它永不驱动行为,只用于观测与走势可视化。
This is multi-round evidence accumulation with objective strong-evidence counting, not prior/posterior probabilistic inference; strong evidence is counted in code, never the model's self-reported confidence. It is observation-only — for trends and visualization, never driving behavior.
沿用心理学公认的大五人格(OCEAN)五维封闭量表,每维带分值、置信与证据引用,不许模型自创维度。每个记忆周期 append 一张人格快照(封顶留存),构成演化序列。
It uses the psychology-standard Big Five (OCEAN) as a closed five-facet scale — each facet carrying a score, confidence and evidence refs, with no model-invented dimensions. Each memory cycle appends a capped personality snapshot, forming an evolution sequence.
人格是纯观测旁路:只写不读,绝不进入逐轮决策、闸门或选择逻辑。这是为了避免「基于人格标签的偏见」——画像供人看、供复盘,但不替客户预设回应。
Personality is a pure observation side-channel: written, never read into per-turn decisions, gates or selection. This avoids personality-label bias — the profile informs humans and retrospectives, but never pre-scripts a customer's treatment.
每轮把归一化的推进结果记入意图轨迹(50 项滑窗)。它是真正被消费的时间序列:统计「连续未推进轮数」,叠加末轮负面信号,触发换策略或向幕后请示,并注入下一轮决策提示词。
Each round records a normalized progress outcome into the intent trajectory (a 50-item sliding window). This time series is actually consumed: it counts consecutive unprogressed turns, and with a negative final turn triggers a strategy switch or a behind-the-scenes consult, then feeds the next decision prompt.
与人格 / 贝叶斯信号不同,意图轨迹真的改变行为——这是「会复盘、会调整」落到代码层的体现,不是只存不用的装饰字段。
Unlike personality / Bayesian signals, the intent trajectory genuinely changes behavior — the code-level embodiment of "reflect and adapt," not a stored-but-unused decorative field.
无论是标签、人格还是记忆事实,只要证据序位映射不到对话里的真实锚点,置信度一律归零——这条 fail-closed 规则贯穿记忆与画像全链路。严谨是智能的前提,宁可承认不知道,也不凭印象给人贴标签。
Whether a tag, a personality facet or a remembered fact — if its evidence can't be mapped to a real anchor in the conversation, confidence is zeroed. This fail-closed rule runs through the entire memory and profiling chain. Rigor precedes intelligence: better to admit not knowing than to label on a hunch.
纯单元测试只能证明代码没崩,证明不了大模型在真实业务里说得对不对。所以我们另起一套:用真实大模型,对每个业务域跑端到端真实剧本——真调用、真决策、真评审、真发送判定,不 mock、不打桩。
Unit tests prove the code doesn't crash; they can't prove the model behaves correctly in real business. So we run a second track: real LLMs executing end-to-end scripts per domain — real calls, decisions, review and send judgments, with no mocks or stubs.
每个域是一段完整运营剧本,由真实大模型从头跑到尾。发现的问题只抽象成可复现的方法论缺陷再修,绝不对单条对话、单次样本点对点打补丁——这是写进纪律的反过拟合红线。
Each domain is a complete operating script run end-to-end by a real LLM. Findings are abstracted into reproducible methodology gaps before fixing — never patched point-by-point against a single conversation or sample. This anti-overfitting line is written into our discipline.
演化器是一个完全隔离的子系统:它不引用网关、发件箱、MCP 或任务循环(CI 静态扫描强制这条隔离红线)。它从历史决策日志里学习,生成阈值与提示词候选,在影子里重放重判,只有显著变好且通过安全回归门,再经管理员二次确认,才会真正发布。
The evolver is a fully isolated subsystem: it references no gateway, outbox, MCP or task loop (a CI scan enforces this isolation line). It learns from past decision logs, generates threshold and prompt candidates, replays and re-grades them in the shadow, and only releases after a significant, safety-passing result — confirmed by an admin.
从决策日志选取队列,产出阈值候选(纯统计)与提示词候选(Critic LLM)。
Select cohorts from decision logs; produce threshold candidates (pure stats) and prompt candidates (a critic LLM).
cohort · threshold · criticcohort · threshold · critic只读历史 agent_run_logs 重放重判,零副作用:不调网关、不入发件箱、不调 MCP、不写出站消息。
Reads past run logs and re-grades — zero side effects: no gateway, no outbox, no MCP, no outbound writes.
只读 · 零副作用read-only · no side effects必须达到最小样本与改进幅度;安全回归默认零容忍——任何原本被安全闸拦下的消息被放行,直接否决。
Needs minimum samples and improvement; safety regression is zero-tolerance by default — any once-blocked message now allowed is rejected.
零容忍安全回归zero-tolerance safety发布与回滚都要管理员身份与确认串,留下 released_by / rolled_back_by。回滚永远手动,没有自动回滚。
Release and rollback require an admin and a confirmation string, recording released_by / rolled_back_by. Rollback is always manual — never automatic.
admin-only · 可回滚admin-only · reversible每次知识写入都是双写:先写一条不可变的修订记录(带 sha256 前后哈希),再更新可变的当前切片。历史永远在,回溯任何一次改动都有据。而 AI 写入的知识一律落草稿、标记待核验——AI 永不自动核验自己产出的知识。
Every knowledge write is a double-write: first an immutable revision record (with before/after sha256 hashes), then the mutable current slice. History always survives; any change is auditable. Knowledge written by the AI always lands as a draft marked for review — the AI never self-verifies its own output.
每次变更追加一条修订,记录前后 sha256 哈希与修订 ID,永不覆盖——构成完整的知识变更史。
Each change appends a revision with before/after sha256 hashes and a revision ID, never overwritten — a full history of knowledge change.
保存当前最新切片,供 Agent 检索引用。AI 来源强制 status=draft + 待核验,核验字段被 AI 写入会被拒。
Holds the latest slice for the agent to retrieve. AI-sourced writes are forced to status=draft + needs-review; verification fields written by AI are rejected.
从「客户永远只跟 AI 对话」到「AI 永不自动核验知识」,这些不是承诺,是被守门函数、CI 静态扫描和测试基线强制执行的约束。
From "customers only ever talk to the AI" to "the AI never self-verifies knowledge" — these aren't promises but constraints enforced by guard functions, CI scans and a test baseline.