基于Vue3与UniApp的全端AI问答助手实现方案与踩坑实录
2026/9/14 9:38:38 网站建设 项目流程

最近在给产品搭一个统一的AI问答入口,要求能同时跑在微信小程序、H5网页和App三个端上。核心功能其实不复杂:一个聊天式的智能问答助手,能渲染Markdown和数学公式,还要支持上传图片做多模态识别交互。这种需求在Vue生态里做单端很容易,但一旦要求全端覆盖,很多坑就冒出来了。折腾了几天,我决定用Vue3 + UniApp来实现这套方案,把之前的Web端经验直接复用过去,整体落地的过程虽然有不少摩擦,但结果还是值得的。这篇文章就把完整技术方案、选型思考、实现细节和踩坑实录记录下来,给打算做类似全端AI助手的同学一个可以直接抄作业的参考。

先交代一下项目边界:目标是做一个面对用户的智能问答助手,形态是沉浸式聊天界面,要求支持流式输出、Markdown渲染、LaTeX公式展示、图片上传并参与多模态理解。平台覆盖微信小程序、H5以及iOS/Android App。由于产品设计希望三个端交互完全一致,所以没有选择分别开发原生或Web版本,而是直接押注在UniApp上。下面从架构设计开始,逐步拆解整个实现过程。

1. 项目背景与整体设计

1.1 为什么选择Vue + UniApp而不是其他方案

这几乎是每个全端项目都要先回答的问题。对比过React Native、Flutter和原生三端开发,最终选UniApp的核心原因有三条:第一,团队已经熟悉Vue,Vue3的组合式API写起来效率很高;第二,UniApp对小程序、H5、App的编译支持成熟,一套代码能覆盖大部分业务场景;第三,AI问答助手这类应用以文本交互为主,不依赖重原生能力,跨端性能瓶颈不明显。

当然也要诚实说它的短板:复杂的自定义原生组件、高性能画布渲染、独立的原生动画,这些在UniApp里做起来会有些别扭。但我们的业务核心是文本流、Markdown渲染和图片上传,UniApp完全能接住。如果你做的是类似ChatGPT客服这类界面型应用,选UniApp是性价比很高的路线。

1.2 沉浸式交互的定义与功能拆解

“沉浸式”这个词说起来虚,但在产品层面是可落地的。我把它拆成了四个可度量的子需求:

  • 视觉统一:三端微信小程序、H5、App界面看起来几乎没有差异,使用同一套设计语言、动效和暗黑模式。
  • 交互连续:输入、发送、流式接收、停止生成,整个过程流畅不闪烁,键盘弹出不遮挡输入框。
  • 内容表现力:AI返回的Markdown、代码块、公式、表格都能漂亮地呈现,而不是一堆乱七八糟的符号。
  • 多模态入口:用户可以用图片参与对话,AI能理解图片内容并基于图片继续回复。

基于这些拆解,后端接口需要支持文本对话和图片理解两条链路,前端则重点解决跨端渲染和交互一致性。后面每个部分我都会沿着这条主线展开。

1.3 技术栈清单与工程准备

我使用的技术栈清单如下:

  • 框架:Vue 3.4 + Vite + UniApp最新稳定版。
  • 状态管理:Pinia,用来存会话列表、当前对话上下文和全局设置。
  • CSS方案:SCSS + CSS变量,方便做暗黑模式切换。
  • Markdown渲染:mp-html + 自定义解析补丁,后面细说。
  • 公式渲染:H5端用KaTeX,小程序端走towxml的公式组件。
  • 请求层:封装uni.request,流式部分使用uni.connectSocket。
  • 图片处理:uni.chooseImage + 本地压缩后转Base64或临时文件路径。

工程准备上,如果团队有Vite经验,建议直接用CLI方式创建项目,而不是HBuilderX的可视化创建。原因很简单:CLI项目文件结构标准,Webpack/Vite配置可见,方便集成本地依赖和自动化流水线。当然如果你只是个人快速体验,HBuilderX上手更简单,但后面做多人协作和CI/CD会麻烦一些。

2. 工程初始化与多端配置细节

2.1 用CLI还是HBuilderX创建UniApp项目

这一步属于“看起来是小事、踩起坑来能急死人”的典型环节。我推荐Vue3 + Vite的CLI方式创建,命令如下:

npx degit dcloudio/uni-preset-vue#vite-ts my-ai-assistant cd my-ai-assistant npm install npm run dev:mp-weixin # 微信小程序运行 npm run dev:h5 # H5运行 npm run dev:app # App运行

