对话流程设计
当前多渠道对话主链路:统一消息 -> 写入 Fact -> 人物识别 -> 轻量预加载 -> agent loop(AI 自主决策)-> 风险路由 -> hook 补漏。 对话不是天然的 Concern 输入,而是天然的 Fact 输入;是否进入议程,由统一认知中枢判断。 模型可以直接推进已有 Concern,但新的 Concern 立项必须经过认知中枢。 本文中的状态写入边界,同时受《产品与架构设计》约束。 如本文与《产品与架构设计》《认知中枢设计》冲突,以后者为准。 最后更新:2026-03-18
一、完整流程
用户发消息(TG / 飞书)
↓
① 渠道入口封装 UnifiedMessage
↓
② 写入 Fact Layer(对话事实)
↓
③ identify_user() 解析到 person_id / person_context / role
↓
④ 轻量预加载:session_brief + always providers(人物/档案/concern)
↓
⑤ 注入 concern 回复候选与 concern tools
↓
⑥ build_avatar_prompt() 生成 system blocks
↓
⑦ LiveSessionManager + LLM agent loop
├── AI 按需调用 SaveInsight 保存记忆
├── AI 按需调用 UpdateBrief 更新简报
├── AI 按需调用 QueryBusinessContext 查询业务数据
├── AI 命中已有 concern 时调用 advance_concern 记录回复/证据
└── AI 识别 delegation / promise / risk 候选,交由议程判断链路处理
↓
⑧ 解析风险标记并路由发送
↓
⑨ on_stop hook 补漏(跳过 AI 已完成的步骤)二、核心数据结构
UnifiedMessage
UnifiedMessage(
channel="telegram" | "feishu",
channel_user_id="...",
channel_msg_id="...",
channel_chat_id="...",
text="...",
user_name="...",
is_group=False,
raw={...},
)UserIdentity
UserIdentity(
role="owner" | "admin" | "team_lead" | "employee" | "guest",
name="...",
channel="telegram" | "feishu",
channel_user_id="...",
department="...",
job_title="...",
person_id="p_xxx",
person_context=PersonContext(...),
)ChannelSender
统一抽象各渠道发送差异:
send_text()send_smart()reply_in_group()
三、用户识别
identify_user() 是当前唯一身份入口。
识别顺序
- 按
channel + channel_user_id查people - 读取
PersonContext - 根据
people.org.company_role映射系统角色 - 缺记录时按渠道信息自动创建基础人物主档
- 返回
person_id + person_context + role
角色只决定基础服务方式,不代表天然拥有全量上下文读取权;读取边界见《权限与可见性设计》。
角色映射
| 人物档案中的角色 | 对话角色 |
|---|---|
boss | owner |
admin | admin |
| 其他已识别内部成员 | employee / team_lead |
| 无记录 | guest |
四、上下文组装
预加载策略
handle_avatar() 并行加载轻量数据:
load_session_brief(uid, ...)— 会话简报resolve_context(...)— 仅 always providers(人物画像/档案/concern)
业务数据(项目/任务/考勤/审批)不再预加载,改由 AI 通过 QueryBusinessContext 工具按需查询。
当前注入内容
| 层 | 内容 | 方式 |
|---|---|---|
| 固定层 | 渠道规则、身份说明、行为规则、persona | 始终注入 |
| 人物层 | person context slice | always provider |
| 会话层 | session_brief | 始终注入 |
| concern 层 | 活跃 concern 摘要与回复候选 | always provider |
| 业务层 | 项目/任务/考勤/审批 | AI 工具按需拉取 |
| 工具层 | 渠道工具、MemorySearch、Concern 工具、人物工具 | 按条件注入;议程候选检测由 hook 补漏后送认知中枢 |
上下文层次原则
- 固定规则、人格、短期会话状态分层注入
- 人物信息统一来自
PersonContext - concern 作为独立层进入 prompt
- 记忆默认按需检索,不整包预塞
- 业务数据由 AI 按需查询,不再关键词触发预加载
- 对话先进入 Fact,再由认知中枢决定是否影响人物状态或进入 Concern
- 所有注入内容先经过角色可见性裁剪,不能把不应暴露的他人档案、Concern 明细或 Fact 原文直接塞进 prompt
concern 增强
当当前说话人存在待回复 concern 时,会额外注入:
[Concern 回复候选]- 候选 concern 编号、发起人、事项摘要、当前沟通状态
- 提示模型优先考虑
advance_concern
五、Prompt 结构
build_avatar_prompt() 返回多个独立 content blocks。
Block 1
渠道规则、身份说明、人物切片、历史提示、行为规则、业务上下文。
Block 2
persona.md
Block 3
session_brief
这三层保持独立,便于模型在固定规则、人格定义和短期会话状态之间分层关注。
六、工具注入
默认工具
- 渠道业务工具
MemorySearchMemorySave
AI 自主决策工具(所有会话)
| 工具 | 作用 |
|---|---|
SaveInsight | 保存对话中发现的有价值信息到记忆系统 |
QueryBusinessContext | 按需查询业务数据(项目/任务/考勤/审批) |
UpdateBrief(非群聊) | 更新当前对话者的会话简报 |
条件追加工具
| 条件 | 工具 |
|---|---|
| 有 concern 引擎 | advance_concern / check_concerns |
非特权用户且有 person_id | update_work_status(仅用于确认近期客观工作状态) |
| 特权用户 | person_tools |
七、风险路由
当前只识别两种显式升级标记:
<!--escalate-->
<!--block-->未标记时默认为直接发送。
路由规则
| 条件 | 路由 |
|---|---|
block | approval_block |
escalate + 私聊 | approval |
escalate + 群聊 | group_silent |
| 默认 + 私聊 | direct_send |
| 默认 + 群聊 | group_reply |
| owner/admin | 强制直发 |
八、过程感反馈
对话 agent loop 中,Claude 每次调用工具前会有一段等待时间。当前这段时间对用户来说是空白。通过在工具调用触发时发送一条自然语言状态提示,可以让用户感知到清海在做什么,而不是干等。
原则
- 说人话,不暴露技术细节 — 用户看到的是"我看看项目进度",不是"调用 QueryBusinessContext"
- 不加 LLM 调用 — 纯映射表,工具名 → 自然语言提示
- 最终回复发出后,中间状态消息删除或折叠 — 不留噪音
工具状态映射
| 工具 | 用户看到的状态提示 |
|---|---|
MemorySearch | 我回忆一下相关情况... |
QueryBusinessContext | 看一下业务数据... |
check_concerns | 确认一下有没有在跟进的事... |
advance_concern | 更新一下跟进进展... |
search_contacts | 查一下联系人... |
query_calendar | 看一下日程安排... |
query_tasks | 查一下任务情况... |
SaveInsight | 记一下这个信息... |
UpdateBrief | 更新一下简报... |
不在映射表中的工具不显示状态提示(静默执行)。
渠道实现方式
| 渠道 | 实现 | 说明 |
|---|---|---|
| Telegram | editMessageText | 先发一条状态消息,后续持续编辑更新,最终替换为正式回复 |
| 飞书 | 更新卡片消息 | 用交互卡片展示状态,最终替换为正式回复 |
多次工具调用时的行为
agent loop 可能连续调用多个工具。每次新工具调用时,编辑同一条状态消息为最新提示。用户看到的效果:
用户: 最近研发怎么样
清海: 我回忆一下相关情况...
↓(1秒后编辑为)
清海: 看一下业务数据...
↓(2秒后编辑为)
清海: 确认一下有没有在跟进的事...
↓(3秒后替换为正式回复)
清海: 📊 研发团队本周状态...九、收尾:hook 补漏模式
发送阶段
direct_send->sender.send_smart()group_reply->sender.reply_in_group()approval-> TG 审批消息approval_block-> 仅通知清海,不发给用户
on_stop hook 补漏
on_stop 接收 tools_called 集合,根据 AI 已完成的工具调用决定跳过哪些步骤:
| AI 已调用 | hook 行为 |
|---|---|
SaveInsight ∈ tools_called | 跳过 fallback 记忆保存 |
advance_concern ∈ tools_called | 跳过 concern 回复补录 |
| 其他 delegation / promise / risk 候选 | 统一执行议程候选检测,送认知中枢去重裁决 |
始终尝试执行:absorb_dialog_signal 做对话事实分流;只有命中近期客观工作状态时才更新 person_work_state,承诺 / 委托 / 风险统一进入议程判断链路。对话层不直接创建 Concern。
十、渠道差异
| 维度 | Telegram | 飞书 |
|---|---|---|
| 用户标识 | chat_id | open_id |
| 群聊触发 | @bot 或回复 bot | @bot |
| 审批承载 | TG 原生 | 转 TG 审批 |
| 富文本输出 | 纯文本分段 | 纯文本或消息卡片 |
| 额外能力 | 跨会话消息、系统命令 | 飞书业务工具集 |
十一、当前原则
- 任何渠道先统一成
UnifiedMessage - 任何人先统一到
person_id - 人物信息只通过
person context slice注入 - 记忆默认按需检索,不整包预塞
- concern 摘要和 concern 推进能力作为一等能力进入对话上下文和工具集
- AI 自主决策:记忆保存、简报更新、业务查询由 AI 在对话中按需完成,hook 只补漏
当前对话链路的目标不是"回答一条消息",而是:
在正确识别人、正确组装上下文的前提下,做出可执行、可升级、可沉淀的回复。
十二、AI 自主决策机制
设计思路
从「固定 pipeline → AI 自主决策 + hook 兜底」的转变:
- 旧模式:每条消息走完全相同的固定流程,对话结束后用便宜模型重新分析 Claude 刚处理过的对话
- 新模式:AI 在对话过程中顺手完成记忆/简报/业务查询,并可直接推进已有 concern;新 concern 的立项由 hook + 认知中枢统一裁决
工具设计
三个核心工具通过闭包绑定会话信息:
- SaveInsight:直接
embed_text+save_memory,不经过extract_metadata和 LLM 提炼 - UpdateBrief:AI 直接产出完整简报写入 MongoDB,不再调 LLM 做合并
- QueryBusinessContext:复用
context_providers的_fetch_*函数,按需拉取
Concern 相关的原则调整为:
- 已有 concern 的回复或新证据:模型可直接调用
advance_concern - 新的 delegation / promise / risk:模型不直接立项,只进入议程候选检测链路
Fallback 策略
on_stop 根据 tools_called 集合决定补漏(伪代码):
if "SaveInsight" not in tools_called:
_lightweight_save(...) # 仅 embed + save,0 次 LLM
if "advance_concern" not in tools_called:
_maybe_advance_existing_concern(...) # 仅补已有 concern 的回复关联
_detect_agenda_candidates(...) # 始终执行,内部去重,再交认知中枢统一裁决调用优化效果
| 场景 | 改造前 | 改造后 |
|---|---|---|
| AI 主动保存 | 1 Claude + 3 内部 LLM + 2 embed = ~9 次 | 1 Claude + 1 embed = 2 次 |
| AI 未保存(fallback) | 同上 | 1 Claude + 1 embed = 2 次 |
| 简单寒暄 "嗯" | 同上(全流程) | 1 Claude = 1 次 |