Skip to content

企微组织架构识别

清海接入企业微信环境的第一步:通过企微通讯录 API 认识公司每个人,为后续所有业务场景提供身份基础。 角色维度的会话旅程见 角色场景,能力定义见 Skill 清单


背景与现状

企业微信(WeCom)是腾讯旗下的企业协同工具,在制造业、零售、金融等传统行业有较高渗透率。清海需要通过企微通讯录建立组织感知能力。与飞书/钉钉的核心差异在于:企微的消息回调支持两种模式——普通自建应用(XML 格式,FromUserName)和智能机器人(JSON 格式,from.userid);通讯录变更同样支持事件回调,但事件字段体系与钉钉有所不同。

维度说明
数据源企微通讯录 API(qyapi.weixin.qq.com
接入方式企业自建应用(推荐)或智能机器人
用户识别自建应用消息 FromUserName(XML)、智能机器人 from.userid(JSON),均为企业内 userid
同步策略每日全量同步一次 + 通讯录变更事件实时补偿
存储MongoDB unified_users 集合 + PersonIndex 内存索引 + 本地缓存 data/cache/wecom_contacts.json

企微 API 核心鉴权

参数说明
corpid企业 ID,管理后台「我的企业 → 企业信息」
corpsecret应用密钥,各应用独立(「应用管理 → 应用」中查看)
access_token调用凭证,通过 corpid + corpsecret 换取,有效期 7200 秒,每应用独立获取
GET https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
返回:{ "access_token": "xxx", "expires_in": 7200 }

⚠️ access_token 有效期 2 小时,建议提前 5 分钟刷新并全局缓存,避免每次请求前重复获取。

已实现 vs 待实现

能力状态说明
企微通讯录同步⬜ 待实现需新建 WeComSync.sync_contacts()
PersonIndex 内存索引✅ 复用已有实现,扩展 channels.wecom 即可
PersonContextResolver✅ 复用已有实现
身份自动识别⬜ 待实现需适配 FromUserName / from.useriduserid 匹配
search_contacts 工具✅ 复用底层 PersonIndex 相同,无需改动
别名学习 / 平台绑定✅ 复用save_contact_alias + link_platform_identity
通讯录变更事件接收⬜ 待实现企微特有,需配置回调服务器
access_token 自动刷新⬜ 待实现企微特有,飞书/钉钉已有类似逻辑可参考
权限过滤⬜ 待实现与飞书版本一致,按角色分层

当前设计方式

本场景组织架构识别在系统层自动完成,AI 通过通用工具 search_contacts 查询人员信息。

企微消息进来

avatar_core.identify_user()

PersonContextResolver.resolve_by_channel("wecom", userid)  ← 从 unified_users 读组织信息

system prompt Block 1: "你正在和张三对话,他是技术部的后端工程师"  ← 身份注入

AI 对话(如果用户问组织问题)

AI 调用 search_contacts(query="技术部", department=...)  ← 组织查询工具

PersonIndex.search() → 返回结果

场景与能力总览

企微组织架构识别覆盖 4 大会话场景

场景 → 能力映射表

场景触发方式需要的能力企微 API
身份自动识别收到任意消息时自动触发通讯录同步 + PersonIndex + userid 解析GET /cgi-bin/user/get?userid=USERID
组织架构查询用户主动询问PersonIndex 部门查询GET /cgi-bin/department/list?id=1
人员信息查询用户主动询问PersonIndex 人员查找 + PersonContextGET /cgi-bin/user/list?department_id=1
人员变动感知企微事件回调(实时)+ 每日全量同步兜底通讯录变更事件 + 定时同步Event=change_contactChangeType=create_user/update_user/delete_user

场景一:身份自动识别

核心价值:员工在企微发消息时,清海自动知道对方是谁,带入身份认知。

两种接入模式对比

企微有两种主要接入模式,消息格式不同:

接入模式消息格式用户 ID 字段推荐场景
自建应用(配置接收消息)XMLFromUserName通用场景,权限更完整
智能机器人(AI 机器人)JSONfrom.userid对话交互场景,配置简单

两种模式的 userid 值相同,均为企业内唯一标识。

识别流程(自建应用模式)

消息 ID 字段

自建应用(XML)

xml
<xml>
  <ToUserName><![CDATA[企业微信CorpID]]></ToUserName>
  <FromUserName><![CDATA[zhangsan]]></FromUserName>  <!-- 即 userid -->
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[消息内容]]></Content>
  <MsgId>1234567890123456</MsgId>
  <AgentID>1</AgentID>