CLI的好处是可以用npm管理插件,比如Pinia、sass、mp-html都能在package.json里统一锁版本。HBuilderX方式更适合不熟悉命令行的朋友,但它的依赖都在HBuilderX内部,一旦团队协作或者换设备,环境还原比较痛苦。

这里有个很关键的细节:UniApp的Vue3版本,在App端编译时使用Vite,小程序端还是复用uni自己的编译器。所以遇到一些第三方库兼容性问题时,要先分清是编译期还是运行期的问题,否则会白折腾很久。

2.2 manifest.json里必须关注的配置项

manifest.json是UniApp的全端配置文件,很多人会忽略它,直到真机预览出问题才回来翻。这里列几个我实际调过的关键项:

  • 微信小程序appid:在mp-weixin节点配置,不填的话很多权限和域名配置没法生效。
  • 应用名称和logo:在App端打包时需要,名称不能太随意,审核会查。
  • 网络超时配置:socket请求一定要设置合理的超时时间,流式问答经常有长时间不返回的场景。
  • 权限配置:图片上传和语音输入需要声明相机、相册、麦克风权限,尤其App端必须写在原生manifest里。
  • H5路由模式:默认是hash模式,如果想用history模式,需要后端配SEO或伪静态,一般建议AI助手用hash,省心。

实际配置中,我还在commonStyle节点做了全局主题色和导航栏颜色,这样三端从视觉上就先统一了一半。

2.3 页面结构、路由与状态管理

页面结构我用了最常规的分层方案:

  • 页面目录pages/home:欢迎页和会话列表。
  • 页面目录pages/chat:主聊天交互页。
  • 页面目录pages/settings:设置页,包含暗黑模式、字体大小、清空上下文等。
  • 组件目录components:消息气泡、输入工具栏、图片预览等组件。

路由方面,UniApp沿用pages.json配置,我用的是普通uni.navigateTo跳转,没有开pages.json里的tabBar,因为更希望聊天页有全屏沉浸式体验,而不是被底部导航固定住。如果你需要多个平级功能模块,再考虑tabBar,但AI助手这种工具类应用,单入口反而更聚焦。

状态管理使用Pinia,创建了一个useChatStore来缓存会话消息数组、当前会话ID和全局配置。特别注意一个小程序端的限制:全局状态在小程序被切换到后台一段时间后可能会被回收,所以长对话一定要做本地缓存,我用uni.setStorageSync把最近20条消息持久化,回到页面时再恢复。这部分不复杂,但能显著提升使用体验。

3. 聊天核心:消息模型与流式响应

3.1 消息数据结构和聊天页布局

先定义消息模型,这是整个聊天功能的地基。我用的结构是:

interface ChatMessage { id: string; role: 'user' | 'assistant' | 'system'; type: 'text' | 'image' | 'loading'; content: string; images?: string[]; // 用户上传的图片本地路径 createdAt: number; status?: 'pending' | 'streaming' | 'completed' | 'error'; }

这里有几个设计点需要解释:role用来区分消息归属;type除了文本,还加了image类型,用户如果只发图片不带文字,也能单独占一条消息;status非常关键,UI要根据它显示加载占位、流式光标、错误提示等不同状态。

聊天页布局比标准IM简单,因为不用考虑好友列表和群组。核心就是三个区域:顶部自定义导航栏、中间可滚动消息列表、底部固定输入工具栏。输入工具栏放了一个textarea和两个按钮,一个是图片上传,一个是发送/停止切换。

为了沉浸式效果,我把消息列表的背景做成了渐变底色,消息气泡刻意弱化边框,用轻阴影区分,整体更接近极简笔记风格,而不是传统IM气泡。

3.2 流式响应的几种方案对比与选型

AI问答助手最核心的体验就是流式输出,也就是AI说的是“打出来的”,不是等很久一下全部返回。唯有多端统一,我才选了WebSocket方案。

先说我在调研时遇到的三个方案:

  • fetch + ReadableStream:H5很好用,但小程序不支持原生的fetch流式读取,而且小程序没有ReadableStream。
  • uni.request轮询:简单,但要不停轮询,延迟高、响应慢,体验差。
  • uni.connectSocket + WebSocket:小程序、H5、App都支持,是真正的“一套代码三端跑”,虽然需要后端额外提供WebSocket接口,但这是目前最合理的全端流式方案。

我们后端的协议设计大致是:

