首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
AI应用架构重构实录:从获客工具到开源Web交互层的技术转型
📅 2026/9/24 23:13:32
✍️ 爱科研究院
👁 阅读 3,247
大概半年前我们做了一个在外人看来有点败家的决定把一个已经上线运行一年多、攒了几十家付费客户、代码量接近十万行的 AI 获客工具整体推倒重写变成一个开源的 Web AI 交互层。当时团队的反对声不少产品同学直接问我客户要的是能带来线索的机器人你要给人家一个开发框架这句话听着扎心但恰恰戳中了原项目的命门——我们其实一直没有一个清晰的定位。这篇文章想讲的不只是我们重写了什么更是我们为什么必须重写。如果你正在做 AI 应用、正准备开源自己的项目或者纠结于手里这套代码到底要不要重构这里面的思考过程和踩坑记录应该能帮你省下一些弯路。1. 旧版获客工具的问题清单我们到底在哪些地方忍不下去了先交代一下旧项目的背景。我们最早做的是一套 AI 获客工具核心功能是让企业把聊天机器人挂到微信、企业微信、网页上自动做售前答疑、线索筛选和人工交接。从功能上看它确实能跑客户也有续费但我心里清楚这套东西的架构已经快撑不住了。1.1 业务逻辑和模型能力被绑死在同一个代码库里旧项目用的是 Python FastAPI代码结构扁平得一塌糊涂。会话状态、线索清洗规则、话术模板、模型调用 API、数据库访问全部揉在一个目录里。客户要新增一个 IM 渠道我们得同时改路由层、消息解析层、会话状态层任何一个地方漏了线上就出问题。最典型的一个场景某客户希望机器人先判断用户是不是高意向线索再决定要不要转接人工。这个逻辑听起来很简单但在旧架构里它横跨了消息入口、意图分类、线索评分、转接调度四个模块每个模块之间靠全局变量传状态。有一次为了给一个客户加地域判断规则我们不小心影响到了另一个客户的话术匹配对方直接投诉到 CEO 那边。这种耦合带来的隐性成本远比我们以为的高。1.2 模型接入方式写死换模型等于伤筋动骨旧版代码里对模型供应商的调用是散落在各业务函数里的。当时接了三家模型服务商每一家的参数格式、流式返回结构、限流策略都不一样于是代码里到处都是if provider A然后又elif provider B这样的分支。最初我们只接一家时还好但后来发现不同模型在不同场景下表现差异极大——有的适合做意图识别有的擅长长文本总结有的响应速度快适合闲聊。我们想把哪个模型处理哪个环节做成可配置的结果发现每做一次模型切换都要翻出核心业务代码来改测试一遍全量回归上线后还要胆战心惊盯几天。模型接入和业务逻辑强耦合导致我们根本不敢尝试新模型这在 2024 年那个模型能力快速迭代的背景下等于自断后路。1.3 Web 端被当成二等公民体验一直没做对旧产品的主战场是 IM 渠道Web 聊天界面是后面临时补的——用 iframe 嵌一个页面样式跟主站完全脱节刷新加载慢长连接经常断。但过去一年我们发现了一个趋势越来越多的客户想在官网放一个 AI 助手而不是只放在 IM 里。官网访客没有微信/企业微信好友关系他们打开页面就想直接问问题对加载速度、视觉一致性、移动端适配的要求比 IM 渠道高得多。我们曾经花了两周去优化 Web 端的长连接稳定性结果发现根源是 WebSocket 服务没有做心跳保活和断线重连。这种问题在 IM 渠道里不突出因为微信那边会自己维护连接但浏览器端的网络环境复杂得多用户锁屏、切换 WiFi、后台休眠都会断开连接。旧架构里 Web 端是后补的底层设计根本没考虑这些场景修起来牵一发动全身。1.4 配置体系薄弱运营改一句话都要提工单旧项目的提示词、话术模板、知识库关联规则全部写在配置文件和数据库表里但管理界面极其简陋。运营人员想给机器人加一句欢迎语都得在群里我们开发我们改了再发版。有一次客户的活动页需要临时改一套话术我们排期排了三天活动都结束了话术才上线。更难受的是很多企业客户根本理解不了提示词这个概念。你让他自己写一段 prompt他写出来的东西往往质量很差。这说明一个问题产品不够面向非技术用户配置复杂度全在代码层。我们明明做了一个 AI 产品却让用户连最简单的调整都要依赖工程师这不是产品该有的样子。这些问题积累了大半年之后我们开了一次复盘会。讨论的结论出乎所有人意料不是怎么修补而是要不要推倒重写。2. 重写前的定位推演AI 交互层到底解决什么问题推倒重写这四个字在工程领域一向被视为禁忌。没有哪个成熟的工程师会轻易支持重写因为业务在跑、客户在等、时间在烧。但那次会上我们想明白了一件事旧项目的天花板不在代码质量而在产品定位。2.1 从帮客户获客到让客户自己接入 AI获客工具的逻辑是企业提供话术、知识库、线索规则机器人去执行然后把线索捞回来。这个逻辑本身没问题但它把应用场景锁死了——只有获客这一件事。而实际上企业里需要 AI 交互的地方太多了售前咨询、售后客服、内部知识问答、HR 面试筛选、技术支持分类每一个场景的交互模式和数据结构都不一样。如果我们继续做获客工具我们就永远是一家做漏斗的 SaaS 公司客户群有限、客单价有限、想象力也有限。但如果把它重构成一层AI 交互层定位就完全变了我们不再替客户定义你的 AI 应该用来做什么而是提供一个基础设施让客户自己决定怎么接、怎么用。一句话概括新定位模型给你编排逻辑给你Web 交互组件给你你只需要接上自己的业务数据和应用场景。2.2 为什么优先级最高的是 Web而不是继续深耕 IM渠道选择上我们把 Web 提到了最高优先级这个决策当时有争议。IM 渠道看似流量大但开发成本极高——每个平台的消息协议、回调机制、审核要求都不一样而且很多平台的机器人能力是受限的。Web 的优势在于通用分发成本最低一个script标签嵌进去任何网站都能拥有一个 AI 助手不需要通过平台审核。浏览器能力完整WebSocket 长连接、Service Worker 离线推送、IndexedDB 本地缓存、多媒体输入输出该有的都有。与企业现有系统融合容易绝大多数企业的客服后台、CRM、工单系统都是 Web 应用交互层作为 Web 组件可以嵌入任意系统而不是要求用户去另一个 IM 里使用。说白了Web 是 AI 助手的最大公约数。我们不可能为一个 IM 平台写一套交互层那样又回到了旧版的老路。2.3 开源是护城河不是慈善定位为交互层之后代码要不要开源的争论就变得很自然了。如果我们是卖获客工具开源等于自毁商业但如果我们做的是通用基础设施闭源反而会增加信任成本——企业凭什么是把你的 SDK 嵌到官网里它怎么知道你的代码有没有在后台上传它的用户数据开源解决了这个问题。代码放出来安全团队可以自己审计同时也降低了集成门槛开发者不再需要先注册你家的控制台、申请 API Key、看冗长的文档他可以先 clone 下来本地跑通再决定要不要用你的托管服务。护城河从来不是靠藏着代码建立的而是靠生态、兼容性、社区贡献和行业默认选择建立的。这个定位想清楚之后重写就有了骨架。我们停下来花了三周把架构重新设计了一遍然后才开始动工。3. 交互层架构落地的四个核心模块新项目用 TypeScript 全栈前端 React后端 Node.jsNestJS数据库 PostgreSQL Redis。技术选型的原因后面细说先讲四个核心模块的设计思路它们是整个交互层的支柱。3.1 模型网关统一抽象避免被单一供应商锁死模型网关是整套系统的地基。不管后面接多少个模型业务层永远只面对一个统一的接口。// 统一模型适配器接口 interface ModelAdapter { chat(messages: ChatMessage[], options?: ChatOptions): PromiseChatResponse; stream(messages: ChatMessage[], options?: ChatOptions): AsyncIterableChatChunk; } // OpenAI 兼容协议适配器 class OpenAICompatibleAdapter implements ModelAdapter { async chat(messages: ChatMessage[], options?: ChatOptions) { // 调用任何支持 OpenAI 兼容协议的服务 } async *stream(messages: ChatMessage[], options?: ChatOptions) { // 流式返回 } } // 本地模型适配器vLLM / Ollama 等 class LocalLLMAdapter implements ModelAdapter { // ...实现各自的流式协议 }核心思想是适配器模式。业务层只依赖ModelAdapter这个抽象接口具体走哪家模型由配置文件和环境变量决定。这样做的直接收益是我们可以在不同模型之间自由切换同一个会话中用户问产品报价可能走的意图识别模型 A用户问售后政策可能走的对话生成模型 B而业务代码一行都不用改。模型网关还承担了另外两个职责一是统一限流和重试策略不同模型的速率限制差异很大在网关层统一做指数退避和熔断比在业务层到处补异常处理优雅得多二是统一日志和可观测性每个请求的模型名、token 消耗、延迟、错误码都打成结构化日志方便后期做成本分析和质量监控。3.2 会话与上下文管理token 预算才是对话质量的关键做 AI 助手的同学都有体会模型本身能力差距其实没那么大真正拉开体验差距的是你怎么把上下文喂给它。旧项目按消息条数硬截断只保留最近 20 条超出就丢掉导致模型经常失忆回答质量堪忧。新架构里我们建立了严格的 token 预算体系上下文组成部分预算分配以 32k 窗口为例系统提示词4k tokens工具/函数定义2k tokens可用的对话历史20k tokens预留输出空间6k tokens对话历史的组织不再按条数而是按 token 预算动态裁剪。核心逻辑是优先保留最近的对话最早的消息如果超出预算则用一段摘要替换而不是直接丢掉。function buildContext(conversation: Message[], budget: number): Message[] { let tokens 0; const result: Message[] []; // 从最近的用户消息开始往回拼装 for (let i conversation.length - 1; i 0; i--) { const msg conversation[i]; if (tokens msg.tokens budget) { break; } result.unshift(msg); tokens msg.tokens; } // 如果还有剩余空间把最早的几条合并成摘要 if (tokens budget * 0.7 conversation.length 10) { const summary generateSummary(conversation.slice(0, 5)); return [summary, ...result]; } return result; }这里有一个容易被坑的细节不同模型的 token 计算方法不一样。有的模型用 BPE 分词有的用字符级 token直接用len(text) / 4去估算会导致预算严重失真。我们的做法是让模型网关在适配器层返回真实的 token 计数业务层只认这个值避免各模块自己算导致的口径不一致。3.3 插件/工具调用机制交互层最重要的扩展点如果模型网关是地基插件机制就是承重墙。企业在自己的场景里接入 AI 助手十有八九需要让它调用现有系统——查订单、查库存、创建工单、查询 CRM 记录。这些能力不可能由我们内置必须通过插件暴露出去。插件机制的实现借鉴了 Koa 的洋葱模型app.use(async (ctx, next) { // 请求前钩子可以改写用户上下文、注入系统信息 ctx.state.injectDate new Date().toISOString(); await next(); // 响应后钩子可以改写模型输出、记录日志 });每个插件就是一个中间件函数可以在请求发出前修改上下文拿到模型结果后再做后处理。比如某个客户想让机器人回答之前自动查一下公司最新的产品库存他只需要写一个插件在请求前调用库存接口把结果注入到系统提示词里模型就知道了最新库存状态。这里必须提醒一句插件机制越强大安全边界越要谨慎。我们最初的设计过于开放允许插件代码在服务进程内任意执行结果在做安全测试时发现一个被投毒的第三方插件完全可以读取服务器上的任意文件。后来我们改了设计插件只能通过声明式的 JSON Schema 定义工具参数运行时把工具调用放在独立的沙箱进程中执行并对每个插件的文件系统、网络、环境变量访问做好权限隔离。3.4 前端 Web Chat Widget可嵌入是传播的前提模型网关和会话管理再好用户接触到的还是那个聊天气泡。所以我们把前端 Chat Widget 当成一个独立产品来做而不是顺便写个页面。它的核心要求只有一个任何网站加一行脚本就能跑起来。script srchttps://cdn.example.com/chat-widget.js>
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/24 23:08:31
基于CNN的恶意软件检测:从exe转灰度图到模型训练全流程
2026/9/24 23:08:31
存算分离架构实战:从对象存储到数据湖高效整合
2026/9/24 23:08:31
VS Code+NumPy 环境配置:从虚拟环境到自动提示全攻略
2026/9/25 1:03:42
前端DOM完全指南:从节点操作、渲染性能到虚拟DOM与事件流
2026/9/25 1:03:42
中兴B863AV3.2-M机顶盒线刷全攻略:原理、实操与救砖
2026/9/25 1:03:42
Go2机器狗搭载Livox Mid360的Ubuntu 20.04全栈适配指南
2026/9/25 1:03:42
Keil4与Keil5双版本共存配置实战指南
2026/9/25 1:03:42
Edge浏览器supercopy插件:解除网页复制限制的完整指南
2026/9/25 0:03:37
深度学习新闻分类推荐系统:从TextCNN到个性化推荐
2026/9/25 0:03:37
AI元人文:从工具使用到思维重构的深度探索
2026/9/25 0:03:37
Python+CNN车牌识别实战:从数据预处理到模型训练与部署
2026/9/25 0:03:37
Vim基础操作全攻略:保存退出、模式切换与高频命令实战
2026/9/23 19:31:10
深入解析Transformer多头注意力机制与工程优化
2026/9/23 19:31:10
OpenClaw 的 Skills 跑学习任务,模型通道改到 TaoToken 通道行不行?
2026/9/23 19:31:09
ChatGPT报错Oops, an error occurred! 全链路排查指南