Spring Boot + ChatGLM 实战AI数字人面试官系统

随着人工智能技术的飞速发展,AI在招聘领域的应用越来越广泛。本文将介绍如何使用Spring Boot框架和ChatGLM模型构建一个AI数字人面试官系统,以提高招聘过程的效率和公平性。

1. 项目背景

在传统的招聘过程中,面试官往往需要花费大量时间和精力来筛选简历和进行面试。AI数字人面试官可以自动与候选人进行初步沟通,评估其技能和适应性,从而节省人力资源,提高招聘效率。

2. 技术选型

  • Spring Boot:用于构建后端服务,提供RESTful API接口。
  • ChatGLM:基于Transformer架构的预训练语言模型,用于生成自然语言对话。
  • MySQL:用于存储候选人信息和面试记录。
  • Docker:用于容器化部署,确保环境一致性。
  • 前端框架:可以选择React或Vue.js,用于构建用户界面。

3. 系统架构

系统架构图

  1. 前端界面:提供用户界面,包括候选人登录、面试开始、面试结束等功能。
  2. 后端服务:使用Spring Boot构建,处理前端请求,调用ChatGLM模型生成面试问题和答案。
  3. 数据库:存储候选人信息、面试记录等数据。
  4. ChatGLM模型:用于生成自然语言对话,模拟面试官的行为。

4. 关键技术实现

4.1 后端服务
4.1.1 项目初始化

使用Spring Initializr初始化项目,选择以下依赖:

  • Spring Web
  • Spring Data JPA
  • MySQL Driver
  • Lombok
4.1.2 实体类

定义候选人实体类 Candidate 和面试记录实体类 InterviewRecord

@Entity
public class Candidate {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    // 其他字段
}

@Entity
public class InterviewRecord {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne
    private Candidate candidate;
    private String question;
    private String answer;
    private LocalDateTime timestamp;
}
4.1.3 服务层

实现候选人和面试记录的增删改查操作。

@Service
public class CandidateService {
    @Autowired
    private CandidateRepository candidateRepository;

    public Candidate save(Candidate candidate) {
        return candidateRepository.save(candidate);
    }

    public List<Candidate> findAll() {
        return candidateRepository.findAll();
    }
}

@Service
public class InterviewRecordService {
    @Autowired
    private InterviewRecordRepository interviewRecordRepository;

    public InterviewRecord save(InterviewRecord record) {
        return interviewRecordRepository.save(record);
    }

    public List<InterviewRecord> findByCandidate(Candidate candidate) {
        return interviewRecordRepository.findByCandidate(candidate);
    }
}
4.1.4 控制器

提供RESTful API接口。

@RestController
@RequestMapping("/api/candidates")
public class CandidateController {
    @Autowired
    private CandidateService candidateService;

    @PostMapping
    public Candidate createCandidate(@RequestBody Candidate candidate) {
        return candidateService.save(candidate);
    }

    @GetMapping
    public List<Candidate> getAllCandidates() {
        return candidateService.findAll();
    }
}

@RestController
@RequestMapping("/api/interviews")
public class InterviewController {
    @Autowired
    private InterviewRecordService interviewRecordService;

    @PostMapping
    public InterviewRecord createInterviewRecord(@RequestBody InterviewRecord record) {
        return interviewRecordService.save(record);
    }

    @GetMapping("/{candidateId}")
    public List<InterviewRecord> getInterviewRecordsByCandidate(@PathVariable Long candidateId) {
        Candidate candidate = new Candidate();
        candidate.setId(candidateId);
        return interviewRecordService.findByCandidate(candidate);
    }
}
4.2 ChatGLM模型集成
4.2.1 模型部署

将ChatGLM模型部署为一个独立的服务,可以通过HTTP请求调用。可以使用Flask或FastAPI等轻量级框架来实现。

from flask import Flask, request, jsonify
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

app = Flask(__name__)

model_name = "ChatGLM"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

@app.route('/generate', methods=['POST'])
def generate():
    data = request.json
    prompt = data['prompt']
    inputs = tokenizer(prompt, return_tensors="pt")
    outputs = model.generate(**inputs, max_length=100)
    response = tokenizer.decode(outputs[0], skip_special_tokens=True)
    return jsonify({"response": response})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
4.2.2 调用模型

在Spring Boot项目中调用ChatGLM模型生成面试问题和答案。

@Service
public class InterviewService {
    @Autowired
    private RestTemplate restTemplate;

    public String generateQuestion(String prompt) {
        String url = "http://localhost:5000/generate";
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("prompt", prompt);
        ResponseEntity<Map> response = restTemplate.postForEntity(url, requestBody, Map.class);
        return (String) response.getBody().get("response");
    }
}
4.3 前端界面

使用React或Vue.js构建用户界面,提供候选人登录、面试开始、面试结束等功能。

// React示例
import React, { useState } from 'react';
import axios from 'axios';

function App() {
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');
    const [questions, setQuestions] = useState([]);
    const [answers, setAnswers] = useState([]);

    const startInterview = async () => {
        // 创建候选人
        await axios.post('/api/candidates', { name, email });

        // 开始面试
        const initialQuestion = await axios.get('/api/interviews/question');
        setQuestions([initialQuestion.data]);
    };

    const submitAnswer = async (index, answer) => {
        // 提交答案
        await axios.post('/api/interviews', { candidateId: 1, question: questions[index], answer });

        // 获取下一个问题
        const nextQuestion = await axios.get('/api/interviews/question');
        setQuestions([...questions, nextQuestion.data]);
        setAnswers([...answers, answer]);
    };

    return (
        <div>
            <h1>AI数字人面试官</h1>
            <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
            <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
            <button onClick={startInterview}>开始面试</button>
            <ul>
                {questions.map((question, index) => (
                    <li key={index}>
                        <p>{question}</p>
                        <input type="text" placeholder="回答" onChange={(e) => setAnswers(index, e.target.value)} />
                        <button onClick={() => submitAnswer(index, answers[index])}>提交</button>
                    </li>
                ))}
            </ul>
        </div>
    );
}

export default App;

5. 部署与运维

使用Docker容器化部署,确保环境一致性。编写Dockerfile和docker-compose.yml文件。

# Dockerfile for Spring Boot application
FROM openjdk:11-jre-slim
COPY target/your-app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
# docker-compose.yml
version: '3'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
      - chatglm

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: interview_db
    volumes:
      - db_data:/var/lib/mysql

  chatglm:
    build: ./chatglm
    ports:
      - "5000:5000"

volumes:
  db_data:

6. 结论

通过上述步骤,我们可以构建一个功能完善的AI数字人面试官系统。该系统不仅能够提高招聘过程的效率,还能确保面试的公平性和客观性。未来,随着AI技术的进一步发展,这类系统将变得更加智能和高效。