代码实现:
src/intent/(IntentCategory/IntentRegistry/TOOL_ACTION_MAP) 运行时观测:GET /api/intents(返回完整分类体系 + 工具映射)
action.query)。具体词作为某意图的证据词库集中在注册表里维护,新增场景只需扩充证据词,无需改匹配分支。business(需处理)还是 social(纯社交、跳过)。social 下再分子型(致谢/确认/道别/礼貌),仅用于语义细分与日志观测,不改变”跳过”判定。DEFAULT_INTENTS 注册一个 IntentCategory;新增工具 = 在 TOOL_ACTION_MAP 加一行。都不需要改匹配分支。business 与 social 互斥(命中 business 即不归 social),由 classify_disposition 的优先级裁决。| 类别 | 父 | 语义边界(核心语义) | 典型触发条件 |
|---|---|---|---|
business 业务意图 |
— | 消息包含可被助手处理的行动意图(提问/请求/指令),或涉及工作/生活领域的具体内容,需要响应或执行操作。与 social 互斥。 | 含疑问词(什么/怎么/为什么/多少/哪);含请求动词(帮我/排查/创建);命中领域关键词(审批/天气/文档/股价…);或较长非套话消息 |
social 社交意图 |
— | 消息仅为礼节性社交交换(致谢/确认/道别/问候/称赞/寒暄/情绪感叹),不含任何需执行或回答的请求/问题/指令。助手应跳过(或极简回应)。 | 短消息且命中社交词表、且不含 business 证据 |
↳ social.gratitude 致谢 |
social | 表达谢意、认可对方付出,无后续行动诉求 | 含感谢类词(谢谢/感谢/辛苦了/蟹蟹/thx)+ 长度 ≤ 阈值;注:仅在剥离尾部礼貌语后判定,「请求 + 谢谢」整体归 business |
↳ social.acknowledge 确认收到 |
social | 确认已读/知晓,无新请求或问题 | 含确认类词(收到/好的/OK/明白/嗯,短英文词边界匹配防误命中品牌名)+ 长度 ≤ 阈值;超长降级为 business |
↳ social.closing 结束语 |
social | 表达结束对话、暂时离开 | 含道别类词(再见/拜拜/晚安/先这样/收工/回头聊) |
↳ social.polite 招呼/礼貌 |
social | 问候、客套、引起注意或致歉,无实质请求 | 含招呼/客套词(你好/在吗/请问/抱歉/哈喽/早)+ 短消息 |
↳ social.compliment 称赞/夸奖 |
social | 对助手或他人的成果、能力表达赞许、惊叹,无后续执行诉求 | 含赞许类词(厉害/太棒了/666/yyds/牛啊)+ 长度 ≤ 阈值 |
↳ social.smalltalk 闲聊/寒暄 |
social | 无明确诉求的日常寒暄、近况询问、拉家常,不指向任何需执行的任务 | 含寒暄类词(在忙吗/最近好吗/吃饭了吗)+ 长度 ≤ 阈值 |
↳ social.emotion 情绪/感叹 |
social | 情绪化感叹、笑叹、吐槽式表达(大笑/无语/服了),无执行诉求 | 含情绪感叹类词(哈哈/无语/服了/emo/破防)+ 长度 ≤ 阈值 |
优先级裁决(保证互斥):
business>social.gratitude>social.polite>social.compliment>social.acknowledge>social.smalltalk>social.emotion>social.closing> 默认business。 注:polite早于acknowledge是为了让”你好”这类问候优先归为礼貌而非被单字”好”误判为确认收到(修复原实现的一个跳过 bug);compliment早于acknowledge是为了让”可以啊”这类赞许优先归为称赞而非被”可以”误判为确认收到。所有社交子型的长度阈值默认由pure_thank_max_length(20)驱动(closing 用pure_closing_max_length,acknowledge 用pure_ack_max_length)。 此外,社交子型判定前会先做尾部礼貌语剥离(_strip_polite):「请求 + 谢谢」整体归business;「收到,谢谢」剥离后核心为「收到」→ 归acknowledge(不被谢谢翻成致谢);纯致谢(剥离后核心为空)仍归thank_you。详见下方处置层第 3 步。
行动意图彼此正交、可共存(一条消息可同时是
query+communicate),不做互斥约束。
| 类别 | 语义边界 | 典型触发条件 |
|---|---|---|
action.query 信息查询 |
获取已有信息/状态/数据,无副作用(天气/搜索/知识库/文档/通讯录/日历/审批/考勤/未读/消息记录/组织/系统状态等读取类) | 含查询/搜索/了解/疑问词,或指向某类可读信息(天气/审批/考勤/文档/股价…) |
action.execute 执行操作 |
创建/修改/发送/触发,产生状态变更或副作用 | 含发送/创建/新建/安排/设置/提交/上传/提醒/预约/办理/开通等动作动词 |
action.analyze 分析生成 |
对已有信息总结/对比/分析,或生成新内容(草稿/归纳/复盘) | 含总结/概括/分析/对比/生成/起草/整理/归纳/提炼/复盘等 |
action.communicate 通讯会话 |
与人的消息往来、会话管理(发消息/看未读/查会话/搜记录/@某人) | 涉及给人发消息、查看/检索会话与消息记录、@ 提醒等 |
action.media 媒体处理 |
上传或处理图片/文件/语音/视频等媒体素材 | 涉及上传图片/文件、发送截图/语音/视频、媒体操作 |
TOOL_ACTION_MAP(src/intent/)是新增/调整工具时的唯一改动点。
| 工具 | 服务意图 |
|---|---|
| send_message | action.execute, action.communicate |
| save_memory | action.analyze |
| recall_memory | action.query, action.analyze |
| web_search / get_weather / kb_search | action.query |
| search_doc / get_doc_content / search_contact | action.query |
| get_calendar_events / get_attendance / approval_get_detail / approval_list_pending | action.query |
| get_my_profile / list_orgs / get_current_org | action.query |
| system_status / message_stats / keyword_rules | action.query |
| config_manage | action.query, action.execute |
| get_unread / get_conversation_info / search_messages | action.query, action.communicate |
| create_todo / send_ding | action.execute (+ send_ding: action.communicate) |
| upload_image | action.execute, action.media |
rule_engine → IntentRegistry.classify_disposition)businessbusiness 证据 → business(覆盖社交)business 而非被一个「谢谢」翻盘成 social.gratitude 跳过。剥离只认末尾、不动句首的「请 / 麻烦」等请求助词。
business(business 优先级高于 social)。social 子型(基于剥离后的核心),受长度阈值约束;acknowledge 超长降级为 businessbusinessagent._keyword_match_tool_names)intent_keywords)→ 仅据此精准判定(主要信号,保证 smart 路由精确性)smart 模式:命中相关工具则精准暴露;无命中回退全量(交给主模型自选,保证不漏)keyword 模式:命中则暴露,无命中回退 FALLBACK;all 模式:恒全量config.intent_filter 中的关键词/阈值(business_keywords / thank_you / acknowledge / closing / polite / pure_thank_max_length / pure_ack_max_length)仍可通过 IntentRegistry.apply_intent_filter 覆盖默认证据词,运维无需改代码即可调整意图识别。intent_keywords(具体场景词)保留为精准匹配信号,抽象意图层作为补充与文档化载体。代码实现:
src/decision_tracker.py(DecisionRecord/DecisionTracker) 持久化:src/memory/sqlite_store.py—decisions表
每条消息的处理决策都会被记录,形成可追溯、可查询的决策时间线。
| 字段 | 类型 | 说明 |
|---|---|---|
ts |
datetime | 决策时间戳 |
sender |
str | 发送者名称 |
sender_id |
str | 发送者 ID |
chat |
str | 会话名称 |
conversation_id |
str | 会话 ID |
content |
str | 消息内容预览(截断至 100 字符) |
intent |
str | 意图分类结果(如 business、social.gratitude) |
action |
str | 处理动作:skip(跳过) / reply-rule(关键词规则) / llm(LLM处理) |
routing_mode |
str | 工具路由模式:smart / all / keyword |
routed_tools |
list[str] | 本轮暴露给 LLM 的工具名称列表 |
reply_preview |
str | 回复预览(截断至 100 字符) |
tracker.record(...)
├─ 写入进程内 deque(maxlen=300,近实时展示,重启清空)
└─ 写入 SQLite decisions 表(持久化,重启不丢失)
└─ 支持按 sender/intent/action 多维度筛选
tracker,在 src/platform/ 中通过 tracker.set_sqlite_store(store) 注入存储后端record() 方法同时写入内存队列和 SQLite,持久化写入失败不阻塞主流程recent(n) 方法从内存读取,供首页卡片近实时展示| 场景 | action | 携带信息 |
|---|---|---|
| 意图过滤跳过(社交意图、黑名单、免打扰等) | skip |
intent, sender, conversation, content |
| 关键词规则直接回复 | reply-rule |
intent, sender, conversation, content, reply_preview |
| 交给 LLM 处理 | llm |
intent, sender, conversation, content, routing_mode, routed_tools, reply_preview |
GET /api/decisions 从内存队列读取,每 5 秒轮询刷新)GET /api/decisions/history),支持按发送者/意图/动作筛选,含概览统计卡片和决策列表GET /api/decisions/stats 获取各维度计数分布