news 2026/9/1 22:36:35

LangChain4j+PGVector构建RAG智能客服与工单系统实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain4j+PGVector构建RAG智能客服与工单系统实战

企业客服系统一旦接上大模型,最容易出现的问题不是模型不会说话,而是模型什么话都敢说。为了让人工智能客服先查资料再回答,RAG(Retrieval-Augmented Generation,检索增强生成)成为企业知识库客服落地的核心方案。本文基于 LangChain4j + Spring Boot + Vue + RAG + PGVector + Embedding 这套技术栈,完整实现一个企业智能客服与工单处理系统。

文章会从系统链路设计开始,先说明 RAG 在企业客服场景中的价值和边界,然后完成数据库、后端、前端三部分的搭建。后端覆盖文档导入、文本切分、向量存储、相似度检索、大模型生成回答、转人工工单创建六个环节;前端覆盖聊天窗口、知识库管理、工单列表三个界面。最后给出运行验证、常见问题排查和生产环境落地清单。

这套方案适合正在做企业知识库问答、内部客服机器人、工单系统智能化的后端或全栈开发者。学完后,你可以把方案迁移到 FAQ 助手、售前咨询、运维工单等场景,而不只是看一个演示项目。

1. 先把智能客服和工单系统的整体链路想清楚

1.1 RAG 为什么适合企业客服场景

大模型直接回答业务问题时,有两个明显短板:一是模型训练数据里没有企业内部信息,例如某产品的退款政策、售后流程、排障手册;二是模型可能一本正经地编造答案,也就是幻觉。RAG 的思路是在模型回答问题之前,先从企业知识库中检索出相关片段,把这些片段作为上下文拼进提示词里,再让模型基于这些材料回答。

这种方式的优点很直接:

  • 回答有据可依,模型被限定在给定文档范围内。
  • 企业文档更新后,不需要重新训练模型,只需要更新向量库。
  • 可以追溯答案来源,给用户展示“这段回答来自哪份文档”。
  • 实现成本远低于微调,适合中小团队快速落地。

RAG 不是万能方案。如果企业知识库文档质量差、切分不合理或检索命中率低,模型回答质量依然上不去。所以本文会在验证阶段给出评价指标,而不是只看“能对话”这个表面效果。

1.2 系统职责划分:智能问答、知识库、工单

一个完整的企业客服系统至少要拆成三个模块。

智能问答模块负责接收用户问题,调用 RAG 链路生成回答,并判断是否需要进行人工介入。知识库模块负责文档上传、解析、切分、向量化、存储和删除。工单模块负责在回答无法解决用户问题时,创建工单、分配处理人、记录处理状态。

这三个模块的关系是:知识库为问答提供数据,问答为工单提供触发条件,工单承载无法自动解决的问题。把这三个模块拆开设计,后面无论是替换 Embedding 模型,还是接入企业工单审批流,都不会牵一发动全身。

1.3 最小闭环链路

整套系统按下面这条链路工作:

用户提问后,后端对问题做 Embedding 向量化,在 PGVector 中检索相似的历史知识片段,把 topK 片段拼入 Prompt,调用大模型生成回答。模型回答时如果发现知识库内容不足以回答问题,会在回答中标记“需要转人工”。此时前端可以展示转人工按钮,用户确认后创建工单,工单进入后台处理队列。

这条链路中,PGVector 承担向量存储和相似度检索,LangChain4j 提供模型调用、向量检索、文档切分的标准化接口,Spring Boot 负责把各环节串成 REST 接口,Vue 负责交互界面。

注意:RAG 链路里最容易出错的是“检索到的内容到底有没有被大模型真正使用”。调试时建议把命中片段和最终回答一起返回,方便判断是检索问题还是生成问题。

2. 环境准备与项目初始化

2.1 环境版本清单

先明确版本边界。LangChain4j 的版本迭代速度较快,不同版本之间 API 存在差异,尤其是EmbeddingStore的构建方式和 Spring Boot Starter 的自动配置类。下面表格是最小可用组合,实际项目以官方文档为准。

组件版本建议说明
JDK17LangChain4j 对 Java 8 支持有限,推荐 17
Spring Boot3.2.x3.3 以上需要确认 LangChain4j 版本兼容性
LangChain4j0.35.0 为例版本变化快,落地前查看官方 release note
PostgreSQL16对向量索引支持更稳定
pgvector0.7.0需要安装 PostgreSQL 扩展
Vue3.4使用 Vite 构建
Node.js18 或 20对应 Vite 5 的构建要求
模型Qwen 或 BGE 系列通过 OpenAI 兼容接口或 Ollama 本地调用

