wanghanlin
|
2001dc3a0f
|
fix(doc): 修复重新处理文档会按 2000 字截断预览重建导致内容丢失
问题
- knowledge_document.content 上传时被截断到 2000 字符(有意的预览设计),
但 reprocessDocument 把它当原文重建分块,而 DocumentProcessingService 以
cleanBeforeFirstAttempt=true 运行(先删光旧向量)——对超过 2000 字符的文档
执行 POST /document/batch/reprocess 会永久丢失其余内容
修复
- content 改存原文全文(列已是 TEXT,无需 DDL),并写 extra_config.contentComplete
作为完整性标记
- 实体 content 加 @JsonIgnore:全文任何接口都不返回(否则 GET /document/list
无字段投影,每行都会带上整篇正文);文档详情接口单独组装响应,返回 2000 字预览
(键名仍是 content)与 contentTruncated 标志,前端据此提示截断
- reprocessDocument 的数据源按优先级解析:
1) 有 contentComplete 标记 → 用库内全文(语义最忠实,JSON 的 fields/pointer
模式不受影响,也不依赖文件是否还在)
2) 历史遗留文档(无标记,content 是截断预览)→ 按 fileType 从原始文件重解析
(md → MarkdownDocumentLoader,json → JsonDocumentLoader,其余 → Tika),
成功后回填全文并打标记,此后不再依赖原始文件
3) 两者都不可用 → 明确报错拒绝,绝不静默按截断预览重建
无法完整还原时在标记 PROCESSING 之前抛错,事务回滚,文档状态与已有向量都不受影响
- contentTruncated 判据覆盖历史数据:长度恰好等于上限且无 contentComplete 标记时
同样判定为已截断,避免把截断预览误报成完整内容
- 同步 content 列注释(DatabaseInitConfig / init-database.sql / knowledge-base.sql),
该注释会在下次启动幂等刷新到库
验证(真实库 + 557 篇存量文档环境)
- 上传 4891 字符正文:库内存全文,详情接口返回 2000 字预览 + contentTruncated=true
- 重新处理:chunk_count 与首次完全一致(修复前会降为个位数),内容无丢失
- 模拟历史数据(截断 + 无标记):有文件时从文件重解析成功并回填全文;
文件也丢失时明确拒绝,且文档状态与 chunk_count 保持不变(向量未被破坏)
- 回填后再删文件重跑仍成功(已自愈);GET /document/list 不再含 content
- RAG 对话回归正常
已知降级
- JSON 的 basic/fields/pointer 解析模式上传时未持久化,历史 JSON 文档从文件重解析
只能按 basic 还原(不丢数据,仅抽取口径可能变化,日志有 WARN)
- 存量中疑似被截断的文档需重跑一次才能回填全文(均已保留原始文件,均可恢复)
|
2 days ago |
wanghanlin
|
84eea7564f
|
refactor: 自造轮子改用 Spring AI 标准组件、清理死代码并修复既有缺陷
组件替换(改用 1.1.x 标准组件)
- 文档提取:删除自写 TikaDocumentReader(内部直接 new org.apache.tika.Tika()),
改用官方 org.springframework.ai.reader.tika.TikaDocumentReader。
pom 早已引入 spring-ai-tika-document-reader 却从未使用其类,属典型「引了标准依赖却手写实现」
- 意图识别:IntentRouter 的手写正则解析(含去 BOM/零宽字符/全角空格等约 60 行防御逻辑)
改用标准 BeanOutputConverter<IntentResult>,保留原有降级语义(空输入/解析失败 → RAG)
- 推荐问题:SuggestionGenerator 的哨兵字符串 + 代码块剥离 + 按行降级解析改用
ChatClient.entity(ParameterizedTypeReference<List<String>>),整体删除 SuggestionResponseParser
- 分块:删除 MyTokenTextSplitter 薄壳,新增 OverlapTokenTextSplitter
分块器 overlap 缺陷修复(本次验证中发现并修复)
- 旧实现把 knowledge.chunk.overlap 传进了 TokenTextSplitter 第 2 个形参 minChunkSizeChars 位,
overlap 从未生效(Spring AI 的 TokenTextSplitter 根本没有 overlap 形参)
- 新实现继承标准 TextSplitter,复刻 TokenTextSplitter 全部切分语义,仅把前进步长改为
chunkSize - overlap,使重叠真正生效
- 验证中发现:标点截断会缩短本块消耗的 token 数,与 overlap 叠加后可把前进步长压到
1 个 token,分块数膨胀 10 倍(实测 349 块 vs 修复后 44 块)。故仅当截断后仍能前进
至少 (chunkSize - overlap) / 2 个 token 时才采用该截断,否则宁可切断句子
- overlap=0 时与标准 TokenTextSplitter 逐块一致(已对比验证)
- ⚠️ 存量文档需重新分块 + 重新向量化(POST /document/batch/reprocess),否则新旧向量口径混杂
其他既有缺陷修复
- RerankerService:原用 new RestTemplate() 且无任何超时,慢 provider 会把检索线程拖到
TCP 超时;改用 RestClient + JdkClientHttpRequestFactory 显式设置 connect/read 超时(各 3s)
- McpServerConfigController:MCP Server 增删改/启停/全量刷新后未清 AssistantApp 的
ChatClient 缓存,导致继续使用旧工具集;现补调 clearCache()
死代码清理(均已 grep 确认零引用)
- 删除 FileBasedChatMemory、ReReadingAdvisor(零装配且 before() 逻辑为 no-op)、
SseEventBuilder(零引用)、SuggestionResponseParser
- McpToolCallback 删除 EVENTS ThreadLocal 与 drainEvents()/resetEvents()(零调用),
保留在用的 MCP_EVENTS_KEY/MCP_ROUNDS_KEY ToolContext 机制
文档
- 同步更新 CLAUDE.md / README.md / DEPLOY.md 的版本号、组件说明与架构描述
- 修正 CLAUDE.md 中与代码不符的既有描述:主启动类并未排除 PgVectorStoreAutoConfiguration
(项目用的是非 starter 坐标,classpath 上本就没有该自动配置);分类过滤实现已完成,
原「Spring AI filter 支持有限」的 TODO 已不成立
|
3 days ago |
wanghanlin
|
d0cd06f9fc
|
fix(document): 修复批量上传向量化只成功小文档问题并加固处理链路
- 移除逐 chunk 串行 AI 关键词提取(MyKeywordEnricher):产出 excerpt_keywords 全库无检索消费点,却将外部调用放大 chunkCount 倍且与在线对话共用模型抢限流
- 向量化改按批入库(默认 50 块/批, knowledge.vector.batch-size)逐批 try-catch 隔离:失败批只记录缺失区间继续,已入库块保留,error_message 聚合"已入库 x/y 块+缺失区间+原因",chunk_count 改为实际入库块数
- 新增文档级失败自动整体重试(≤2 次, 仅 timeout/429/5xx 等瞬时错误):重试前清残留向量防重复;处理期间删除文档即终止写入避免孤儿向量;外层兜底保证状态不悬挂 PROCESSING
- Embedding 客户端(DashScope/OpenAI 兼容/豆包多模态)补显式 connect 10s/read 60s 超时,避免慢响应无限挂起占死 documentExecutor 线程
- 文档同步 CLAUDE.md/README.md,新增 knowledge.vector.batch-size 配置说明
|
1 week ago |
wanghanlin
|
f06422d5e9
|
docs: 补充开发规范与踩坑记录
- 列表排序字段白名单、vector_store 物理删除、数据库初始化幂等自愈、Java 文本块拼 SQL 等规则
|
2 weeks ago |
wanghanlin
|
3038cd0387
|
fix(security): CORS 拆分为 SDK 开放与管理白名单双轨
修复 9338fcb 收紧 CORS 白名单后引发的线上 403 回归:
将 corsConfigurationSource 与 addCorsMappings 拆分为两套配置——SDK 第三方接入接口
(/ai/**、/category/tree、/category/list、/feedback、/attachment/upload)开放 allowedOriginPatterns("*"),
管理后台接口保持 allowed-origins 白名单防 CSRF;并在 application-prod.yml 白名单补上线上域名
https://aidoc.dgscdw.com:11300,同时记录 CORS 双轨制踩坑规范。
|
3 weeks ago |
wanghanlin
|
2fe322aa7d
|
完成「LLM 调用追踪面板」开发
|
4 weeks ago |
wanghanlin
|
4438545693
|
TDesign 术语对齐
|
4 weeks ago |
wanghanlin
|
fc1193c4f3
|
完成了 AI 执行链流程图的 5 项差异修正,并建立了三层持续同步机制(CLAUDE.md 规则 + Stop Hook + JavaDoc 标记)
|
1 month ago |
wanghanlin
|
91c4c185b3
|
重构(AI对话): 统一对话管道,收敛接口形态,补齐Open API能力
|
2 months ago |
wanghanlin
|
14c5ccf6ab
|
、API Key 绑定客服角色、编写 SDK 集成文档
|
2 months ago |
wanghanlin
|
d95c921227
|
重构配置页面,对标cc-switch三要素设计,新增动态模型列表获取
|
2 months ago |
wanghanlin
|
250f643a42
|
,修复了分块查询、状态切换和批量操作三个核心问题
|
2 months ago |
wanghanlin
|
09d8b909cf
|
修复用户管理功能异常,并将教训更新到文档
|
2 months ago |
wanghanlin
|
cdaff49533
|
优化前端操作交互体验。
ai大模型配置错误不影响启动服务。
去除后台系统提示词,直接使用前端角色设定提示词。
|
2 months ago |
wanghanlin
|
f7eb0bfaf1
|
feat(P0): 完成阶段一全部需求 — 混合检索/内容安全/用户反馈/FAQ精准匹配
P0-001 混合检索+重排序引擎:
- HybridSearchService 支持 VECTOR/KEYWORD/HYBRID 三种检索模式
- RrfFusion RRF 融合算法 (k=60)
- RerankerService 支持 DashScope + OpenAI 兼容多提供商
- vector_store 新增 content_tsvector 列 + GIN 索引 + 触发器
- DocSearch.js 增加检索模式下拉选择
P0-004 内容安全过滤:
- ContentSafetyService DFA 字典树引擎(volatile + copy-on-write 线程安全)
- ContentSafetyAdvisor BaseAdvisor 实现,输入/输出双向审核
- SensitiveWordService 敏感词 CRUD + 批量导入 + 字典树热加载
- SensitiveWordManager.js 前端管理组件
P0-002 用户反馈系统:
- MessageFeedbackService upsert 语义反馈提交 + 统计 API
- ChatPanel.js 添加 👍/👎 反馈按钮
- Chat SDK handleFeedback() 对接后端 POST /feedback
- ConversationService 导出集成反馈信息
P0-003 意图识别+FAQ精准匹配:
- IntentRouter LLM 意图分类(FAQ/RAG/CHITCHAT)
- FaqMatchEngine 三级匹配(精确→关键词→向量语义,阈值 0.85)
- FaqService FAQ CRUD + 异步向量化
- FaqManager.js 前端管理(CRUD + 批量导入/导出 + 启用/禁用)
共享变更:
- DatabaseInitConfig 新增 5 张表 + 全文检索初始化
- api.js 新增反馈/敏感词/FAQ API 封装
- app.js 注册 SensitiveWordManager + FaqManager 组件
- application.yml 新增 knowledge.faq.semantic-threshold 配置
|
3 months ago |
wanghanlin
|
8e586a8c35
|
求移除未使用的 PRODUCT_EXTRACT(商品信息抽取)类型配置
|
3 months ago |
wanghanlin
|
26d6f9823b
|
增加项目数据库初始化sql
增加前端模型配置校验
设置默认向量维度为1024(豆包模型低向量维度)
|
3 months ago |
wanghanlin
|
476e34f704
|
ChatSDK完善客服 SDK 的页面样式与交互功能。两轮共落地 13 项改进(快捷问题、暗色模式、停止生成、消息反馈、a11y等)
增加开发、生产配置文件
增加部署文档DEPLOY.md
|
3 months ago |
wanghanlin
|
ed3f3b3070
|
豆包多模态向量模型能正常工作
|
3 months ago |
wanghanlin
|
c4af6699cf
|
把嵌入模型支持从仅千问扩展到多厂商。前端限制、后端自动覆盖
|
3 months ago |
wanghanlin
|
f79350c363
|
完成了模型配置管理页面(5家AI提供商集成+运行时动态切换)
|
3 months ago |
wanghanlin
|
e1fc0b023a
|
二期-修复文件上传bug
|
3 months ago |
wanghanlin
|
6f861fcf79
|
二期-文档列表完善批量操作、上传校验、去重、分块配置与上传进度功能
|
3 months ago |
wanghanlin
|
cff087fad0
|
一期-前端重构
|
3 months ago |
wanghanlin
|
54f6da84c8
|
一期-雪花算法生成的 Long 类型 ID(18-19 位数字)超过 JavaScript 安全整数范围(2^53-1),JSON
反序列化时精度丢失,导致前端显示和传参的 ID 与数据库中不一致。
|
3 months ago |