早上 8 点整,没有人给「涌现」发消息,它已经起床干活了。
涌现是我的钉钉数字员工。每天早上 8 点整,任务消息准时到达,日程表上排着五项早读:读公众号后台、读 GA、digest 小红书、更新 token 消耗、扫一遍 aibase,预算一小时。中午 12:05,下一班任务照样准点到——它安静干完活,报告发进群,日志里一行 ok=True,一条兜底都没有。(这是我在 谁停掉了数字员工的早读? 里给它验完尸之后的日常。)
没有人 @ 它,没有人提问。它是被自己的日程叫醒的。
这个细节值得停一下:聊天机器人被消息召唤,员工被日程叫醒。而被日程叫醒只是起点——一个真正意义上的员工,还得记得昨天答应过什么,知道十点该跟进谁,干完活主动来汇报。这些都不是「回答得更聪明」的问题,是架构问题。
而这两年,全行业的力气都花在把 Agent Loop 做得更大、更聪明上。我的判断是:数字员工缺的不是一个更大的 Loop,是另一个 Loop。
一、行业在造的 Loop,和数字员工缺的 Loop
打开任何一个主流 Agent 框架——Claude Code、Codex、OpenCode,或者 dsh(DeepSeek Harness)这类开源运行时——默认形态都是一个 全能 Agent:一个 loop、一套工具、一份记忆,收到目标就开始 reason → tool call → observe → reason,直到把事做完。我在 一切皆员工:我们在 DeepSeek Harness 上装了一支钉钉数字员工团队 里写过,这个形态对个人助理是优点,对企业员工是要第一个消灭的属性。
但当时我没把话说透。消灭「全能」靠的是制度裁剪,而更根本的问题是:这个 loop 回答的从来只是「这件事怎么做成」,从不回答「我现在应该做什么」。
前者是执行问题,后者是存在问题。把它们拆开,就是两个 Loop:
Digital Employee
│
┌────────────┴────────────┐
│ │
Employee Loop Execution Loop
(存在) (生产)
│ │
┌───────┼───────┐ ┌─────┼─────┐
│ │ │ │ │ │
Chat Calendar Events Sandbox Cloud Code
│ │ │ Agent Agent Agent
│ │ │
└───────┴───────┘
│
Coordinator
│
Task / Approval
│
↓
Execution Loop
# generated by hugo AI
- Employee Loop 负责「像一个员工一样存在」:长生命周期、事件驱动,感知组织、维持关系、记住承诺、协调工作。它是神经系统、秘书和 Coordinator 的合体。
- Task Execution Loop 负责「像一个 Agent 一样干活」:短生命周期、目标驱动,plan → act → observe → verify → retry,把一件事变成可验证的结果。
两者的差别不是「谁更聪明」,几乎每一项都相反:
| Employee Loop | Task Execution Loop | |
|---|---|---|
| 核心问题 | 我现在应该做什么? | 这件事怎么做成? |
| 角色 | 员工 / Coordinator | Worker / Executor |
| 生命周期 | 长期存在 | 一个 Task 一个生命周期 |
| Trigger | Event(消息/日程/timer/组织事件) | Task 派发 |
| 输出 | 决策、回复、委派、提醒 | Result / Artifact |
| 主要优化 | 拟人化、关系、上下文、协调 | 完成率、正确性、可靠性 |
| 状态 | Employee State(永久持续) | Task State(做完归档) |
| 典型工具 | Chat、Calendar、Org、Approval | Browser、Shell、Code、SQL、MCP |
| 失败处理 | 沟通 / 协调 / 升级 | Retry / Recover / Verify |
| 结束条件 | 没有真正结束 | 完成 / 失败 / Cancel |
看最后一行。Task Loop 有终止条件,Employee Loop 没有——员工不下班,只是睡着。 这是两个 Loop 在定义上的分界线,也解释了为什么把执行能力堆到天花板也堆不出一个员工:你造出来的是一个永远在等下一条消息的、很强的聊天机器人。
我在 SPEC 里给这个关系写了一句最狠的约束:
The Employee Loop is the Digital Employee. The Task Executor is merely a capability. Do not invert this relationship.
Employee Loop 才是数字员工本体,Task Executor 只是它借用的能力。Claude Code 再强,也只是员工手里的一件工具——工具可以换,员工不能散架。这个关系一旦倒置(用一个巨大的执行 loop 兼任员工),就会出现企业里最常见的那种数字员工:问一句答一句,答得极好,但从不记得昨天说过什么。
顺带说一句,这个横向拆分和我在 数字员工背后的 Agent,是五层基础设施的叠加 里的纵向五层是互相解释的,不是两套说法硬凑:五层里的身份、上下文、学习三层,全部住在 Employee State 里;执行、验收两层,属于 Task Loop。纵向回答「要建什么」,横向回答「怎么跑」。
二、分界线是时间,不是智力
把两个 Loop 分开之后,最容易误解的一点是:以为 Employee Loop 是「更难的那个」,需要更强的模型。恰恰相反——它需要的不是智力,是记性。
两个 Loop 真正的分界线是时间状态:Employee Loop 是 Stateful Agent,Task Loop 是 Episodic Agent。
Task State 是任务期内的事:goal、plan、当前步骤、tool calls、artifacts、重试记录。任务结束,整个 state 归档,干干净净。
Employee State 是永远不归档的事:
Identity 我是谁,我的主管是谁,我的职责边界
Relationships 我和每个同事的关系、沟通偏好
Commitments 我答应过什么,什么时候到期
Calendar 我的日程,以及日程背后要准备什么
Pending Tasks 我派出去的活,哪些还没回来
Conversations 进行中的对话,谁在等我回复
# generated by hugo AI
它要能记住「我昨天答应 Alice 今天上午给她报告」这句话里的全部信息:答应过、对象是谁、期限、以及现在期限快到了。聊天机器人的记忆里只有 context window;员工的记忆住在窗口外面,是一个可查询、可重放的持久对象。
Anthropic 四月的工程博客《Scaling Managed Agents》从另一个方向走到了同一个结论:他们把 Agent 拆成 Session(append-only 的事件日志)+ Harness(调用模型的 loop)+ Sandbox(执行环境),把「大脑」和「双手」解耦,session 挂在窗口之外,harness 崩了可以用 wake(sessionId) 从日志续跑。他们管解耦前的形态叫「宠物」——容器一挂,session 就丢。数字员工的 Employee State 就是那只不能死的宠物:进程可以重启,员工不能失忆。
时间连续性具体怎么工程化?三样东西:
1. 承诺(Commitment)是一等对象。 「下午三点提醒我给张三打电话」不是一条聊天记录,是一个有生命周期的结构化对象——有 owner、有 due_at、有状态,由 timer 驱动:
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
class CommitmentStatus(Enum):
"""承诺的生命周期:创建 → 到点触发 → 三种终态。"""
PENDING = "pending" # 还没到点
TRIGGERED = "triggered" # timer 已触发,等待员工跟进
ACKNOWLEDGED = "acknowledged" # 人确认了
OVERDUE = "overdue" # 到点没闭环,员工要主动解释
CANCELLED = "cancelled"
@dataclass
class Commitment:
"""数字员工的「记性」:员工答应过的事,不随会话结束消失。"""
id: str
employee_id: str
description: str # "给张三打电话"
owner: str # 这件事是谁的:提醒对象
due_at: datetime # 承诺期限——员工被它叫醒
status: CommitmentStatus = CommitmentStatus.PENDING
source_event_id: str = "" # 从哪条消息里长出来的,可回溯
@dataclass
class EmployeeState:
"""窗口之外的持久员工:进程可以重启,这个对象不能失忆。"""
employee: dict # 身份、角色、主管、工作时间
status: str # AVAILABLE / BUSY / WAITING_HUMAN ...
active_conversations: list[str] = field(default_factory=list)
commitments: list[Commitment] = field(default_factory=list)
pending_tasks: list[str] = field(default_factory=list)
scheduled_followups: list[str] = field(default_factory=list)
recent_events: list[dict] = field(default_factory=list)
relationships: dict[str, dict] = field(default_factory=dict)
# generated by hugo AI
Commitment 里最容易被忽略的字段是 source_event_id——承诺必须能回溯到「从哪句话里长出来的」,否则审计时无法回答「它为什么认为该做这件事」。
2. 一切重要动作进事件日志。 chat.message.received、decision.made、task.created、followup.scheduled、message.sent——事件流是唯一事实源,EmployeeState 从事件重放恢复,而不是靠模型 context 续命。
3. 重启测试是验收项,不是健壮性加分项。 我在 PoC SPEC 里写了一条硬 Eval:创建一个未到期的 follow-up,杀掉进程,重启,等 timer 到点——提醒必须照常发生。过了这条,才有资格说自己「持续存在」。
这三样加起来,就是那个杀手级 demo。我特意在 SPEC 里写明,PoC 不许用「AI 帮我订会议」做演示——任何 chatbot 都能订会议。必须演示的是:
10:00 人:「下午三点提醒我给张三打电话。」
↓
Employee Loop 创建 Commitment + Timer
↓
……五个小时,它什么都不做,它在睡觉……
↓
15:00 timer.triggered
↓
Employee Loop 被唤醒
↓
它主动发来消息:「现在是下午三点,该给张三打电话了。」
# generated by hugo AI
没有人发消息,它先开口。一个 timer,就划开了员工和聊天机器人。
有人会说:定时提醒,cron 加个 chatbot 就能做。差别在 timer 的前后两头。前一头,「下午三点提醒我」是自然语言里长出来的 Commitment 对象——谁答应的、答应给谁、从哪句话里来的,全部结构化;cron 里只有一行 crontab。后一头,到点唤醒的不是一个固定脚本,而是一个带着全部 Employee State 醒来的员工——它知道这个提醒的上下文,知道你十分钟前刚说过「张三那个事不用催了」,于是它可以决定不提醒,或者换个说法提醒。cron 触发的是动作,Employee Loop 触发的是判断。
三、把副作用从模型手里收走
存在循环要 7×24 无人值守地跑,就不能让 LLM 直接碰副作用。这是 Employee Loop 最重要的一条工程纪律:模型只返回结构化决策,一切动作过 Coordinator 校验执行。
决策合同长这样:
{
"decision": "CREATE_TASK",
"reason": "用户要求分析客户流失原因,属于复杂分析任务,应由 Task Executor 完成",
"actions": [
{
"type": "CREATE_TASK",
"title": "分析客户近 30 天流失原因",
"assigned_to": "analysis-executor",
"correlation_id": "conv-8821"
},
{
"type": "SEND_MESSAGE",
"conversation_id": "conv-8821",
"content": "收到,我开始分析,预计一小时内给你结论。"
}
]
}
// generated by hugo AI
决策是一个封闭集合:REPLY / CREATE_TASK / UPDATE_TASK / SCHEDULE_FOLLOWUP / ASK_HUMAN / WAIT / IGNORE / DELEGATE。动作也是封闭集合:SEND_MESSAGE、SCHEDULE_TIMER、REQUEST_APPROVAL、UPDATE_COMMITMENT 等。LLM 永远不直接调外部 API,所有副作用走 typed action。
主循环因此非常朴素:
while employee_is_alive:
event = await next_event() # 没事件就睡,不轮询模型
context = build_context(event, employee_state) # 只装相关上下文
decision = await agent.decide(context) # 返回结构化决策
actions = validate(decision) # ← 权力搬到了这一行,下文细说
for action in actions:
execute_action(action) # Coordinator 执行,不是模型执行
persist_state() # 落事件日志
emit_events()
# generated by hugo AI
注意第一行:事件驱动,没有事件就睡。存在循环的成本模型因此和 Task Loop 完全不同——它一天被唤醒几十次,每次只做分类和决策;昂贵的长推理只发生在它派出去的 Task 里。
Task Executor 在 PoC 阶段是一个 Mock:接口只有 create / cancel / get 三个方法,异步模拟任务从 CREATED 到 RUNNING 再到 COMPLETED(偶尔 FAILED),完成后把结果作为事件发回 Employee Loop。这个抽象是整个架构的承重墙——Mock 之后可以整体换成 Sandbox Agent、Cloud Agent、SQL Agent,甚至换成一个真人,Employee Loop 一行不改。员工不换,手里的工具随便换。
四、两个反直觉
反直觉一:Employee Loop 不需要最聪明的模型
「老板在群里 @ 我」这个事件的第一层处理,根本不需要深度推理:
@我
↓
Intent Classification(规则 + 小模型)
↓
Need Action?
├── No → REPLY(「好的」「收到」级别的回应)
└── Yes → CREATE_TASK(昂贵的推理留给 Task Loop)
# generated by hugo AI
存在循环追求的是便宜、稳定、永远在线;执行循环才追求聪明。把两个目标塞进一个 Loop,代价是用最贵的模型维持心跳——每次「好的,收到」都烧一遍旗舰模型的推理。分开之后,系统明显更便宜,也更稳:心跳层只做分类和路由,错误面小,出了错还有 validator 兜底。
拟人化的大头也不在推理,在 State。「好的,我下午 3 点前给你」这句话背后没有任何复杂思考,但它需要知道自己是谁、和你什么关系、承诺意味着什么、到点要主动回来。这些全是 Employee State 的供给,不是模型智商的供给。推到底:Employee Loop 的护城河全在组织侧——关系、日程、审批链、职责边界,这些数据只有组织平台给得起。模型再强,也推理不出「张三是谁、归谁管、什么事要他审批」。
反直觉二:validate 那一行,是新的权力中心
决策合同把副作用从 LLM 手里收走了,但权力没有消失,只是搬家了——搬进了 validate(decision) 这一行。
哪个 action 允许直接执行、哪个要升级人工审批、哪个无论如何不许发生,全部由 validator 的规则决定。模型再聪明,出不了这个闸口;validator 一松,前面所有约束形同虚设。而 SPEC 写完我发现自己没有回答一个问题:validator 归谁管?
它的配置权、变更权、审计归属,必须有明确的人。按我在 数字员工的第一准则不是可控性 里立的主管负责制,validator 必须挂在数字员工的主管名下,每次变更进审计日志——否则架构里出现了一个没有主人的新权限层:出了问题,模型的决策有据可查,放行决策的闸口却无人认领。
把权力从模型手里收走是对的;收走之后不给权力找到主人,等于把风险从可见的地方挪到了不可见的地方。
五、模型会吞掉双 Loop 吗
写到这里必须正面回应一个反方,而且是我自己论证过的反方:我在 模型正在吞噬 Agent 框架 里说过,模型每强一代,框架的能力层就被吃掉一层。长记忆、自主规划、事件感知,迟早都是模型内置的。那双 Loop 会不会也是过渡产物——一个足够强的 Agent,为什么不能既是员工又是执行者?
我的回答分两层。
第一层,#403 里已经立过的分界:被模型吞掉的永远是 能力层(loop、调度、上下文压缩),吞不掉的是 职责层(对谁负责、谁审批、出错找谁)。就算未来的模型自带完美记忆和主动性,「这个员工的承诺由谁验收、validator 归谁管」仍然是组织问题,不是模型问题。
第二层是本文新增的:两个 Loop 的优化目标冲突,合并不掉。 存在循环要便宜、稳定、永不宕机;执行循环要聪明、能失败、可重试。合并成一个 Loop,意味着用最贵的组件承载心跳、用最不可控的组件承载承诺。这不是能力问题,是账本问题——账本问题不会因为模型变强而消失,就像电力再便宜,工厂的照明电路和动力电路也不会并成一路。
所以我的预期是:Task Loop 会被模型和运行时持续吞噬,越来越薄;Employee Loop 会持续变厚,因为它沉淀的全是组织供给的状态——那部分不是技术,是资产。
结尾:它睡着的时候,还是不是员工
最后把授权线合拢。Employee Loop 的本质是无人值守运行,而 Anthropic 上个月给 Claude Tag 加的权限体系(我在 权限跟着人走,还是跟着工号走 里拆过)恰好从反面印证了这个架构:个人借给 Agent 的权限(personal connector)明确 不允许无人值守,一切定时例程和自主发起的动作,只能走组织授予的共享权限。
翻译过来:一个 7×24 存在、会被 timer 叫醒、会主动开口的 Loop,天然要求组织级授权——独立身份、service account、管理员划的边界、可审计的日志。这不是巧合。「敢不敢给数字员工发工号」的工程实质,就是敢不敢让一个 Employee Loop 无人值守地存在。
回到开头那个 8 点整的场景。涌现被日程叫醒时,没有任何人在场——那一刻支撑它「是员工而不是聊天机器人」的,不是模型多聪明,而是它的承诺在数据库里、它的权限在组织的授权里、它的动作在 validator 的闸口后面、它的历史在可重放的事件日志里。
所以检验一个数字员工,别问「它回答得够不够聪明」,问一个更狠的问题:
它睡着的时候,还是不是员工?
你在给数字员工做架构时,把「存在」和「执行」分开了吗?欢迎留言聊聊你的拆法。