企业内部 AI Chat 的产品化之路:从技术 Demo 到合规可运营的产品
2026/7/22 10:11:29 网站建设 项目流程

企业内部 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 List<DocumentChunk> search(String originalQuery, int maxResults) { // 查询改写:将口语化查询转为精确检索词 String rewrittenQuery = queryRewriter.rewrite(originalQuery); log.info("查询改写: {} -> {}", originalQuery, rewrittenQuery); // 向量语义检索 CompletableFuture<List<DocumentChunk>> vectorFuture = CompletableFuture.supplyAsync(() -> vectorStore.similaritySearch(rewrittenQuery, VECTOR_TOP_K)); // BM25关键词检索 CompletableFuture<List<DocumentChunk>> bm25Future = CompletableFuture.supplyAsync(() -> bm25Index.search(rewrittenQuery, BM25_TOP_K)); // 并行检索后合并 List<DocumentChunk> 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()); // 重排序 List<DocumentChunk> 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等 List<SensitiveMatch> 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); } // 检测输出中是否泄露了敏感信息 List<SensitiveMatch> 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:HRrole:managerlevel:P4+),检索时注入当前用户的部门和角色属性,过滤掉无权限的文档后,将权限标签注入 Prompt 上下文,LLM 在生成回答时会根据用户的权限等级调整回答粒度。

审计方面,每一次对话的完整上下文(用户提问、检索文档、LLM 回答、安全审核结果)都被结构化存储到独立的审计数据库中,并关联用户身份和操作时间。审计记录保留 180 天,满足内部合规审查的要求。

五、产品化的经验总结

从 Demo 到产品的过程中,团队最大的认知转变是:AI Chat 产品化的瓶颈不在模型能力,而在工程链路。模型可以花钱买更好的,但检索质量、安全审核、权限控制、审计追溯这些工程问题,没有一个是可以花钱跳过的。

目前系统日均越 1.2 万次对话,回答准确率 89%,用户满意度评分 4.3/5。下一步重点是引入 Agent 模式,从"一问一答"升级为"多步推理",让 AI Chat 不仅能回答问题,还能执行操作(如帮用户提交请假申请、查询并预定会议室)。


作者:李然(程序员鸭梨),Java 架构师,专注 AI 应用的产品化落地。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询