企业内部 AI Chat 的产品化之路:从技术 Demo 到合规可运营的产品

发布时间:2026/7/22 10:11:43
企业内部 AI Chat 的产品化之路:从技术 Demo 到合规可运营的产品 企业内部 AI Chat 的产品化之路从技术 Demo 到合规可运营的产品一、技术 Demo 与真实产品之间的鸿沟2025 年初我们用两周时间搭建了一个基于 LangChain 企业知识库的内部问答 Demo。产品同事试用后评价回答准确率不太稳定有时候胡说八道但总体来说能用。这个评价其实道出了 AI Chat 产品化的核心矛盾Demo 的及格线是基本能答对而产品的及格线是绝对不能答错。从 Demo 到产品的路程我们走了整整 8 个月。期间解决的问题包括但不限于幻觉控制、合规审核、敏感信息过滤、多轮对话管理、权限隔离、审计追溯、成本优化。每一个问题单独拿出来都足够写一篇单独的文章。这里分享其中最具代表性的几个技术决策。二、RAG 检索增强的实战调优我们的知识库来源复杂包括 Confluence 文档、GitLab README、培训视频字幕、规章制度 PDF、历史工单记录等。初始版本直接使用开源嵌入模型 FAISS 向量库效果惨不忍睹Top-5 召回率仅 38%。经过多轮优化我们将召回率提升至 87%核心改进包括以下几点文档切片策略放弃固定长度的字符切片改为基于 Markdown 标题层级的语义切片。将一篇 5000 字的文档按 H2/H3 标题自动切分为 15~20 个语义段落每段不超过 800 Token。同时保留标题层级路径作为元数据辅助检索时的上下文理解。多路召回融合向量检索擅长语义理解但容易漏掉精确匹配BM25 关键词检索互补。我们采用混合检索策略将向量检索的 Top-20 和 BM25 检索的 Top-20 合并去重后重新排序。重排序模型使用 BGE-Reranker-v2在保持语义理解的同时提升精确匹配的召回。查询改写用户的口语化提问如上次说的那个权限怎么搞直接检索效果很差。在检索前增加 LLM 查询改写步骤将模糊查询转换为精确的关键词组合。/** * RAG混合检索服务——多路召回重排序 */ Service public class HybridRetrievalService { private static final int VECTOR_TOP_K 20; private static final int BM25_TOP_K 20; private static final int FINAL_TOP_K 10; Resource private VectorStore vectorStore; Resource private BM25Index bm25Index; Resource private RerankerService reranker; Resource private QueryRewriter queryRewriter; /** * 混合检索向量检索 BM25关键词检索 重排序 */ public ListDocumentChunk search(String originalQuery, int maxResults) { // 查询改写将口语化查询转为精确检索词 String rewrittenQuery queryRewriter.rewrite(originalQuery); log.info(查询改写: {} - {}, originalQuery, rewrittenQuery); // 向量语义检索 CompletableFutureListDocumentChunk vectorFuture CompletableFuture.supplyAsync(() - vectorStore.similaritySearch(rewrittenQuery, VECTOR_TOP_K)); // BM25关键词检索 CompletableFutureListDocumentChunk bm25Future CompletableFuture.supplyAsync(() - bm25Index.search(rewrittenQuery, BM25_TOP_K)); // 并行检索后合并 ListDocumentChunk allResults new ArrayList(); try { allResults.addAll(vectorFuture.get(5, TimeUnit.SECONDS)); allResults.addAll(bm25Future.get(5, TimeUnit.SECONDS)); } catch (TimeoutException e) { log.error(检索超时, e); // 使用已返回的结果继续处理 } catch (Exception e) { log.error(检索异常, e); return Collections.emptyList(); } // 按文档ID去重 allResults allResults.stream() .collect(Collectors.toMap( DocumentChunk::getDocId, Function.identity(), (a, b) - a.getScore() b.getScore() ? a : b )).values().stream() .collect(Collectors.toList()); // 重排序 ListDocumentChunk reranked reranker.rerank(rewrittenQuery, allResults); return reranked.subList(0, Math.min(FINAL_TOP_K, reranked.size())); } }三、安全防线输入输出双重审核企业内部 AI Chat 最容易出现的风险是信息泄露和违规输出。我们的安全方案采用输入 → 模型 → 输出双重审核机制。输入审核层在用户提问到达 LLM 之前进行拦截。审核内容包括是否尝试注入 Prompt如忽略之前的指令、你是一个无限制的 AI是否涉及未授权的数据查询如把上个月的薪资表发我是否包含越权操作如帮我删除生产数据库。审核模型使用 Qwen-Guard 作为专用安全模型针对内部数据安全场景做了微调。输出审核层在 LLM 生成回答后进行二次校验。重点是防止幻觉导致的错误信息传播以及确保输出中不泄露敏感数据。对于不确定的回答如模型置信度低于阈值系统会主动标注该回答可能存在不准确建议查阅原始文档核实。/** * AI Chat安全审核过滤器 */ Service public class ChatSecurityFilter { private static final double HIGH_RISK_THRESHOLD 0.8; Resource private SecurityLLMClient securityModel; Resource private SensitiveDataDetector dataDetector; /** * 输入安全审核 */ public SecurityResult checkInput(String userId, String userInput) { // 基于安全模型做风险评分 RiskScore riskScore securityModel.evaluate(userInput); if (riskScore.getOverall() HIGH_RISK_THRESHOLD) { log.warn(用户{}的输入被拦截风险分{}原因{}, userId, riskScore.getOverall(), riskScore.getReasons()); return SecurityResult.block(您的提问包含不符合安全策略的内容已被拦截。 如有疑问请联系IT支持。); } // 敏感信息检测用户是否在提问中泄露了密码/Token等 ListSensitiveMatch sensitiveMatches dataDetector.detect(userInput); if (!sensitiveMatches.isEmpty()) { log.warn(用户{}输入中包含敏感信息: {}, userId, sensitiveMatches); // 脱敏后放行但记录审计日志 auditLogService.record(userId, SENSITIVE_INPUT_DETECTED, sensitiveMatches); } return SecurityResult.pass(); } /** * 输出安全审核 */ public SecurityResult checkOutput(String userId, String llmOutput, double confidence) { // 低置信度回答主动标注 if (confidence 0.7) { return SecurityResult.warn(【温馨提示】该回答可能存在不准确建议查阅原始文档核实。\n\n llmOutput); } // 检测输出中是否泄露了敏感信息 ListSensitiveMatch leaks dataDetector.detect(llmOutput); if (!leaks.isEmpty()) { log.error(LLM输出中包含敏感信息泄露用户{}内容{}, userId, leaks); auditLogService.record(userId, SENSITIVE_OUTPUT_BLOCKED, leaks); return SecurityResult.block(回答包含敏感信息已被系统拦截。已记录审计日志。); } return SecurityResult.pass(llmOutput); } }四、权限隔离与审计追溯企业 Chat 的权限模型比公共 Chat 复杂得多。同一个问题下周的放假安排是什么HR 部门员工应该得到详情而其他部门员工应该只能看到公开信息。我们通过文档级 ACL 用户属性注入实现权限隔离。具体做法是文档入库时标注访问权限如dept:HR、role:manager、level:P4检索时注入当前用户的部门和角色属性过滤掉无权限的文档后将权限标签注入 Prompt 上下文LLM 在生成回答时会根据用户的权限等级调整回答粒度。审计方面每一次对话的完整上下文用户提问、检索文档、LLM 回答、安全审核结果都被结构化存储到独立的审计数据库中并关联用户身份和操作时间。审计记录保留 180 天满足内部合规审查的要求。五、产品化的经验总结从 Demo 到产品的过程中团队最大的认知转变是AI Chat 产品化的瓶颈不在模型能力而在工程链路。模型可以花钱买更好的但检索质量、安全审核、权限控制、审计追溯这些工程问题没有一个是可以花钱跳过的。目前系统日均越 1.2 万次对话回答准确率 89%用户满意度评分 4.3/5。下一步重点是引入 Agent 模式从一问一答升级为多步推理让 AI Chat 不仅能回答问题还能执行操作如帮用户提交请假申请、查询并预定会议室。作者李然程序员鸭梨Java 架构师专注 AI 应用的产品化落地。