教育平台自动化答题系统开发日记:从AI交互到HTTP请求的全流程实践
一、背景与目标
近期在开发一个教育平台的自动化答题工具,核心需求是根据不同题型(单选/多选/判断/填空)自动获取AI答案并提交。涉及技术点包括:
- 火山引擎大模型交互(ArkService)
- HTTP请求模拟(Java HttpClient)
- JSON解析与数据处理(Gson)
- 题型差异化处理逻辑
二、开发过程与关键技术
1. AI交互核心:精准控制答案格式
痛点:
AI返回常包含多余解释或格式错误(如填空题带引号),需严格约束输出。
解决方案:
- 系统提示强约束:针对不同题型设置专属指令
switch (qsnType) { case 1: // 单选题 content = "只返回单个选项字母(如:A),无需任何解释"; break; case 6: // 填空题 content = "直接返回答案内容,禁止添加任何引号、括号或解释性文字"; } - 答案清洗层:统一处理多余字符
private static String processAnswer(String content, int qsnType) { if (qsnType == 6) { return content.trim().replaceAll("^[\"“”']|['\"“”]$", ""); // 去除首尾引号 } return content; }
2. HTTP请求陷阱:受限头引发的异常
错误复现:
IllegalArgumentException: restricted header name: "Connection"
Java HttpClient禁止手动设置部分请求头(如Connection、Keep-Alive)。
修复方案:
- 请求头白名单机制:过滤受限头
private boolean isRestrictedHeader(String name) { String lower = name.toLowerCase(); return Set.of("connection", "keep-alive", "transfer-encoding").contains(lower); } - 合规头构建:仅保留合法字段(User-Agent、X-Access-Token、Referer等),避免触发客户端限制。
3. 题型差异化处理:从答案提取到提交
单选题/多选题:
- 正则过滤非字母字符并转大写
contentStr.replaceAll("[^A-Za-z]", "").toUpperCase();
判断题:
- 映射“正确”/“错误”到布尔值
userAnswer = aiResult.equalsIgnoreCase("正确") ? "true" : "false";
填空题:
- 保留原始内容并包装HTML标签(平台要求)
userAnswer = "<p>" + aiResult + "</p>";
三、代码架构解析
1. 主流程逻辑(伪代码)
for (题目 : 题目列表) {
if (已有答案) continue; // 跳过已答题目
根据qsnType生成AI请求 → 获取rawAnswer → 清洗处理 → 组装userAnswer;
if (答案有效) {
构造Http请求头(含X-Access-Token) → 发送POST请求;
打印提交响应;
}
}
if (AUTO_SUBMIT) 提交整份作业; // 全局开关控制
2. AI交互核心模块
private static String getAnswerFromAi(...) {
List<ChatMessage> messages = new ArrayList<>();
messages.add(系统提示);
messages.add(用户问题+选项);
ChatCompletionRequest request = ChatCompletionRequest.builder()
.model("deepseek-r1-250120")
.messages(messages)
.build();
return arkService.createChatCompletion(request)
.getChoices()
.stream()
.map(choice -> processAnswer(choice.getMessage().getContent(), qsnType))
.findFirst()
.orElse("");
}
3. 鲁棒性设计
- 空值保护:所有JSON解析处添加
has("字段")检查 - 异常重试:HTTP请求添加重试机制(示例未展示,建议实现)
- 日志输出:关键节点打印AI答案和提交响应,便于调试
四、踩坑记录与最佳实践
-
JSON解析陷阱
- 问题:字段缺失导致
JsonSyntaxException - 方案:使用
has()方法预检查,如if (detailData.has("userAnswer"))
- 问题:字段缺失导致
-
AI响应不可靠性
- 方案:添加正则兜底处理,如填空题强制去除首尾引号,多选题确保字母大写
-
HTTP请求头匹配
- 必须严格与浏览器抓包一致(User-Agent、Referer等),建议使用工具(如Charles)获取真实请求头
五、优化方向
- 支持更多题型:扩展解答题、计算题处理逻辑
- 性能优化:批量提交题目,减少AI交互次数
- 错误处理增强:记录失败题目ID,支持断点续传
- 配置化:将题型映射、AI模型参数等移至配置文件
六、总结
本次开发深度实践了“AI交互+网络请求+业务逻辑”的三层架构,核心挑战在于格式控制和兼容性处理。通过系统提示强约束、答案清洗层、合规请求头设计,有效解决了自动化流程中的关键问题。后续可进一步结合题库缓存、代理池等技术提升稳定性,适合教育类自动化场景复用。
github链接github.com/journs/U-pl…
#掘金日新计划 #Java开发 #教育科技 #自动化工具 #大模型应用