1. 项目概述与设计思路
作为一个长期关注传统文化数字化传播的技术从业者,我注意到茶道文化在年轻群体中的认知度正在下降。传统的信息展示方式缺乏互动性和深度解读能力,这正是我们开发这套系统的初衷。系统采用前后端分离架构,前端基于Vue3生态链,后端使用SpringBoot框架,特别引入AI能力增强交互体验。
技术选型上,我们放弃了传统的SSR方案,选择Vite+Vue3的组合。实测中,Vite的冷启动速度比Webpack快3-8倍,HMR更新几乎瞬时完成。Element Plus作为UI库,其预设的茶色系配色方案与茶文化主题高度契合。后端采用SpringBoot 2.7.x版本,这是LTS版本,确保长期维护支持。
关键决策:使用LangChain4j而非直接调用API,主要是考虑未来可能对接多模型的需求。实测显示,通过LangChain4j的抽象层,切换模型时的代码改动量减少70%。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心架构解析
2.1 前端工程化实践
项目采用monorepo管理,通过pnpm workspace划分多个子模块:
code复制├── apps
│ ├── admin # 管理端
│ └── web # 用户端
├── packages
│ ├── ai # AI通用组件
│ ├── types # 类型定义
│ └── utils # 工具库
特别值得分享的是AI悬浮助手的实现方案。我们在main.ts中全局注册组件:
typescript复制import AIChatFloat from '@packages/ai/components/FloatChat.vue'
app.component('AIChatFloat', AIChatFloat)
然后在App.vue中使用teleport实现跨路由悬浮:
html复制<teleport to="body">
<AIChatFloat v-if="!isMobile" />
</teleport>
2.2 后端微服务设计
采用经典的三层架构,但增加了AI服务层:
code复制com.tea.culture
├── config # 配置类
├── controller # 控制器
├── service
│ ├── ai # AI服务
│ └── impl # 业务实现
├── mapper # MyBatis接口
└── model # 实体类
AI服务层的核心是TeaAIService类,封装了五种AI场景的调用:
java复制public class TeaAIService {
private final ChatLanguageModel chatModel;
public String generateArticleSummary(String content) {
// 使用特定prompt模板
String prompt = """
你是一位资深茶道专家,请用通俗易懂的语言总结以下文章要点,
要求:1.分点列出 2.每点不超过20字 3.保留专业术语但解释含义
文章内容:%s
""";
return chatModel.generate(prompt.formatted(content));
}
}
3. 关键功能实现细节
3.1 AI文章讲解实现
前端通过IntersectionObserver API实现滚动到内容区域时触发AI解析:
javascript复制const observer = new IntersectionObserver((entries) => {
if(entries[0].isIntersecting) {
fetchAIExplanation(articleId.value)
}
}, { threshold: 0.5 })
onMounted(() => {
observer.observe(document.querySelector('#article-content'))
})
后端处理时采用流式响应提升用户体验:
java复制@GetMapping("/article/{id}/ai-explain")
public SseEmitter getAIExplanation(@PathVariable Long id) {
SseEmitter emitter = new SseEmitter(60_000L);
executorService.execute(() -> {
try {
Article article = articleService.getById(id);
StreamingResponseHandler handler = new StreamingResponseHandler(emitter);
chatModel.generate(article.getContent(), handler);
} catch (Exception e) {
emitter.completeWithError(e);
}
});
return emitter;
}
3.2 全站AI助手技术方案
实现中最复杂的是保持对话上下文。我们的解决方案是:
- 前端使用Pinia存储最近5轮对话
- 每次请求携带对话指纹(MD5(最近对话))
- 后端用Redis缓存上下文,过期时间30分钟
核心对话处理逻辑:
java复制public ChatResponse handleChat(ChatRequest request) {
String contextKey = "ai:chat:" + request.getFingerprint();
List<ChatMessage> history = redisTemplate.opsForList().range(contextKey, 0, -1);
if (CollectionUtils.isEmpty(history)) {
history = new ArrayList<>();
history.add(SystemMessage.from("你是一位精通中国茶道的专家,回答要专业但易懂"));
}
history.add(HumanMessage.from(request.getContent()));
AiMessage response = chatModel.generate(history).content();
history.add(response);
// 维护上下文长度
if (history.size() > 10) {
history = history.subList(history.size() - 10, history.size());
}
redisTemplate.opsForList().rightPushAll(contextKey, history);
return new ChatResponse(response.text());
}
4. 性能优化实践
4.1 前端资源优化
通过Vite的代码分割策略,将AI相关组件单独打包:
javascript复制export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'ai-vendor': ['@langchain/core', 'axios'],
'ai-components': ['@/components/ai']
}
}
}
}
})
实测优化效果:
| 优化前 | 优化后 | 提升幅度 |
|---|---|---|
| 2.8MB | 1.2MB | 57% |
| 3.4s | 1.1s | 68% |
4.2 后端缓存策略
采用多级缓存架构:
- 热点数据:Caffeine内存缓存(最大500条目,过期时间5分钟)
- 常规数据:Redis集群(过期时间2小时)
- 持久层:MySQL + MyBatis二级缓存
配置示例:
java复制@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager();
manager.setCaffeine(Caffeine.newBuilder()
.maximumSize(500)
.expireAfterWrite(5, TimeUnit.MINUTES));
return manager;
}
}
5. 部署与运维方案
5.1 容器化部署
Docker Compose编排文件关键配置:
yaml复制services:
backend:
image: tea-culture-backend:1.0
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- REDIS_HOST=redis
depends_on:
- redis
- mysql
frontend:
image: tea-culture-frontend:1.0
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
Nginx配置优化要点:
code复制http {
gzip on;
gzip_types text/plain application/javascript image/svg+xml;
server {
location /api {
proxy_pass http://backend:8080;
proxy_set_header Connection '';
proxy_http_version 1.1;
}
}
}
5.2 监控方案
我们采用Prometheus+Grafana监控体系,关键指标包括:
- 接口响应时间P99
- AI调用成功率
- 并发用户数
- 系统错误率
SpringBoot启用监控端点配置:
properties复制management.endpoints.web.exposure.include=health,metrics,prometheus
management.metrics.tags.application=tea-culture
6. 典型问题排查实录
6.1 AI响应延迟高问题
现象:文章AI讲解平均响应时间超过8秒
排查过程:
- 检查网络延迟:从Pod内ping模型服务 <50ms
- 分析线程堆栈:发现大量BLOCKED线程等待模型响应
- 检查prompt长度:平均超过2000字符
解决方案:
- 增加请求超时设置:
java复制@Bean
public ChatLanguageModel chatModel() {
return new QwenChatModel(QwenChatModel.builder()
.maxRetries(2)
.timeout(Duration.ofSeconds(30))
.build());
}
- 优化prompt模板,添加长度限制:
java复制String shortContent = content.length() > 500 ?
content.substring(0, 500) + "..." : content;
6.2 移动端样式错乱
现象:iOS Safari上AI悬浮按钮遮挡内容
修复方案:
css复制/* 添加移动端特定样式 */
@media (max-width: 768px) {
.ai-float-btn {
bottom: 80px !important;
right: 15px !important;
transform: scale(0.9);
}
}
7. 扩展开发建议
-
知识图谱集成:将茶文化知识结构化,使用Neo4j构建关系网络,增强AI回答的准确性
-
用户行为分析:接入埋点系统,分析热门内容,优化AI推荐策略
-
多模态扩展:增加图片识别功能,用户拍照即可识别茶叶种类
-
国际化支持:利用AI翻译能力,增加多语言版本
这套系统在实际运行中表现稳定,日均处理AI请求约2.3万次,平均响应时间控制在1.5秒以内。最大的收获是认识到合理的prompt工程能显著提升AI输出质量,我们建立了专门的prompt模板库,目前积累有效模板47个。对于想尝试类似项目的开发者,建议先从小的AI功能点切入,逐步扩展,避免一开始就设计过于复杂的AI交互流程。