</xml>

智能机器人(JSON)

json
{
  "msgid": "CAIQrcjMjQYY...",
  "aibotid": "AIBOTID",
  "chattype": "single",
  "from": { "userid": "zhangsan" },
  "response_url": "RESPONSEURL",
  "msgtype": "text",
  "text": { "content": "消息内容" }
}

存储字段(unified_users.channels.wecom

来自 GET https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=TOKEN&userid=USERID

企微 API 字段存储位置用途
useridchannels.wecom.userid消息身份匹配主键(= FromUserName / from.userid
namedisplay_name显示名称
departmentchannels.wecom.department所属部门 ID 列表
positionchannels.wecom.position职位
is_leader_in_deptchannels.wecom.is_leader是否部门主管(数组,对应每个部门)
direct_leaderchannels.wecom.direct_leader直属上级 userid(数组,支持多上级)
statuschannels.wecom.status1=已激活,2=已禁用,4=未激活,5=退出企业
telephonechannels.wecom.telephone手机号(需申请权限)
hire_datechannels.wecom.hire_date入职时间

关键约束

  • FromUserName / from.userid 在企业内唯一且稳定,识别准确率 100%
  • 企微回调消息经过 AES 加密,需先用 Token + EncodingAESKey 解密
  • status=5(退出企业)→ is_active=False,消息静默处理
  • 企微 response_url(智能机器人模式)每次仅可使用一次,有效期 1 小时

场景二:组织架构查询

核心价值:自然语言查询公司组织结构,不用打开企微通讯录。

典型对话

用户问法清海应答需要的能力
"公司有哪些部门"列出所有部门(名称 + 人数)部门列表查询
"技术部有谁"列出技术部全部成员(姓名 + 职位)部门成员查询
"技术部下面有几个组"列出子部门结构子部门ID列表 + 递归
"前端组几个人"返回人数 + 成员列表部门成员查询

企微 API 数据来源

查询类型企微 API关键参数
全量部门列表GET /cgi-bin/department/listid=1(根部门);返回所有层级,同步用
子部门 ID 列表GET /cgi-bin/department/getid性能更优,仅返回 id/parentid/order
部门成员详情GET /cgi-bin/user/listdepartment_id,支持 fetch_child=1 包含子部门成员
部门返回字段id(整数)、namename_endepartment_leader(数组)、parentidorder
成员返回字段useridnamepositiondepartment(数组)、direct_leaderis_leader_in_dept

关键约束

  • 企微根部门 id = 1(与钉钉相同,飞书是 "0"
  • 部门名支持模糊匹配:「技术」→「技术部」
  • 兼职/多部门人员以 department[0] 主部门为准
  • department/list 接口性能较低,建议只在同步时调用;实时查询走 PersonIndex 内存

场景三:人员信息查询

核心价值:快速了解某人的部门、职位、上下级关系。

典型对话

用户问法清海应答需要的能力
"张三是什么部门的"张三的部门 + 职位search_contacts(query="张三")
"张三的上级是谁"direct_leader 字段直接返回上级 useridquery_person_relations
"李四管哪些人"李四的直属下属列表PersonIndex 逆向关联查询
"小明是谁"模糊匹配结果(可能多个)search_contacts(query="小明")

上级关系查询流

关键约束

  • direct_leader 字段支持多上级(数组),同步时保存完整列表
  • is_leader_in_dept 为数组,与 department 字段一一对应,标识该用户在各部门中是否为主管
  • 人名模糊匹配:PersonIndex 支持部分名、别名

场景四:人员变动感知

核心价值:实时感知入职、离职、调岗,保持组织数据准确。

变动类型与处理

变动类型企微事件 (Event=change_contact)ChangeType清海处理
新员工入职成员变更create_user自动创建 unified_users 记录 + 更新 PersonIndex
员工信息变更成员变更update_user更新字段,保留别名等非企微数据
员工离职/退出成员变更delete_useris_active=False + 消息静默
新增部门部门变更create_party触发该部门成员同步
部门信息变更部门变更update_party更新部门名/层级 + 重建索引
部门删除部门变更delete_party将该部门成员设为无部门 + 等待全量同步
标签成员变更标签变更update_tag更新标签关联,按需更新 PersonIndex

事件推送格式(加密 XML)

企微事件回调采用 XML 格式,且消息内容经过 AES 加密:

xml
<xml>
  <ToUserName><![CDATA[企业微信CorpID]]></ToUserName>
  <Encrypt><![CDATA[加密内容,解密后得到事件 XML]]></Encrypt>
</xml>

解密后的成员新增事件示例:

xml
<xml>
  <ToUserName><![CDATA[企业微信CorpID]]></ToUserName>
  <FromUserName><![CDATA[sys]]></FromUserName>
  <CreateTime>1403610513</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[change_contact]]></Event>
  <ChangeType>create_user</ChangeType>
  <UserID><![CDATA[zhangsan]]></UserID>
  <Name><![CDATA[张三]]></Name>
  <Department><![CDATA[1,2]]></Department>
  <Position><![CDATA[后端工程师]]></Position>
</xml>

双重保障策略

回调服务配置

企微管理后台:应用 → 接收消息 → 设置API接收,填写 URL / Token / EncodingAESKey,勾选「通讯录变更」事件类型。

配置项说明
URL公网可访问的 HTTPS 回调地址
Token用于计算签名(自定义字符串)
EncodingAESKey43 位字符,用于 AES 消息加密/解密

关键约束

  • 企微通讯录数据为权威源(authoritative_sync),覆盖推断和观察数据
  • 同步时保留 aliases、平台绑定等非企微来源数据
  • 企微回调消息必须验证签名后才能处理(防伪造)
  • 事件推送的 UserIDdelete_user 事件)可能只有 userid,需结合缓存还原完整信息

角色权限与场景覆盖

不同角色在各场景中的可见范围不同,详见 角色场景

角色 × 场景矩阵

场景老板部门负责人员工
身份自动识别全员信息全员信息仅自己(系统自动)
组织架构查询全公司架构 + 人员明细全公司架构 + 本部门人员明细全公司架构(公开信息)
人员信息查询全员详细信息本部门个人信息 + 其他部门公开信息仅自己的信息
人员变动感知全公司变动本部门变动仅自己相关

⚠️ 当前状态:权限过滤尚未实现,所有用户可查所有数据。


与飞书/钉钉版本的核心差异

维度飞书钉钉企业微信
用户主键open_idou_ 开头)useridsenderStaffIduseridFromUserName / from.userid
Bot 消息格式JSONJSONXML(自建应用)/ JSON(智能机器人)
消息加密无加密无加密AES 加密(必须先解密)
Token 获取POST + app_id + app_secretGET/POST + AppKey + AppSecretGET + corpid + corpsecret每应用独立 token
Token 有效期最长 2 小时2 小时7200 秒(2 小时)
部门根节点parent_department_id=0dept_id=1id=1
部门主管字段通讯录 leader_user_idleader_in_deptdepartment_leader(数组)+ is_leader_in_dept(数组)
直属上级字段需额外查询manager_useriddirect_leader(数组,支持多上级)
事件变更同步定时轮询(30 分钟)事件订阅(实时)事件回调(实时)
通讯录事件字段user_add_org / user_leave_orgchange_contact + ChangeType

复用能力与全局约束

复用的现有能力、全局约束详见 Skill 清单 — 复用的现有能力Skill 清单 — 全局约束

Boss-AGI · 超级 AI 企业助理