从能用到好用,从演示到生产,这一步是很多AI应用项目的分水岭。本文通过四个版本的迭代,展示如何将一个原型级的AI代码审查服务优化为生产级应用,性能提升100倍,成本降低90%。
时间:45分钟 | 难度:⭐⭐⭐⭐ | Week 2 Day 13
📚 学习目标
- 理解原型代码的性能瓶颈和优化方向
- 掌握缓存策略的设计和实现,提升40000倍性能
- 学会使用并行处理优化AI调用,提升50%效率
- 实现生产级的错误处理、重试和熔断机制
- 掌握AI应用的成本优化三大杠杆
- 建立生产部署的完整检查清单
🚀 快速入门:为什么需要优化?
原型版的问题
你的v1版本已经工作了,演示效果不错,但是:
💰 成本问题
- 每次代码审查调用GPT-4:$0.03
- 每天1000次审查 = $30/天 = $900/月
- 很多是重复的代码片段
⏱️ 性能问题
- 平均响应时间:8秒
- P95响应时间:15秒
- 用户体验差
🔥 可靠性问题
- API失败率:2%(每50次就有1次失败)
- 没有重试机制
- 没有降级方案
优化后的效果
✅ v4生产版
- 平均响应时间:200ms(缓存命中)/ 4秒(未命中)
- 成本降低:90%(缓存+模型优化)
- 可用性:99.9%(重试+熔断)
- 可观测性:完整的metrics和tracing
🎯 深度讲解 - 四个版本的进化
1️⃣ v1:原型版 - 能用但慢
代码实现
package com.example.codereview.v1;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.stereotype.Service;
/**
* v1版本:最简单的实现
* 特点:能用,但慢、贵、不可靠
*/
@Service
public class CodeReviewServiceV1 {
private final ChatLanguageModel model;
public CodeReviewServiceV1() {
this.model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4") // 最贵的模型
.build();
}
/**
* 审查代码
* 问题:每次都调用API,没有缓存
*/
public String reviewCode(String code) {
String prompt = String.format(
"请审查以下Java代码,指出潜在问题:\n\n%s",
code
);
// 直接调用,没有错误处理
return model.generate(prompt);
}
}
控制器
package com.example.codereview.v1;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/v1/review")
public class CodeReviewControllerV1 {
private final CodeReviewServiceV1 service;
public CodeReviewControllerV1(CodeReviewServiceV1 service) {
this.service = service;
}
@PostMapping
public String review(@RequestBody String code) {
// 没有参数验证、异常处理
return service.reviewCode(code);
}
}
性能指标
📊 v1性能数据
├─ 平均响应时间:8000ms
├─ P95响应时间:15000ms
├─ 成本/请求:$0.03
├─ 失败率:2%
└─ 缓存命中率:0%
2️⃣ v2:缓存优化 - 提升40000倍
为什么需要缓存?
分析发现:
- 60%的代码审查请求是重复的
- 相同的代码片段被反复提交
- 审查结果是确定性的(相同输入→相同输出)
优化思路:
- 使用Spring Cache缓存审查结果
- Key = code的hash值
- 缓存命中时直接返回,避免API调用
缓存配置
package com.example.codereview.v2.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/**
* 缓存配置
* 使用Caffeine作为本地缓存
*/
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager("code-reviews");
cacheManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(10000) // 最多缓存10000条
.expireAfterWrite(24, TimeUnit.HOURS) // 24小时过期
.recordStats()); // 记录统计信息
return cacheManager;
}
}
服务实现
package com.example.codereview.v2;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* v2版本:添加缓存
* 性能提升:40000倍(缓存命中时从8s降到0.2ms)
*/
@Service
public class CodeReviewServiceV2 {
private final ChatLanguageModel model;
public CodeReviewServiceV2() {
this.model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4")
.build();
}
/**
* 审查代码(带缓存)
* Key使用代码的hashCode,相同代码返回缓存结果
*/
@Cacheable(value = "code-reviews", key = "#code.hashCode()")
public String reviewCode(String code) {
System.out.println("🔥 Cache miss - 调用AI模型");
String prompt = String.format(
"请审查以下Java代码,指出潜在问题:\n\n%s",
code
);
return model.generate(prompt);
}
}
缓存监控
package com.example.codereview.v2;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.stereotype.Service;
/**
* 缓存统计服务
*/
@Service
public class CacheStatsService {
private final CacheManager cacheManager;
public CacheStatsService(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* 获取缓存统计
*/
public CacheMetrics getMetrics() {
CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache("code-reviews");
Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
CacheStats stats = nativeCache.stats();
long totalRequests = stats.hitCount() + stats.missCount();
double hitRate = totalRequests == 0 ? 0 : (double) stats.hitCount() / totalRequests;
return new CacheMetrics(
stats.hitCount(),
stats.missCount(),
hitRate,
nativeCache.estimatedSize()
);
}
public record CacheMetrics(
long hitCount,
long missCount,
double hitRate,
long size
) {}
}
性能对比
📊 v2性能数据(60%缓存命中率)
├─ 缓存命中响应:0.2ms(提升40000倍)
├─ 缓存未命中响应:8000ms(与v1相同)
├─ 平均响应时间:3200ms(0.6*0.2 + 0.4*8000)
├─ 成本/请求:$0.012(降低60%)
└─ 缓存命中率:60%
💡 关键收益:
- 成本立即降低60%
- 60%的请求响应时间从8s降到0.2ms
- 减少了60%的API调用,降低限流风险
3️⃣ v3:并行优化 - 提升50%
问题分析
当前流程(串行):
1. 安全检查 → 3秒
2. 性能检查 → 3秒
3. 代码风格检查 → 2秒
总计:8秒
优化方案(并行):
同时执行三个检查,总时间 = max(3,3,2) = 3秒
理论提升:8s → 3s,提升62.5%
并行服务实现
package com.example.codereview.v3;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
/**
* v3版本:并行优化
* 多个检查项并行执行,提升50%性能
*/
@Service
public class CodeReviewServiceV3 {
private final ChatLanguageModel model;
public CodeReviewServiceV3() {
this.model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4")
.build();
}
/**
* 并行审查代码
*/
@Cacheable(value = "code-reviews", key = "#code.hashCode()")
public String reviewCode(String code) {
// 并行执行三个检查
CompletableFuture<String> securityCheck = checkSecurity(code);
CompletableFuture<String> performanceCheck = checkPerformance(code);
CompletableFuture<String> styleCheck = checkStyle(code);
// 等待所有检查完成
CompletableFuture.allOf(securityCheck, performanceCheck, styleCheck).join();
// 组合结果
return formatReviewResult(
securityCheck.join(),
performanceCheck.join(),
styleCheck.join()
);
}
/**
* 安全检查(异步)
*/
@Async
public CompletableFuture<String> checkSecurity(String code) {
return CompletableFuture.supplyAsync(() -> {
String prompt = String.format(
"检查以下代码的安全问题(SQL注入、XSS等):\n\n%s",
code
);
return model.generate(prompt);
});
}
/**
* 性能检查(异步)
*/
@Async
public CompletableFuture<String> checkPerformance(String code) {
return CompletableFuture.supplyAsync(() -> {
String prompt = String.format(
"检查以下代码的性能问题(N+1查询、内存泄漏等):\n\n%s",
code
);
return model.generate(prompt);
});
}
/**
* 代码风格检查(异步)
*/
@Async
public CompletableFuture<String> checkStyle(String code) {
return CompletableFuture.supplyAsync(() -> {
String prompt = String.format(
"检查以下代码的风格问题(命名、注释、可读性等):\n\n%s",
code
);
return model.generate(prompt);
});
}
/**
* 格式化审查结果
*/
private String formatReviewResult(String security, String performance, String style) {
return String.format("""
## 代码审查报告
### 🔒 安全检查
%s
### ⚡ 性能检查
%s
### 📝 代码风格
%s
""", security, performance, style);
}
}
线程池配置
package com.example.codereview.v3.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* 异步任务配置
*/
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "reviewExecutor")
public Executor reviewExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); // 核心线程数
executor.setMaxPoolSize(20); // 最大线程数
executor.setQueueCapacity(100); // 队列容量
executor.setThreadNamePrefix("review-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
}
性能对比
📊 v3性能数据
├─ 缓存命中响应:0.2ms
├─ 缓存未命中响应:4000ms(并行后从8s降到4s)
├─ 平均响应时间:1600ms
├─ 成本/请求:$0.012(与v2相同,但体验更好)
└─ 性能提升:50%(未命中场景)
⚠️ 注意事项:
- 并行会增加并发API调用,注意限流
- 需要合理配置线程池大小
- Token消耗总量不变,但峰值增加
4️⃣ v4:生产级 - 完整的可靠性保障
架构图
┌─────────────────────────────────────────────────┐
│ Controller Layer │
│ ┌──────────────────────────────────────────┐ │
│ │ - 参数验证 │ │
│ │ - Rate Limiting │ │
│ │ - Request/Response日志 │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ Service Layer │
│ ┌──────────────────────────────────────────┐ │
│ │ Cache (Caffeine) │ │
│ │ ↓ (miss) │ │
│ │ Retry (指数退避) │ │
│ │ ↓ │ │
│ │ Circuit Breaker (Resilience4j) │ │
│ │ ↓ │ │
│ │ Parallel Execution │ │
│ │ ↓ │ │
│ │ AI Model Call │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ Observability Layer │
│ - Metrics (Micrometer) │
│ - Tracing (OpenTelemetry) │
│ - Health Check │
└─────────────────────────────────────────────────┘
完整的服务实现
package com.example.codereview.v4;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.RetryConfig;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
/**
* v4版本:生产级实现
* 特点:
* - 缓存(性能)
* - 并行(效率)
* - 重试(可靠性)
* - 熔断(容错)
* - 监控(可观测性)
*/
@Service
public class CodeReviewServiceV4 {
private final ChatLanguageModel model;
private final Retry retry;
private final CircuitBreaker circuitBreaker;
private final Counter successCounter;
private final Counter failureCounter;
private final Counter cacheHitCounter;
private final Timer reviewTimer;
public CodeReviewServiceV4(MeterRegistry meterRegistry) {
// 初始化AI模型
this.model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-3.5-turbo") // 使用更便宜的模型
.timeout(Duration.ofSeconds(30))
.maxRetries(0) // 我们自己处理重试
.build();
// 配置重试策略
RetryConfig retryConfig = RetryConfig.custom()
.maxAttempts(3) // 最多重试3次
.waitDuration(Duration.ofSeconds(1)) // 初始等待1秒
.intervalFunction( // 指数退避
intervalFunction -> intervalFunction * 2
)
.retryExceptions(RuntimeException.class)
.build();
this.retry = Retry.of("codeReview", retryConfig);
// 配置熔断器
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.slidingWindowSize(10) // 滑动窗口10个请求
.failureRateThreshold(50) // 失败率50%触发熔断
.waitDurationInOpenState(Duration.ofSeconds(30)) // 熔断30秒
.permittedNumberOfCallsInHalfOpenState(3) // 半开状态允许3个测试请求
.build();
this.circuitBreaker = CircuitBreaker.of("codeReview", circuitBreakerConfig);
// 初始化监控指标
this.successCounter = Counter.builder("code_review.success")
.description("成功的代码审查次数")
.register(meterRegistry);
this.failureCounter = Counter.builder("code_review.failure")
.description("失败的代码审查次数")
.register(meterRegistry);
this.cacheHitCounter = Counter.builder("code_review.cache.hit")
.description("缓存命中次数")
.register(meterRegistry);
this.reviewTimer = Timer.builder("code_review.duration")
.description("代码审查耗时")
.register(meterRegistry);
}
/**
* 审查代码(生产级)
*/
@Cacheable(value = "code-reviews", key = "#code.hashCode()")
public ReviewResult reviewCode(String code) {
return reviewTimer.record(() -> {
try {
// 并行执行三个检查
CompletableFuture<String> security = executeWithResilience(
() -> checkSecurity(code)
);
CompletableFuture<String> performance = executeWithResilience(
() -> checkPerformance(code)
);
CompletableFuture<String> style = executeWithResilience(
() -> checkStyle(code)
);
// 等待所有检查完成
CompletableFuture.allOf(security, performance, style).join();
// 记录成功
successCounter.increment();
return new ReviewResult(
true,
security.join(),
performance.join(),
style.join(),
null
);
} catch (Exception e) {
// 记录失败
failureCounter.increment();
return new ReviewResult(
false,
null,
null,
null,
"审查失败: " + e.getMessage()
);
}
});
}
/**
* 带重试和熔断的执行
*/
private CompletableFuture<String> executeWithResilience(Supplier<String> supplier) {
return CompletableFuture.supplyAsync(() -> {
// 先通过熔断器
Supplier<String> decoratedSupplier = CircuitBreaker
.decorateSupplier(circuitBreaker, supplier);
// 再添加重试
decoratedSupplier = Retry.decorateSupplier(retry, decoratedSupplier);
return decoratedSupplier.get();
});
}
/**
* 安全检查
*/
private String checkSecurity(String code) {
String prompt = String.format(
"简要检查以下代码的安全问题(限50字):\n\n%s",
code
);
return model.generate(prompt);
}
/**
* 性能检查
*/
private String checkPerformance(String code) {
String prompt = String.format(
"简要检查以下代码的性能问题(限50字):\n\n%s",
code
);
return model.generate(prompt);
}
/**
* 代码风格检查
*/
private String checkStyle(String code) {
String prompt = String.format(
"简要检查以下代码的风格问题(限50字):\n\n%s",
code
);
return model.generate(prompt);
}
/**
* 审查结果
*/
public record ReviewResult(
boolean success,
String security,
String performance,
String style,
String error
) {}
}
健康检查
package com.example.codereview.v4;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
/**
* 健康检查
*/
@Component
public class CodeReviewHealthIndicator implements HealthIndicator {
private final CircuitBreaker circuitBreaker;
public CodeReviewHealthIndicator(CodeReviewServiceV4 service) {
this.circuitBreaker = service.getCircuitBreaker();
}
@Override
public Health health() {
CircuitBreaker.State state = circuitBreaker.getState();
if (state == CircuitBreaker.State.OPEN) {
return Health.down()
.withDetail("circuitBreaker", "OPEN")
.withDetail("message", "代码审查服务熔断中")
.build();
}
if (state == CircuitBreaker.State.HALF_OPEN) {
return Health.up()
.withDetail("circuitBreaker", "HALF_OPEN")
.withDetail("message", "代码审查服务恢复中")
.build();
}
return Health.up()
.withDetail("circuitBreaker", "CLOSED")
.withDetail("message", "代码审查服务正常")
.build();
}
}
限流控制器
package com.example.codereview.v4;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Refill;
import jakarta.validation.constraints.NotBlank;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.Duration;
/**
* v4控制器(生产级)
*/
@RestController
@RequestMapping("/api/v4/review")
@Validated
public class CodeReviewControllerV4 {
private final CodeReviewServiceV4 service;
private final Bucket rateLimiter;
public CodeReviewControllerV4(CodeReviewServiceV4 service) {
this.service = service;
// 限流:每分钟100个请求
Bandwidth limit = Bandwidth.classic(
100,
Refill.intervally(100, Duration.ofMinutes(1))
);
this.rateLimiter = Bucket.builder()
.addLimit(limit)
.build();
}
/**
* 审查代码
*/
@PostMapping
public ResponseEntity<?> review(
@RequestBody @NotBlank(message = "代码不能为空") String code
) {
// 限流检查
if (!rateLimiter.tryConsume(1)) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body(new ErrorResponse("请求过于频繁,请稍后重试"));
}
// 代码长度检查
if (code.length() > 10000) {
return ResponseEntity.badRequest()
.body(new ErrorResponse("代码长度不能超过10000字符"));
}
// 执行审查
CodeReviewServiceV4.ReviewResult result = service.reviewCode(code);
if (!result.success()) {
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(new ErrorResponse(result.error()));
}
return ResponseEntity.ok(result);
}
private record ErrorResponse(String message) {}
}
依赖配置
<!-- pom.xml -->
<dependencies>
<!-- Resilience4j(重试、熔断)-->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Bucket4j(限流)-->
<dependency>
<groupId>com.bucket4j</groupId>
<artifactId>bucket4j-core</artifactId>
<version>8.7.0</version>
</dependency>
<!-- Micrometer(监控)-->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
配置文件
# application.yml
spring:
cache:
caffeine:
spec: maximumSize=10000,expireAfterWrite=24h
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
tags:
application: code-review-service
💰 成本优化 - 三大杠杆
杠杆1️⃣:模型选择(10倍成本差异)
/**
* 不同模型的成本对比
*/
public class ModelCostComparison {
// GPT-4: $0.03/1K tokens (输入) + $0.06/1K tokens (输出)
private static final ChatLanguageModel GPT4 = OpenAiChatModel.builder()
.modelName("gpt-4")
.build();
// GPT-3.5-turbo: $0.0015/1K tokens (输入) + $0.002/1K tokens (输出)
private static final ChatLanguageModel GPT35 = OpenAiChatModel.builder()
.modelName("gpt-3.5-turbo")
.build();
// Claude 3.5 Sonnet: $0.003/1K tokens (输入) + $0.015/1K tokens (输出)
private static final ChatLanguageModel CLAUDE = AnthropicChatModel.builder()
.modelName("claude-3-5-sonnet-20241022")
.build();
/**
* 成本对比(假设500 tokens输入,1000 tokens输出)
*/
public void compareCost() {
double gpt4Cost = 0.5 * 0.03 + 1.0 * 0.06 = 0.075; // $0.075
double gpt35Cost = 0.5 * 0.0015 + 1.0 * 0.002 = 0.00275; // $0.00275
double claudeCost = 0.5 * 0.003 + 1.0 * 0.015 = 0.0165; // $0.0165
// GPT-3.5比GPT-4便宜27倍!
System.out.printf("成本对比:GPT-4 = %.4f, GPT-3.5 = %.4f (便宜%.0f倍)\n",
gpt4Cost, gpt35Cost, gpt4Cost / gpt35Cost);
}
}
智能模型路由
package com.example.codereview.optimization;
import dev.langchain4j.model.chat.ChatLanguageModel;
/**
* 根据任务复杂度选择模型
*/
@Service
public class SmartModelRouter {
private final ChatLanguageModel gpt4;
private final ChatLanguageModel gpt35;
/**
* 智能选择模型
*/
public ChatLanguageModel selectModel(String code) {
// 简单任务用GPT-3.5(成本低)
if (isSimpleTask(code)) {
return gpt35;
}
// 复杂任务用GPT-4(效果好)
return gpt4;
}
private boolean isSimpleTask(String code) {
// 代码短、逻辑简单 → 用便宜模型
return code.length() < 500 && !code.contains("async") && !code.contains("lambda");
}
}
杠杆2️⃣:历史压缩(5倍Token节省)
package com.example.codereview.optimization;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import java.util.ArrayList;
import java.util.List;
/**
* 对话历史压缩
* 问题:每次请求都带上完整历史,Token消耗线性增长
* 解决:只保留最近N轮对话 + 摘要
*/
public class ConversationCompressor {
private static final int MAX_HISTORY = 5; // 最多保留5轮
/**
* 压缩对话历史
*/
public List<ChatMessage> compress(List<ChatMessage> history) {
if (history.size() <= MAX_HISTORY * 2) {
return history; // 无需压缩
}
List<ChatMessage> compressed = new ArrayList<>();
// 1. 添加摘要(用AI总结前面的对话)
String summary = summarizeHistory(history.subList(0, history.size() - MAX_HISTORY * 2));
compressed.add(new UserMessage("之前的讨论摘要:" + summary));
// 2. 保留最近N轮完整对话
compressed.addAll(history.subList(history.size() - MAX_HISTORY * 2, history.size()));
return compressed;
}
private String summarizeHistory(List<ChatMessage> messages) {
// 用便宜的模型生成摘要
return "讨论了代码安全问题和性能优化建议";
}
}
Token使用对比
❌ 不压缩(第10轮对话)
├─ 历史消息:10轮 × 200 tokens = 2000 tokens
├─ 新问题:500 tokens
├─ 总输入:2500 tokens
└─ 成本:$0.075
✅ 压缩后
├─ 摘要:100 tokens
├─ 最近5轮:5 × 200 = 1000 tokens
├─ 新问题:500 tokens
├─ 总输入:1600 tokens
└─ 成本:$0.048(节省36%)
杠杆3️⃣:Prompt优化(2倍效率提升)
/**
* Prompt优化对比
*/
public class PromptOptimization {
/**
* ❌ 低效Prompt(输出冗长)
*/
public String inefficientPrompt(String code) {
return String.format("""
你是一个资深的Java开发专家,拥有20年的开发经验。
请仔细审查以下代码,从多个维度进行深入分析:
1. 安全性方面,包括但不限于SQL注入、XSS攻击、CSRF等
2. 性能方面,包括但不限于算法复杂度、数据库查询优化等
3. 可维护性方面,包括但不限于代码结构、命名规范等
请给出详细的分析报告,每个问题都要说明原因和解决方案。
代码:
%s
请开始你的详细分析:
""", code);
// 预计输出:1500 tokens
// 成本:$0.09
}
/**
* ✅ 高效Prompt(输出简洁)
*/
public String efficientPrompt(String code) {
return String.format("""
检查代码问题(每项限30字):
1. 安全
2. 性能
3. 风格
%s
""", code);
// 预计输出:300 tokens
// 成本:$0.018(节省80%)
}
}
Few-Shot优化
/**
* 使用Few-Shot减少输出Token
*/
public String fewShotPrompt(String code) {
return String.format("""
参考示例回答:
示例1:
输入:public void delete(int id) { sql = "DELETE FROM users WHERE id=" + id; }
输出:SQL注入风险 | 缺少事务 | 无异常处理
示例2:
输入:for (User u : users) { db.save(u); }
输出:N+1查询 | 应批量保存 | 缺少null检查
现在检查:
%s
输出:
""", code);
// AI会模仿示例,输出简洁格式
}
📋 生产部署Checklist
可靠性
- 错误处理:所有AI调用都有try-catch
- 重试机制:使用Resilience4j,指数退避
- 熔断器:失败率超过50%自动熔断
- 超时设置:所有API调用都有timeout
- 降级方案:AI服务不可用时返回默认结果
- 限流保护:防止恶意调用和成本失控
性能
- 缓存策略:合理的缓存Key和过期时间
- 并行优化:独立任务并行执行
- 连接池:HTTP client使用连接池
- 异步处理:长时间任务异步化
- 资源限制:线程池、内存、Token上限
成本
- 模型选择:根据任务选择合适的模型
- Prompt优化:简洁的Prompt,限制输出长度
- 历史压缩:多轮对话场景压缩历史
- 成本监控:每日/每月成本告警
- 配额管理:设置每个用户的调用限额
可观测性
- 日志记录:关键操作记录日志
- Metrics监控:成功率、延迟、成本等指标
- Tracing追踪:分布式链路追踪
- 健康检查:/actuator/health端点
- 告警配置:失败率、延迟、成本告警
安全
- API密钥保护:密钥存储在环境变量/密钥管理服务
- 参数验证:严格的输入验证
- 输出过滤:防止敏感信息泄露
- 访问控制:API需要认证授权
- 审计日志:记录谁在何时调用了什么
📊 性能对比总结
| 指标 | v1原型 | v2缓存 | v3并行 | v4生产 |
|---|---|---|---|---|
| 平均延迟 | 8000ms | 3200ms | 1600ms | 800ms |
| P95延迟 | 15000ms | 8000ms | 4000ms | 2000ms |
| 成本/请求 | $0.03 | $0.012 | $0.012 | $0.003 |
| 失败率 | 2% | 2% | 2% | 0.1% |
| 缓存命中率 | 0% | 60% | 60% | 60% |
| 可用性 | 98% | 98% | 98% | 99.9% |
| 监控 | ❌ | ❌ | ❌ | ✅ |
| 熔断 | ❌ | ❌ | ❌ | ✅ |
| 限流 | ❌ | ❌ | ❌ | ✅ |
综合提升
🚀 v1 → v4 提升总结
性能提升:
├─ 平均延迟:8000ms → 800ms(提升10倍)
└─ P95延迟:15000ms → 2000ms(提升7.5倍)
成本降低:
├─ 每请求:$0.03 → $0.003(降低90%)
└─ 每月(10万请求):$3000 → $300(节省$2700)
可靠性提升:
├─ 失败率:2% → 0.1%(提升20倍)
└─ 可用性:98% → 99.9%(提升1.9%)
运维能力:
├─ 监控:无 → 完整的Metrics + Tracing
├─ 告警:无 → 多维度告警
└─ 健康检查:无 → /actuator/health
💡 练习题
练习1:缓存策略设计
场景:你的代码审查服务有以下特点:
- 70%的请求是重复代码
- 代码会更新,旧版本的审查结果应失效
- 需要支持"强制刷新"功能
问题:
1. 如何设计Cache Key?(提示:不能只用hashCode)
2. 如何处理代码更新的缓存失效?
3. 如何实现"强制刷新"?
请实现一个改进的缓存策略。
练习2:成本优化
场景:你的服务每天处理10000次代码审查
- 当前成本:$300/天
- 目标成本:$100/天
数据分析:
- 40%是简单问题(<100行代码)
- 30%是中等复杂度(100-500行)
- 30%是复杂问题(>500行)
任务:
1. 设计一个模型路由策略
2. 计算每个场景的成本
3. 验证是否能达到目标成本
提示:GPT-4 ($0.03/1K), GPT-3.5 ($0.001/1K), Claude Haiku ($0.00025/1K)
练习3:可靠性设计
场景:OpenAI API的实际表现
- 平均成功率:98%
- 偶发性故障(1-2分钟)
- 限流:3500 RPM
问题:
1. 如何配置重试策略?(重试次数、间隔)
2. 如何配置熔断器?(窗口大小、阈值、恢复时间)
3. 如何设计降级方案?
请实现一个完整的容错方案,目标可用性99.9%。
🎯 下一步
恭喜你完成了Week 2的最后一课!从原型到生产,你学会了:
- ✅ 缓存优化(40000倍提升)
- ✅ 并行优化(50%提升)
- ✅ 成本优化(90%降低)
- ✅ 可靠性保障(99.9%可用性)
下一篇:[[14-Week2完整总结和周发布]]
- Week 2完整知识图谱
- 三个项目的最佳实践
- 周发布准备清单
- Week 3预告
学习路径
Week 2进度:13/14 ✅
Day 8-9:项目1 - 智能文档问答 ✅
Day 10-11:项目2 - AI代码审查助手 ✅
Day 12-13:项目3 - 智能客服系统 ✅
Day 14:Week 2总结 → 下一篇
最后更新:2026-03-08