持续事项引擎设计
Concern 不是系统总脑,而是统一议程中的持续事项对象与状态机。 它负责记录、推进、复查和回流那些已经正式进入议程的事项。 Concern 只承接已经被认知中枢正式立项的事项,不直接接收未经判断的原始事实。 如本文仍保留旧实现术语(如周期发现直接归 Concern),凡与《产品与架构设计》《认知中枢设计》冲突之处,以后者为准。 最后更新:2026-03-18
一、架构定位
在统一认知架构下,Concern 的位置应理解为:
对话 / 事件 / 定时触发
↓
认知中枢(统一判断是否进入议程)
↓
Concern Engine(持续事项状态机)
↓
Concern Scheduler / Concern Channel
↓
Action / 回流Concern 只应承担三件事:
- 经认知中枢立项的持续事项统一进入 concern
- 单条事项的状态机与 next action 管理
- 回流、升级、等待、追问等持续推进链路
二、Concern 是什么
Concern 不是外部业务系统里的任务,而是清海自己的执行对象:
- 我在跟哪件事
- 涉及谁
- 我已经做过什么
- 下一步该做什么
- 什么时候再看
只要一件事具有“持续跟进”属性,就应该落到 Concern。
三、创建来源
1. 对话委托
用户要求清海联系某人、提醒某人、跟进某件事。
2. 定时触发
到点执行的计划事项,需要直发、借会话处理或系统独立处理。
3. 事实 / 信号经认知中枢抬升
业务系统事件、感知信号、缺席检测结果进入认知中枢后,经议程判断,再创建或补充 concern。
4. 对话中的承诺 / 风险抬升
用户在对话里表露风险、承诺后续、说明卡点后,先形成 Fact / Signal,再由认知中枢决定是否抬升为新的 follow-up concern。
任何原始对话、事件、扫描结果都不能绕过认知中枢直接进入 Concern。
四、数据结构
当前 concern 核心字段如下:
{
"concern_id": "con_20260316_001",
"type": "delegation",
"status": "waiting_reply",
"priority": "medium",
"title": "联系张三确认提测时间",
"goal": "拿到张三的具体提测时间点",
"source": {
"type": "delegation",
"detail": "帮我问问张三提测什么时候能给",
"initiator": {
"name": "清海",
"channel": "telegram",
"channel_user_id": "123"
}
},
"people": [
{
"person_id": "p_owner",
"display_name": "清海",
"role_in_concern": "发起者",
"comm_status": "not_needed"
},
{
"person_id": "p_zhangsan",
"display_name": "张三",
"role_in_concern": "当事人",
"comm_status": "waiting_reply"
}
],
"timeline": [
{"ts": "...", "type": "discovered", "detail": "Concern 创建"},
{"ts": "...", "type": "action_send", "detail": "已发送给张三"}
],
"conversation_log": [
{
"person_name": "张三",
"person_id": "p_zhangsan",
"direction": "outbound",
"text": "老板想了解提测什么时候能给?",
"channel": "feishu",
"ts": "2026-03-17T10:00:00"
},
{
"person_name": "张三",
"person_id": "p_zhangsan",
"direction": "inbound",
"text": "我看看",
"channel": "",
"ts": "2026-03-17T10:05:00"
}
],
"next_action": {
"what": "等待张三回复",
"who_person_id": "p_zhangsan",
"when": "2026-03-16T10:00:00+00:00"
}
}字段分工
| 字段 | 说明 |
|---|---|
type | 当前 concern 类别,如 delegation / schedule / absence_followup / followup |
status | 当前执行状态 |
priority | 优先级,影响发送时段和后续策略 |
goal | 完成条件 — 什么时候算办完了,用于 agent loop 判断是否 resolve |
source | 触发来源与原始原因 |
people[] | 此事涉及的人,以及他们在此事中的角色 |
timeline[] | 已发生动作与判断 |
conversation_log[] | 完整对话记录(按时间排序,含 outbound/inbound),供 agent loop 理解上下文 |
next_action | 下一步计划 |
delegation | 委托类 concern 的回复等待与回流配置 |
trigger | 定时类 concern 的触发参数 |
executions[] | 定时类 concern 的执行记录 |
五、状态流转
当前设计围绕以下主状态展开:
pending
↓
in_progress
↓
waiting_reply
↓
escalated / resolved / dropped状态含义
| 状态 | 含义 |
|---|---|
pending | concern 已创建,等待首次处理 |
in_progress | 已进入处理循环 |
waiting_reply | 已联系相关人,等待回复 |
escalated | 已升级给更高层或更合适的人 |
resolved | 事项已完成 |
dropped | 系统判断无需继续推进 |
六、执行循环
Concern 的核心不是静态存储,而是持续推进。
创建或被触发
↓
加载 concern 本体(含 goal + conversation_log)
↓
补充人物切片、业务上下文、回复候选
↓
模型判断:goal 是否达成?
↓
达成 → resolve_concern 关闭 + 回流
未达成 → 自主决定下一步(追问 / 查数据 / 等待 / 升级)
↓
设置 next_action,等待新触发再次进入循环触发器
当前会让 concern 重新进入执行循环的事件有:
next_action.when到期- 回复到达(
advance_concern→ trigger="reply") - 超时扫描命中(trigger="timeout")
- 定时 concern 到点
- 认知中枢判定有新的相关事实或缺席信号
多轮推进机制
v3.0 引入 goal + conversation_log,从"单次触达"升级为"多轮智能推进":
- 创建时:
raise_concern设定goal(完成条件),发送初始消息同步写入conversation_log(outbound) - 对方回复时:对话层调用
advance_concern(而非直接 resolve),记录 inbound 到conversation_log,异步触发 agent loop - agent loop 评估:读取 goal + 完整对话记录,自主判断是否达成目标
- 达成 →
resolve_concern关闭 + 回流 - 未达成 → 追问 / 调查 / 设置下次检查时间 / 升级
- 达成 →
- agent loop 发消息:
send_message_to同步写入conversation_log(outbound),保证记录完整 - 超时时:不再发固定提醒模板,改为触发 agent loop(trigger="timeout"),由 AI 根据对话历史和对方态度自主决定跟进方式
回流规范
resolve_concern 触发回流时,遵循以下规则:
回流条件
| concern 类型 | 是否回流 | 回流对象 |
|---|---|---|
delegation | 始终回流 | 发起人(initiator) |
followup | 有明确发起人时回流 | 发起人 |
heartbeat | 仅 high/critical 回流 | owner(老板) |
schedule | 不回流(执行结果记入 executions) | — |
回流内容
回流消息由 agent loop 生成,但必须包含:
[回流] {concern.title}
结果:{一句话结论}
关键信息:{对方的核心回复内容}
耗时:{创建到关闭的时间}agent loop 可以在此基础上补充背景,但不能省略上述字段。
回流渠道
- 优先使用发起人的
interaction_policy.preferred_channel - 如果发起渠道和偏好渠道不同,使用偏好渠道
- 如果偏好渠道不可达,降级到发起渠道
追问间隔策略
agent loop 在 trigger="timeout" 或设置 next_action 时,追问间隔受以下约束:
| 优先级 | 首次追问 | 二次追问 | 三次及以后 | 最大追问次数 |
|---|---|---|---|---|
critical | 30 分钟 | 1 小时 | 2 小时 | 不限(直到升级) |
high | 2 小时 | 4 小时 | 8 小时 | 5 次 |
medium | 4 小时 | 8 小时 | 24 小时 | 3 次 |
low | 24 小时 | 48 小时 | — | 2 次 |
间隔递增(避免骚扰),达到最大次数后:
critical/high→ 自动触发 escalatemedium/low→ 标记为dropped,写入 recent_decisions
对方态度识别
agent loop 根据 conversation_log 判断对方态度,调整策略:
| 对方回复 | 态度判断 | 追问策略 |
|---|---|---|
| "好的,明天给你" | 有明确承诺 | 按承诺时间设 next_action,不提前追问 |
| "我看看"/"嗯" | 模糊回应 | 按正常间隔追问 |
| "别催了"/"已经在做了" | 抗拒但在进行 | 间隔翻倍,语气变柔 |
| 完全无回复 | 无响应 | 按正常间隔,3 次后考虑换渠道或升级 |
部分达成判定
goal 的达成判定由 agent loop 自主完成,但遵循以下原则:
| 场景 | 判定 | 动作 |
|---|---|---|
| goal 要求"具体时间",对方给了"大概这两天" | 未达成 | 追问具体日期 |
| goal 要求"确认",对方说"好" | 达成 | resolve + 回流 |
| goal 要求"提测",GitLab 出现 merge 事件 | 达成(间接证据) | resolve + 回流 |
| goal 要求"完成 A 和 B",只完成了 A | 未达成 | 追问 B 的进展 |
| 发起人说"算了不用问了" | 取消 | 标记 dropped + 不回流 |
七、中途汇报
Concern 协调事项通常跨越数小时甚至数天。在最终回流之前,发起人(通常是老板)不知道事情推进到哪了。中途汇报解决这个问题:在关键状态节点主动向发起人同步进展。
汇报节点
| 状态跳转 | 汇报内容 | 示例 |
|---|---|---|
| 创建 → pending | 确认收到 + 计划 | 好的,我来问张三,有回复及时同步给你 |
| pending → 已发出 | 已联络,等回复 | 已经联系张三了,等他回复 |
| 等待中 → 超时未回 | 仍在跟进 | 张三还没回复,我再跟一下 |
| 收到部分结果 | 部分进展 | 李四确认了,张三和王五还没回 |
| 需要发起人决定 | 卡点上报 | 张三说上午有会,能换下午吗? |
| 全部完成 | 最终结果(正式回流) | 三个人都确认了,会议定在周一下午两点 |
不汇报的情况
- 正在编辑消息草稿(太细)
- 系统内部判断过程(用户不需要知道)
- 工具调用报错重试(内部问题)
- 静默级 concern(
low优先级且无发起人)
简单场景:模板驱动
状态跳转、超时提醒等确定性节点,使用模板生成汇报消息,不调用 LLM:
STATUS_TEMPLATES = {
"contacted": "已经联系{target_name}了,等{pronoun}回复。",
"timeout_retry": "{target_name}还没回复,我再跟一下。",
"partial": "{done_names}确认了,{pending_names}还没回。",
"created": "好的,我来联系{target_name},有进展及时同步给你。",
}复杂场景:复用已有 LLM 输出
当对方回复了复杂内容、情况发生变化时,模板不够用。但此时 advance_concern 的 agent loop 已经在做 LLM 调用(评估 goal、理解回复、决定下一步)。不需要额外调用,只需让 agent loop 在已有输出中多产出一个字段:
# agent loop 输出结构(已有)
{
"goal_met": False,
"next_action": "1小时后再跟进",
"summary": "张三说卡在第三方回调,提了临时方案...",
# 新增字段 ↓
"owner_update": "张三回复了,核心意思是第三方沙箱还没到,他提了个临时方案。需要你决定:接受临时方案赶周五,还是等沙箱到了再上。"
}当 owner_update 非空时,向发起人发送该内容。当 owner_update 为空时(agent loop 判断无需汇报),不打扰。
汇报频率约束
中途汇报同样受 notification.py 防骚扰约束:
- 同一 concern 的中途汇报间隔不低于 30 分钟
- 每日中途汇报总量不超过每日通知上限
- 非工作时段的中途汇报延迟到次日工作时段
完整示例
老板: 帮我问一下张三李四,v2.0 什么时候能提测
清海: 好的,我来问张三和李四,有进展及时同步给你。
← 模板:created
... 30 分钟后 ...
清海: 已经联系张三和李四了,等他们回复。
← 模板:contacted
... 2 小时后,李四回复了 ...
清海: 李四说前端部分周四能提测。张三还没回复,我再跟一下。
← 模板:partial + timeout_retry
... 又过了 1 小时,张三回复了复杂内容 ...
清海: 张三回复了:后端支付模块卡在第三方回调接口,他提了个
临时方案——先用 mock 跑通主流程,上线后第一周人工对账。
需要你决定:接受临时方案赶周五,还是等沙箱到了再上。
← agent loop 产出的 owner_update八、与人物上下文的关系
Concern 不保存完整人物主档,只保存最小必要的人物关系:
person_iddisplay_namerole_in_concerncomm_status- 最近一次触达渠道
需要完整人物信息时,由上层通过 person_id 读取:
resolve_person_context(person_id)build_person_context_slice(person_id, "concern")
这样 concern 本体保持轻量,而人物信息始终使用同一真源。
九、对话侧能力
Concern 当前通过三类工具进入 Avatar 对话:
| 工具 | 作用 |
|---|---|
raise_concern | 创建新的跟进事项(含 goal 完成条件) |
advance_concern | 记录对方回复进展,触发 agent loop 评估是否达成目标 |
check_concerns | 查询当前活跃 concern |
resolve_concern仍然存在,但仅由 agent loop 内部调用,不再暴露给对话层。对话层统一用advance_concern记录进展,由系统自动判断是否完成。
同时,对话上下文还会注入:
- 当前用户相关的 concern 摘要
- 待回复 concern 候选(提示使用
advance_concern) - 该用户的
person context slice
十、调度策略
ConcernScheduler 统一负责:
| 方法 | 作用 |
|---|---|
scan_due_concerns() | 扫描 next_action.when 到期事项 |
scan_timeouts() | 扫描超时未回复事项 → 触发 agent loop(trigger="timeout"),由 AI 自主决定跟进方式 |
scan_schedules() | 扫描定时 concern |
守护进程需要驱动 ConcernScheduler 处理 concern 生命周期;缺席检测和事实扫描属于认知中枢侧能力,不属于 ConcernScheduler。
v3.0 变更:
scan_timeouts不再直接发送固定提醒模板或标记过期,而是统一触发 agent loop,由 AI 根据 goal、conversation_log、对方态度自主决定下一步。
十一、与 Agenda 层的关系
Concern 是 Agenda 的子对象。Agenda 负责"全局在推进什么",Concern 负责"这件事怎么持续推进"。
注册与移除
| 事件 | Agenda 操作 |
|---|---|
raise_concern() 创建成功 | 写入 Agenda.concern_refs,含 concern_id / priority / status / agenda_role |
resolve_concern() 关闭 | 从 Agenda.concern_refs 移除,写入 recent_decisions |
| priority 变化 | 同步更新 Agenda.concern_refs 中对应条目 |
调度边界
| 职责 | 归属 |
|---|---|
| Concern 生命周期(到期、超时、定时触发) | ConcernScheduler |
全局优先级排序(focus_queue) | 认知中枢 |
| watch_item → concern 升级 | 认知中枢 |
| concern 的 next_action、状态机 | Concern Engine |
ConcernScheduler 不改变全局优先级,只驱动单条 concern 的生命周期。全局议程排序和 watch 升级由认知中枢统一裁决。
十二、设计原则
- 被认知中枢判定为需要持续推进的事情,才进入 concern
- concern 只保存”这件事”和”此事相关的人”
- 人物长期信息统一来自
PersonContext - concern 不负责立项,只负责承接已立项事项
- 所有主动推进都通过 concern 调度器进入执行循环
- 回复回流是 concern 的一等能力,不是外部补丁
- goal 驱动判定:收到回复不直接关闭,由 agent loop 对照 goal 判断是否达成
- 对话记录完整:conversation_log 记录所有 outbound/inbound,agent loop 据此理解全貌
- AI 自主决策:追问时机、跟进方式、时间间隔全由 AI 根据场景判断,不走固定模板
- Agenda 集成:concern 创建时注册到 Agenda.concern_refs,关闭时移除,优先级同步
Concern 的职责可以概括成一句话:
让清海对一件事有持续记忆、持续行动和明确的下一步。