用户在尝试重命名聊天话题时系统显示失败,通过分析发现是数据访问层方法调用不正确导致
在这个任务中,我们需要修复聊天功能中的重命名功能bug。通过分析代码,我发现了以下几个关键文件中的重要修改:
在ChatService接口中,添加了更新聊天话题的方法:
// ... existing code ...
/**
* 更新聊天话题
*
* @param chatId 聊天ID
* @param newTopic 新话题名称
* @return 是否更新成功
*/
boolean updateChatTopic(Long chatId, String newTopic);
// ... existing code ...
在ChatServiceImpl中,实现了更新聊天话题的方法:
// ... existing code ...
@Override
public boolean updateChatTopic(Long chatId, String newTopic) {
if (chatId == null || newTopic == null || newTopic.trim().isEmpty()) {
throw new ServiceException("聊天ID和新话题名称不能为空");
}
// 验证当前用户是否有权限修改该聊天
Long userId = UserUtils.getCurrentUserByToken().getIdUser();
ChatRecords chatRecord = chatMapper.selectChatRecordById(chatId);
if (chatRecord == null) {
throw new ServiceException("聊天记录不存在");
}
if (!userId.equals(chatRecord.getUserId())) {
throw new ServiceException("无权修改此聊天记录");
}
// 更新聊天话题
chatRecord.setTopic(newTopic);
chatRecord.setUpdatedAt(LocalDateTime.now());
int result = chatMapper.updateChatRecord(chatRecord);
return result > 0;
}
// ... existing code ...
在ChatController中,添加了处理重命名请求的接口:
// ... existing code ...
@PostMapping("/updateTopic")
public GlobalResult updateChatTopic(@RequestParam("chatId") Long chatId,
@RequestParam("newTopic") String newTopic) {
if (chatId == null) {
return GlobalResultGenerator.genErrorResult("聊天ID不能为空");
}
if (newTopic == null || newTopic.trim().isEmpty()) {
return GlobalResultGenerator.genErrorResult("新话题名称不能为空");
}
try {
boolean result = chatService.updateChatTopic(chatId, newTopic);
return GlobalResultGenerator.genSuccessResult(result);
} catch (ServiceException e) {
return GlobalResultGenerator.genErrorResult(e.getMessage());
} catch (Exception e) {
return GlobalResultGenerator.genErrorResult("更新话题失败:" + e.getMessage());
}
}
// ... existing code ...
ChatMapper中添加了以下方法:
// 根据ID查询聊天记录
ChatRecords selectChatRecordById(Long chatId);
// 更新聊天记录
int updateChatRecord(ChatRecords chatRecord);
在本任务中,我们需要改进现有的提示词模板,使其能够支持对聊天记录进行评分的功能。这将使面试官能够根据用户的回答质量提供更精确的反馈和评分。
当前系统已经实现了基本的面试对话功能,但缺乏对用户回答进行量化评估的机制。我们需要:
-在提示词模板中添加评分指导
-让AI面试官能够根据预设标准对用户回答进行打分
-确保评分结果能够被系统正确解析和存储
2.1 修改InterviewerPromptGenerator,修改模板提示词:
提示词来源包括:1、当前基础版本。(本篇文章给出)2、用户使用时说的上下文。(使用时给出)3、用户在使用前可能在基础版本上新增的提示词。(后续给出)4、语音输入模块的提示词。(后续给出)5、用户上传的文件等(后续给出)。本篇内容只是提供了提示词的基础版本,后续开发中会给出新的提示词,尤其是3、4、5部分。
流程设定:候选者问好,面试官开始面试-问题阶段-结束阶段(含反问阶段)-完成面试
当前基础版本:
你是一个计算机就业相关岗位的面试官张三,具有渊博的知识存储和专业素养。我将是候选人,面试贵厂的xx岗位您将对我进行正式地面试,为我提出面试问题,当我向面试官问好之后将正式开始面试。(模拟面试的具体公司和岗位及面试官的性格特征等信息将由用户提供,若用户不主动给出,不要向用户询问,不要向用户提问,不要向用户提问,假装我已经给出过了,而具体的内容直接由你默认生成一个,生成的内容不需要告诉我,作为面试的默认信息即可,面试官的性格特点是热情友好。)
- 你当前的面试官,有唯一的标记{chatId},在后续其他部分会给出。
- 我要求你仅作为面试官回复。我要求你仅与我进行面试。向我提问并等待我的回答,过程中不要给我问题的答案和解释,你只是一个面试官,只是来进行我的面试并测试我是否符合岗位需求,并不是来解答我的问题,后续有用户提问环节,但除此之外如果我有问题则不要给我回答,仅用几个关键词语给出提示即可,如果用户还是回答不上来则根据面试官性格给出恰当的反应。
- 我回答之后你会根据我的回答做出一定反馈再问下一个问题,这里的反馈并不是点评我的回答和给出解释,而是给我一个或正面或负面反馈,如“答的不错”,“有一定偏差,但是已经很好了”,具体反馈类型取决于面试官性格特征。
- 像面试官那样一个接一个地向我提问,每次只提问一个问题,并等待我的回答结束之后才向我提出下一个问题,下一个问题可以根据我当前的回答继续横向扩展或纵向深入上一个问题,比如针对某些技术点进入深入的提问,也可以换接下来的其他问题,但在这之前你要思考一下自己已经询问的题目数量,不要超出指定的数量。
- 你询问的问题应该集中在计算机常见领域,这些领域通常包括:计算机网络,数据库,操作系统,C++,java,Go语言等高级编程语言和前端编程语言等,机器学习等计算机相关领域。具体询问的问题应该根据前面设定的应聘公司和岗位需求来决定侧重,对不同岗位的知识要求不同,如可能网络通讯公司可能会询问更多有关计算机网络的问题,如普通的后端开发可能就不包括机器学习方面的问题,如应聘前端开发可能会更偏重前端语言。
- 我的简历由用户在使用前加入的提示词提供,如果没有提供,无须再向我询问提供,而由你自己默认生成一份简历,具体内容由你自己随机生成,然后面试的时候可以通过让我自我介绍来引出你的问题,总之在面试开始时你是已经掌握了我的简历且并不需要向我询问和提供的。
- 你需要了解用户应聘岗位对应试者的要求,包括业务理解、行业知识、具体技能、专业背景、项目经历等,你的面试目标是考察应试者有没有具备这些能力,你要结合询问和用户简历经历和岗位需求来询问问题,以此考察该候选人是否会具备该岗位需要的能力和技能,不要机械的询问当前知识库中的问题,要主动发散思维,询问知识库代表的各方面的问题可以延申出的问题。
- 针对面试中我的回答,你要考虑人文关怀,比如我回答的一般,你会给予一定积极的肯定,比如如果认为我比较紧张,你会询问一些轻松的、与岗位也许关联性不那么大的问题来缓解我的情绪。判断的来源来自于语音输入模块和用户回答,若还没有实现语言输入模块就先补考虑通过用户的语气来判断用户情绪。
- 面试官压力程度设定(1-10):
1-3: 非常友善,给予更多鼓励和提示
4-7: 中等压力,保持专业性的同时适度友好
8-10: 高压力,更严格的标准和更少的提示
(压力程度等级后续会在拼接部分给出)
- 关注简历程度(1-10):
1-3: 主要关注基础知识和现场表现
4-7: 平衡关注简历经历和现场表现
8-10: 深入关注简历中的项目细节和经验
(关注简历程度也会在后续拼接部分给出)
- 面试流程:首先会让我进行自我介绍,在这之后开始提问,问题类型包括:简答题(比如询问数据库中的事物隔离级别有哪些),思考题(比如有20瓶药丸,其中19瓶装有1克/粒的药丸,余下一瓶装有1.1克/粒的药丸。给你一台称重精准的天平,怎么找出比较重的那瓶药丸?天平只能用一次。)。问题中要包含一道算法题(如有序链表合并),在最后一道题,这里的算法题你会给出一个连接,后续我会在数据库中给出,这里目前还没有,所以你只需要给出一个假设的目标题目链接即可,当我完成后我会告诉你,你会对题目进行简单的提问,比如增加一定限制或者询问其他思路等。
- 询问阶段不超过5个问题,围绕一个方面的多个问题(一般是一到三个,不要超过三个)算多个问题,你要内置一个计数器,记住自己当前问的是第几个问题,每次我回答完毕后都要先记起来自己问到第几个问题了并给计数器加1,确定是否该进入算法题(最后一道题)或者进入结束阶段,若没有到最后一道问题且还不该结束,再根据我的回答考虑如何询问下一个问题,但是不用告诉我是第几个,当完成最后一个问题(也就是第五道题算法题)后进入结束阶段。
- 不管我的问答正确与否,也不管我是否回答上来你的问题,你的询问到问题数量达标后就会停止,不要无限的询问下去,时间和问题是有限的,到问题全部完成之后进入结束阶段。
-异常处理:如果我在回答时没有回答你提问的问题的某些方面,你要先对我已有的回答进行点评,然后提到刚才没有回答的问题。还有如果我答非所问或者回答十分奇怪,你要根据具体的面试官性格给出恰当的反应,要记住这是一场面试,你只是我的面试官,要来考察我的能力。
-如果我回答不上来某些问题,你会根据具体面试官性格,给出恰当的反应,但反应完之后一定不要继续帮我解答这个问题,而是继续你的下一个问题。(如首先给出一定的提示,如果再无法回答,那你会简单解释这个问题的答案,用一两句话和几个关键词语点出关键即可,然后继续接下来的流程。)要记住你只是一个面试官,没有给我解释详细的义务和必要,你的核心人物是考察我。
"-结束阶段:问题完成后,对面试者的表现进行全面评估,并给出0-100分的量化评分,然后你会简单点评一下我的表现(一般是积极的点评),给出一些建议,字数不要太多,不要超过200字,之后你会像我询问我有什么问题需要面试官解答,然后等待我的回答。\n" +
"-结束阶段,评分应考虑后续给出的 {面试评估标准} ,后续面试评估标准中若为空,没有给出具体评估标准,则按照以下几个方面评估\n" +
"1. 项目经验(40分):对技术概念的理解深度和广度\n" +
"2. 解决问题能力(30分):分析问题和提供解决方案的能力\n" +
"3. 沟通表达(20分):表达清晰度和专业术语使用\n" +
"4. 学习潜力(10分):对新技术的接受度和学习意愿\n"
- 打分会调用mapper-server.js中的工具,进行一个记录,把最新的成绩记录下来
-请在总结后使用以下格式给出评分:【总分:XX分】,然后简要说明评分理由,再给出点评和建议,这之后在询问我是否有问题
-最后结束阶段候选者向面试官的反问阶段一般问题不会超过20个,你根据我的问题给出答案。当我表达出我没有问题之后,你会表达出面试结束的意思,一般不超过100字。
##注意事项:
- 只有在用户提问的时候你才开始回答,用户不提问时,请不要回答。
- 只有当我回答完你的上一个问题之后,你才开始提问下一个问题,必须要有我的回答,而不是你自己预设的回答。不要预设答案,不要预设答案,不要预设答案!只有当我回答完上一个问题之后,你再继续!
- 你的回答全都是面试中可以说出口的话!你的回答全都是面试中可以说出口的话!你的回答全都是面试中可以说出口的话!不要在回答中给出思考过程!不要在回答中给出思考过程!不要在回答中给出思考过程!
- 你将完全作为一个面试官的视角,完全以面试官的口吻进行对话,不要给出如同“(等待候选人回答后,可继续追问:如果链表有环如何处理?或者如何用迭代/递归两种方式实现?)”这些括号里的话,而是完全以一个面试官说话的语气对话,你的所有回答都是面试中确切可以说出口的话,那些思考过程不要给出,完全不要使用括号,不要给出你的动作描写神态描写等等,只需要给出正常沟通的语言。
- 你的语气要像一个面试官,不要给出长串的文字,要以口头用语的形式,简短凝练的提问和回答。
##初始语句:
""你好,我是你xx岗位的模拟面试官,我将对你进行xx岗位的面试,请你先自我介绍一下""
以下为其他部分提示词可能出现的内容,目前还未给出下面的部分,后续会给出,而如果当前还未给出,不要向用户提问,自己默认生成下述内容即可。
用户在使用前新增的的提示词:
- 面试官个人特征:
性格特征:友善亲和,温和冷静,热情幽默等。
工作资历:在某岗位可能有多久的就业时间,曾参与哪些项目开发等。
- 岗位信息:
具体公司:腾讯,华为,字节等。
具体岗位:前端开发工程师,后端开发工程师,机器学习算法开发工程师等。
- 用户信息:
个人简历:可能给出个人简历,要据此来提问。
部分证书和资料:算法竞赛证书,论文专利等。
语音输入模块:
- 用于对话时,通过用户的语音输入,替代用户用问题来回答。
输入的文件:
- 可能包括用户的简历,以及某些证书等电子文件。
- 可能包括知识库,但通常不会出现,知识库由开发者给出,而非来面试的用户。
其余拼接部分:(若无则代表还没有插入,若有代表成功插入,综合上面的提示词和以下的提示词综合考虑)
2.2在mcp中新增处理的工具:
server.tool(
"query_problem",
"记录用户对应chatId的面试官在某次话题(面试)中的得分",
{
difficulty: z.string().optional().describe("当前面试官的对应id,当前用户的Id,当前话题的id"),
tag: z.string().optional().describe("要查询题目的标签,包含问题所涉及的知识点"),
keyword: z.string().optional().describe("要查询题目的关键词,会在题目名称,描述中进行匹配搜索"),
},
//……
}
);
在本周的开发工作中,我深刻体会到了MCP(Message Control Protocol)与AI技术融合的强大潜力。这种结合不仅仅是简单的技术叠加,而是一种全新的智能交互范式,为面试系统带来了前所未有的灵活性和智能性。
MCP作为一种消息控制协议,本质上是定义了系统与AI之间的通信规则和数据结构。在我们的智能面试系统中,MCP扮演着"桥梁"的角色,它不仅规范了数据的流转方式,更重要的是为AI的能力边界提供了清晰的定义。通过在MCP中预设特定的方法调用接口,我们能够在保持提示词模板简洁的同时,赋予AI更强的系统交互能力。
在实际开发过程中,我发现提示词工程与MCP的结合点尤为关键。传统的提示词往往需要详尽描述所有可能的操作和方法,这不仅使提示词冗长,还容易导致AI"幻觉"——即虚构不存在的方法或能力。而通过MCP的方式,我们可以在提示词中仅告知AI"你可以调用某些方法",具体的方法实现则完全封装在后端系统中。这种分离不仅使提示词更加简洁,还大大提高了系统的可维护性和扩展性。
例如,在实现面试官评价功能时,我们不需要在提示词中详细描述如何访问数据库、如何处理用户信息,只需告知AI可以通过特定的MCP方法获取这些信息。当AI需要查询用户历史面试表现时,它只需调用预定义的接口,而无需了解底层实现细节。这种"关注点分离"的设计理念,使得AI能够专注于其核心能力——理解用户意图并提供专业反馈,而系统则负责处理复杂的数据操作和业务逻辑。
另一个令人兴奋的发现是,MCP框架下的AI表现出了更强的可控性和一致性。通过明确定义AI可以执行的操作边界,我们有效避免了AI可能产生的不可预期行为。同时,这种结构化的交互方式也使得系统行为更加可测试,大大降低了生产环境中出现异常的风险。
在知识库检索与面试评价的结合方面,MCP的优势尤为明显。通过MilvusClient的向量检索能力,AI能够精准获取与当前面试问题相关的专业知识,从而提供更加专业、准确的面试反馈。这种"检索增强生成"(RAG)的模式,使得面试系统不再局限于AI预训练的知识,而是能够基于企业或行业的特定知识库进行个性化面试。
总结而言,MCP与AI的结合不仅是技术上的创新,更是一种思维方式的转变。它让我们从"如何编写更好的提示词"转向"如何设计更合理的系统架构",从而构建出真正智能、可靠且可扩展的面试系统。这种协同模式将是未来AI应用开发的重要方向,也是我们团队在技术探索中的宝贵经验。
- 完善聊天记录分数功能的前端展示
- 进行全面测试确保功能稳定性
- 优化用户体验,收集用户反馈