感知层设计
感知层不是系统总脑,而是认知中枢中的信号解释子能力。 它负责事件进入后"怎么理解它、产出什么 signal",不独立拥有长期议程。 本文同时包含 Signal 类型的完整定义(第八章),Signal 是 Perception 输出、Cognitive Core 输入的结构化中间语言。 本文采用规范命名
working_summary/attention_watchlist,当前实现也已按此命名收口。 如本文与《产品与架构设计》《认知中枢设计》冲突,以后者为准。 最后更新:2026-03-18
一、架构定位
在统一认知架构下,感知的定位应理解为:
外部事件(飞书 / GitLab / 业务系统)
↓
事件系统 ─── 接入、验签、去重、转为 UnifiedEvent、路由
↓
感知层 ───── 接收事件、理解变化、产出 signal
↓
认知中枢 ─── 统一判断是否进入议程、是否直接行动
↓
持续事项引擎 ─ 持续推进已进入议程的事项各层职责边界应收口为:
| 层 | 职责 | 不做什么 |
|---|---|---|
| 事件系统 | 把外部变化转成 UnifiedEvent,路由到下游 | 不判断事件重要性,不决定后续行动 |
| 感知层 | 理解事件含义,产出结构化 signal 与候选建议 | 不负责长期议程,不直接替代认知中枢做最终优先级裁决 |
| 持续事项引擎 | 持续跟进已进入议程的事项 | 不负责世界建模,不负责维护第二套系统大脑 |
感知层解决的核心问题应收口为:新事实发生时,系统如何正确理解它意味着什么。
二、认知工作区
工作区不是系统事实真源,也不是第二套 Agenda。它只是认知中枢的短期运行时视图:持久化 working_summary 与 event_buffer,并在读取时从 Agenda 投影 attention_watchlist / recent_observations。
数据结构
attention_watchlist 是 Agenda.watch_items 在读取时生成的投影视图,加上运行时事件匹配字段。真源始终是 Agenda.watch_items,不再额外回写一份 Workspace 缓存副本。
{
"_id": "workspace_qinghai",
"working_summary": "公司本周在冲 v2.0 上线,张三负责的后端接口还差两个未提测,李四请假到周三...",
"attention_watchlist": [
{
"watch_id": "watch_001",
"topic": "v2.0 后端提测进度",
"priority": "high",
"person_refs": ["p_zhangsan"],
"promote_condition": "18:00 仍无提测证据则升级为 concern",
"match_rules": {
"event_types": ["task_status_change", "gitlab_merge"],
"keywords": ["提测", "v2.0"]
},
"source_agenda_ref": "watch_001",
"projected_at": "2026-03-17T09:00:00"
}
],
"event_buffer": [
{
"event_id": "evt_001",
"source": "feishu",
"event_type": "task_status_change",
"summary": "张三将'用户接口'标记为开发中",
"timestamp": "2026-03-17T10:30:00",
"processed": true,
"action_taken": "silent_record"
}
],
"recent_observations": [
{
"timestamp": "2026-03-17T10:30:00",
"observation": "张三已开始开发用户接口,进度正常,暂不需要干预",
"triggered_by": "evt_001",
"action": "none"
}
],
"updated_at": "2026-03-17T10:30:00"
}字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
working_summary | string | 运行时摘要,从 recent Facts + Agenda.focus_queue + Concern summaries 汇总生成,不是系统长期真源 |
attention_watchlist | array | Agenda.watch_items 的读取时投影视图,附带运行时 match_rules 用于事件匹配 |
event_buffer | array | 近期事件流(滚动窗口,保留最近 N 条) |
recent_observations | array | Agenda.recent_decisions 的读取时投影视图,供后续决策参考 |
存储方式
- MongoDB 单文档存储(
workspace集合) - 持久化字段只保留
working_summary与event_buffer这类运行时状态 attention_watchlist在读取时从Agenda.watch_items + active concern refs投影生成,不再写回 workspace 集合working_summary从recent Facts + Agenda.focus_queue + Concern summaries汇总生成event_buffer滚动窗口,超过上限自动淘汰旧事件recent_observations在读取时从Agenda.recent_decisions投影生成,不再写回 workspace 集合
三、事件驱动流程
感知层的核心是事件驱动,不是定时轮询。
处理步骤
- 事件到达:事件系统路由后的 UnifiedEvent 进入感知层
- 规则过滤:用
attention_watchlist的match_rules匹配事件,命中则升级 - LLM 理解:将事件 +
working_summary+ 相关recent_observations送入 LLM,产出signal + candidate_action - 认知中枢裁决:
- 创建新 Concern(发现需要跟进的事项)
- 推进已有 Concern(
advance_concern,如业务数据变化说明进展) - 直接通知(紧急且不需要多轮跟进的事项)
- 静默记录(记下观察,不行动)
- 更新工作区运行时状态:刷新
working_summary、维护event_buffer;recent_observations由 Agenda 最近决策自然投影得到
四、缺席检测的新角色
从"扫描一切"到"缺席检测"
旧实现里的 scan_heartbeat 承担了过多职责:遍历所有业务数据、发现异常、生成通知。统一认知架构下,应把这类能力收口为认知中枢侧的缺席检测:
检查"应该发生但没发生"的事。
| 旧心跳 | 新心跳 |
|---|---|
| 主动扫描飞书任务、日历、考勤等 | 事件驱动,业务变化推送过来 |
| 全量遍历,发现一切异常 | 只检查"预期事件未到达" |
| 是清海主动性的唯一来源 | 是感知层的补充机制 |
缺席检测的典型场景
- 张三说今天提测,到下班了还没有 GitLab merge 事件
- 日报应该每天 18:00 前提交,到时间了没看到
- 审批流程通常 2 小时内处理,超时没有状态变更事件
迁移方式
旧的 scan_heartbeat 不应再被视为 Concern 调度的一部分,而应拆成 Concern 生命周期调度与认知中枢侧的缺席检测:
ConcernScheduler(保留)
├─ scan_due_concerns() ── Concern 到期检查
├─ scan_timeouts() ── Concern 超时检查
└─ scan_schedules() ── 定时 Concern 触发
认知中枢支持能力(新增)
├─ handle_event() ── 事件驱动主流程
└─ scan_absence() ── 缺席检测(旧 `scan_heartbeat` 的规范形态)五、与持续事项引擎的关系
感知层是 Concern 的上游信号源之一,但真正决定是否写入 Concern 的仍然是认知中枢。
三个上游
对话层 ──→ 认知中枢 ──→ Concern:用户指令驱动("帮我问张三...")
感知层 ──→ 认知中枢 ──→ Concern:事件/异常驱动(发现任务逾期)
Scheduler ─→ 认知中枢 ─→ Concern:内部时钟驱动(定时事项到期)感知层与 Concern 的交互方式
| 场景 | 感知层输出 | 认知中枢动作 |
|---|---|---|
| 发现新的需要跟进的事项 | signal + create_concern_candidate | 调用 raise_concern() 创建新 Concern |
| 业务数据变化与已有 Concern 相关 | signal + concern_evidence | 调用 advance_concern() 推进已有 Concern |
| 事项已在 Concern 中跟踪,收到确认信号 | signal + resolve_candidate | 调用 advance_concern() 提供新证据,由 agent loop 判断是否 resolve |
间接推进示例
Concern: 等待张三确认提测时间
↓
感知层收到事件: 张三在飞书多维表格把任务状态改为"已提测"
↓
感知层判断: 这个状态变更与活跃 Concern 相关
↓
认知中枢调用 advance_concern(reply_summary="张三已将任务状态改为已提测")
↓
agent loop 评估: goal 达成 → resolve_concern这意味着即使张三没有直接回复清海,感知层也能通过业务数据变化间接推进 Concern。
六、与事件系统的关系
事件系统和感知层是上下游关系,职责清晰分离。
事件系统的职责
- 接收外部 webhook / 推送
- 验签、去重
- 转为
UnifiedEvent统一结构 - 路由到下游处理器
感知层的职责
- 接收路由后的
UnifiedEvent - 用
attention_watchlist规则做初步过滤 - 需要时调用 LLM 理解事件含义
- 产出结构化 signal 与候选建议
- 维护工作区缓存
数据流
飞书 webhook ──→ EventAdapter ──→ UnifiedEvent ──→ EventRouter
↓
感知层 handle_event()
↓
过滤 → 理解 → 输出 signal
↓
认知中枢统一决策事件系统只负责"事实送进系统",感知层负责"理解事实",认知中枢负责"最终决策"。
七、LLM 成本控制
不是每个事件都需要调用 LLM。感知层通过分级处理控制成本。
三级处理策略
| 级别 | 条件 | 处理方式 | LLM 调用 |
|---|---|---|---|
| L0 静默 | 未命中任何 attention_watchlist 规则,非高优先级 | 写入 event_buffer,不做判断 | 无 |
| L1 规则 | 命中 attention_watchlist 但规则明确(如"状态变为已完成") | 按预定义逻辑形成 signal / 记录 | 无 |
| L2 判断 | 命中关注项但情况复杂,或高优先级事件 | 送入 LLM 综合判断 | 有 |
过滤层设计
事件到达
↓
attention_watchlist 规则匹配 ─── 无命中 → L0 静默写入
↓ 命中
规则是否足够明确? ─── 明确 → L1 规则处理
↓ 需要判断
L2 LLM 判断(带 working_summary 上下文)LLM 调用的输入
L2 判断时,送入 LLM 的上下文包括:
- 当前事件详情
working_summary(公司现状摘要)- 相关的
recent_observations(近期判断) - 匹配到的
attention_watchlist项(为什么关注这个) - 相关的活跃 Concern 摘要(是否与已有事项相关)
这确保 LLM 有足够上下文做出准确判断,同时通过前置过滤避免不必要的调用。
八、Signal 类型定义
Signal 是 Perception 输出、Cognitive Core 输入的结构化中间语言。 每个 Signal 必须能追溯到至少一个 Fact(通过
source_fact_ref)。
8.1 架构定位
Signal 在系统数据流中的位置:
外部事实(消息 / 事件 / 定时触发)
↓
Fact Layer ─── 记录原始事实,不可变
↓
Perception ─── 理解事实含义
↓
Signal ──────── 结构化中间产物,"这意味着什么"
↓
Cognitive Core ── 统一裁决,决定写入 Session / Person / Agenda / Concern / ActionSignal 不是真源。它是处理管道中的中间产物,不需要长期持久化。认知中枢消费 Signal 后,真正的运行态变化落在 Person / Fact / Agenda / Concern 四类真源里。
8.2 基础结构
所有 Signal 共享以下通用字段:
Signal(
signal_type: str, # 信号类型,如 "delegation_signal"
source_fact_ref: str, # 触发此信号的 Fact ID
person_refs: list[str], # 关联的 person_id 列表
confidence: str, # "low" / "medium" / "high"
summary: str, # 一句话描述
detail: dict, # 类型特定的结构化详情
timestamp: str, # 信号产出时间(ISO 8601)
)字段说明
| 字段 | 说明 |
|---|---|
signal_type | 信号类型标识,10 种之一 |
source_fact_ref | 追溯到触发此信号的原始事实 |
person_refs | 信号涉及的人员列表(可能为空) |
confidence | 信号可信度,由 Perception 产出时初步设定(规则产出默认 high,LLM 产出由模型给出),evaluate() 可根据上下文调整 |
summary | 人类可读的一句话摘要 |
detail | 每种信号类型有各自的结构化字段 |
timestamp | 信号产出时间,非事实发生时间 |
8.3 信号类型目录
| signal_type | 定义 | 典型触发场景 | 默认 confidence |
|---|---|---|---|
delegation_signal | 用户要求系统联系/提醒/跟进某人某事 | 老板说"帮我催一下张三" | high |
promise_signal | 某人承诺在某时间完成某事 | 员工说"周五前给你结果" | medium |
reply_signal | 某人对系统追问或 concern 做出回复 | 被追问者回复了消息 | high |
blocker_signal | 发现明确阻塞或卡点 | 员工说"卡在联调,等对方接口" | medium |
risk_signal | 发现异常或风险迹象 | 关键任务连续两天无进展 | low |
completion_signal | 某项工作/任务确认完成 | GitLab MR 合入、任务状态改为已完成 | high |
absence_signal | 预期事件未发生 | 承诺今天提测但到下班仍无提交 | medium |
preference_signal | 某人表达了稳定偏好 | 用户说"以后别给我发太长的消息" | medium |
work_state_signal | 某人的客观工作状态发生变化 | 员工说"这周在搞支付模块" | high |
cancellation_signal | 用户明确取消或否定之前的指令/关注 | "算了,不用催了" | high |
8.4 各信号类型详细定义
8.4.1 delegation_signal(委托信号)
用户要求系统代为联系、提醒或持续跟进某人某事。这是 Concern 立项最直接的信号来源。
detail 结构:
{
"target_name": "张三",
"task_description": "确认 v2.0 后端接口的提测时间",
"deadline": "2026-03-19T18:00:00+08:00",
"urgency": "high"
}典型场景: 老板在 Telegram 说"帮我问一下张三,v2.0 后端什么时候能提测,今天给我个时间"。系统解析出委托意图,产出 delegation_signal,认知中枢据此创建 Concern。
8.4.2 promise_signal(承诺信号)
某人在对话中承诺在某时间点前完成某事。系统需要记录承诺并在到期时验证。
detail 结构:
{
"promiser_person_id": "p_zhangsan",
"promise_content": "完成用户接口的联调",
"deadline": "2026-03-20T18:00:00+08:00",
"verification_method": "gitlab_merge"
}典型场景: 张三对清海说"这个接口我周五下班前肯定调通"。系统产出 promise_signal,认知中枢可能先写入 Agenda.watch_items,到期后若无 completion 证据再升级为 Concern。
8.4.3 reply_signal(回复信号)
某人对系统此前的追问或某个活跃 Concern 做出了回复。这是 Concern 推进的核心信号。
detail 结构:
{
"concern_id": "con_001",
"reply_content": "已提测,MR 链接是 https://gitlab.com/...",
"satisfies_goal": true
}典型场景: 清海此前代老板追问张三提测时间,张三回复"已提测"。系统产出 reply_signal,认知中枢调用 advance_concern,agent loop 评估 goal 是否达成。
8.4.4 blocker_signal(阻塞信号)
发现某人或某事存在明确阻塞,导致工作无法继续推进。
detail 结构:
{
"blocked_person_id": "p_zhangsan",
"blocker_description": "支付回调接口联调被阻塞,等待第三方提供沙箱环境",
"impact_scope": "v2.0 支付模块上线",
"duration_estimate": "2-3 天"
}典型场景: 张三说"卡在联调了,对方沙箱环境一直没给"。系统产出 blocker_signal,认知中枢评估影响范围后决定是否立项或升级。
8.4.5 risk_signal(风险信号)
发现异常迹象或潜在风险,但尚未构成明确阻塞。通常 confidence 较低,需要持续观察。
detail 结构:
{
"risk_description": "v2.0 后端接口连续 3 天无代码提交",
"affected_scope": "v2.0 上线计划",
"severity": "medium",
"evidence_refs": ["fact_1001", "fact_1002", "fact_1003"]
}典型场景: 感知层发现张三负责的关键模块连续多天无 GitLab 活动。系统产出 risk_signal,认知中枢可能先写入 watch_item 持续观察,证据积累后再升级。
8.4.6 completion_signal(完成信号)
某项工作或任务已确认完成。可能触发已有 Concern 的关闭或 watch_item 的消除。
detail 结构:
{
"completed_item": "v2.0 用户接口联调",
"completed_by_person_id": "p_zhangsan",
"verification_source": "gitlab_merge_event"
}典型场景: GitLab 收到 MR 合入事件,匹配到张三负责的提测任务。系统产出 completion_signal,认知中枢调用 advance_concern 提供完成证据。
8.4.7 absence_signal(缺席信号)
预期事件在预期时间内未发生。这是心跳缺席检测的标准输出。
detail 结构:
{
"expected_event": "张三提交 v2.0 用户接口的提测 MR",
"expected_by": "2026-03-18T18:00:00+08:00",
"hours_overdue": 4,
"related_person_id": "p_zhangsan"
}典型场景: 张三承诺今天提测,到 22:00 仍无 GitLab 合入事件。缺席检测产出 absence_signal,认知中枢评估后可能升级为 Concern 或直接通知。
8.4.8 preference_signal(偏好信号)
某人在对话中表达了一个相对稳定的个人偏好或沟通习惯。
detail 结构:
{
"preference_type": "communication_style",
"preference_content": "不喜欢太长的消息,希望简洁一些",
"confidence_reason": "用户明确表达,且非临时情绪"
}典型场景: 用户说"以后回复别那么长,简洁点就行"。系统产出 preference_signal,认知中枢验证后写入 Person.profile。
8.4.9 work_state_signal(工作状态信号)
某人的客观工作状态发生变化,如当前重点、进行中任务、角色变化。
detail 结构:
{
"state_change_type": "current_focus",
"before": "v1.9 bug 修复",
"after": "v2.0 支付模块开发",
"source_event": "对话自述"
}典型场景: 张三说"这周开始做支付模块了,bug 那边交给李四"。系统产出 work_state_signal,认知中枢据此更新 Person.work_state。
8.4.10 cancellation_signal(取消/否定信号)
用户明确取消之前的指令、委托,或否定某个正在进行的 concern/watch。这是唯一能直接触发 concern 关闭(dropped)或 watch 移除的信号。
detail 结构:
{
"cancel_type": "concern_cancel",
"target_concern_id": "con_20260318_001",
"target_watch_id": null,
"reason": "用户说算了不用催了",
"cancelled_by_person_id": "p_owner"
}典型场景: 老板说"张三那个事不用问了,我直接跟他说了"。系统产出 cancellation_signal,认知中枢将对应 concern 标记为 dropped,不回流。
cancel_type 枚举:
| cancel_type | 含义 | 认知中枢动作 |
|---|---|---|
concern_cancel | 取消特定 concern | 标记 dropped,不回流 |
watch_cancel | 取消特定 watch | 移除 watch_item |
general_cancel | 模糊取消("那个事算了") | 由认知中枢匹配最相关的 concern/watch |
8.5 Signal 产出方式
Signal 有三种产出路径,对应感知层的三级处理策略:
LLM 产出(L2 判断)
事件命中关注项且情况复杂,由 LLM 综合分析后产出 Signal。
- 上下文包括:事件详情 +
working_summary+ 相关recent_observations+ 活跃 Concern 摘要 - 可以产出任意类型的 Signal
- 成本最高,但准确度最高
规则产出(L1 规则匹配)
命中 attention_watchlist 且规则足够明确时,无需 LLM 即可直接产出 Signal。
典型规则:
| 规则 | 产出的 Signal |
|---|---|
回复消息命中活跃 Concern 的 person_refs | reply_signal |
| 任务状态变为"已完成" | completion_signal |
| watch_item 到期仍无匹配事件 | absence_signal |
对话分析产出
在对话处理链路中(hooks._detect_followup_concerns),从用户消息中提取隐含信号。
典型提取:
- 用户说"帮我问一下..." →
delegation_signal - 用户说"我周五前搞定" →
promise_signal - 用户说"我不喜欢..." →
preference_signal
8.6 Signal 生命周期
Signal 是短期中间产物,不做长期持久化。
产出
-> 传入 Cognitive Core evaluate()
-> 认知中枢消费:决定写入 Person / Agenda / Concern / Action
-> 可选:归入 Workspace.recent_observations 作为短期缓存
-> 不做长期持久化生命周期要点
| 阶段 | 说明 |
|---|---|
| 产出 | Perception 或规则匹配产出 Signal |
| 消费 | Cognitive Core 统一裁决,Signal 作为判断输入之一 |
| 缓存 | 消费后可选写入 Workspace.recent_observations,供后续短期参考 |
| 过期 | 随 recent_observations 滚动窗口自动淘汰 |
8.7 与 Fact 的区别
Signal 和 Fact 是系统中最容易混淆的两个概念。
| 维度 | Fact | Signal |
|---|---|---|
| 回答什么 | "发生了什么" | "这意味着什么" |
| 本质 | 原始事实记录 | 对事实的解释与判断 |
| 可变性 | 不可变 | 可被后续事实推翻或修正 |
| 持久化 | 长期持久化,可追溯 | 短期中间产物,不持久化 |
| 是否真源 | 是 | 否 |
| 来源 | 渠道入口、事件适配器、动作执行器 | Perception、规则引擎、对话分析 |
| 示例 | "张三在飞书把任务状态改为已提测" | "张三已完成提测承诺,可能满足 con_001 的 goal" |
核心原则:Fact 先于 Signal 存在。每个 Signal 必须能追溯到至少一个 Fact(通过 source_fact_ref)。
九、设计原则
感知层原则
- 事件驱动,不是轮询 — 业务变化推送过来,不主动遍历
- 心跳只做缺席检测 — 检查"应该发生但没发生"的事,不再扫描一切
- 工作区是短期认知缓存 — 清海每次被唤醒时,通过工作区恢复近期判断上下文,但它不是系统真源
- 感知不等于决策 — 感知层负责看懂与提议,认知中枢负责裁决,持续事项引擎负责持续推进
- 分级处理控制成本 — 不是每个事件都调 LLM,规则过滤在前
- attention_watchlist 是动态的 — 关注项随公司状态和老板指令变化,不是静态配置
- 间接推进是一等能力 — 业务数据变化可以作为 Concern 的推进信号,不依赖对方直接回复
- 工作区单文档存储 — 简单可靠,避免分散状态的一致性问题
Signal 原则
- Signal 是中间语言,不是真源 — Signal 连接 Perception 和 Cognitive Core,消费后不做长期持久化
- 每个 Signal 必须可追溯 — 通过
source_fact_ref回溯到触发它的原始事实 - Signal 不直接决定行动 — Signal 只是认知中枢的输入之一,最终裁决权在 Cognitive Core
- confidence 影响裁决阈值 — low 通常进 watch,medium 需要综合评估,high 可能直接立项
- 优先合并而非重复产出 — 同一事实不应产出语义重叠的多个 Signal
- 规则优先于 LLM — 能用 L1 规则明确判定的信号,不调用 L2 LLM
- Signal 类型是封闭集合 — 新增类型须更新本文档,不允许产出未定义的 signal_type
- person_refs 必须尽量填充 — 信号关联到具体的人,才能在认知中枢阶段正确绑定上下文
感知层的职责可以概括成一句话:
让清海在事件发生时先看懂,再把是否行动交给统一认知中枢。