本机需要同时安装 PostgreSQL、JDK、Maven、Node.js。建议先用学习环境跑通,再考虑生产部署。

2.2 初始化数据库和 PGVector

安装 PostgreSQL 后,进入数据库创建业务库和扩展。pgvector 不是 PostgreSQL 自带的,需要单独安装。Linux 下通过apt install postgresql-16-pgvector安装;Windows 下需要下载对应 PostgreSQL 16 版本的预编译 DLL 文件,放到 PostgreSQL 的lib目录。

psql -U postgres -c "CREATE DATABASE customer_service;" psql -U postgres -d customer_service -c "CREATE EXTENSION IF NOT EXISTS vector;"

vector扩展创建成功后,创建知识库向量表和工单表。

CREATE TABLE knowledge_chunk ( id BIGSERIAL PRIMARY KEY, doc_id VARCHAR(64) NOT NULL, chunk_index INT NOT NULL, content TEXT NOT NULL, source VARCHAR(255), embedding VECTOR(1024), created_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_knowledge_chunk_vector ON knowledge_chunk USING hnsw (embedding vector_cosine_ops); CREATE TABLE ticket ( id BIGSERIAL PRIMARY KEY, question TEXT NOT NULL, answer TEXT, status VARCHAR(16) DEFAULT 'PENDING', assignee VARCHAR(64), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() );

embedding字段的长度必须和 Embedding 模型输出的向量维度一致。例如text-embedding-v3输出 1024 维,就用VECTOR(1024);换成 BGE-M3 后输出维度可能不同,需要重新建表或迁移字段。

hnsw索引适合数据量大的场景,vector_cosine_ops表示使用余弦相似度。数据量小时可以不建索引,直接暴力检索。

2.3 Spring Boot 基础工程与依赖

创建一个 Spring Boot 3.2 工程,引入以下依赖。以 Maven 为例:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-spring-boot-starter</artifactId> <version>0.35.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-pgvector</artifactId> <version>0.35.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>0.35.0</version> </dependency>

langchain4j-open-ai用于通过 OpenAI 兼容协议调用大模型和 Embedding 服务。这样可以兼容多种模型服务,而不绑定某一家。

2.4 后端配置文件

application.yml中配置数据源、模型服务和向量库参数。

spring: datasource: url: jdbc:postgresql://localhost:5432/customer_service username: postgres password: postgres langchain4j: open-ai: chat-model: base-url: ${AI_BASE_URL} api-key: ${AI_API_KEY} model-name: qwen-plus temperature: 0.1 embedding-model: base-url: ${AI_BASE_URL} api-key: ${AI_API_KEY} model-name: text-embedding-v3

API Key 不要写死在配置里,使用环境变量注入。temperature调低到 0.1 是为了让客服回答更保守,减少创造性发挥。

2.5 前端项目初始化

使用 Vite 创建 Vue 3 项目,并安装 Element Plus 和 Axios。

npm create vite@latest ai-cs-frontend -- --template vue cd ai-cs-frontend npm install element-plus axios

前端只需要三个视图:聊天窗口、知识库管理、工单列表。路由可以放在/chat/knowledge/ticket下。

3. 后端核心代码:知识库导入、向量存储、检索问答

3.1 知识库文档处理流程

企业知识库中常见的文件格式包括 Markdown、TXT、PDF、Word。前端上传文件后,后端需要完成提取文本、切分片段、向量化、入库四步。

文本切分是影响检索质量的关键步骤。切分太大会让片段包含过多无关信息,检索精度下降;切分太小会让语义不完整,大模型无法理解上下文。LangChain4j 提供了DocumentSplitter接口,常见实现包括:

切分器策略适用场景
ParagraphDocumentSplitter按段落切分结构化文档
RecursiveDocumentSplitter递归切分长文本、混合结构
DocumentByWordSplitter按词数切分英文文档

对中文场景,推荐先按段落切分,再控制最大字符数。示例中每段约 200 字,重叠 20 字。

3.2 Embedding 与向量存储 Bean

创建VectorStoreConfig,把EmbeddingStore注册为 Spring Bean。

@Configuration public class VectorStoreConfig { @Bean public EmbeddingStore<TextSegment> embeddingStore(DataSource dataSource) { return PgVectorEmbeddingStore.builder() .dataSource(dataSource) .tableName("knowledge_chunk") .dimension(1024) .build(); } }

PgVectorEmbeddingStore在写入向量时会自动往knowledge_chunk表插入数据,读取时会执行相似度查询。dimension(1024)必须和表中VECTOR(1024)以及模型输出维度保持一致,否则运行时会直接报错。

3.3 知识库导入服务

KnowledgeBaseService负责文件解析、切分、向量化和入库。

@Service public class KnowledgeBaseService { private final EmbeddingModel embeddingModel; private final EmbeddingStore<TextSegment> embeddingStore; public KnowledgeBaseService(EmbeddingModel embeddingModel, EmbeddingStore<TextSegment> embeddingStore) { this.embeddingModel = embeddingModel; this.embeddingStore = embeddingStore; } public int importDocument(String docId, String content, String source) { Document document = Document.from(content, Metadata.from("source", source)); DocumentSplitter splitter = new ParagraphDocumentSplitter(200, 20); List<TextSegment> segments = splitter.split(document); List<Embedding> embeddings = embeddingModel.embedAll(segments).content(); embeddingStore.addAll(embeddings, segments); return segments.size(); } }

这里需要注意embedAll是批量接口,比循环调用embed效率高。addAll会把 Embedding 和 TextSegment 一起写入 PGVector。

3.4 问答检索服务与提示词

ChatService是 RAG 链路的核心。先向量化用户问题,再检索 topK 片段,最后构造提示词调用大模型。

@Service public class ChatService { private final EmbeddingModel embeddingModel; private final EmbeddingStore<TextSegment> embeddingStore; private final ChatLanguageModel chatModel; public String answer(String question, double minScore) { Embedding queryEmbedding = embeddingModel.embed(question).content(); List<EmbeddingMatch<TextSegment>> matches = embeddingStore.findRelevant(queryEmbedding, 4, minScore); if (matches.isEmpty()) { return "系统未在知识库中找到相关内容,建议转人工处理。"; } String context = matches.stream() .map(match -> match.embedded().text()) .collect(Collectors.joining("\n\n")); String prompt = """ 你是一名企业客服。请只根据下面的知识库内容回答问题。 如果知识库内容无法回答用户问题,请直接回复:需要转人工。 回答要简洁、准确,不要编造。 知识库内容: %s 用户问题: %s """.formatted(context, question); return chatModel.generate(prompt); } }

minScore是相似度阈值。低于该阈值的片段即使被检索到也不使用。这个参数需要根据实际数据调,阈值太高会导致大量问题无法回答,太低会导致无关内容被拼进提示词。

注意:不要把检索结果全部拼入提示词。topK 取 4 到 6 为宜,片段太多会超过上下文窗口,也会让模型被无关信息干扰。

3.5 工单处理服务

工单服务负责创建工单、更新状态和查询列表。

@Service public class TicketService { private final JdbcTemplate jdbcTemplate; public TicketService(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public Long create(String question) { KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(con -> { PreparedStatement ps = con.prepareStatement( "INSERT INTO ticket(question, status) VALUES (?, 'PENDING')", Statement.RETURN_GENERATED_KEYS); ps.setString(1, question); return ps; }, keyHolder); return keyHolder.getKey().longValue(); } }

在生产环境中,工单处理还需要考虑分配策略、超时通知、回访记录和权限控制。这里先保留最小可运行接口。

3.6 Controller 接口

提供三个 REST 接口:问答、导入知识库、创建工单。

@RestController @RequestMapping("/api") public class CustomerServiceController { private final ChatService chatService; private final KnowledgeBaseService knowledgeBaseService; private final TicketService ticketService; @PostMapping("/chat") public Map<String, Object> chat(@RequestBody ChatRequest request) { String answer = chatService.answer(request.question(), 0.5); return Map.of("answer", answer); } @PostMapping("/knowledge/import") public Map<String, Object> importKnowledge(@RequestParam String docId, @RequestParam String source, @RequestBody String content) { int chunks = knowledgeBaseService.importDocument(docId, content, source); return Map.of("chunks", chunks); } @PostMapping("/ticket") public Map<String, Object> createTicket(@RequestBody ChatRequest request) { Long ticketId = ticketService.create(request.question()); return Map.of("ticketId", ticketId); } }

实际项目里,文件上传接口应该接收MultipartFile,而不是直接接收原始字符串。上面代码用于展示核心流程,文件解析部分需要根据实际格式扩展。

4. 前端页面:聊天窗口、知识库管理、工单列表

4.1 聊天窗口

聊天窗口使用 Vue 3 组合式 API,调用后端/api/chat接口。

<template> <div class="chat-panel"> <div v-for="(msg, index) in messages" :key="index" class="message"> <div :class="msg.role">{{ msg.content }}</div> </div> <div class="input-row"> <el-input v-model="question" placeholder="请输入问题" @keyup.enter="send" /> <el-button type="primary" @click="send">发送</el-button> </div> </div> </template> <script setup> import { ref } from 'vue' import axios from 'axios' const question = ref('') const messages = ref([]) async function send() { if (!question.value.trim()) return messages.value.push({ role: 'user', content: question.value }) const resp = await axios.post('/api/chat', { question: question.value }) messages.value.push({ role: 'assistant', content: resp.data.answer }) question.value = '' } </script>

如果后端返回的内容包含文档来源,前端可以在回答下方展示“参考来源:某文档.pdf”。这样用户能确认回答是否可信。

4.2 知识库上传页面

知识库管理页面提供一个上传入口,调用/api/knowledge/import。实际项目中,建议把文件先上传到服务端,由服务端完成文本提取,而不是在前端直接发送原文。这样可以统一处理 PDF、Word 等格式。

4.3 工单列表

工单列表页面调用/api/ticket/list接口,展示状态和处理人。为了简化,这里不展开完整实现,核心点是:当聊天窗口出现“需要转人工”时,点击按钮调用创建工单接口,然后跳转到工单列表页查看进度。

4.4 跨域与接口联调

Vite 开发服务器默认端口是 5173,Spring Boot 默认端口是 8080,存在跨域问题。推荐在 Vite 配置代理,而不是在后端开启全局 CORS。

// vite.config.js export default { server: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }

这样前端请求/api/chat时会自动转发到后端,避免前端开发时反复处理跨域。

5. 运行验证与效果评估

5.1 启动顺序和初始化检查

按以下顺序启动系统:

  1. 启动 PostgreSQL,确认customer_service库和knowledge_chunkticket表存在。
  2. 启动 Spring Boot 应用,观察日志中是否有EmbeddingStore初始化成功的记录。
  3. 启动 Vue 开发服务器,访问聊天页面。

如果后端日志出现 PGVector 相关报错,优先检查CREATE EXTENSION vector是否执行成功,以及VECTOR维度是否匹配。

5.2 验证知识库导入

导入一个 FAQ 文档,例如:

退货政策:用户签收后 7 天内可以申请无理由退货。 发货时间:工作日 16:00 前付款的订单当天发货。

调用导入接口后,查询knowledge_chunk表确认切分结果。

SELECT doc_id, chunk_index, left(content, 30) FROM knowledge_chunk;

正常结果应该出现 1 到 2 条记录。如果记录数为 0,检查切分器配置和文本内容是否被正确读取。

5.3 验证问答链路

在聊天窗口输入“退货有几天时间”,预期回答来自退货政策片段。如果回答不对,按以下顺序排查:

  • 先确认knowledge_chunk表是否有数据。
  • 再确认minScore阈值是否过高,导致检索结果为空。
  • 再确认模型调用是否成功,查看后端日志是否出现模型服务报错。

建议在ChatService中临时打印命中的片段文本,确认检索结果是否相关。

5.4 验证工单闭环

输入一个知识库中没有的问题,例如“我的发票开错了,怎么改”。如果提示词中设置了“无法回答时回复需要转人工”,模型会返回“需要转人工”。此时前端显示转人工按钮,点击后创建工单,在工单列表中能看到状态为PENDING的记录。

5.5 用命中率、拒答率评估 RAG 效果

RAG 系统不能只看“能不能回答”,还需要关注质量指标。

指标计算方式期望
命中率检索到相关片段的提问数 / 总提问数越高越好
拒答率模型明确拒绝回答的提问数 / 总提问数过低说明模型可能在胡编
引用准确率回答中引用的片段是否真实相关应接近 100%
响应耗时从提问到返回回答的耗时200ms 检索 + 模型生成耗时

如果命中率低,优先优化切分策略和 topK;如果拒答率过低且回答内容出现幻觉,提高minScore阈值,或在提示词中加强“无法回答时必须拒绝”的约束。

6. 常见问题排查

6.1 pgvector 扩展不存在

现象:启动时执行 SQL 报错type "vector" does not exist,或者CREATE EXTENSION vector失败。

原因:PostgreSQL 服务端没有安装 pgvector 扩展。只添加了 Java 依赖还不够,数据库需要单独安装。

排查:

psql -U postgres -d customer_service -c "SELECT * FROM pg_available_extensions WHERE name = 'vector';"

如果没有结果,说明扩展未安装。Linux 使用apt install postgresql-16-pgvector,Windows 需要把对应版本的 DLL 文件复制到 PostgreSQL 的lib目录并重启服务。

预防:写初始化脚本,把CREATE EXTENSION放入数据库迁移脚本中。

6.2 向量维度不一致

现象:写入向量时抛出类似expected 1536 dimensions, not 1024的异常。

原因:表结构中的VECTOR(1024)和当前 Embedding 模型输出维度不一致。更换模型后,如果保留旧表结构就会报错。

排查:

  • 确认application.yml中 embedding-model 的model-name
  • 查询模型 API 文档确认输出向量维度。
  • 查看建表 SQL。

解决:删除旧表重建,或新建一张维度匹配的表。不要试图在同一张表中混用不同维度的向量。

6.3 Spring Boot 版本过高导致的自动配置问题

现象:引入 LangChain4j Starter 后,ChatLanguageModelBean 注入失败,或者配置项完全不生效。

原因:LangChain4j 的 Spring Boot Starter 与 Spring Boot 版本存在兼容窗口。如果使用 Spring Boot 3.4 或更高版本,某些自动配置类可能因为版本变化未被加载。

排查:

  • 查看启动日志中DevLangChain4jAutoConfiguration是否生效。
  • 检查spring.factoriesAutoConfiguration.imports中的自动配置类。
  • 使用debug=true启动,观察条件装配结果。

解决:根据官方文档选择匹配的 LangChain4j 版本,或者回退 Spring Boot 到 3.2.x。不要盲目升级 Spring Boot,RAG 系统稳定运行比新版本特性更重要。

6.4 中文知识库检索效果差

现象:知识库里明明有相关内容,但模型回答总是“未找到”。

原因:中文按句切分时,如果片段太短,单个片段可能不包含完整的业务信息;如果 Embedding 模型对中文支持一般,检索分数整体偏低,导致minScore把它们全部过滤掉。

排查:

  • 打印检索到的EmbeddingMatch的分数,看是否低于阈值。
  • 打印 topK 片段,看内容是否和问题相关。
  • 尝试调整切分器最大字符数和重叠字符数。

解决:

  • 先降低minScore,确认内容能被检索出来。
  • 再优化切分:优先按段落切分,保留标题和结构。
  • 中文场景优先选择对中文支持更好的模型,例如text-embedding-v3或本地 BGE 系列。

6.5 模型服务调用失败或超时

现象:问答时返回 5xx 错误,或者等待很长时间后才返回错误。

排查:

  • 检查 API Key 和base-url是否配置正确。
  • 用 curl 直接调用模型服务,确认接口可用。
  • 检查超时配置,模型服务响应慢时调整 HTTP 客户端超时时间。

解决:在application.yml中为模型服务增加超时和重试配置。生产环境建议使用异步任务处理问答请求,避免用户请求阻塞在模型调用上。

7. 生产环境落地清单

7.1 学习环境与生产环境的差异

本文示例可以直接在本地运行,但生产环境需要补充多项能力。

项目学习环境生产环境
配置管理application.yml 写本地参数使用配置中心或环境变量
知识库更新手动导入定时同步企业文档库
日志默认日志结构化日志 + 检索链路追踪
监控命中率、拒答率、响应耗时指标
权限区分客服、管理员、用户角色
工单流程只有创建和查询分配、流转、通知、回访
安全数据脱敏、文档访问权限

7.2 发布前检查清单

上线前逐项确认:

  • 数据库迁移脚本是否包含CREATE EXTENSION vector和索引创建语句。
  • Embedding 模型维度是否和表结构一致。
  • API Key 是否通过环境变量注入,是否已加入服务发布配置。
  • 是否配置了模型调用的超时和重试。
  • 是否准备了一份测试问题集,至少覆盖知识库命中、未命中、边界相似度三种情况。
  • 知识库导入是否具备幂等性,重复导入同一文档不会产生重复数据。
  • 工单创建是否具备防重复提交机制。
  • 是否记录 RAG 链路日志,包括问题原文、检索片段、相似度分数、模型回答。

7.3 可复用排错清单

  • 接口 404:检查 Controller 路由和前端代理配置。
  • 接口 500:先看后端堆栈日志,确认是数据库、模型还是代码问题。
  • 回答为空:检查模型调用参数,确认ChatLanguageModel是否正确配置。
  • 检索结果为空:检查knowledge_chunk表数据,再检查minScore阈值。
  • 回答与知识库无关:检查 topK 片段内容,确认切分质量。
  • 工单创建失败:检查数据库表是否存在,字段是否匹配。

8. 从演示系统走向可维护产品:三条建议

第一,把知识库的更新变成自动化流程。演示系统里是手动上传文档,生产环境应该监听企业文档平台,文档变更后自动重新切分、重新向量化,并标记旧版本内容失效。

第二,把 RAG 质量评估日常化。至少维护一份问题集,每次模型或切分策略调整后,批量跑一遍,对比命中率、拒答率和回答质量。没有指标约束的 RAG 系统,上线后很难判断到底变好了还是变坏了。

第三,把转人工的判定机制做得更精细。当前示例使用的是“模型主动返回需要转人工”,过于依赖提示词。更稳的方式是结合相似度分数:检索分数低于阈值时直接触发转人工,让模型决定和分数判断互为兜底。

这套基于 LangChain4j + Spring Boot + Vue + RAG + PGVector + Embedding 的企业智能客服系统,作为入门项目已经覆盖了完整链路。下一步可以继续扩展多轮会话记忆、客服知识权限隔离、工单自动分类和更细粒度的 RAG 指标采集。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 22:35:46

H3U与上位机Modbus TCP通信测试全流程实战指南

简介&#xff1a;本资源是一套面向工业自动化初学者与C#上位机开发者的H3U汇川PLC Modbus TCP通信实战项目&#xff0c;聚焦解决PLC与上位机基于以太网的稳定数据交互问题&#xff0c;适用于远程监控、设备联调及产线数据采集等典型场景。压缩包共71个文件&#xff0c;含15个核…

作者头像 李华
网站建设 2026/9/1 22:35:35

英雄游戏数据分析岗秋招笔试复盘:SQL、留存率与业务思维全解析

2023年秋招投英雄游戏数据分析岗&#xff0c;收到笔试邀请的那一刻&#xff0c;我其实是有点意外的。说实话&#xff0c;游戏行业的数据分析岗一向热门&#xff0c;每年简历堆成山&#xff0c;能进笔试已经算过了第一关。但紧接着就是紧张——笔试怎么考、考什么、难度多大&…

作者头像 李华
网站建设 2026/9/1 22:34:34

应用安全开发:用户凭证处理与数据加密最佳实践

在开发过程中&#xff0c;我们经常需要处理各种数据验证、权限检查和边界安全。今天要讨论的&#xff0c;不是一个具体的海关案例&#xff0c;而是一个在软件开发中极具警示意义的技术主题&#xff1a;如何在应用程序中安全地处理用户凭证&#xff08;如密码、PIN码、生物特征&…

作者头像 李华
网站建设 2026/9/1 22:28:57

大模型项目申请翻了5倍,我用这个框架砍掉了80%的无效投入

大模型项目申请翻了5倍,我用这个框架砍掉了80%的无效投入 当市场部想用大模型生成广告文案、客服部想用大模型替代人工、研发部想用大模型自动写代码注释的时候,我就意识到公司的 AI/ML 项目要出大问题了--这些需求听起来合理,但一算账全是坑。作为技术总监,我去年刚学完 面向…

作者头像 李华
网站建设 2026/9/1 22:28:10

AI客服不自由发挥:硬规则引擎+LLM结构化约束实战方案

这次我们来看一个实战问题&#xff1a;AI 客服上线后“自由发挥”怎么办&#xff1f;业务部门要求所有话术必须按规章来&#xff0c;但大模型一开口就经常跑偏&#xff0c;甚至承诺“可以无理由退款 100%”。问题不在模型本身&#xff0c;而在你把客服的“规则”全部塞进了提示…

作者头像 李华
网站建设 2026/9/1 22:27:10

基于SpringBoot+Vue的成绩管理系统:毕设项目实战全解析

简介&#xff1a;这是一套面向计算机专业本科生的高质量Java毕业设计实战资源&#xff0c;聚焦高校教务场景中的成绩管理核心业务&#xff0c;采用主流前后端分离架构&#xff08;SpringBoot Vue&#xff09;实现&#xff0c;兼顾工程规范性与教学适用性。资源包共385个文件&a…

作者头像 李华