一、项目背景与核心功能

无领导小组讨论(群面)是校招、社招的核心筛选环节,多数候选人因缺乏实战模拟经验,难以掌握角色定位与沟通节奏。本次开源的群面智伴系统,通过模拟不同MBTI人格、不同群面角色的AI智能体,帮助候选人低成本完成高拟真群面练习。

核心功能清单

功能模块 描述
MBTI智能体选择 支持16种MBTI人格类型,每种类型对应专属性格向量
群面角色切换 5类核心角色可选:LEADER(领导者)、COORDINATOR(协调者)、VIEWPOINT(观点者)、EXECUTOR(执行者)、SUPPORTER(支持者)
上下文对话 智能体记忆多轮对话历史,回复符合人格与角色设定
大模型驱动 接入DeepSeek V4 Flash API,生成自然流畅的对话内容

二、整体技术架构

项目采用前后端分离架构,分层设计如下:

┌─────────────────┐
│   前端层(Vue3) │  MBTI选择/角色切换/聊天界面
└────────┬────────┘
         │ Axios HTTP
┌────────┴────────┐
│  后端服务层(Spring Boot) │  智能体管理/会话缓存/API转发
└────────┬────────┘
         │ RestTemplate
┌────────┴────────┐
│  AI模型层(DeepSeek API) │  对话生成/上下文理解
└─────────────────┘

技术栈选型

  • 前端:Vue3 + Vite + Axios,使用Composition API开发
  • 后端:Spring Boot 3.x + Lombok + Jackson,轻量级RESTful服务
  • AI能力:DeepSeek V4 Flash API,支持长上下文对话
  • 缓存:内存会话缓存(单节点场景,后续可扩展Redis)

三、核心模块设计

3.1 MBTI智能体体系

智能体系统基于策略模式+工厂模式设计,保证扩展性与复用性。

3.1.1 人格与角色定义

16种MBTI类型封装为枚举,每种类型包含5维性格向量、4维情绪向量、5维能力向量:

// MbtiType枚举(部分示例)
public enum MbtiType {
    INTJ("建筑师", "LEADER", 
         0.2, 0.8, 0.3, 0.4, 0.9,  // 性格向量:外倾/支配/合作/风险偏好/条理性
         0.3, 0.8, 0.2, 0.9,       // 情绪向量:紧张度/自信度/攻击性/稳定性
         0.9, 0.7, 0.6, 0.8, 0.9  // 能力向量:逻辑/沟通/协作/领导力/专业性
    ),
    ESFP("表演者", "EXECUTOR", 
         0.9, 0.5, 0.8, 0.8, 0.3,
         0.4, 0.7, 0.3, 0.8,
         0.6, 0.8, 0.9, 0.6, 0.7
    );
    // 省略getter方法
}

5类群面角色通过AgentFactory工厂类创建,每个角色继承AbstractAgent基类,实现专属的发言逻辑:

// AgentFactory核心逻辑
public AbstractAgent createAgentByRole(String roleType, String agentId, AgentProfile profile) {
    return switch (roleType) {
        case "LEADER" -> new LeaderAgent(agentId, profile, deepSeekService);
        case "COORDINATOR" -> new CoordinatorAgent(agentId, profile, deepSeekService);
        case "VIEWPOINT" -> new ViewpointAgent(agentId, profile, deepSeekService);
        case "EXECUTOR" -> new ExecutorAgent(agentId, profile, deepSeekService);
        case "SUPPORTER" -> new SupporterAgent(agentId, profile, deepSeekService);
        default -> new ViewpointAgent(agentId, profile, deepSeekService);
    };
}

3.2 大模型集成模块

DeepSeekService封装所有API调用逻辑,支持带历史上下文的对话生成:

// 带历史上下文的对话生成方法
public String generateResponseWithHistory(String systemPrompt, List<Map<String, String>> conversationHistory) {
    List<Map<String, String>> messages = new ArrayList<>();
    messages.add(Map.of("role", "system", "content", systemPrompt));
    messages.addAll(conversationHistory);  // 拼接历史对话
    
    Map<String, Object> requestBody = Map.of(
        "model", deepSeekConfig.getModel(),
        "messages", messages,
        "temperature", deepSeekConfig.getTemperature()
    );
    
    // 发送HTTP请求到DeepSeek API
    ResponseEntity<String> response = restTemplate.exchange(
        deepSeekConfig.getBaseUrl() + "/v1/chat/completions",
        HttpMethod.POST,
        new HttpEntity<>(requestBody, headers),
        String.class
    );
    return extractResponseContent(response.getBody());
}

