03-AI应用全栈实战-从原型到生产
AI 应用全栈实战 · 从原型到生产
风格说明:本篇是 设计型(主)+ 操作型(辅)+ 机制型(辅)混合——前半段(§1-§4)讲 AI 项目与传统项目的本质差异与融合架构;中段(§5-§8)讲两个端到端实战(存量系统接入 AI + Dify 原型到 Spring AI 生产化)和 AI 项目的测试/CI/CD;后半段(§9-§12)讲转型路线图、团队组织、成本管理;尾段(§13-§15)讲大厂题、事故复盘、速记卡。这是 Java 后端开发者转型 AI 的方法论主线——能讲清"如何在存量系统中渐进式引入 AI"的候选人极少,这是面试区分度最高的能力。
前置阅读:01-Spring-AI与LangChain4j.md(Spring AI 核心 API);02-低代码AI平台-Dify-Coze与企业落地.md(Dify 架构与实战);03-RAG(RAG 全流程);04-Agent(Agent 框架)。
后续展开:02-Agent工程实践-生产落地Playbook.md(Agent 生产 12 域);01-电商AI辅助交易场景.md(电商 AI 落地)。
1. AI 应用与传统应用的本质差异
1.1 一句话定义
AI 应用 = 传统工程 + 不确定性管理。传统系统追求"确定性"(给定输入,输出唯一确定),AI 系统必须"管理概率"(给定输入,输出是概率分布,每次可能不同)。
1.2 确定性系统 vs 概率性系统
| 维度 | 传统系统 | AI 系统 |
|---|---|---|
| 输出确定性 | 相同输入 → 相同输出 | 相同输入 → 不同输出(temperature > 0) |
| 测试策略 | 断言 assertEquals(expected, actual) |
评估集 + 准确率/召回率阈值判定 |
| 错误处理 | try-catch + 重试 + 降级 | 幻觉检测 + 护栏 + 多级降级 + 人工兜底 |
| 版本管理 | Git 管代码 | Git 管代码 + Prompt + 模型版本 + 知识库版本 |
| 监控指标 | QPS / P99 / 错误率 | + Token 吞吐 / TTFT / 幻觉率 / 用户满意度 |
| SLA 定义 | “99.9% 请求 < 200ms” | “90% 回复准确 + 幻觉率 < 2% + P99 < 5s” |
| 部署模式 | 代码变更 → CI/CD → 上线 | 代码 / Prompt / 模型 / 知识库 四维独立部署 |
| 回滚策略 | 回滚代码版本 | 回滚 Prompt 版本 / 切换模型 / 回滚知识库 |
1.3 工程心智模型转换
| 传统思维 | AI 思维 | 实践转变 |
|---|---|---|
| 防止 bug(输出必须正确) | 管理不确定性(输出"足够好"即可) | 从 100% 正确到 95% 准确 + 5% 降级 |
| 单元测试通过 = 正确 | Eval 达标 = 可接受 | 从 assert 到评估集 + 阈值 |
| 代码决定行为 | Prompt + 模型 + 数据共同决定行为 | 三个变量都要版本管理 |
| 日志排查问题 | Trace 回放(每步 thought → action → observation) | 从 log.error 到 LangFuse trace |
| 固定成本(服务器月租) | 变动成本(按 token 计费) | 从 capacity planning 到 token budget |
| 接口契约(Swagger/OpenAPI) | 行为契约(Eval 集定义"什么是好回复") | 从 schema 到 golden dataset |
1.4 面试金句
“AI 系统的核心工程挑战不是’让 AI 更聪明’,而是’在 AI 不够聪明时,系统仍然可用’——降级、兜底、人工兜底是 AI 工程化的三道防线。”
2. AI 项目生命周期 vs 传统项目
2.1 两种生命周期对比
关键差异:AI 项目多了 “场景验证”(验证 LLM 能不能干这件事)和 “数据准备”(没有数据就没有 AI)两个前置阶段,且 "原型"阶段就要验证效果——而非像传统项目那样上线后才发现功能不符预期。
2.2 AI 项目特有阶段详解
| 阶段 | 目标 | 产出物 | 时长 | 常见陷阱 |
|---|---|---|---|---|
| 场景验证 | 确认 LLM 能解决这个问题 | 可行性报告 + 竞品调研 | 3-5 天 | 跳过此步直接写代码 |
| 数据准备 | 收集 FAQ / 知识库 / 标注数据 | 清洗后的数据集 | 1-2 周 | 数据质量差但急于开工 |
| 原型 PoC | 验证效果(准确率/召回率) | Dify 原型 + 效果报告 + badcase 清单 | 1-2 周 | 原型效果好就直接上生产 |
| MVP | 最小可用版本,小范围灰度 | Spring AI 项目 + 基础监控 | 2-4 周 | 没有降级/兜底就上线 |
| 生产化 | 工程加固:熔断/降级/监控/安全 | 生产级服务 + Eval CI/CD | 2-4 周 | 只关注 happy path |
| 持续优化 | 反馈闭环:badcase → 改 prompt/知识库 | 周报 + 指标趋势 | 持续 | 上线后无人维护 |
2.3 风险前移原则
AI 项目的核心原则是 “风险前移”——在原型阶段就验证效果,越早发现"AI 做不了",浪费越少。
Kill Criteria(终止条件清单):
| 信号 | 判定 | 动作 |
|---|---|---|
| PoC 准确率 < 60% | LLM 能力不足以解决此场景 | 停止,转规则/人工 |
| 知识库覆盖率 < 50% | 数据不足以支撑 RAG | 暂停,先补数据 |
| 关键 badcase 无法通过 prompt 修复 | 模型能力边界 | 评估微调 or 放弃 |
| 用户接受度调研 < 30% | 商业价值不足 | 停止 |
| 单次对话成本 > 人工成本 | ROI 不合理 | 降本 or 停止 |
2.4 面试金句
“AI 项目最大的浪费不是代码写多了,而是场景选错了——花 3 个月做了一个 LLM 做不了的事。场景验证是 AI 项目的第一道关。”
3. 传统 Java 项目引入 AI 的 5 种模式
3.1 模式总览
3.2 模式 1:API 增强
定义:在现有 API 上新增一个 AI 端点,不修改任何已有接口。
典型场景:订单摘要、商品描述自动生成、评论情感分析。
技术实现:新增 Controller + Service,调用 Spring AI ChatClient。
改动量:新增 2-3 个类,0 个类修改。
风险等级:🟢 极低——AI 不可用不影响任何现有功能。
@RestController
@RequestMapping("/api/v1/orders")
public class OrderAIController {
private final ChatClient chatClient;
@GetMapping("/{id}/summary")
public Mono<String> getOrderSummary(@PathVariable Long id) {
Order order = orderService.getById(id);
return chatClient.prompt()
.user("用一句话总结这个订单: " + order.toDescription())
.stream().content();
}
}
3.3 模式 2:旁路辅助
定义:AI 作为旁路提供推荐/摘要/标签,主业务流程完全不受影响。
典型场景:商品推荐理由生成、物流异常预警摘要、用户画像标签。
技术实现:异步调用 AI,结果写入缓存/DB,前端展示时取用。
改动量:新增 3-5 个类,0 个类修改。
风险等级:🟢 低——AI 结果不影响业务决策。
@Async("aiThreadPool")
public CompletableFuture<Void> generateRecommendReason(Product product) {
try {
String reason = chatClient.prompt()
.user("为这个商品写一句推荐理由: " + product.getName())
.call().content();
cache.put("recommend:" + product.getId(), reason, Duration.ofHours(24));
} catch (Exception e) {
// 旁路失败不影响主流程,只记日志
log.warn("AI 推荐理由生成失败: productId={}", product.getId(), e);
}
return CompletableFuture.completedFuture(null);
}
3.4 模式 3:决策支持
定义:AI 生成建议/草稿,人类确认后执行。
典型场景:客服回复草稿(人工审核后发送)、审核建议(AI 初审 + 人工复核)、退款建议。
技术实现:AI 生成建议 → 存入待审队列 → 人工确认 / 修改 → 执行。
改动量:新增 5-8 个类,修改 1-2 个类(添加审核流程)。
风险等级:🟡 中——AI 结果影响人的决策,但有人兜底。
public AuditSuggestion generateRefundSuggestion(RefundRequest request) {
String aiSuggestion = chatClient.prompt()
.system("你是风控审核员。判断退款是否合理,给出建议和理由。")
.user(request.toPrompt())
.call().content();
// AI 只给建议,不直接执行
return AuditSuggestion.builder()
.requestId(request.getId())
.aiRecommendation(aiSuggestion)
.status(AuditStatus.PENDING_HUMAN_REVIEW) // 必须人工确认
.build();
}
3.5 模式 4:流程替代
定义:AI 替代原有规则引擎/分类器,直接参与业务流程。
典型场景:工单自动分类(替代关键词规则)、风控评分(替代规则引擎)、智能路由。
技术实现:AI 作为 Service 实现替换原有 RuleEngine 实现,保留 fallback。
改动量:新增 5-8 个类,修改 2-5 个类(替换实现)。
风险等级:🟠 高——AI 直接参与业务决策,必须有降级。
// 策略模式:AI 实现 vs 规则实现
public interface TicketClassifier {
TicketCategory classify(Ticket ticket);
}
@Primary // AI 实现作为主实现
@Service
public class AITicketClassifier implements TicketClassifier {
@Override
@CircuitBreaker(name = "aiClassifier", fallbackMethod = "fallback")
public TicketCategory classify(Ticket ticket) {
return chatClient.prompt()
.user("分类这个工单: " + ticket.getContent())
.call()
.entity(TicketCategory.class);
}
// 降级到规则引擎
private TicketCategory fallback(Ticket ticket, Throwable t) {
return ruleClassifier.classify(ticket);
}
}
3.6 模式 5:AI-Native 新应用
定义:从零构建以 AI 为核心的全新应用。
典型场景:AI 客服 Bot、智能数据分析平台、代码生成工具。
技术实现:Spring AI + RAG + Agent + 前端 Chat UI。
改动量:全新项目。
风险等级:🔴 高——需要完整的 AI 工程化能力。
3.7 渐进式演进路径
| 阶段 | 模式 | 团队就绪度 | 建议时长 | 产出 |
|---|---|---|---|---|
| 起步 | 模式 1-2 | 1 人有 AI 基础 | 2-4 周 | 1 个旁路 AI 功能上线 |
| 验证 | 模式 3 | 2-3 人有经验 | 1-2 月 | AI 辅助决策流程 |
| 深入 | 模式 4 | 团队有 Eval 体系 | 2-3 月 | AI 替代部分规则引擎 |
| 成熟 | 模式 5 | AI 能力中心 | 3-6 月 | AI-Native 新产品 |
3.8 面试金句
“引入 AI 的正确姿势是’先加一个旁路,再替一个规则’——不是重写系统,是渐进增强。”
4. 技术架构:AI 层如何嵌入现有架构
4.1 分层架构集成
4.2 AI Service Layer 设计原则
| # | 原则 | 说明 | 实践 |
|---|---|---|---|
| 1 | 对上暴露确定性接口 | 入参 DTO + 出参 DTO,永不抛异常 | CustomerReply generateReply(CustomerQuery q) |
| 2 | 内部处理不确定性 | 重试 / 降级 / 兜底全在 AI 层解决 | 业务代码不知道回复来自 AI 还是规则 |
| 3 | 独立线程池 | AI 调用不占用业务线程(P99 可能 5-30s) | @Async("aiThreadPool") |
| 4 | 超时控制 | AI 调用必须设超时上限 | ChatOptions.builder().timeout(Duration.ofSeconds(5)) |
| 5 | 幂等设计 | AI 调用可安全重试 | 请求 ID + 缓存结果 |
| 6 | 审计日志 | 每次 AI 调用留完整 trace | trace_id + prompt + response + latency + cost |
4.3 降级策略(三道防线)
| 防线 | 延迟 | 准确率 | 成本 | 适用场景 |
|---|---|---|---|---|
| 第一道:AI(LLM) | 1-5s | 85-95% | $0.01-0.05/次 | 正常情况 |
| 第二道:语义缓存 | <100ms | 80-90% | ~$0 | AI 超时、高频重复问题 |
| 第三道:规则引擎 | <50ms | 60-70% | ~$0 | AI + 缓存都不可用 |
| 最终兜底:人工 | 分钟级 | 95%+ | $0.5-2/次 | 所有自动方案失败 |
4.4 与微服务架构融合:AI Gateway 模式
在微服务架构中,推荐引入 AI Gateway 作为所有 AI 调用的统一代理:
| 职责 | 说明 |
|---|---|
| 统一模型路由 | 按任务类型选模型(简单分类 → DeepSeek,复杂推理 → GPT-4o) |
| Token 限流 | 按租户 / App / 用户维度限流 |
| 成本分账 | $/request 按 BU/Team 分配 |
| 统一 Trace | trace_id 从 HTTP → AI Gateway → LLM Provider 贯穿 |
| 灰度发布 | Prompt 版本 / 模型版本 A/B 测试 |
| 熔断降级 | Provider 级熔断(OpenAI 挂了 → 切 DeepSeek) |
4.5 关键代码:AI Service 接口契约
/**
* AI Service 对外暴露确定性接口。
* 业务代码不知道回复来自 AI / 缓存 / 规则引擎——全部在内部处理。
*/
public interface CustomerServiceAI {
/**
* 生成客服回复。
* 承诺:永远不会抛异常,永远返回一个可用回复。
* AI 不可用时自动降级到规则引擎。
*/
CustomerReply generateReply(CustomerQuery query);
}
@Service
@Slf4j
public class CustomerServiceAIImpl implements CustomerServiceAI {
private final ChatClient chatClient; // Spring AI
private final SemanticCache semanticCache; // 语义缓存
private final RuleEngine ruleEngine; // 降级规则引擎
private final MeterRegistry meterRegistry; // 监控
@Override
public CustomerReply generateReply(CustomerQuery query) {
Timer.Sample sample = Timer.start(meterRegistry);
try {
// 第一道:AI 生成
CustomerReply reply = callAI(query);
sample.stop(meterRegistry.timer("ai.reply", "source", "ai"));
return reply;
} catch (Exception e) {
log.warn("AI 调用失败,尝试缓存降级: {}", e.getMessage());
try {
// 第二道:语义缓存
CustomerReply cached = semanticCache.findSimilar(query);
if (cached != null) {
sample.stop(meterRegistry.timer("ai.reply", "source", "cache"));
return cached;
}
} catch (Exception cacheEx) {
log.warn("语义缓存查询失败: {}", cacheEx.getMessage());
}
// 第三道:规则引擎
sample.stop(meterRegistry.timer("ai.reply", "source", "rule"));
return ruleEngine.generateReply(query);
}
}
@CircuitBreaker(name = "llm", fallbackMethod = "circuitFallback")
@TimeLimiter(name = "llm") // 5s 超时
private CustomerReply callAI(CustomerQuery query) {
String response = chatClient.prompt()
.system("你是电商客服助手。根据知识库回答客户问题。不确定时说'我帮您转接人工客服'。")
.advisors(new QuestionAnswerAdvisor(vectorStore)) // RAG
.advisors(new SafeGuardAdvisor()) // 护栏
.user(query.getContent())
.call()
.content();
return new CustomerReply(response, ReplySource.AI);
}
}
4.6 线程池隔离配置
@Configuration
public class AIThreadPoolConfig {
@Bean("aiThreadPool")
public Executor aiThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50); // 独立线程池,不影响业务
executor.setQueueCapacity(100);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("ai-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
4.7 面试金句
“AI Service Layer 的核心设计原则:对上确定性,对下管不确定性。业务代码不应该知道’这个回复是 AI 生成的还是规则引擎生成的’。”
5. 实战 1:为存量订单系统添加智能客服
5.1 场景描述
| 维度 | 现状 |
|---|---|
| 现有系统 | Spring Boot 2.7 + MyBatis + MySQL + Redis |
| DAU | 10K,日均客服咨询 500 次 |
| 现有客服 | 规则引擎(关键词匹配 200 条规则)+ 人工(3 人) |
| 痛点 | 规则覆盖率 40%,60% 转人工;人工成本 $3K/月 |
| 目标 | AI 客服覆盖率 80%+,人工处理量降 50% |
| 约束 | 不改动现有订单/支付代码 |
5.2 架构设计
5.3 实施步骤
Step 1:梳理 FAQ 数据(2 天)
-- 从现有客服记录提取高频问题
SELECT question_category, COUNT(*) as cnt,
GROUP_CONCAT(DISTINCT question SEPARATOR '\n') as samples
FROM customer_service_log
WHERE created_at > DATE_SUB(NOW(), INTERVAL 6 MONTH)
GROUP BY question_category
ORDER BY cnt DESC
LIMIT 50;
产出:50 个 FAQ 分类,每类 5-10 个标准问答对,共 ~300 条。
Step 2:搭建 RAG 知识库(3 天)
// application.yml
spring:
ai:
vectorstore:
pgvector:
dimensions: 1024
index-type: HNSW
openai:
embedding:
model: text-embedding-3-small
// 知识库初始化
@Component
public class KnowledgeBaseLoader implements CommandLineRunner {
@Override
public void run(String... args) {
// 1. 读取 FAQ 文档
List<Document> docs = new JsonReader("classpath:faq.json").get();
// 2. 分块
TokenTextSplitter splitter = new TokenTextSplitter(500, 100, 5, 1000, true);
List<Document> chunks = splitter.apply(docs);
// 3. 写入向量库
vectorStore.accept(chunks);
log.info("知识库初始化完成: {} 文档 → {} 片段", docs.size(), chunks.size());
}
}
Step 3:接入订单查询 Tool(2 天)
@Component
public class OrderTools {
private final OrderService orderService; // 现有 Service,不修改
@Tool(description = "根据订单号查询订单状态、物流信息")
public OrderInfo queryOrder(
@ToolParam(description = "订单号,格式如 ORD202601001") String orderId) {
Order order = orderService.getByOrderNo(orderId);
if (order == null) {
return new OrderInfo("未找到订单 " + orderId);
}
return OrderInfo.from(order); // DTO 转换,不暴露内部字段
}
@Tool(description = "查询用户最近5笔订单")
public List<OrderInfo> queryRecentOrders(
@ToolParam(description = "用户ID") Long userId) {
return orderService.getRecentOrders(userId, 5)
.stream().map(OrderInfo::from).toList();
}
}
Step 4:添加 Advisor 护栏(1 天)
@Component
public class CustomerServiceGuardrail implements CallAdvisor {
// 禁止 AI 承诺的敏感操作
private static final List<String> BLOCKED_PATTERNS = List.of(
"我帮你退款", "已为您退款", "赔偿.*元",
"我代表公司承诺", "保证.*天内"
);
@Override
public String getName() { return "customer-service-guardrail"; }
@Override
public int getOrder() { return Ordered.HIGHEST_PRECEDENCE + 10; }
@Override
public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
ChatClientResponse response = chain.nextCall(request);
String content = response.chatResponse().getResult().getOutput().getText();
for (String pattern : BLOCKED_PATTERNS) {
if (Pattern.compile(pattern).matcher(content).find()) {
return ChatClientResponse.builder()
.chatResponse(ChatResponse.builder()
.generations(List.of(new Generation(
"这个问题需要人工客服为您处理,正在为您转接。")))
.build())
.build();
}
}
return response;
}
}
Step 5:流式输出 SSE(1 天)
@RestController
@RequestMapping("/api/v1/chat")
public class ChatController {
@PostMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> chat(@RequestBody ChatRequest request) {
return customerServiceAI.generateReplyStream(request.toQuery())
.map(chunk -> ServerSentEvent.<String>builder()
.data(chunk)
.build())
.concatWith(Flux.just(ServerSentEvent.<String>builder()
.event("done")
.data("[DONE]")
.build()));
}
}
Step 6:降级 + 熔断(1 天)
# application.yml
resilience4j:
circuitbreaker:
instances:
llm:
failure-rate-threshold: 50
wait-duration-in-open-state: 30s
sliding-window-size: 10
timelimiter:
instances:
llm:
timeout-duration: 5s
Step 7:监控上线(2 天)
@Aspect
@Component
public class AIMetricsAspect {
@Around("execution(* com.example.ai..*.*(..))")
public Object trackAIMetrics(ProceedingJoinPoint pjp) throws Throwable {
Timer.Sample sample = Timer.start(meterRegistry);
try {
Object result = pjp.proceed();
Counter.builder("ai.calls.total")
.tag("status", "success")
.tag("method", pjp.getSignature().getName())
.register(meterRegistry).increment();
return result;
} catch (Exception e) {
Counter.builder("ai.calls.total")
.tag("status", "error")
.tag("method", pjp.getSignature().getName())
.register(meterRegistry).increment();
throw e;
} finally {
sample.stop(meterRegistry.timer("ai.call.duration",
"method", pjp.getSignature().getName()));
}
}
}
5.4 改动量评估
| 类别 | 数量 | 说明 |
|---|---|---|
| 新增类 | 8 个 | ChatController, CustomerServiceAI, AIServiceImpl, OrderTools, Guardrail, Metrics, Config, Loader |
| 修改类 | 0 个 | 零改动现有业务代码 |
| 新增配置 | 3 个 | application-ai.yml, resilience4j 配置, 线程池配置 |
| 新增依赖 | 4 个 | spring-ai-openai, spring-ai-pgvector, resilience4j, langfuse-java |
| 新增表 | 1 个 | vector_store(PgVector 自动创建) |
| 改动 DB | 0 | 不改动现有表结构 |
5.5 效果量化
| 指标 | 改造前 | 改造后 | 提升 |
|---|---|---|---|
| AI 覆盖率(不转人工) | 40% | 83% | +43pp |
| 平均响应时间 | 3-5 min(人工) | 2.1s(AI) | 100×+ |
| 人工客服处理量 | 300 次/天 | 120 次/天 | -60% |
| 月度人力成本 | $3,000 | $1,200 | -60% |
| AI API 成本 | $0 | $150/月 | 新增 |
| 用户满意度 | 72% | 81% | +9pp |
6. 实战 2:Dify 原型 → Spring AI 生产化
6.1 三阶段迁移
6.2 Phase 1:Dify 原型验证(1-2 周)
Day 1-2:创建 Dify 知识库
- 上传 FAQ 文档(PDF / Markdown / 在线链接)
- Chunking 配置:按 heading 分割 + 500 token + overlap 100
- Embedding 模型:bge-large-zh-v1.5(中文场景)
Day 3-5:配置 Chat App
- 选择模型(DeepSeek-V3 / GPT-4o-mini)
- 绑定知识库,配置 TopK=3、Score Threshold=0.6
- 编写 System Prompt,加入规则约束
Day 6-10:内测 + 收集 badcase
- 邀请 5 个客服人员使用,记录每次对话
- 标注 badcase(答非所问 / 幻觉 / 过度承诺)
- 统计效果:准确率 / 召回率 / 幻觉率
Day 10-14:效果报告
| 指标 | 目标 | 实际 | Go/No-Go |
|---|---|---|---|
| 准确率 | ≥80% | 84% | ✅ Go |
| 召回率 | ≥70% | 72% | ✅ Go |
| 幻觉率 | ≤5% | 3.2% | ✅ Go |
| 平均延迟 | ≤5s | 2.8s | ✅ Go |
6.3 Phase 2:Spring AI 生产化(2-4 周)
从 Dify 复用的结论(不需要重新实验):
| 结论 | Dify 验证结果 | Spring AI 沿用 |
|---|---|---|
| Chunking 策略 | 按 heading 分割 + 500 token | TokenTextSplitter(500, 100) |
| Embedding 模型 | bge-large-zh-v1.5 | spring.ai.embedding.model=bge-large-zh |
| 检索参数 | TopK=3, Score>0.6 | SearchRequest.defaults().withTopK(3).withSimilarityThreshold(0.6) |
| Prompt 模板 | 验证过的 system prompt | 直接搬到 Spring AI |
| LLM 模型 | DeepSeek-V3 | spring.ai.model=deepseek-chat |
Spring AI 重写新增的工程能力:
| 能力 | Dify 不提供 | Spring AI 实现 |
|---|---|---|
| 降级兜底 | ❌ | Resilience4j + 规则引擎 fallback |
| 独立线程池 | ❌ | @Async("aiThreadPool") |
| 多租户 | 有限 | 按 tenant 隔离 VectorStore + API Key |
| 深度集成 | ❌ | 直接查订单 DB、调用内部 RPC |
| 自定义 Eval CI | ❌ | Maven + Eval Runner + 阈值卡点 |
| 精细监控 | 有限 | Micrometer + Grafana + LangFuse |
6.4 Phase 3:混合运营(持续)
| 场景 | Dify 承担 | Spring AI 承担 |
|---|---|---|
| 核心客服流程 | ❌ | ✅ 高并发 + 降级 + 监控 |
| 运营自助(FAQ 更新) | ✅ 运营自己上传文档 | ❌ |
| 新 Prompt 实验 | ✅ 在 Dify 上 A/B 测试 | 效果好再搬到代码 |
| 内部知识库 QA | ✅ 低流量场景 | ❌ |
| 培训数据标注 | ✅ 导出对话记录 | ❌ |
6.5 成本对比
| 维度 | 纯自研(Spring AI) | 纯 Dify | 混合模式 |
|---|---|---|---|
| PoC 人天 | 15-20 人天 | 2-3 人天 | 3 人天(Dify PoC) |
| 生产化人天 | 20-30 人天 | 5-10 人天 | 15-20 人天(Spring AI 核心) |
| 上线速度 | 6-8 周 | 2-3 周 | 4-5 周 |
| 维护成本/月 | 中(代码维护) | 低(平台维护) | 中 |
| 灵活度 | 🟢 完全可控 | 🟡 受限于平台 | 🟢 核心可控 |
| 并发支撑 | 🟢 万级 | 🟡 百级(SaaS) | 🟢 核心万级 |
| 适用团队 | ≥3 人有 AI 经验 | 1 人即可 | 1 人 AI + 2 人 Java |
7. AI 项目的测试策略
7.1 传统测试 vs AI 测试
| 维度 | 传统测试 | AI 测试 |
|---|---|---|
| 正确性判定 | assert expected == actual |
准确率 / 召回率 / F1 阈值 |
| 测试数据 | 固定 fixture | 评估集(100-2000 条标注数据) |
| 回归标准 | 零回归(0 test failure) | 可容忍范围内(≤2% 回归) |
| Mock 策略 | Mock 外部依赖 | Mock LLM 输出 + 真实 LLM 测试 |
| 覆盖率 | 代码覆盖率 | 场景覆盖率(FAQ 分类覆盖) |
| 环境 | 本地/CI 可运行 | 需要模型 API(成本) |
7.2 AI 测试金字塔
| 层 | 目的 | Mock LLM? | 运行频率 | 示例 |
|---|---|---|---|---|
| L1 Unit | 测试解析、格式化、降级逻辑 | ✅ Mock | 每次提交 | AI 返回 null 时降级是否正常 |
| L2 Integration | 验证 happy path + 核心场景 | ❌ 真实 LLM | 每日 CI | 问"订单状态"是否正确调用 Tool |
| L3 Eval | 量化质量指标 | ❌ 真实 LLM | 每次 Prompt 变更 | 500 条标注数据跑准确率 |
| L4 Shadow | 线上真实效果 | ❌ 真实流量 | 持续 | 1% 流量影子对比 AI vs 规则 |
7.3 评估集构建
数据来源:
| 来源 | 方法 | 数量 |
|---|---|---|
| Dify 对话记录 | 导出 → 人工标注 “好/坏” | 100-200 条 |
| 客服历史记录 | 提取问答对 + 客服评价 | 200-300 条 |
| 人工构造 | 边界 case、对抗样本 | 50-100 条 |
| 线上 badcase | 用户👎反馈的对话 | 持续积累 |
评估集格式:
{
"id": "eval-001",
"input": "我的订单 ORD202601001 到哪了?",
"expected_behavior": "调用 queryOrder 工具,返回物流状态",
"expected_keywords": ["物流", "配送", "到达"],
"forbidden_keywords": ["退款", "赔偿"],
"category": "order_query",
"difficulty": "easy"
}
规模指引:
| 阶段 | 评估集规模 | 说明 |
|---|---|---|
| MVP | 100 条 | 覆盖 Top 20 FAQ 类别 |
| Production | 500 条 | 覆盖全部 FAQ + 边界 case |
| Mature | 2000+ 条 | + 对抗样本 + 多轮对话 |
7.4 Prompt 回归测试
Prompt v1.2 变更 → 自动触发 Eval 跑批 → 对比 v1.1 指标
↓
准确率下降 > 2%?
↓ ↓
是 否
↓ ↓
Block 部署 允许部署
7.5 关键代码:Spring AI 测试示例
// Layer 1: Unit Test(Mock LLM)
@ExtendWith(MockitoExtension.class)
class CustomerServiceAITest {
@Mock ChatClient chatClient;
@Mock RuleEngine ruleEngine;
@InjectMocks CustomerServiceAIImpl service;
@Test
void should_fallback_to_rule_engine_when_ai_fails() {
// Given: LLM 超时
when(chatClient.prompt()).thenThrow(new AITimeoutException("timeout"));
when(ruleEngine.generateReply(any()))
.thenReturn(new CustomerReply("请稍候", ReplySource.RULE));
// When
CustomerReply reply = service.generateReply(new CustomerQuery("我的订单呢"));
// Then: 降级到规则引擎,不抛异常
assertThat(reply.getSource()).isEqualTo(ReplySource.RULE);
assertThat(reply.getContent()).isNotEmpty();
}
}
// Layer 3: Eval 评估集跑批
@SpringBootTest
@Tag("eval") // CI 中单独跑
class CustomerServiceEvalTest {
@Autowired CustomerServiceAI service;
@ParameterizedTest
@JsonFileSource(resources = "/eval-dataset.json")
void eval_accuracy(EvalCase evalCase) {
CustomerReply reply = service.generateReply(
new CustomerQuery(evalCase.getInput()));
// 关键词命中检查
for (String keyword : evalCase.getExpectedKeywords()) {
assertThat(reply.getContent()).contains(keyword);
}
// 禁止词检查
for (String forbidden : evalCase.getForbiddenKeywords()) {
assertThat(reply.getContent()).doesNotContain(forbidden);
}
}
}
8. AI 项目的 CI/CD 与版本管理
8.1 传统 CI/CD vs AI CI/CD
| 管理维度 | 传统 CI/CD | AI CI/CD |
|---|---|---|
| 代码 | ✅ Git | ✅ Git |
| Prompt | ❌ 不存在 | ✅ Git + 语义版本号 |
| 模型版本 | ❌ 不存在 | ✅ 锁定版本(gpt-4o-2024-08-06) |
| 评估集 | ❌ 不存在 | ✅ Git LFS + 版本号 |
| 知识库 | ❌ 不存在 | ✅ 文档版本 + 向量重建触发 |
| 回归门槛 | 0 test failures | 准确率 ≥ 阈值 + 幻觉率 ≤ 阈值 |
8.2 AI CI/CD Pipeline
8.3 Prompt as Code
src/main/resources/prompts/
├── customer-service/
│ ├── v1.0/
│ │ ├── system.txt # System Prompt
│ │ ├── user-template.txt # User Template
│ │ └── CHANGELOG.md
│ ├── v1.1/
│ │ ├── system.txt
│ │ ├── user-template.txt
│ │ └── CHANGELOG.md
│ └── current -> v1.1/ # 符号链接指向当前版本
├── refund-review/
│ └── ...
└── prompt-config.yml # 配置哪个场景用哪个版本
# prompt-config.yml
prompts:
customer-service:
version: v1.1
model: deepseek-chat
temperature: 0.3
refund-review:
version: v1.0
model: gpt-4o
temperature: 0.1
PR Review 时,Prompt 变更必须附带:
- 变更原因(修复什么 badcase)
- Eval 对比结果(v1.0 vs v1.1 的指标差异)
- badcase 改善截图
8.4 灰度策略
| 灰度维度 | 方法 | 示例 |
|---|---|---|
| Prompt 版本 A/B | 按用户 ID hash 分流 | 50% v1.0 + 50% v1.1 |
| 模型 A/B | 按请求路由 | 80% DeepSeek + 20% GPT-4o |
| 知识库版本 A/B | 按 tenant 分流 | 新版知识库给内部测试用户 |
8.5 CI 配置示例
# .github/workflows/ai-ci.yml
name: AI CI Pipeline
on: [push, pull_request]
jobs:
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build & Unit Test
run: mvn test -Dgroups="!eval" # 排除 eval 标签
eval-gate:
needs: unit-test
runs-on: ubuntu-latest
if: contains(github.event.head_commit.message, '[eval]') ||
github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Run AI Eval
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: mvn test -Dgroups="eval" -Deval.output=eval-results.json
- name: Check Eval Threshold
run: |
ACCURACY=$(cat eval-results.json | jq '.accuracy')
HALLUCINATION=$(cat eval-results.json | jq '.hallucination_rate')
echo "Accuracy: $ACCURACY, Hallucination: $HALLUCINATION"
if (( $(echo "$ACCURACY < 0.85" | bc -l) )); then
echo "❌ Accuracy $ACCURACY below 0.85 threshold"
exit 1
fi
if (( $(echo "$HALLUCINATION > 0.03" | bc -l) )); then
echo "❌ Hallucination rate $HALLUCINATION above 3% threshold"
exit 1
fi
echo "✅ Eval passed"
9. AI 项目的可观测性
9.1 传统监控 + AI 专属指标
| 类别 | 指标 | 来源 | 告警阈值 |
|---|---|---|---|
| 传统 | QPS / P99 / 错误率 | Micrometer | P99 > 5s |
| AI - 延迟 | TTFT(首 token 时间) | AI Service | TTFT > 3s |
| AI - 延迟 | TPOT(token 间延迟) | AI Service | TPOT > 100ms |
| AI - 质量 | 幻觉率 | LangFuse + 人工标注 | > 5% |
| AI - 质量 | 工具调用成功率 | AI Service | < 95% |
| AI - 质量 | RAG 召回率 | VectorStore | < 70% |
| AI - 质量 | 用户满意度(👍👎) | 前端反馈 | 👎率 > 15% |
| AI - 成本 | $/request | AI Gateway | 单日 > $X |
| AI - 成本 | Token 吞吐(input/output) | AI Gateway | 日用量 > 预算 |
| AI - 降级 | 降级触发率 | Resilience4j | > 10% |
9.2 成本监控
成本分账公式:
月成本 = Σ(每次请求的 input_tokens + output_tokens) × 模型单价
按维度拆分:
- 按 App: 客服 $120/月, 工单分类 $30/月
- 按 Model: DeepSeek $80/月, GPT-4o $70/月
- 按 Tenant: 华东 $60/月, 华南 $45/月
告警规则:
- 幻觉率 > 5% → P1 告警(立即排查)
- 单日 AI 成本 > 预算 120% → P2 告警(限流)
- 降级率 > 20% → P1 告警(模型 Provider 可能故障)
9.3 Trace 贯穿
将 AI 调用的 trace 与现有 OpenTelemetry 链路打通:
@Component
public class AITraceInterceptor implements CallAdvisor {
@Override
public String getName() { return "ai-trace-langfuse"; }
@Override
public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
Span currentSpan = Span.current();
String traceId = currentSpan.getSpanContext().getTraceId();
String userText = request.prompt().getUserMessage().getText();
langfuse.trace(TraceParams.builder()
.traceId(traceId)
.name("ai-customer-service")
.input(userText)
.metadata(Map.of(
"model", request.prompt().getOptions() != null
? String.valueOf(request.prompt().getOptions()) : "default",
"prompt_version", "v1.1"
))
.build());
return chain.nextCall(request);
}
}
一次请求的 trace 链路:HTTP Request → Spring MVC → Service → AI Service → LLM Call → Tool Call(订单查询) → LLM Response → Guardrail → Response——每一步都可在 LangFuse 中回放。
9.4 Grafana Dashboard 指标清单
| 面板 | 指标 | PromQL 示例 |
|---|---|---|
| AI 调用 QPS | rate(ai_calls_total[5m]) |
按 source 分(ai/cache/rule) |
| AI 延迟分布 | histogram_quantile(0.99, ai_call_duration_bucket) |
P50/P95/P99 |
| 降级率 | rate(ai_calls_total{source="rule"}[5m]) / rate(ai_calls_total[5m]) |
目标 < 5% |
| Token 用量 | sum(ai_tokens_total) by (type) |
input vs output |
| 日成本 | sum(ai_cost_usd) |
目标 < $X/天 |
| 幻觉率 | rate(ai_hallucination_total[1h]) / rate(ai_calls_total{source="ai"}[1h]) |
目标 < 2% |
| 用户满意度 | rate(ai_feedback{type="positive"}[1d]) / rate(ai_feedback[1d]) |
目标 > 85% |
10. Java 开发者转型路线图
10.1 四阶段转型
10.2 每阶段详解
Phase 1:认知期(Month 1-2)
| 维度 | 内容 |
|---|---|
| 学习目标 | 理解 LLM 能力边界 + Prompt 工程基础 + Dify 使用 |
| 实践项目 | 用 Dify 为团队搭一个内部知识库 QA |
| 产出物 | Dify 原型 + 效果报告 + 技术调研文档 |
| 面试加分项 | “我用 Dify 2 天搭了一个内部知识库,准确率 78%,验证了 RAG 可行性” |
| 推荐资源 | 本套件 02-Prompt + 15-低代码平台 + Dify 官方文档 |
Phase 2:实战期(Month 2-4)
| 维度 | 内容 |
|---|---|
| 学习目标 | Spring AI 核心 API + RAG 工程化 + Tool Calling |
| 实践项目 | 在现有系统中加一个 AI 功能(§5 模式 1-2) |
| 产出物 | 上线的 AI 功能 + 监控 Dashboard + Eval 集 |
| 面试加分项 | “我在存量订单系统中加了 AI 客服,零改动业务代码,AI 覆盖率从 40% 提升到 83%” |
| 推荐资源 | 本套件 03-RAG + 14-Spring AI + Spring AI 官方文档 |
Phase 3:深化期(Month 4-8)
| 维度 | 内容 |
|---|---|
| 学习目标 | Agent 架构 + 微调基础 + Eval 体系 + LLM 原理 |
| 实践项目 | 多工具 Agent(客服 + 订单 + 物流 + 退款)+ Eval CI 管线 |
| 产出物 | Agent 系统 + Eval CI/CD + 微调实验报告 |
| 面试加分项 | “我设计了 4 工具 Agent,建了 500 条评估集,Prompt 变更自动跑回归” |
| 推荐资源 | 本套件 04-Agent + 13-Playbook + 01-Transformer + 09-微调 |
Phase 4:架构期(Month 8-12)
| 维度 | 内容 |
|---|---|
| 学习目标 | AI 平台化 + 成本治理 + 团队赋能 |
| 实践项目 | AI Gateway + 内部 AI SDK + 培训课程 |
| 产出物 | AI 平台架构文档 + SDK + 团队 AI 能力提升 |
| 面试加分项 | “我设计了公司 AI 平台,提供 Spring Boot Starter,3 个业务团队接入 AI 的时间从 4 周降到 3 天” |
| 推荐资源 | 本套件 07-部署 + 12-前沿 + 全域架构知识 |
10.3 技能矩阵:Java → AI 技能映射
| 现有 Java 技能 | 对应 AI 技能 | 学习门槛 |
|---|---|---|
| Spring MVC Controller | Spring AI ChatClient / SSE Stream | 🟢 低(API 类似) |
| MyBatis / JPA | VectorStore / DocumentReader | 🟢 低(CRUD 思维通用) |
| REST API 设计 | Tool / Function Calling 设计 | 🟢 低(JSON Schema) |
| JUnit / Mockito | AI Eval 评估集 + Prompt 回归测试 | 🟡 中(思维转换) |
| Resilience4j 熔断降级 | AI 调用降级兜底 | 🟢 低(直接复用) |
| Spring Security | AI Guardrails / Advisor 护栏 | 🟡 中(拦截器模式类似) |
| Micrometer + Grafana | AI 可观测性(Token/幻觉率/成本) | 🟢 低(加指标而已) |
| Spring Boot Starter 开发 | AI 接入 Starter(封装最佳实践) | 🟢 低 |
| 分布式事务 Saga | Agent 多步任务回滚 / Checkpoint | 🟡 中 |
| 规则引擎(Drools) | LLM 替代规则 + 降级回规则 | 🟡 中 |
10.4 面试金句
“Java 开发者转 AI 的最大优势是工程化能力——AI 研究员能让模型准确率从 85% 到 90%,但 Java 工程师能让 AI 在生产环境 99.9% 可用。”
11. 团队转型与组织适配
11.1 转型四阶梯
| 阶段 | 人员 | 目标 | 产出 | 时长 |
|---|---|---|---|---|
| 1. 单人先行 | 1 名 Senior Java 工程师 | 跑通 PoC | Dify 原型 + 可行性报告 | 2-4 周 |
| 2. 双人小组 | 1 Java + 1 AI(或 1 人兼) | 做 MVP | Spring AI 生产级功能 | 1-2 月 |
| 3. AI 能力中心 | 3-5 人 AI 平台组 | 提供 SDK/平台 | AI Gateway + Starter + Eval 平台 | 3-6 月 |
| 4. AI-First 组织 | 每团队有 AI 能力 | 全面 AI 化 | 所有业务线有 AI 功能 | 6-12 月 |
11.2 组织反模式(5 个不要做的事)
| 反模式 | 为什么错 | 正确做法 |
|---|---|---|
| ❌ 全员转 Python | Java 工程能力是核心优势 | 用 Spring AI,保持 Java 主栈 |
| ❌ 单独建 AI 团队不与业务融合 | AI 脱离业务场景无法落地 | AI 平台组 + 业务团队 embedding |
| ❌ 没有 Eval 体系就上生产 | 幻觉率不可控 | 先建 Eval 集,再上线 |
| ❌ 让算法工程师做工程化 | 算法≠工程,生产化需要 Java 基建功底 | 算法调模型 + Java 工程师做生产化 |
| ❌ 追求 AGI 而忽视 ROI | 绝大多数业务只需要 RAG + Tool Calling | 从高 ROI 场景开始(客服、分类) |
11.3 Tech Lead 决策清单
在决定让团队引入 AI 之前,确认以下 10 项:
- 1. 明确了 AI 要解决的具体业务问题(不是"我们也要做 AI")
- 2. 有可用的数据/知识库(FAQ、文档、历史记录)
- 3. 至少 1 人有 Prompt 工程基础或能快速学习
- 4. 有明确的效果指标和验收标准(准确率、覆盖率)
- 5. 有降级方案(AI 不可用时怎么办)
- 6. 有 API 预算和成本上限
- 7. 已评估数据安全和合规要求(敏感数据是否可经外部 API)
- 8. 有 Eval 集构建计划(至少 100 条)
- 9. 有监控计划(幻觉率、成本、延迟)
- 10. 管理层理解"AI 不是 100% 准确"并接受一定容错
12. 成本管理与 FinOps
12.1 AI 应用成本结构
12.2 成本公式
月成本 = DAU × 平均对话轮次 × 平均 token/轮 × 模型单价
示例(电商客服):
DAU = 10,000
平均对话轮次 = 3
平均 token/轮 = 800 (input 500 + output 300)
模型单价 = $0.002 / 1K tokens (DeepSeek-V3)
月成本 = 10,000 × 3 × 0.8 × $0.002 × 30 天
= $1,440/月
12.3 降本 5 招
| # | 策略 | 降本幅度 | 实施难度 | 说明 |
|---|---|---|---|---|
| 1 | Prompt 压缩 | 30-50% | 🟢 低 | 精简 system prompt + 移除冗余上下文 |
| 2 | 语义缓存 | 20-40% | 🟡 中 | 相似问题命中缓存,不调 LLM |
| 3 | 小模型路由 | 50-70% | 🟡 中 | 简单任务→DeepSeek,复杂→GPT-4o |
| 4 | 批量推理 | 30-50% | 🟢 低 | 非实时任务攒批调用,Batch API 5折 |
| 5 | 自部署开源模型 | 60-80% | 🔴 高 | >10K req/day 时经济拐点,用 vLLM 部署 Qwen/Llama |
12.4 案例:从月费 $12K 降到 $3K
背景:电商智能客服,50K DAU,全量使用 GPT-4o,月成本 $12K。
优化过程:
| 步骤 | 动作 | 成本变化 | 效果影响 |
|---|---|---|---|
| Step 1 | Prompt 压缩(2500→1500 tokens/轮) | $12K → $7.2K | 无影响 |
| Step 2 | 60% 简单问题路由到 DeepSeek | $7.2K → $3.6K | 准确率 -1pp(可接受) |
| Step 3 | 语义缓存(命中率 25%) | $3.6K → $2.7K | 无影响 |
| Step 4 | 非实时场景用 Batch API | $2.7K → $2.4K | 延迟增加但可接受 |
| 总计 | — | $12K → $2.4K(-80%) | 准确率 -1pp |
// 模型路由示例
@Service
public class ModelRouter {
public String routeModel(CustomerQuery query) {
int complexity = assessComplexity(query);
if (complexity <= 3) {
return "deepseek-chat"; // 简单问题,便宜模型
} else if (complexity <= 7) {
return "gpt-4o-mini"; // 中等问题
} else {
return "gpt-4o"; // 复杂问题,最强模型
}
}
private int assessComplexity(CustomerQuery query) {
// 基于规则的复杂度评估(不调 LLM)
int score = 0;
if (query.containsOrderId()) score += 2; // 涉及订单查询
if (query.isMultiTurn()) score += 3; // 多轮对话
if (query.containsRefund()) score += 4; // 涉及退款
if (query.getContent().length() > 200) score += 1; // 长文本
return score;
}
}
13. 大厂面试题 5 道
Q1: 🟧阿里 — 如何将存量 Java 微服务体系渐进式引入 AI 能力,不影响现有 SLA
(1) 标准答案
核心方法论是 “AI Service Layer 隔离 + 三道降级防线 + 独立资源池”。在现有微服务中新增 AI Service Layer,对上暴露确定性接口(入参 DTO + 出参 DTO,永不抛异常),对下管理 LLM 调用的不确定性。AI 调用走独立线程池,不占用业务 Tomcat 线程。三道降级防线保障 AI 不可用时业务正常:AI → 语义缓存 → 规则引擎 → 人工兜底。
(2) 原理 walk
渐进式引入遵循 5 种模式(从低风险到高风险):
- API 增强(加一个
/summary端点,零风险) - 旁路辅助(异步生成推荐理由,主流程不受影响)
- 决策支持(AI 出退款建议,人工确认后执行)
- 流程替代(AI 替代工单分类规则引擎,有 fallback)
- AI-Native(全新 AI 应用)
每个阶段需要不同的团队成熟度和工程保障。推荐从模式 1-2 开始,积累经验后再推进到 3-4。
关键是 AI Service Layer 的接口设计——策略模式封装 AI 实现和规则实现,上层代码不感知切换:
public interface TicketClassifier {
TicketCategory classify(Ticket ticket);
}
// AI 实现 @Primary + @CircuitBreaker(fallback = ruleClassifier)
// 规则实现作为 fallback
(3) 权衡与量化数字
| 指标 | 要求 | 说明 |
|---|---|---|
| AI 调用 P99 | ≤ 5s(含降级) | 超过 5s 触发熔断 |
| 独立线程池 | max=50,与业务 200 线程分离 | AI 线程耗尽不影响订单/支付 |
| 降级延迟 | 缓存 <100ms,规则 <50ms | 降级后延迟必须可接受 |
| 熔断参数 | 50% 错误率开启,30s 半开探测 | Resilience4j 配置 |
| 降级率 | 正常 <5%,大促 <15% | 超过 15% 说明 AI 能力不足 |
(4) 落地清单
- AI 调用独立线程池(max pool size = min(50, 业务线程 × 25%))
- Resilience4j 熔断 + 超时(5s)
- 三级降级链(AI → 缓存 → 规则 → 人工)
- 配置中心 AI 开关(可一键关闭所有 AI)
- AI 调用审计日志(trace_id + prompt + response + latency + cost)
- Eval 集 ≥ 100 条 + CI 卡点
- Token 成本预算 + 日限额告警
- 上线前压测:强制关闭 AI,验证降级链路
(5) 风险
| 风险 | 概率 | 影响 | 缓解 |
|---|---|---|---|
| AI 调用超时阻塞业务线程 | 高 | 全站不可用 | 独立线程池 + 超时 5s |
| LLM 幻觉导致错误承诺 | 中 | 客诉 + 赔偿 | Guardrail 护栏 + 人工审核 |
| Token 成本失控 | 中 | 预算超支 | 限额 + 告警 + 模型路由 |
| Prompt 注入 | 低 | 数据泄露 | 输入清洗 + system prompt 隔离 |
Q2: 🟦字节 — AI 项目从 PoC 到生产的效果衰减(线下 90% → 线上 60%)如何解决
(1) 标准答案
效果衰减的根因通常是 评估集不代表真实分布。解决方法是建立 “线上-线下一致性闭环”:从生产流量回采样例到评估集、用 Shadow 模式对比线上线下效果、建立持续的 Eval 监控。
(2) 原理 walk
效果衰减的 4 大根因:
| 根因 | 占比 | 表现 |
|---|---|---|
| 评估集偏倚 | 40% | PoC 用干净数据测试,线上用户提问千奇百怪 |
| 分布偏移 | 25% | 线上问题分布与评估集分布不同(高频≠标注多) |
| 上下文差异 | 20% | PoC 是单轮测试,线上是多轮对话 + 历史上下文 |
| 对抗输入 | 15% | 用户故意/无意输入 edge case |
修复流程:
线上 badcase 收集 → 分类(幻觉/错误/拒答/格式)
→ 按类型修复(Prompt/RAG/Tool/Guardrail)
→ 新 badcase 加入评估集
→ 重跑 Eval → 确认修复 + 无回归
→ 上线 → 继续收集 → 闭环
(3) 权衡与量化数字
| 指标 | PoC | 上线初期 | 优化后 | 目标 |
|---|---|---|---|---|
| 准确率 | 90% | 60% | 82% | ≥80% |
| 评估集大小 | 100 条 | 100 条 | 800 条 | 1000+ |
| 评估集分布 | 人工构造 | 人工构造 | 50% 线上回采 | 80% 线上 |
| badcase 修复周期 | - | 无 | 周级 | 日级 |
(4) 落地清单
- 每周从线上日志采样 50 条加入评估集
- 用户👎反馈自动进入 badcase 队列
- badcase 分类看板(幻觉 / 错误 / 拒答 / 格式)
- Shadow 模式:1% 流量同时跑旧版 + 新版,比对效果
- 评估集分布对齐:按线上问题分类比例调整评估集
- 每次 Prompt 变更跑全量 Eval + 回归检测
(5) 风险
- 过度拟合评估集(Eval 集分数高但线上依然差)→ 定期刷新采样
- 评估标准不一致(不同标注者判断不同)→ 标注规范 + 双人标注 + kappa 系数
Q3: 🟪蚂蚁 — 金融交易系统接入 LLM 的安全架构设计
(1) 标准答案
金融场景接入 LLM 需要 四层安全架构:数据隔离层(敏感数据不出 VPC)、输入护栏层(PII 脱敏 + Prompt 注入检测)、输出护栏层(金额/承诺/合规过滤)、审计追溯层(全链路留痕 + 可回放)。核心原则是 “LLM 只做建议,不做决策;数据不出域,结果可追溯”。
(2) 原理 walk
四层安全架构:
Layer 1 - 数据隔离
├── 自部署模型(Qwen/Llama via vLLM)或 VPC 内 API
├── 敏感字段在调用 LLM 前脱敏(卡号 → ***,金额 → [AMOUNT])
└── 响应后还原
Layer 2 - 输入护栏
├── PII 检测(正则 + NER 模型)
├── Prompt 注入检测(分类器)
└── 输入长度限制 + 频率限制
Layer 3 - 输出护栏
├── 禁止输出:具体金额承诺、理赔保证、投资建议
├── 合规过滤:监管敏感词
└── 格式校验:结构化输出 + JSON schema
Layer 4 - 审计追溯
├── 每次 AI 调用完整记录(input + output + model + latency + cost)
├── 保留期 ≥ 5 年(金融合规)
├── 可按 trace_id 回放完整对话
└── 异常对话自动告警
(3) 权衡与量化数字
| 安全指标 | 目标 | 实现方式 |
|---|---|---|
| PII 泄露率 | 0% | 调用 LLM 前 100% 脱敏 |
| Prompt 注入检测率 | ≥99% | 输入分类器 + 规则 |
| 审计日志保留 | ≥5 年 | 冷存储 + 索引 |
| HITL 审批 SLA | ≤30 min | 金额 >$100 触发人工 |
| 数据出域 | 0 条 | VPC 内部署 or 脱敏 |
(4) 落地清单
- LLM 部署在 VPC 内(自部署 Qwen QwQ 或 Azure Private Endpoint)
- 输入层 PII 检测 + 自动脱敏(卡号/身份证/手机号/金额)
- 输出层禁止词列表 + 正则过滤
- 审计日志:完整 input/output + 5 年保留
- HITL:金额 >$100 的 AI 建议必须人工确认
- 季度安全审计 + 红队测试(Prompt 注入攻防)
- 模型版本锁定(不自动跟随 Provider 升级)
(5) 风险
| 风险 | 缓解 |
|---|---|
| Prompt 注入绕过安全规则 | 多层防御 + 红队测试 |
| 模型幻觉"承诺"赔偿金额 | 输出护栏硬拦截 + 正则 |
| 审计日志不完整 | 强制 Advisor 链,跳过即阻断请求 |
| 数据脱敏后影响 AI 理解 | 用占位符保留语义 [USER_NAME]说要退[AMOUNT]元 |
Q4: 🔵Google — 设计一个 AI 应用的 CI/CD pipeline,如何做 Prompt 回归测试
(1) 标准答案
AI CI/CD 在传统 CI/CD 基础上增加 Eval Gate——每次代码或 Prompt 变更自动跑评估集,准确率/幻觉率不达标时阻断部署。Prompt 回归测试的核心是 “对比 baseline”:保存当前 Prompt 版本的 Eval 分数作为 baseline,新版 Prompt 必须 ≥ baseline - ε(允许的容忍范围)。
(2) 原理 walk
四维版本管理:
| 维度 | 版本方式 | 触发 Eval |
|---|---|---|
| 代码 | Git SHA | ✅ Unit + Integration |
| Prompt | 语义版本 v1.0/v1.1 | ✅ Full Eval |
| 模型 | 锁定版本号 gpt-4o-2024-08-06 | ✅ Full Eval |
| 知识库 | 文档 hash + 向量版本 | ✅ RAG Eval 子集 |
Eval Gate 判定逻辑:
def eval_gate(current_results, baseline_results, epsilon=0.02):
for metric in ['accuracy', 'recall', 'f1']:
if current_results[metric] < baseline_results[metric] - epsilon:
return BLOCK, f"{metric} regressed by {delta}"
if current_results['hallucination'] > baseline_results['hallucination'] + epsilon:
return BLOCK, f"hallucination increased"
return PASS
(3) 权衡与量化数字
| 参数 | 推荐值 | 说明 |
|---|---|---|
| Eval 集规模 | 500 条 | 太少不稳定,太多跑太慢 |
| 容忍回归 ε | 2% | 允许小幅波动 |
| CI 跑 Eval 时长 | <15 min | 并行跑 + 缓存 |
| Eval 成本 / 次 | <$5 | 500 条 × $0.01/条 |
| 准确率阈值 | ≥85% | 低于此绝对值 Block |
(4) 落地清单
- Prompt 文件纳入 Git 管理(
src/main/resources/prompts/) - PR 变更 Prompt 时自动触发 Eval job
- Eval 结果 comment 到 PR(accuracy / hallucination / diff vs baseline)
- Baseline 分数存储在 CI artifact 中
- 低于阈值自动 Block merge
- 每月刷新 Eval 集(加入线上 badcase)
(5) 风险
- Eval 集过拟合:定期从线上回采替换旧样例
- LLM 输出非确定性导致 Eval 波动:temperature=0 + 跑 3 次取均值
- CI 成本累加:只在 Prompt/模型变更时跑全量 Eval,普通代码变更只跑 Unit
Q5: 🟡美团 — AI 客服上线后幻觉率 8%,如何在 2 周内降到 2% 以下
(1) 标准答案
先 分类幻觉类型(事实错误 / 编造政策 / 错误订单信息 / 过度承诺),按类型针对性修复。短期用 输出护栏硬拦截 高风险幻觉,中期通过 RAG 优化 + Prompt 改进 减少幻觉源头。
(2) 原理 walk
幻觉分类与对策:
| 幻觉类型 | 占比 | 根因 | 修复方式 | 时间 |
|---|---|---|---|---|
| 编造退款政策 | 35% | System prompt 无约束 | 加 “不知道就说不知道” + 引用来源 | Day 1-2 |
| 错误订单信息 | 25% | Tool 返回格式解析错误 | 修复 Tool 输出格式 + 加校验 | Day 3-4 |
| 虚构商品属性 | 20% | RAG 召回文档不相关 | 调 TopK / Score 阈值 + 加 Re-ranking | Day 5-8 |
| 过度承诺 | 15% | 无输出护栏 | 正则 + 禁止词列表硬拦截 | Day 2-3 |
| 其他 | 5% | 模型能力边界 | Eval 标注 + 定期 review | 持续 |
(3) 权衡与量化数字
| 时间点 | 幻觉率 | 措施累积 |
|---|---|---|
| Day 0 | 8.0% | 基线 |
| Day 3 | 5.2% | + 输出护栏 + Prompt 改进 |
| Day 7 | 3.1% | + Tool 修复 + RAG 调优 |
| Day 14 | 1.8% | + Re-ranking + Eval 自动巡检 |
(4) 落地清单(2 周冲刺)
Week 1:
- Day 1: 标注最近 200 条对话,分类幻觉类型
- Day 2: System Prompt 加 “不确定时说’我帮您确认’” + 护栏禁止词
- Day 3: 修复 OrderTool 输出格式,加字段校验
- Day 4-5: RAG 调优:TopK 3→5,Score 阈值 0.6→0.7,加 Re-ranking
Week 2:
- Day 6-7: 构建 200 条幻觉专项 Eval 集
- Day 8-9: Prompt v2 迭代 + Eval 回归
- Day 10: 灰度 10% 流量验证
- Day 11-12: 全量上线 + 监控幻觉率
- Day 13-14: 建立每日幻觉巡检机制(抽样 50 条人工审核)
(5) 风险
| 风险 | 缓解 |
|---|---|
| 过度限制导致 AI “什么都说不知道” | 监控拒答率,目标 <10% |
| Re-ranking 增加延迟 | 异步 re-rank + 缓存 |
| 修复 A 类幻觉引入 B 类回归 | Eval 集合覆盖所有类型 |
14. STAR-M-P 真实事故
存量系统接入 AI 后无降级导致全站客服瘫痪
S(Situation):
双 11 大促前夕,电商平台刚上线 AI 智能客服 2 周,日均处理 5 万对话。AI 客服使用 GPT-4o API,与主业务共享 Spring Boot Tomcat 线程池(max=200)。系统运行平稳,团队信心满满。
T(Task):
11 月 11 日 00:00 大促开始,流量瞬间 10x。同时 OpenAI API 因全球大规模调用出现服务降级,响应时间从正常 2s 飙升到 30s+,30% 请求直接 504 超时。AI 客服线程阻塞,200 个 Tomcat 线程在 3 分钟内耗尽。连带后果:订单查询、支付回调、库存扣减等核心接口全部排队超时。全站客服 + 部分核心交易链路瘫痪 12 分钟。
A(Action):
- T+3 min:SRE 发现告警,判断为线程池耗尽。尝试扩容无效(根因是线程阻塞不是量不够)。
- T+8 min:紧急在配置中心下发 AI 开关
ai.enabled=false,AI 客服全量切回规则引擎。线程池恢复。 - T+15 min:核心接口完全恢复。客服降级到规则引擎正常服务。
- 大促后 Day 1-3:
- AI 调用从共享线程池迁移到 独立线程池(
@Async("aiThreadPool"), max=50) - 添加 Resilience4j 熔断:5s 超时、50% 错误率触发熔断、30s 半开探测
- 实现 三级降级链:AI → 语义缓存(Redis)→ 规则引擎 → 转人工
- AI 调用从共享线程池迁移到 独立线程池(
- Day 4-5:
- AI 流量走 独立 Nginx upstream,不经过主业务 API Gateway
- 上线 成本 + 降级 Grafana 看板
R(Result):
- 事故影响时间:12 分钟全站不可用 + 3 分钟部分降级
- 改造后压测验证:AI 完全不可用时,主业务接口 P99 < 100ms,零影响
- AI 自动降级:从异常到规则引擎 fallback < 200ms,用户无感知
- 大促当天 AI 自动降级触发 3 次,每次持续 2-5 分钟,全部自动恢复
M(Metrics):
| 指标 | 事故前 | 改造后(AI 正常) | 改造后(AI 降级) |
|---|---|---|---|
| 主业务 P99 | 150ms(正常)→ 30s+(事故) | 150ms | 150ms(不受影响) |
| AI 客服 P99 | 2.1s | 2.1s | 85ms(规则引擎) |
| 准确率 | 87% | 87% | 62%(规则,可接受) |
| 线程池使用率 | 95%(事故时) | 35%(业务)+ 独立池 | 35%(业务) |
| 月均降级 | - | ~3 次,avg 5 min | 自动恢复 |
P(Prevention):
-
发布 《AI 接入规范 v1.0》(8 条硬约束,新项目接入 AI 必须通过 checklist review):
- ① 独立线程池(max ≤ 业务线程 25%)
- ② 熔断必配(超时 ≤ 5s,错误率 50% 触发)
- ③ 降级必有(至少 2 级 fallback)
- ④ 开关必配(配置中心可一键关闭 AI)
- ⑤ 审计日志(trace_id + prompt + response + latency + cost)
- ⑥ 成本预算(日限额 + 告警)
- ⑦ Eval 门槛(上线前 Eval 准确率 ≥ 80%)
- ⑧ 压测验证(上线前强制关闭 AI 压测降级链路)
-
开发 Spring Boot Starter
ai-integration-starter:内置上述 8 条规范,一行依赖自动配置线程池/熔断/降级/监控。 -
每季度 混沌演练:随机关闭 LLM API 30 分钟,验证降级链路。
15. 速记卡 + 90 秒口述
速记卡
| 维度 | 要点 |
|---|---|
| 本质 | AI 应用 = 传统工程 + 不确定性管理 |
| 接入三原则 | ① AI 层不侵入业务代码(Service Layer 隔离)② 必须有降级兜底 ③ 可观测先行 |
| 5 模式 | API 增强 → 旁路辅助 → 决策支持 → 流程替代 → AI-Native |
| 架构 | AI Service Layer 对上确定性接口,对下管不确定性 |
| 降级三防线 | AI → 语义缓存 → 规则引擎 → 人工 |
| 测试金字塔 | Unit(Mock) → Integration(Real LLM) → Eval(标注集) → Shadow(线上) |
| CI/CD | 管 4 个版本:代码 + Prompt + 模型 + 知识库 |
| 转型路径 | Dify 原型 → Spring AI 生产化 → 平台化赋能 |
| 成本 | DAU × 轮次 × token × 单价;降本 5 招(压缩/缓存/路由/批量/自部署) |
| 事故教训 | AI 必须独立线程池 + 熔断 + 超时 + 降级 + 开关 |
90 秒口述脚本
起手(10 秒):
“AI 项目的核心工程挑战不是让 AI 更聪明,而是在 AI 不够聪明时系统仍然可用——降级、兜底、人工兜底是三道防线。”架构(20 秒):
“我的方法是加一个 AI Service Layer——对上暴露确定性接口,对下管理不确定性。业务代码不知道回复来自 AI 还是规则引擎。独立线程池 + Resilience4j 熔断 + 三级降级链。策略模式封装 AI 和规则实现,切换对上层透明。”实战(25 秒):
“实际做法是先用 Dify 搭原型,2 周验证 RAG 效果和 Workflow 可行性,收集 badcase。效果达标后用 Spring AI 重写核心链路,复用 Dify 阶段验证过的 Chunking 策略、Prompt 模板和 Embedding 模型。Dify 继续承担运营自助场景。我在存量订单系统中用这个方法加了 AI 客服,零改动业务代码,覆盖率从 40% 提升到 83%。”工程化(25 秒):
“AI 项目的 CI/CD 要管 4 个版本:代码、Prompt、模型、知识库。每次 Prompt 变更自动跑 500 条评估集做回归测试,准确率低于 85% 或幻觉率超 3% 自动卡部署。上线后用 Micrometer + LangFuse 监控 Token 用量、幻觉率、工具调用成功率、用户满意度。成本通过模型路由降 80%——简单问题走 DeepSeek,复杂走 GPT-4o。”转型(10 秒):
“Java 开发者转 AI 的最大优势是工程化——从存量系统渐进式引入,不重写,不冒险。1 个 senior 工程师 4 周就能跑通第一个 AI 功能。”
🧭 章节导航
| # | 章节 | 核心内容 |
|---|---|---|
| 1 | AI 应用与传统应用的本质差异 | 确定性 vs 概率性;8 维对比;心智模型转换 |
| 2 | AI 项目生命周期 | 6 阶段 vs 传统 6 阶段;风险前移;Kill Criteria |
| 3 | 引入 AI 的 5 种模式 | API 增强 → 旁路 → 决策支持 → 替代 → AI-Native |
| 4 | 架构:AI 层嵌入 | AI Service Layer 6 原则;降级三防线;AI Gateway;完整代码 |
| 5 | 实战 1:存量系统 + AI 客服 | 7 步实施;关键代码;零改动;效果量化 |
| 6 | 实战 2:Dify → Spring AI | 三阶段迁移;复用结论清单;成本对比 |
| 7 | 测试策略 | AI 测试金字塔;评估集构建;Prompt 回归 |
| 8 | CI/CD 与版本管理 | 4 维版本;Prompt as Code;Eval Gate;灰度策略 |
| 9 | 可观测性 | AI 专属指标 10 项;成本监控;Trace 贯穿 |
| 10 | 转型路线图 | 4 阶段 12 月;每阶段产出物;Java→AI 技能矩阵 |
| 11 | 团队转型 | 4 阶梯;5 反模式;Tech Lead 决策清单 |
| 12 | 成本 FinOps | 成本公式;降本 5 招;$12K→$3K 案例 |
| 13 | 面试题 5 道 | 阿里/字节/蚂蚁/Google/美团 |
| 14 | STAR-M-P | AI 无降级致全站瘫痪 |
| 15 | 速记卡 | 90 秒口述脚本 |
📚 关联文件:14-Spring AI · 15-低代码平台 · 03-RAG · 04-Agent · 13-Playbook · 08-电商
官方文档与源码(一级依据)
AI Engineering · 正文机制应来自下方 官方文档(L1) 与 官方源码仓库(L2);
禁止用教程站/博客充当机制依据。本章 QPS/延迟/STAR 为面试示意。
写作规范:docs/official-sources-registry.md §0
L1 · 官方文档
L2 · 官方源码
L3 · 论文 / 开放规范
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)