人物档案设计
当前人物底座只有一套:
people + person_work_state + person_events + PersonContext。 人物档案是真源,但只存“人”的信息,不存运行中的系统议程。 凡涉及 active concern、当前系统是否重点盯某人、next action 等状态,属于 Agenda / Concern 派生视图,不属于人物真源。 本文的字段归属与写入边界,同时受《产品与架构设计》约束。 最后更新:2026-03-18
一、目标
人物工作档案解决三个问题:
- 同一个人跨渠道只对应一个
person_id - 静态资料、客观近期状态、人工长期笔记有统一读取入口
- Concern、对话、通道层、看板都通过同一份人物真源理解“这个人是谁”,而不是把议程状态写回人物档案
系统现在不再依赖任何“人物卡片式补丁字段”。人物理解的唯一入口是 PersonContext。
二、存储结构
主集合
| 集合 | 作用 |
|---|---|
people | 人物主档,保存身份、组织、画像、职责、交互策略、渠道绑定 |
person_work_state | 动态工作状态,保存客观近期状态,如当前重点、进行中事项、阻塞项、近期风险事实 |
person_events | 人物相关事件流,保存任务信号、对话信号、系统更新记录 |
统一读取
读取入口固定为:
resolve_person_by_channel(channel, channel_user_id)resolve_person_context(person_id)resolve_person_by_name(name)
这些接口会把 people 与 person_work_state 组装成完整 PersonContext。
三、唯一主键:person_id
person_id 是整个人物体系的稳定主键。
要求:
- 不依赖单一渠道 ID
- 不依赖显示名
- 可绑定多个渠道身份
当前渠道绑定字段:
{
"person_id": "p_9c4d8d3c7f234abc",
"channel_bindings": [
{"channel": "telegram", "channel_id": "6209850781"},
{"channel": "feishu", "channel_id": "ou_xxx"}
]
}四、PersonContext 七层模型
scripts/person/models.py 当前定义了 7 个稳定层级。
1. identity
回答“这个人是谁”。
包含:
person_iddisplay_namealiasesexternal_idsstatus
2. org
回答“这个人在组织里的位置是什么”。
包含:
departmenttitlemanager_person_iddirect_reportscompany_roleis_key_person
3. profile
回答“这个人的沟通与工作风格是什么”。
包含:
work_stylecommunication_stylepreferencesstrengthsriskstrust_level
4. work_scope
回答“他长期负责什么”。
包含:
responsibilitiesowned_projectsdecision_scopecollaborators
5. work_state
回答“他现在在做什么、卡在哪”。
包含:
employment_statecurrent_focusactive_itemsblockersrecent_risk_flagsrecent_progress_summarylast_progress_at
6. manager_notes
回答“清海长期如何理解这个人”。
包含:
summarylong_term_observationscollaboration_guidanceupdated_bydo_not_overwrite
7. interaction_policy
回答“系统应该如何和这个人互动”。
包含:
preferred_channelallow_proactive_pingmax_proactive_contacts_per_dayreply_timeout_hoursescalation_pathtone_hint
五、读取形态
完整对象
PersonContext(
person_id=...,
identity=...,
org=...,
profile=...,
work_scope=...,
work_state=...,
manager_notes=...,
interaction_policy=...,
channel_bindings=[...],
)场景切片
对上层模块不直接暴露整份对象,而是按场景裁剪:
| 场景 | 输出函数 | 用途 |
|---|---|---|
chat | build_person_context_slice(person_id, "chat") | 对话提示当前人物摘要 |
concern | build_person_context_slice(person_id, "concern") | concern agent loop 读取加强版档案 |
notify | build_person_context_slice(person_id, "notify") | 发送动作读取渠道与触达偏好 |
dashboard | build_person_context_slice(person_id, "dashboard") | 看板或后台查看全量档案 |
六、当前写入路径
1. 启动引导
bootstrap_person() 负责把配置中的核心人物写入或补齐到 people。
2. 渠道识别
ensure_person() 负责在消息首次进入时建立或补齐人物主档与渠道绑定。
3. 对话信号
absorb_dialog_signal() 只把对话中确认的、具有事实依据的近期工作状态写入 person_work_state,例如当前重点、进行中事项、阻塞信息。
稳定偏好进入 profile,承诺 / 委托 / 风险优先进入 Agenda / Concern candidate,而不是写进人物真源。
4. 任务信号
任务同步与任务事件会通过 update_work_state() 和 add_person_event() 更新人物当前状态。
5. 人工维护
人工长期判断、长期观察、互动策略等字段由清海或后台工具直接写入人物主档。
七、与上层模块的关系
Concern
Concern 只通过 person_id 关联人物,不复制人物主档。
对话
identify_user() 先解析到 person_id,再把 PersonContext 填到 UserIdentity.person_context。
通道发送
ConcernChannel.resolve_target() 和 get_person_channel() 都依赖渠道绑定,不再自行拼人。
上下文组装
人物相关内容通过 person context slice 注入,不再注入整份原始主档。
八、当前原则
- 人物真源是
PersonContext - 动态工作状态单独存放在
person_work_state - 任何需要“理解某个人”的模块,都先拿
person_id - 对话上下文只注入场景切片,不直接塞全量档案
- concern 和人物档案只通过
person_id建联,不相互复制
禁止写入
- 人物档案不保存
active_concern、watch_priority、next_action - 单条普通对话不直接写入
manager_notes work_state只记录有事实依据的近期客观状态- 系统当前是否重点盯某人,属于
Agenda派生视图,不属于人物真源
统一人物工作档案的目标很简单:
系统认识一个人,只走 person_id -> PersonContext 这一条路。