揭秘!AI 如何智能生成技术挑战关卡?基于 LangChain4j + 通义千问的实战方案

本文将深入剖析"程序员技术练兵场"项目中的核心功能——AI 智能生成关卡的技术实现,带你掌握 LangChain4j + 通义千问的实战应用。

一、功能概述

1.1 什么是 AI 智能生成关卡?

在程序员技术练兵场平台中,用户可以输入自己的当前薪资学习方向(如 Java 后端、前端、Python、AI 算法等),系统会自动生成符合用户技术水平的技术挑战关卡。

比如,一个薪资 15K 的 Java 后端工程师,可能会收到这样的挑战:

“某电商平台订单服务出现数据库死锁,请分析原因并给出解决方案…”

这种千人千面的关卡生成方式,让每个用户都能获得最适合自己的技术挑战。

1.2 技术选型

技术组件 版本 说明
Spring Boot 3.5.5 基础框架
LangChain4j 1.4.0-beta10 AI 应用开发框架
通义千问 qwen-plus 阿里云大语言模型
MyBatis Plus 3.5.13 数据持久化

二、核心设计思路

2.1 整体流程

用户输入薪资和方向

构建提示词

调用 AI 服务

解析 AI 响应

保存关卡数据

返回给前端

2.2 关键设计点

  1. 提示词工程:设计高质量的 System Prompt,确保 AI 生成的内容符合业务需求
  2. 结构化输出:让 AI 返回 JSON 格式,方便程序解析和存储
  3. 降级机制:当 AI 服务不可用时,提供默认关卡,保证系统可用性
  4. 声明式接口:使用 LangChain4j 的注解方式,代码简洁易维护

三、代码实现详解

3.1 AI 服务接口定义

LangChain4j 采用声明式接口的方式定义 AI 服务,非常优雅:

@AiService
public interface LevelGenerationAiService {

    @SystemMessage(fromResource = "prompts/level-generation-system.txt")
    @UserMessage("{{userMessage}}")
    LevelGenerationResponse generateLevel(String userMessage);
}

关键注解说明:

  • @AiService:标记这是一个 AI 服务接口
  • @SystemMessage:定义系统提示词,fromResource 从资源文件加载
  • @UserMessage:定义用户消息模板,{{userMessage}} 是占位符

3.2 系统提示词设计

提示词文件 level-generation-system.txt 的设计是整个功能的核心:

你是一位资深的技术面试官,擅长根据候选人的水平设计技术挑战题目。

## 任务要求
根据用户的薪资水平和学习方向,生成一个真实企业场景的技术挑战。

## 输出格式
请以 JSON 格式返回,包含以下字段:
- title:挑战标题
- description:挑战描述(真实业务场景)
- options:技术方案选项数组
- correctAnswer:正确答案索引
- difficulty:难度等级(1-5)
- salaryRange:建议薪资范围

## 注意事项
1. 题目要贴近真实企业开发场景
2. 难度要与用户薪资匹配
3. 选项要有迷惑性,不能太明显
4. 避免纯理论题目,要有实际应用价值

3.3 响应结构定义

AI 返回的 JSON 会自动映射到 Java 对象:

@Data
public class LevelGenerationResponse {
    private String title;
    private String description;
    private List<String> options;
    private Integer correctAnswer;
    private Integer difficulty;
    private String salaryRange;
}

3.4 Service 层调用

在 Service 层,我们需要拼接用户消息并调用 AI 服务:

@Service
public class LevelServiceImpl implements LevelService {

    @Resource
    private LevelGenerationAiService levelGenerationAiService;