  1. 客户端发送一个JSON消息到WebSocket,包含会话ID和用户输入。
  2. 后端收到后开始调用大模型,将回包按token拆分成多个消息帧推送回来。
  3. 每帧格式:{ type: 'token', content: '用户问', done: false }
  4. 最后发一个{ type: 'done', id: 'xxx' }帧标记结束。

WebSocket连接要注意心跳包。我每30秒发一次ping,后端要回pong,否则自动重连。还有错误处理:如果网络断掉,必须在上层做断线重连,并在UI给出提示,否则用户会以为AI卡住了。

3.3 打字机效果的实现和性能优化

打字机效果是让流式输出看起来更“自然”的关键。如果每收到一个token就立刻更新整个消息内容,在小程序端会出现两个问题:一是频繁setData导致视图频繁刷新,页面卡顿;二是用户视觉上会觉得文字跳来跳去,不连贯。

我的做法是在状态管理中维护一个displayContent,每次收到新token时,马上更新真实content,但视图层用一个定时器来“逐步放出”内容,每100ms渲染新增的3~5个字符。

// 简化版打字机逻辑 let timer = null; function typewriter(message) { const target = message.content; let len = message.displayContent.length; timer = setInterval(() => { len += Math.ceil((target.length - len) / 10); message.displayContent = target.slice(0, len); if (len >= target.length) clearInterval(timer); }, 60); }

这个方案的好处是视觉效果平滑,而且原始终端频繁setData的压力被限制在了每秒10次左右。实测iPhone中端机型和安卓千元机都能稳定不掉帧。不过需要注意,定时器在App端切换到后台会被挂起,所以我还在页面onHide时清除定时器,等回到前台再重新恢复渲染。

另外一个细节:消息列表一定要用scroll-viewscroll-into-view属性,在流式输出过程中实时滚动到底部。直接用scrollTop在Web端没问题,但在小程序端有渲染层和逻辑层通信延迟,会造成“追不上文字”的滞后感。用scroll-into-view绑到最后一条消息的id,实测更跟手。

4. Markdown、代码高亮与LaTeX公式的全端渲染

4.1 小程序里不能直接用v-html,那怎么办

这是全端AI助手遇到的最大坑。在H5端,v-html可以直接渲染服务端下发的HTML,但小程序没有DOM,根本没有v-html这个概念。第三方库必须专门处理成模板字符串或自定义组件。

常见的跨端Markdown方案有:

