评审日期:2026-05-27
评审范围:views/document_chat、core/document_chat、相关config配置文件
评审重点:AI 对话功能的代码结构层级、文件组织、职责边界与后续可维护性
当前 AI 对话功能的整体分层方向是合理的,主链路也比较清楚:
HTTP 接口层 views/document_chat
-> 工作流编排层 core/document_chat/workflows
-> 业务组件层 core/document_chat/component
-> 技能层 core/document_chat/skills
-> 基础设施层 foundation / Milvus / LLM
从现在只有 document-answer 和 document-modify 两个技能的规模来看,当前结构可以支撑功能运行和短期维护。
但如果后续继续扩展更多技能、检索策略、SSE 事件或复杂对话能力,现有结构会逐渐变重。主要风险集中在两个文件:
core/document_chat/component/retrieval_service.pycore/document_chat/workflows/document_chat_workflow.py这两个文件已经承担了较多职责,是后续重构的优先位置。
综合评价:7/10。
文件:views/document_chat/views.py
主要职责:
/sgbx/document_chat 接口。callback_task_id。document_chat_workflow。调用入口:
POST /sgbx/document_chat
GET /sgbx/document_chat/health
文件:core/document_chat/workflows/document_chat_workflow.py
主要职责:
核心流程:
validate_input
-> 无选中章节: general_answer -> complete
-> 有选中章节: load_context
-> load_skill_registry
-> recognize_intent
-> route_intent
-> clarify -> complete
-> unsupported -> complete
-> answer/modify
-> build_retrieval_query
-> vector_recall
-> rerank_context
-> quality_gate
-> run_answer_skill / run_modify_skill
-> complete
文件:
core/document_chat/schemas.pycore/document_chat/component/state_models.pyschemas.py 定义 API 请求、响应、技能输入输出等结构:
DocumentChatRequestIntentResultDocumentChatSkillInputDocumentChatSkillOutputDocumentChatDataDocumentChatResponsestate_models.py 定义 LangGraph 内部状态:
DocumentChatState整体上,API schema 和 workflow state 分开是合理的。
目录:core/document_chat/component
主要文件:
| 文件 | 当前职责 |
|---|---|
intent_recognizer.py |
LLM 意图识别和启发式兜底 |
skill_dispatcher.py |
加载技能 YAML,分发到技能 handler |
retrieval_service.py |
Query 构建、多路召回、RRF 融合、候选清洗、scope 过滤 |
rerank_service.py |
对召回结果做重排 |
retrieval_quality_gate.py |
过滤低质量参考资料 |
conversation_context.py |
对上下文做轻量整理 |
prompt_loader.py |
加载 prompt 配置 |
llm_utils.py |
JSON 提取、模型输出解析等工具 |
document_chat_logger.py |
文档对话结构化日志 |
目录:core/document_chat/skills
当前技能:
document-answerdocument-modify实现文件:
document_answer.pydocument_modify.pybase.py配置文件:
skills/document-answer/skill.yamlskills/document-modify/skill.yaml当前做法是:YAML 描述技能元信息,Python 文件实现具体能力,SkillDispatcher 负责加载和分发。
相关文件:
config/document_chat_retrieval.yamlconfig/prompt/document_chat_intent.yamlconfig/prompt/document_answer_prompt.yamlconfig/prompt/document_modify_prompt.yaml检索参数和 prompt 外置是合理的,方便调参和迭代提示词。
从接口到工作流,再到组件和技能,方向比较明确。阅读 document_chat_workflow.py 可以快速理解 AI 对话功能的完整执行路径。
工作流并不直接写死问答和修改的全部实现,而是通过 SkillDispatcher 调用具体技能。后续新增技能时,理论上可以沿用 YAML + handler 的方式扩展。
当前 RAG 链路包括:
这个流程划分是清楚的,比直接把向量库结果全部塞进 LLM 更稳。
检索阈值、召回数量、prompt 都放在配置文件中,便于调参,不需要频繁改业务代码。
SkillDispatcher 中的 _HANDLER_CLASSES 是显式白名单,比从 YAML 中任意动态 import 更安全,也更容易追踪依赖。
component 层职责偏杂component 当前包含了服务类、工具函数、状态模型、日志工具、prompt loader、检索核心算法等多类内容。
短期可以接受,但长期来看,component 会越来越像杂物层。建议逐步拆成更明确的子包:
core/document_chat/
application/
workflows/
retrieval/
skills/
events/
schemas.py
retrieval_service.py 过重文件:core/document_chat/component/retrieval_service.py
该文件当前承担了较多职责:
这已经不是单一 service,而是完整的 retrieval 子系统。后续如果要调某一路召回,很容易影响整个文件。
建议拆分为:
core/document_chat/retrieval/
config.py
query_builder.py
service.py
fusion.py
scope.py
candidate.py
keyword_extractor.py
retrievers/
parent_vector.py
child_locator.py
tag.py
chapter_similarity.py
document_chat_workflow.py 偏重文件:core/document_chat/workflows/document_chat_workflow.py
该文件当前同时承担:
建议把图定义和节点实现拆开:
core/document_chat/workflows/
graph.py
nodes.py
response_mapper.py
其中:
graph.py 只负责 LangGraph 节点和边。nodes.py 负责节点逻辑。response_mapper.py 负责 state -> response data。general_answer 没有进入技能体系当前:
document-answer 是技能。document-modify 是技能。general_answer 直接写在 workflow 中。这会导致能力扩展模式不一致。
建议把通用回答也做成技能:
core/document_chat/skills/general-answer/
skill.yaml
core/document_chat/skills/general_answer.py
这样工作流只负责路由,不直接内联 LLM 调用。
文件:views/document_chat/views.py
当前 SSE 事件构建依赖这些节点名:
recognize_intentrerank_contextquality_gaterun_answer_skillrun_modify_skillgeneral_answer如果 workflow 节点名调整,前端事件逻辑也要跟着改。
建议后续让 workflow 或事件转换层输出标准事件,例如:
DocumentChatEvent(
type="retrieval_result",
payload={...}
)
views 层只负责把事件格式化为 SSE。
schemas.py 中定义了:
DiffItemDiffResultDocumentChatData.old_content_hashDocumentChatData.new_content_hashDocumentChatData.diffDocumentChatData.diff_granularitystate_models.py 中也有:
diff_result但当前 workflow 没有实际生成和回填 diff 结果。
这说明有部分字段可能是预留或遗留设计。建议确认前端是否仍需要这些字段:
一个更适合后续扩展的结构可以是:
core/document_chat/
__init__.py
schemas.py
workflows/
graph.py
nodes.py
response_mapper.py
retrieval/
config.py
query_builder.py
service.py
fusion.py
scope.py
candidate.py
keyword_extractor.py
quality_gate.py
rerank_service.py
retrievers/
base.py
parent_vector.py
child_locator.py
tag.py
chapter_similarity.py
intent/
recognizer.py
skills/
base.py
dispatcher.py
document_answer.py
document_modify.py
general_answer.py
document-answer/
skill.yaml
document-modify/
skill.yaml
general-answer/
skill.yaml
events/
sse_mapper.py
observability/
logger.py
utils/
llm_output.py
prompt_loader.py
这不是必须一次性完成的重构目标,可以按风险和收益逐步迁移。
收益最大,风险可控。
建议顺序:
RetrievalConfig 和 load_retrieval_config 到 retrieval/config.py。retrieval/query_builder.py。retrieval/scope.py。retrieval/fusion.py。retrieval/retrievers/。DocumentChatRetrievalService 作为编排入口。建议顺序:
to_response_data 到 response_mapper.py。_build_skill_input 到单独 mapper 或 factory。nodes.py。graph.py 只负责定义节点和边。建议把 general_answer 也做成技能,避免 workflow 内联 LLM 调用。
确认 diff 字段是否仍属于对话功能的稳定契约:
将前端事件构建从 views.py 中移出,避免接口层直接感知 workflow 内部节点名。
如果短期不做结构重构,至少建议做到:
retrieval_service.py 中堆大段逻辑。views/document_chat/views.py 的 SSE 事件映射。DocumentChatData 字段时,同步确认前端消费逻辑。intent_recognizer、retrieval_quality_gate、rerank_service、skill_dispatcher 增加单元测试。当前代码结构不是乱的,主干清楚、功能边界已有雏形,适合继续迭代。
真正需要警惕的是:retrieval_service.py 和 document_chat_workflow.py 已经开始承担子系统级职责。继续扩展时,如果不拆分,这两个文件会成为后续维护、测试和排查问题的主要成本点。
建议后续重构从检索层开始,因为它体量最大、职责最多,而且拆分后对工作流和 API 的外部行为影响最小。