[Feature] Web chat 意图识别层开发及 PR 计划列表
Web Intent 模块合入:最小 PR 拆分计划
背景 / Background
意图识别层位于 Web Chat 对话入口:把用户消息解析为结构化意图——识别其中的股票、板块、市场等主体和分析、比较、提问等意图,并处理同名歧义与无效指称;高置信结果直达下游执行,不确定的保持原样、宁可不做不可做错。预计四个 PR 递进:①名称解析基础;②分词层(六步管道切词打标);③核心解析器(意图判定与歧义确认);④SSE/API 集成(意图事件与确认闭环)。
本计划将 Web Intent 合入拆成 4 个有依赖顺序的子 PR,全部围绕 Web Intent 主目标。
拆分原则
- 只保留 Web Intent 模块及其必要依赖;
- 不包含与意图识别无关的上游测试修复;
- 每个 PR 是独立的审查与回归单元:分支自带全部依赖、可独立运行测试、diff 有界可独立 review;合入顺序受依赖约束(PR-1 → PR-2 → PR-3 → PR-4 串行),但不捆绑合入、前者合入不作废后者的评审;
PR 总览
| # | 子 PR | 核心内容 | 依赖 | 目标范围 |
|---|---|---|---|---|
| PR-1 | Web Intent 依赖:名称解析基础 | name_to_code_resolver.py 必要增强 + 单测 |
无 | 仅意图层依赖 |
| PR-2 | Web Intent 分词层 | 新增 web_intent_types.py + web_intent_tokenizer.py + 分词单测 |
PR-1 | 不接 SSE/API |
| PR-3 | Web Intent 核心解析器 | 新增 web_intent_resolver.py + 纯 resolver 单测 |
PR-1、PR-2 | 不接 SSE/API |
| PR-4 | Web Intent SSE/API 集成 | agent.py + config/env + docs + 事件流测试(含确认生命周期正确性) |
PR-1、PR-2、PR-3 | 意图事件、确认短路、pending 生命周期收敛 |
PR-1:Web Intent 依赖:名称解析基础
功能描述 / Feature Description
合入 Web Intent 所依赖的 name_to_code_resolver.py 必要能力,只做意图层需要的最小增强,不改变 Bot/导入解析等外部行为。
使用场景 / Use Case
Web Intent 解析股票名称/代码时,需要 Stock、stockDB、resolver_name_to_code_list()、US_stock_code_match()、extend_AkShare() 等基础能力。
期望实现 / Proposed Solution
Stock数据类:code / name / market;stockDB与 AkShare 扩展(缓存、失败退避、单飞锁);resolver_name_to_code_list():精确/子串/拼音/模糊匹配,跨市场排序;US_stock_code_match():仅本地库命中才返回;- 配套
tests/test_name_to_code_resolver.py单测。
备选方案 / Alternatives Considered
- 将名称解析并入 PR-2 / PR-3:会扩大 Web Intent 核心 PR 的审查面;
- 不动名称解析:Web Intent 无法稳定解析股票名称。
相关信息 / Additional Context
- 影响文件:
src/services/name_to_code_resolver.py、tests/test_name_to_code_resolver.py - 验收命令:
python -m pytest tests/test_name_to_code_resolver.py -q
PR-2:Web Intent 分词层(web_intent_types + web_intent_tokenizer)
功能描述 / Feature Description
合入 Web Intent 的数据模型层与分词管道。web_intent_types.py 采用方案A:全量随本 PR 合入,不做二次切分;合入后无任何外部行为变化(生产代码尚无调用方)。
使用场景 / Use Case
Web Chat 意图识别第一阶段:将用户输入切分为带语义标签的 Token 序列(stock_code / stock_name / subject_* / sector / time …),完成代码形提取、股票全名精确匹配、市场词消歧与多策略匹配,供 PR-3 的 resolver 消费。
期望实现 / Proposed Solution
web_intent_types.py(全量,方案A):- 分词侧:
Token、Market、全套TAG_*常量、wrong_code_tag()/unknown_code_tag()及判定函数、关键词表(_TAG_KEYWORD_LISTS_*)与正则编译函数; - resolver 侧提前量(约 100 行):
WebIntent枚举、WebIntentResolution、_EXECUTING_INTENTS、CONFIRMATION_CONFIDENCE_THRESHOLD/LLM_CONFIDENCE_CAP、RECENT_STOCKS_KEY/PENDING_ACTIONS_KEY/LAST_INTENT_KEY;
- 分词侧:
web_intent_tokenizer.py:六步分词管道(_preprocess_text)、代码形提取与库校验(_identify_stock_codes)、市场提取(_extract_markets_from_tokens)、识别率统计(_recognition_rate)等;tests/test_web_intent_tokenizer.py:离线单测,AkShare 扩展路径以最小 mock 数据覆盖,不依赖真实网络。
备选方案 / Alternatives Considered
- 方案B(types 严格二分,resolver 专属常量后置到 PR-3):职责更纯,但 PR-3 需二次修改共享文件
web_intent_types.py,stacked PR 冲突面与 rebase 成本上升; - 分词与 resolver 保持同一个 PR:单 PR 体量大,review 困难。
相关信息 / Additional Context
- 影响文件:
- 新增
src/agent/web_intent_types.py(约 470 行) - 新增
src/agent/web_intent_tokenizer.py(约 687 行) - 新增
tests/test_web_intent_tokenizer.py(约 521 行)
- 新增
- 依赖:PR-1
- 验收命令:
python -m pytest tests/test_web_intent_tokenizer.py -q
PR-3:Web Intent 核心解析器(web_intent_resolver)
功能描述 / Feature Description
合入 WebIntentResolver 主流程:基于 PR-2 的 token 序列做规则分类、LLM 兜底、多候选/低置信度确认消费,以及会话簿记与 SSE 事件构建辅助。仍不接 SSE/API(留给 PR-4)。
使用场景 / Use Case
Web Chat 需要在 Agent 执行前判断用户意图,并在多候选股票/低置信度时产出确认动作;本 PR 提供纯 Python 层的解析能力,供 PR-4 的 agent_chat_stream() 调用。
期望实现 / Proposed Solution
WebIntentResolver.resolve()主流程:消费_preprocess_text/_identify_stock_codes产物,规则优先、LLM 兜底(置信度上限LLM_CONFIDENCE_CAP);- 会话簿记:
apply_resolution_to_session()/clear_pending_actions(),recent_stocks / pending_actions / last_intent 读写; - SSE 事件构建辅助:
build_intent_resolved_event()/build_action_required_event(); - 对 tokenizer 符号的兼容 re-export(
_multi_match/_split_by_codes等); - 纯 resolver 单测,不依赖
agent.py; - 不改变
WebIntentResolver.resolve()的调用方式。
备选方案 / Alternatives Considered
- 在本 PR 内同时接入
agent.py:确认生命周期与解析核心混在一个 review,留待 PR-4; - resolver 与分词层保持同一个 PR:单 PR 体量大,review 困难。
相关信息 / Additional Context
- 影响文件:
- 新增
src/agent/web_intent_resolver.py(约 1390 行) - 新增
tests/test_web_intent_resolver.py(约 1231 行)
- 新增
- 依赖:PR-1、PR-2(stacked:base 指向 PR-2 分支,PR-2 合入后 rebase 到 main)
- 验收命令:
python -m pytest tests/test_web_intent_resolver.py tests/test_web_intent_tokenizer.py -q
PR-4:Web Intent SSE/API 集成(含确认生命周期正确性)
功能描述 / Feature Description
将 PR-3 的解析结果接入 agent_chat_stream(),新增 accepted 首事件契约、intent_resolved / action_required SSE 事件、配置开关与文档。
使用场景 / Use Case
Web Chat 需要在 Agent 工作前展示意图状态;歧义或低置信度时先请求用户确认,再决定是否进入执行。确认流程在正常与失败路径下都必须有清晰、可回归的生命周期。
期望实现 / Proposed Solution
agent.py在prepare_turn()前调用WebIntentResolver.resolve(),并保持accepted为首事件;- 非确认分支:发送
intent_resolved,注入web_intent/ 主股票代码; - 确认分支:按序发送
accepted → intent_resolved → action_required → done,短路返回; - 新增
AGENT_WEB_INTENT_ENABLED配置与.env.example; - 同步
docs/agent-stream-events.md/docs/CHANGELOG.md; - 仅纳入本链路必需的
stock_scope.py/executor.py最小改动:让确认轮resolved_stock_codes能参与作用域推导与上下文渲染,不并入独立的多股作用域 PR; - 集成验收边界(不是独立功能):确认生命周期必须完整,包含
prepare_turn()失败、确认分支失败、意图层降级、会话簿记失败等路径; - 统一不变量:每一轮 accepted 后,无论成功、失败、降级、被拒,旧 pending action 都必须随本轮关闭;
- 回归测试:确认失败只能以
error终态结束,且失败后的无关消息不得再触发confirmation消费。
备选方案 / Alternatives Considered
- 把失败路径清理当作后续独立 PR:会让引入 pending_action 的 PR 自带已知 blocker;
- 只在
prepare_turn()异常处加一行清理:无法覆盖所有失败路径; - 在 resolver 侧忽略所有旧 pending:会破坏正常确认消费。
相关信息 / Additional Context
- 影响文件:
api/v1/endpoints/agent.pysrc/agent/stock_scope.py(仅确认轮作用域所需字段与覆盖逻辑)src/agent/executor.py(仅确认轮比较标的渲染)src/config.py.env.exampledocs/agent-stream-events.mddocs/CHANGELOG.mdtests/test_agent_chat_intent_stream.pytests/test_agent_chat_api.py(accepted 首事件契约调整)tests/test_agent_executor.py(确认轮作用域/渲染回归)
- 依赖:PR-1、PR-2、PR-3
- 验收命令:
python -m pytest tests/test_agent_chat_intent_stream.py tests/test_agent_chat_api.py tests/test_agent_executor.py -q
建议合入顺序
PR-1 名称解析基础(Web Intent 依赖)
↓
PR-2 分词层(types 全量 + tokenizer)
↓
PR-3 Web Intent 核心解析器(resolver)
↓
PR-4 SSE/API 集成(含确认生命周期)
明确排除项
- 不包含与 Web Intent 无关的上游测试修复;
- 不包含独立扩展
stock_scope.py/executor.py的多股作用域 PR; - 不包含 FAQ / full-guide / 其他业务模块文档同步;
- 不将 Bot 路由、导入解析等外部调用方纳入本次合入范围。
最终目标
web_intent_resolver.py拆成 types / tokenizer / resolver 3 个模块,分词层与解析器各自独立成 PR,单文件与单 PR 审查面显著下降;- Web Intent 按 4 个 PR 顺序合入,每个 PR 可独立回归;
- 确认生命周期在 PR-4 内完整收敛,不遗留已知 blocker;
- 与 main 的冲突逐个 PR 解决,不再集中爆发。
Source: ZhuLinsen/daily_stock_analysis