  • mp-html:一个支持小程序、H5、App的富文本组件,可以渲染解析后的HTML字符串,内置了很多扩展节点。
  • towxml:专门为小程序设计的MD解析库,支持MathJax和代码高亮,但对H5支持稍弱。
  • uni-app的rich-text组件:只支持少量节点和样式,不能满足复杂Markdown和公式。
  • 自己写解析器:只适合极简场景,渲染数学公式和表格时工程量太大。

经过权衡,我选择了“mp-html + 自定义补丁”的方案。理由是通过mp-html渲染基础Markdown转HTML,同时我用calculator扩展组件去处理公式标签,这样能兼顾三端兼容性和开发效率。

4.2 选型对比:mp-html还是towxml

为了讲清楚差异性,我做了一个小表格对比:

方案平台支持Markdown支持LaTeX公式代码高亮自定义节点社区活跃度
mp-html小程序/H5/App较弱(需转HTML)需扩展内置一部分
towxml主要小程序/H5较好支持支持
rich-text小程序/H5极弱不支持不支持官方

我为什么没无脑选towxml?虽然它公式支持好,但它在App端偶尔会出现样式错乱,而且对最新Vue3的响应式处理不太友好。mp-html更像一个基础组件,灵活性更高,我可以控制整个渲染管线的每一个环节。

具体思路是:后端返回Markdown源码,前端用markdown-it统一转成HTML字符串,再对这个HTML做两层处理。第一层,把$$...$$$...$公式提取出来,替换成自定义标签<formula>内容</formula>;第二层,用mp-html渲染时,对formula标签进行自定义插件处理。这样公式既能正确显示,又不影响其余Markdown渲染。

4.3 公式渲染的兼容方案与H5/小程序差异

公式渲染是很多AI问答项目里最容易被低估的部分。如果AI返回的内容涉及数学、物理或金融公式,普通文本渲染会完全乱套。

在H5端,我直接用KaTeX的DOM渲染,性能很好,渲染速度快。但到了小程序端,问题就来了,小程序不能动态执行JavaScript库去操作DOM,所以我用自定义组件模拟了一个公式渲染器:后端在返回Markdown时,如果识别到公式,直接返回一个svg图片地址或base64图片,前端放进<image>标签渲染。

这个“把公式变成图片”的方案在小程序端非常稳定,虽然不如图形化渲染灵活,但胜在兼容性强,而且对用户来说视觉上很清晰。App端我也沿用这套思路,统一通过mp-html的formula标签解析成图片URL。

如果你有更极致的公式排版需求,可以考虑在小程序端集成wx-towxml的公式功能,但要做好样式调试的准备。我的经验是:先保证能显示,再考虑效果,公式图片是性价比最高的起步方案。

4.4 自定义样式让渲染结果更有“沉浸感”

Markdown渲染成HTML后,默认样式往往不美观。沉浸式体验需要一套精心调过的排版风格。我定义了一套全局CSS变量,包括正文颜色、背景色、链接色、代码块配色、表格边框色等。

对于代码块,我用了highlight.js提供的深色主题“Atom One Dark”,并调整了字体和圆角。对于表格,加了横向滚动容器,防止小屏溢出。对于引用块,统一使用左侧竖线加浅色背景,开起来更柔和。

还有一个容易被忽略的是“内容里的图片”。AI有时会在回复中插入图片,如果直接用html渲染小程序里的图片,容易被压缩变形。我通过mp-html的img扩展节点,再配合mode="widthFix"来控制图片宽度自适应。

如果你要做到极致的沉浸感,可以对AI回复里的标签进行白名单过滤,比如禁止<script><iframe>这类危险标签,避免XSS问题。在小程序端,mp-html默认会做安全过滤,但在H5端需要自己额外加一层DOMPurify处理。

这段折腾下来,我的体会是:渲染层是整个项目最耗时的地方,不要上来就追求全功能,先把基础Markdown跑通,再逐步叠加公式、代码高亮和自定义组件,迭代推进会稳很多。

5. 多模态交互:图片上传与视觉理解

5.1 交互入口:拍照、相册、拖拽

多模态交互是AI助手提升体验的重要方式,用户可能想直接拍一道数学题、一张产品截图或者一份手写笔记。UniApp封装了uni.chooseImage,可以同时支持拍照和相册选择:

uni.chooseImage({ count: 1, sizeType: ['compressed', 'original'], sourceType: ['camera', 'album'], success: (res) => { const tempFilePath = res.tempFilePaths[0]; // 进入下一步处理 } });

在H5端,除了点击按钮上传,我还额外做了一个拖拽上传的交互,允许用户直接把图片拖进聊天窗口。这个体验在不熟悉的用户眼里很加分。At App和小程序端只能点按钮触发,不过已经是足够了。

还需要注意,iOS小程序和App对相册权限的提示策略不太一样,如果用户首次拒绝,要引导去设置页打开权限。UniApp提供了uni.authorize可以预检权限,建议在进入聊天页时就检查一次。

5.2 图片压缩和上传封装

图片不能无脑传原图,尤其小程序包体有限制,网络传输也要考虑流量。UniApp的uni.compressImage可以把图片压缩到指定质量或尺寸。

我的压缩策略是:

  • 宽高最大不超过1280px,超了就等比缩放。
  • 质量压缩到0.7,对于视觉问答已经足够清晰。
  • 压缩后体积超过1MB时,再降一档质量重压一次。
  • 支持多张图片时,串行压缩,避免内存暴涨。

压缩完成后,我使用uni.uploadFile上传到自己的服务器。这里有个并行经验:不要直接拿临时文件路径去调用AI接口,因为临时路径在App端是原生临时目录,在H5端又是blob URL,直接转发给后端迟早会出兼容性问题。稳妥做法是先上传到自己的OSS或对象存储,拿到一个稳定的URL,再把这个URL发送给AI服务。

5.3 把图片和文本组装成多模态消息

上传完成后,消息结构里会带上图片URL数组。发送给后端的JSON大致是:

{ "sessionId": "abc-123", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "帮我看看这道题怎么解" }, { "type": "image_url", "image_url": { "url": "https://cdn.example.com/xxx.jpg" } } ] } ] }

这个结构参考了目前主流多模态大模型的输入格式。后端收到后,根据是否有图片字段决定走多模态模型还是纯文本模型,然后在回复中直接说“根据您发的图片,我的分析是...”。