    @Override
    public Level generateLevel(Integer salary, String direction) {
        // 构建用户消息
        String userMessage = String.format("""
            请为以下用户生成技术挑战:
            - 当前薪资:%dK
            - 学习方向:%s
            """, salary, direction);

        try {
            // 调用 AI 服务
            LevelGenerationResponse response = levelGenerationAiService.generateLevel(userMessage);
            
            // 转换为实体并保存
            Level level = convertToEntity(response);
            levelMapper.insert(level);
            return level;
            
        } catch (Exception e) {
            // 降级:返回默认关卡
            log.error("AI 生成关卡失败", e);
            return getDefaultLevel(salary, direction);
        }
    }
}

3.5 AI 服务配置

使用 Java Config 方式配置 AI 服务 Bean:

@Configuration
public class AiConfig {

    @Bean
    public LevelGenerationAiService levelGenerationAiService(
            ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(LevelGenerationAiService.class)
                .chatLanguageModel(chatLanguageModel)
                .build();
    }

    @Bean
    public ChatLanguageModel chatLanguageModel() {
        return QwenChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .temperature(0.7)
                .maxTokens(2000)
                .build();
    }
}

四、技术难点与解决方案

4.1 多参数模板问题

问题:LangChain4j 的 @UserMessage 注解不支持多参数模板。

解决方案:在 Service 层使用 String.format() 拼接完整的用户消息,AI 接口只接收一个 userMessage 参数。

// ❌ 错误写法
@UserMessage("薪资: {{salary}}, 方向: {{direction}}")
Response generate(Integer salary, String direction);

// ✅ 正确写法
@UserMessage("{{userMessage}}")
Response generate(String userMessage);

// 在 Service 层拼接
String userMessage = String.format("薪资: %d, 方向: %s", salary, direction);

4.2 JSON 解析问题

问题:AI 返回的 JSON 可能包含 Markdown 代码块标记。

解决方案:在提示词中明确要求纯 JSON 输出,或添加后处理逻辑:

private String cleanJsonResponse(String response) {
    return response
        .replace("```json", "")
        .replace("```", "")
        .trim();
}

4.3 降级机制

问题:AI 服务可能因网络、配额等原因不可用。

解决方案:提供预定义的默认关卡,保证系统可用性:

private Level getDefaultLevel(Integer salary, String direction) {
    Level level = new Level();
    level.setTitle("系统默认挑战");
    level.setDescription("这是一个默认的技术挑战...");
    level.setOptions(List.of("方案A", "方案B", "方案C"));
    level.setCorrectAnswer(0);
    return level;
}

五、实际效果展示

5.1 前端界面

用户选择薪资和学习方向后,系统自动生成关卡:

AI生成关卡界面

5.2 生成示例

输入

  • 薪资:20K
  • 方向:Java 后端

AI 输出

{
  "title": "高并发订单系统优化",
  "description": "某电商平台的订单服务在秒杀活动中出现大量超卖问题,请分析原因并给出解决方案。",
  "options": [
    "使用 synchronized 锁",
    "使用 Redis 分布式锁",
    "使用数据库乐观锁",
    "使用消息队列削峰"
  ],
  "correctAnswer": 1,
  "difficulty": 4,
  "salaryRange": "18K-25K"
}

六、总结与展望

6.1 技术亮点

  1. 声明式 AI 接口:LangChain4j 的注解方式让代码更简洁
  2. 提示词工程:精心设计的提示词是生成质量的关键
  3. 降级机制:保证系统可用性,用户体验友好
  4. 结构化输出:JSON 格式便于程序处理和存储

6.2 可优化方向

  1. 提示词优化:引入 Few-shot 示例,提高生成质量
  2. 缓存机制:对相同参数的请求添加缓存
  3. 异步生成:大流量场景下使用异步生成提升性能
  4. 多模型支持:支持多种大模型切换

6.3 学习价值

通过这个功能的实现,你可以学到:

  • LangChain4j 框架的实战应用
  • 提示词工程的设计技巧
  • AI 服务的降级策略
  • Spring Boot 3 的现代开发方式

💡 源码地址GitHub - coder-test

如果觉得有收获,欢迎点赞、收藏、关注!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