每个智能体根据自身的MBTI类型、角色动态生成System Prompt,保证回复符合人设:

// LeaderAgent的Prompt生成逻辑
private String buildSystemPrompt(Agent.AgentContext context) {
    return "你是" + profile.getName() + ",一个MBTI类型为" + mbtiType.name() + "的" + mbtiType.getChineseName() + "。\n" +
           "你的特点:善于领导和推动讨论,发言简洁有逻辑。\n" +
           "请用自然、友好的方式直接回答用户的问题,不要提及你是AI或角色设定,回答不超过100字。";
}

3.3 会话与记忆管理

为解决多轮对话上下文丢失问题,系统采用会话级智能体缓存+对话历史维护方案:

  1. 智能体缓存:以sessionId为key,缓存已创建的智能体实例,避免重复初始化
    // AgentChatController中的缓存逻辑
    private final Map<String, AbstractAgent> sessionAgents = new HashMap<>();
    
    String cacheKey = sessionId;
    AbstractAgent agent = sessionAgents.get(cacheKey);
    if (agent == null) {
        agent = agentFactory.createAgent(mbtiType, role, sessionId, message);
        sessionAgents.put(cacheKey, agent);
    }
    
  2. 对话历史维护:每个智能体维护conversationHistory列表,先添加用户消息再调用API,保证首轮对话也能传入用户输入
    // LeaderAgent中的对话历史处理逻辑(修复后)
    public String generateResponse(Agent.AgentContext context) {
        String userPrompt = "用户说:" + context.questionContent();
        conversationHistory.add(Map.of("role", "user", "content", userPrompt));  // 先加用户消息
        
        String response = deepSeekService.generateResponseWithHistory(systemPrompt, conversationHistory);
        conversationHistory.add(Map.of("role", "assistant", "content", response));  // 再加回复
        
        // 保留最近20轮对话,避免上下文过长
        if (conversationHistory.size() > 20) {
            conversationHistory = conversationHistory.subList(conversationHistory.size() - 20, conversationHistory.size());
        }
        return response;
    }
    

3.4 前端交互设计

前端采用Vue3实现,核心交互流程:

  1. 加载16种MBTI类型,渲染为网格选择组件
  2. 选择MBTI后,可选5类群面角色
  3. 进入聊天界面,发送消息后实时显示用户/智能体回复,自动滚动到底部

核心API调用逻辑:

// 前端发送消息逻辑(AgentChatView.vue)
const sendMessage = async () => {
  const sessionId = `${selectedMbti.value}_${selectedRole.value}`
  const result = await chatWithAgent({
    mbti: selectedMbti.value,
    role: selectedRole.value,
    message: userMsg,
    sessionId: sessionId
  })
  messages.value.push({
    role: 'assistant',
    content: result.response,
    mbti: selectedMbti.value,
    roleType: selectedRole.value
  })
}


四、踩坑与优化记录

问题1:首轮对话用户消息未传入大模型

  • 现象:DeepSeek API返回的回复与用户输入无关,日志显示Conversation History size: 0
  • 原因:原逻辑先调用API再添加用户消息到历史列表
  • 修复:调整顺序,先将用户消息加入conversationHistory,再调用generateResponseWithHistory

问题2:智能体重复创建导致上下文丢失

  • 现象:每次发送消息都创建新智能体,对话历史无法累积
  • 原因:缓存key生成规则不一致,前端与后端key不匹配
  • 修复:统一使用前端传入的sessionId作为缓存key,保证同一会话复用同一个智能体

五、效果演示

操作流程 效果
选择MBTI:INTJ,角色:LEADER 智能体回复风格冷静、逻辑缜密,符合INTJ领导者人设
发送消息:"群面中如何体现领导力?" 回复围绕目标拆解、分工协调展开,不超过100字
继续发送:"刚才的方案有哪些风险?" 智能体可以回溯上一轮提到的方案,回复具有连贯性

六、后续规划

  1. 支持多智能体群面模拟:同时创建4-6个AI智能体,自动开展无领导小组讨论
  2. 增加群面表现评估:基于发言逻辑、协作性、情绪稳定性等维度生成评估报告
  3. 扩展大模型适配:对接通义千问、文心一言等更多国产大模型
  4. 增加语音交互:支持语音输入与语音播报,模拟真实面试场景

七、项目地址

完整代码已开源,GitHub地址:待补充(可替换为实际仓库地址) 如有问题欢迎在评论区交流,或提交Issue~

如果觉得本文对你有帮助,欢迎点赞、收藏、关注三连 😊

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