前端展示时,用户消息气泡里如果包含图片,我会在小气泡缩略图基础上再配一个点击查看原图的大图预览。用uni.previewImage可以在三端统一起到预览效果,不用自己写弹窗。

多模态交互目前最容易被忽略的问题是历史消息中的图片处理。如果你把整段图片URL都存进上下文再传给AI,很容易让token量暴涨、响应变慢。因此我在发送前会做一轮优化:只保留当前消息和最近一轮相关图片,之前的图片只保留“用户发过图片”的标记,不携带全量URL。这个策略在真实使用时能显著降低接口费用和延迟。

6. 体验优化与沉浸式细节打磨

6.1 输入框自适应与键盘安全区

聊天输入框做得不好,会直接摧毁整个聊天体验。我用了textarea做输入,开启了auto-height属性,让它随内容自适应高度,最大到6行。同时给textarea加上adjust-position="false",避免键盘弹出时页面整体上移。

键盘弹出的遮挡问题是重灾区。在App和小程序端,输入框底部需要加上安全区高度,通常用uni.getSystemInfoSync().safeArea来获取。H5端移动浏览器里,用visualViewport监听键盘高度。

我还加了一个“按住说话”的语音扩展入口,这个稍后讲。输入工具栏底部我固定一行按钮:加号(图片)、输入框、发送/停止按钮。按钮和输入框颜色都用了主题色渐变,需要和整体视觉保持统一。

6.2 自动滚动、消息缓存与虚拟列表

聊天页的消息列表在长时间对话后可能超过100条,直接用scroll-view一个个渲染也会卡。我做了几个优化:

  • 消息按时间分批渲染,每批最多30条,滚动到底部时自动加载更早的消息。
  • 使用scroll-viewenhanced属性和show-scrollbar为false,提升小程序滚动性能。
  • 每一条消息组件内部用memo优化,避免无关消息更新导致整体重渲染。
  • 搜索场景下,限制历史加载条数,以降低首屏渲染压力。

对于缓存,我是这样做的:每次会话结束时,将最近20条消息压缩后写入storage;进入页面先读缓存,再根据服务端数据做增量更新。如果服务端数据异常,至少用户还能看到历史对话,不会白屏。这个问题在弱网环境下尤其重要。

自动滚动我提过用scroll-into-view,但这里有个细节:新消息进来时,只有当用户停在底部时才自动滚动到底部,如果用户正在往上翻历史,就别强制拉下去。这个判断可以通过监听scroll事件计算是否接近底部来实现。

6.3 暗黑模式和极简UI设计

沉浸式设计的另一个关键是暗黑模式。AI问答场景通常发生在夜间或弱光环境下,一个柔和的暗黑主题能极大提升使用舒适度。

我用了CSS变量来管理主题色:

