news 2026/5/4 9:45:26

Spring AI 1.1实战:用通义千问和OpenAI写个自动周报生成器(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI 1.1实战:用通义千问和OpenAI写个自动周报生成器(附完整代码)

Spring AI 1.1实战:构建智能周报生成器的完整指南

每周五下午,当办公室里的咖啡机开始频繁运作时,总有一群开发者对着空白的周报文档发呆。这种重复性工作不仅消耗时间,更消磨创造力。现在,借助Spring AI 1.1和大型语言模型(LLM),我们可以用Java代码让这个流程自动化——不仅能自动生成内容,还能根据汇报对象(领导/团队)调整表达风格。本文将带你从零构建一个能理解项目上下文、自动归纳工作成果的智能周报系统。

1. 环境配置与项目初始化

在开始编码前,我们需要搭建好开发环境。与简单的Demo项目不同,生产级周报生成器需要考虑模型稳定性、生成质量控制和异常处理机制。

基础环境要求:

  • JDK 17+(Spring AI 1.1的强制要求)
  • Spring Boot 3.2.x
  • Maven 3.6+ 或 Gradle 7.x
  • 任一LLM服务账号(推荐通义千问或OpenAI)

创建项目时,在pom.xml中添加这些核心依赖:

<dependencies> <!-- Spring Boot基础依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring AI核心 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-core</artifactId> </dependency> <!-- 通义千问集成(国内开发者推荐) --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-tongyi-spring-boot-starter</artifactId> </dependency> <!-- 数据校验 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> </dependencies>

application.yml中配置模型参数:

spring: ai: tongyi: access-key-id: ${TONGYI_ACCESS_KEY} access-key-secret: ${TONGYI_SECRET_KEY} chat: model: qwen-plus # 增强版模型 temperature: 0.3 # 降低随机性保证稳定性 max-tokens: 2000

提示:敏感配置建议通过环境变量注入,避免硬编码在配置文件中

2. 周报数据结构设计与输入处理

好的周报生成器首先要解决的是如何结构化输入数据。我们设计一个包含多维度信息的DTO:

public class WeeklyReportRequest { @NotBlank private String userId; @NotNull private LocalDate weekStartDate; @Size(min = 3) private List<WorkItem> completedItems; private List<WorkItem> plannedItems; @NotBlank private String reportStyle; // "leader"或"team" // 嵌套的工作项类 public static class WorkItem { private String projectName; private String taskDescription; private Integer timeSpent; // 分钟 private String difficultyLevel; } }

对应的控制器需要处理数据验证和预处理:

@RestController @RequestMapping("/api/reports") public class ReportController { @PostMapping("/weekly") public ResponseEntity<String> generateWeeklyReport( @Valid @RequestBody WeeklyReportRequest request) { // 数据预处理逻辑 String processedInput = InputPreprocessor.process(request); // 调用AI服务生成报告 String report = reportService.generateReport(processedInput); return ResponseEntity.ok(report); } }

3. 提示词工程与模板设计

周报质量的核心在于提示词设计。我们创建可动态适配不同风格的模板系统:

基础模板(resources/prompts/weekly_base.st):

你是一位专业的{reportStyle.equals('leader') ? '部门主管' : '技术团队成员'},需要基于以下工作记录生成周报: 本周时间范围:{weekStartDate} 至 {weekStartDate.plusDays(4)} 完成事项: {#each completedItems} - 项目:{projectName} | 任务:{taskDescription} | 耗时:{timeSpent}分钟 {/each} 生成要求: 1. 使用{reportStyle.equals('leader') ? '成果导向型' : '协作分享型'}表达 2. 突出技术难点{difficultyLevel != null ? '(难度等级:'+difficultyLevel+')' : ''} 3. 按优先级排序事项 4. 输出Markdown格式

Java模板处理器:

@Service public class PromptEngine { private final TemplateResolver templateResolver; public String buildPrompt(WeeklyReportRequest request) { Context context = new Context(); context.setVariable("reportStyle", request.getReportStyle()); // 设置其他变量... return templateResolver.resolve("weekly_base", context); } }

当检测到特殊需求时,可以动态追加提示词:

if (request.containsKeyword("KPI")) { prompt += "\n额外要求:将工作成果与季度KPI目标关联分析"; }

4. 模型调用与结果优化

基础生成代码很容易写,但要生产可用还需要这些增强处理:

@Service public class ReportGenerator { private final ChatClient chatClient; public String generateReport(String prompt) { // 第一次生成原始内容 String draft = chatClient.generate(prompt); // 二次优化:检查完整性 if (!validateReport(draft)) { String refinementPrompt = prompt + "\n请修复以下问题:\n" + "- 补充缺失的项目关联分析\n" + "- 调整语气更加专业"; draft = chatClient.generate(refinementPrompt); } // 格式标准化处理 return formatHelper.standardizeMarkdown(draft); } private boolean validateReport(String content) { // 实现内容质量检查逻辑 } }

典型优化策略对比表:

问题类型检测方法优化方案
内容空洞关键词密度分析追加具体案例要求
格式混乱正则表达式检查指定Markdown模板
语气不当情感分析调整提示词角色设定
技术细节不足术语识别要求补充实现细节

5. 高级功能实现

5.1 多模型降级策略

为确保服务可用性,实现模型自动切换机制:

@Primary @Service public class FallbackChatClient implements ChatClient { private final List<ChatClient> clients; public String generate(String prompt) { for (ChatClient client : clients) { try { return client.generate(prompt); } catch (Exception e) { log.warn("Model {} failed, trying next", client.getClass()); } } throw new RuntimeException("All models unavailable"); } }

5.2 流式响应实现

对于长周报,采用流式输出提升用户体验:

@GetMapping(value = "/weekly/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> streamWeeklyReport(WeeklyReportRequest request) { String prompt = promptEngine.buildPrompt(request); return chatClient.stream(prompt) .map(ChatResponse::getResult) .map(ChatResult::getOutput) .map(AssistantMessage::getContent); }

5.3 历史上下文支持

让模型记住上周内容以实现连贯性:

public String generateWithContext(WeeklyReportRequest request, String lastWeekReport) { String contextPrompt = """ 以下是上周报告摘要: {lastWeekReport} 请确保本周报告与上周内容保持连贯,特别是关于: - 项目进展的延续性 - 问题解决的后续跟踪 """; String mainPrompt = promptEngine.buildPrompt(request); return chatClient.generate(contextPrompt + mainPrompt); }

6. 部署与性能优化

生产环境部署时,这些配置能显著提升稳定性:

spring: ai: tongyi: connect-timeout: 5000 read-timeout: 30000 retry: max-attempts: 3 initial-interval: 1000 max-interval: 5000

缓存策略实现示例:

@Cacheable(value = "reports", key = "{#request.userId,#request.weekStartDate}") public String generateReport(WeeklyReportRequest request) { // 生成逻辑 }

在Kubernetes环境中,建议配置这些资源限制:

resources: limits: cpu: "1" memory: "1Gi" requests: cpu: "500m" memory: "512Mi"

7. 安全与合规考量

企业级应用必须注意这些安全实践:

  1. 数据脱敏处理

    public String sanitizeInput(String input) { return input.replaceAll("\\d{4}-\\d{4}-\\d{4}", "[CARD]") .replaceAll("\\b\\d{3}-\\d{2}-\\d{4}\\b", "[SSN]"); }
  2. 访问控制

    @PreAuthorize("#request.userId == authentication.name") public String generateReport(WeeklyReportRequest request) { // 生成逻辑 }
  3. 审计日志

    @Aspect @Component public class ReportGenerationAudit { @AfterReturning(pointcut = "execution(* com..ReportService.generate*(..))", returning = "result") public void auditSuccess(JoinPoint jp, Object result) { // 记录生成操作 } }

实际部署中,我们发现在高峰时段为模型调用配置适当的限流策略至关重要。使用Resilience4j实现的断路器模式可以有效防止级联故障:

@Bean public CircuitBreakerConfig circuitBreakerConfig() { return CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofSeconds(30)) .permittedNumberOfCallsInHalfOpenState(5) .build(); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 9:40:51

华为麒麟设备终极解锁指南:PotatoNV简单快速Bootloader解锁方案

华为麒麟设备终极解锁指南&#xff1a;PotatoNV简单快速Bootloader解锁方案 【免费下载链接】PotatoNV Unlock bootloader of Huawei devices on Kirin 960/95x/65x/620 项目地址: https://gitcode.com/gh_mirrors/po/PotatoNV 你是否因为华为设备的Bootloader锁定而无法…

作者头像 李华
网站建设 2026/5/4 9:38:25

原神抽卡数据分析终极指南:免费开源工具完整使用教程

原神抽卡数据分析终极指南&#xff1a;免费开源工具完整使用教程 【免费下载链接】genshin-wish-export Easily export the Genshin Impact wish record. 项目地址: https://gitcode.com/GitHub_Trending/ge/genshin-wish-export 还在为原神抽卡记录无法保存而烦恼吗&am…

作者头像 李华
网站建设 2026/5/4 9:35:51

从C风格字符串到现代C++:用std::string_view重构你的老旧代码库

从C风格字符串到现代C&#xff1a;用std::string_view重构你的老旧代码库 如果你正在维护一个历史悠久的C项目&#xff0c;代码库中充斥着char*、std::string和各种字符串字面量的混用&#xff0c;那么你很可能正在经历字符串处理的"黑暗时代"。这种混杂不仅让代码难…

作者头像 李华
网站建设 2026/5/4 9:33:40

Joy-Con Toolkit完整指南:如何免费修复摇杆漂移和自定义手柄颜色

Joy-Con Toolkit完整指南&#xff1a;如何免费修复摇杆漂移和自定义手柄颜色 【免费下载链接】jc_toolkit Joy-Con Toolkit 项目地址: https://gitcode.com/gh_mirrors/jc/jc_toolkit Joy-Con Toolkit是一款功能强大的Nintendo Switch手柄管理工具&#xff0c;能够深度解…

作者头像 李华
网站建设 2026/5/4 9:28:27

Deep Agents 框架-开发部署

上篇 引言 本篇主要介绍了解一下deepagents开发部署架构。目前来看这个系列适合做个个体应用&#xff0c;不适做服务化&#xff0c;非要做的化估计还得做很多努力。 1 使用CLI部署 Deep Agents Deploy 能够获取你的智能体配置&#xff0c;并将其部署为 LangSmith 部署实例&…

作者头像 李华