:root { --bg-primary: #f7f8fa; --bg-chat: #eef1f5; --text-primary: #1a1d21; --text-secondary: #6b7280; --accent: #4f6ef7; } .dark { --bg-primary: #16181d; --bg-chat: #0f1115; --text-primary: #e5e7eb; --text-secondary: #9ca3af; --accent: #6b8afe; }

在小程序端, uni-app的页面根节点不是html,所以dark类不能直接挂在html上。我是在根组件外层套一个view,用它绑定class,这样所有子组件通过CSS变量自动切换主题色,不用每个组件单独处理。

极简UI方面,我去掉了传统聊天的气泡尾巴,改用细圆角矩形;头像从圆形改成了小巧的圆角方形,更贴近工具属性。技术上的效果就是每屏视觉噪音更少,用户会更关注AI回复本身。

6.4 语音扩展:让问答助手“能听会说”

虽然不是最初的硬性需求,但加上语音可以让整体体验更称得上“沉浸式”。UniApp内置了录音和音频播放能力。

我用uni.getRecorderManager()录制用户语音,录完后调用语音识别接口转成文字,再塞入输入框,让用户确认后发送。这样可以避免语音识别错词直接发给AI。TTS语音播放则是在AI回复流输出完成后,调用uni.createInnerAudioContext()播放服务端返回的合成音频。

这个扩展最麻烦的是权限和格式。App端需要声明麦克风权限,H5端浏览器必须用HTTPS才能录音,小程序的录音格式在iOS上是m4a、在安卓上是mp3,后端解析时需要兼容不同编码格式。如果团队没有语音处理经验,建议先做文本+图片,语音放到第二阶段。

7. 打包上线与常见问题排查实录

7.1 微信小程序打包与域名配置

微信小程序是目前流量最大、审核也相对严格的端。在manifest.json里填好appid后,需要到微信公众平台配置服务器域名。如果后端API是https://api.example.com,WebSocket是wss://api.example.com,都要加入request和socket合法域名,否则真机调试直接失败。

小程序包体也有体积限制,主包不能超过2MB。我会把依赖进行分包处理:聊天页是核心,放主包;设置和引导页放分包。如果使用了mp-html,代码量会增加一些,注意tree-shaking,尽量只引入需要的扩展组件。

上传到微信后台时,还需要做代码依赖分析。如果发现uniapp自身带的某些模块用不到,可以在manifest的optimization里开启subpackagetreeShaking,能明显缩小包体。实测开启后主包从1.8MB降到1.3MB,减少了不少。

7.2 H5部署的跨域与路由模式

H5端部署相对简单,但跨域是绕不开的题。开发环境我使用Vite的proxy代理,将/api转发到后端服务。生产环境如果后端支持CORS,那么前端可以直接请求;如果不支持,就得在Nginx层配置反向代理。

做法是在Nginx的location /指向前端静态文件,location /api反代到后端服务。这样可以避免暴露服务端真实地址,同时解决跨域问题。

路由模式我在前面提过,H5端如果启用history模式,需要Nginx把所有非静态资源请求都rewrite到index.html,否则刷新页面会404。如果不想折腾,直接用hash模式最稳妥。AI助手这类单页工具,hash模式的URL虽然多一个#,但几乎不影响SEO,完全可以接受。

7.3 App云打包痛点

App端我用了UniApp的云打包功能,不需要本地的Android Studio和Xcode。云打包前需要准备好Android证书或iOS证书,iOS还需要苹果开发者账号。证书和描述文件的配置一定要认真对待,不然上传App Store时会卡得很久。

云打包的坑主要集中在原生权限和插件冲突上。比如同时使用摄像头、麦克风、相册权限时,如果配置不当,在Android 13上可能会出现运行时权限崩溃。我建议在打包前先完整测试三轮:H5、微信开发者工具、App自定义调试基座。尤其自定义基座要用起来,它能在不正式打包的情况下调试原生API。

另外,App端推送、版本更新等能力需要额外模块,这会增加包体积。AI问答助手可以暂时不做推送,把精力放在核心体验上。

7.4 高频踩坑问题速查表

为了帮大家避坑,我把整个开发周期里遇到的高频问题整理成了表格,方便对照:

问题现象原因分析解决方案
小程序中AI回复的HTML不渲染小程序没有DOM,v-html不可用使用mp-html组件替换v-html
Markdown表格在小屏端溢出表格默认宽度过大给表格包裹横向滚动容器
公式渲染乱码或显示源码后端返回的LaTeX被转义统一转成HTML标签或图片渲染
WebSocket连接App端经常断缺少心跳包每30秒发送一次ping,断线自动重连
上传图片后其他端无法访问在不同端拿到了本地临时路径先上传到服务器,统一使用CDN URL
键盘弹起遮挡输入框未适配安全区监听safeArea,textarea设置adjust-position
长列表滚动卡顿一次渲染过多消息分批渲染 + 虚拟滚动
暗黑模式切换后子组件不更新变量挂载位置不对根节点挂载变量,子组件全部继承
App云打包后相机权限崩溃原生权限声明不完整检查manifest的本机权限配置
H5刷新404history模式未配伪静态改用hash模式或配置Nginx rewrite

这些坑有些看起来很小,但每个都能消耗半天时间。希望这个表格能帮你少走弯路。

在我个人实操过程中,最深的体验是:跨端AI问答助手的难度不在“调用大模型”,而在“渲染和交互的一致性”。你需要在三端做大量兼容适配,才能让用户感受不到平台差异。如果你在做一个垂直领域的AI问答产品,可以把Markdown渲染和流式输出作为核心优先实现,多模态放在第二优先级。我最初的版本先做到了文本流式,就足够验证业务流程了,后面再陆续加上公式渲染和图片理解。

最后再分享一个小技巧:在小程序端用mp-html渲染Markdown时,最好把后端返回的Markdown字符串先做一次“清洗”,过滤掉可能包含的脚本标签,同时把代码块的换行符处理好。很多诡异的样式错乱,根源都出在特殊字符和嵌套标签上。抓住这几个关键点,整个项目的稳定性会提升一个档次。

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

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

立即咨询