Skip to content

Spring AI 文本生成

文本生成是 AI 应用中最常见的任务之一。Spring AI 提供了强大的文本生成功能,支持从简单文本补全到复杂的内容创建。本文将介绍如何使用 Spring AI 进行各种文本生成任务。

基础文本生成

最简单的文本生成使用 ChatClient 完成:

java
@Service
public class TextGenerationService {
    
    private final ChatClient chatClient;
    
    public TextGenerationService(ChatClient chatClient) {
        this.chatClient = chatClient;
    }
    
    public String generateText(String prompt) {
        ChatResponse response = chatClient.call(new Prompt(prompt));
        return response.getResult().getOutput().getContent();
    }
}

结构化文本生成

Spring AI 支持生成结构化文本,如 JSON 或 XML:

java
@Service
public class StructuredTextService {
    
    private final ChatClient chatClient;
    
    public JsonNode generateJson(String topic) {
        String prompt = String.format("""
            请生成一篇关于"%s"的文章大纲,以JSON格式返回。
            格式要求:
            {
              "title": "文章标题",
              "sections": [
                {
                  "heading": "章节标题",
                  "points": ["要点1", "要点2", "要点3"]
                }
              ],
              "conclusion": "结论"
            }
            仅返回JSON,不要有其他说明文字。
            """, topic);
        
        ChatResponse response = chatClient.call(new Prompt(prompt));
        String jsonContent = response.getResult().getOutput().getContent();
        
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readTree(jsonContent);
        } catch (Exception e) {
            throw new RuntimeException("解析生成的JSON失败", e);
        }
    }
}

自定义生成参数

通过调整生成参数,可以控制文本生成的特性:

java
@Service
public class CustomizedGenerationService {
    
    private final OpenAiChatClient chatClient;
    
    public String generateCreativeStory(String theme, int maxWords) {
        String prompt = String.format("写一个关于%s的创意短篇故事,不超过%d字", theme, maxWords);
        
        ChatOptions options = ChatOptions.builder()
                .temperature(0.9f)       // 较高的温度值,增加创意性
                .topP(0.95f)            // 高 top-p 值,增加多样性
                .maxTokens(1000)        // 限制生成长度
                .build();
        
        ChatResponse response = chatClient.call(new Prompt(prompt), options);
        return response.getResult().getOutput().getContent();
    }
    
    public String generateTechnicalDocumentation(String topic) {
        String prompt = String.format("为%s编写一份技术文档", topic);
        
        ChatOptions options = ChatOptions.builder()
                .temperature(0.1f)       // 低温度值,保持精确性
                .topP(0.2f)             // 低 top-p 值,减少变化
                .maxTokens(2000)        // 允许更长的输出
                .build();
        
        ChatResponse response = chatClient.call(new Prompt(prompt), options);
        return response.getResult().getOutput().getContent();
    }
}

流式文本生成

对于长文本生成,流式响应可以提供更好的用户体验:

java
@RestController
@RequestMapping("/api/text")
public class StreamingTextController {
    
    private final StreamingChatClient streamingChatClient;
    
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamText(@RequestParam String prompt) {
        return streamingChatClient.stream(new Prompt(prompt))
                .map(chunk -> chunk.getResult().getOutput().getContent());
    }
}

Web 应用中使用 Server-Sent Events (SSE) 显示流式生成:

javascript
const eventSource = new EventSource('/api/text/stream?prompt=' + encodeURIComponent(prompt));
const outputDiv = document.getElementById('output');

eventSource.onmessage = function(event) {
    outputDiv.innerHTML += event.data;
};

eventSource.onerror = function() {
    eventSource.close();
};

文本生成控制与约束

输出格式控制

java
public String generateStructuredResponse(String query) {
    String prompt = String.format("""
        回答以下问题:%s
        
        请严格按照以下格式返回:
        
        答案: [简短直接的回答]
        说明: [详细解释]
        参考资料: [相关信息来源,如有]
        """, query);
    
    return chatClient.call(new Prompt(prompt))
            .getResult().getOutput().getContent();
}

内容安全与过滤

java
public String generateSafeContent(String topic, String audience) {
    String prompt = String.format("""
        为%s撰写一篇关于%s的文章。
        
        重要说明:
        - 内容必须适合%s阅读
        - 不包含任何敏感、争议性或不适当内容
        - 语言简单易懂
        - 重点关注教育价值
        """, audience, topic, audience);
    
    return chatClient.call(new Prompt(prompt))
            .getResult().getOutput().getContent();
}

多样化内容生成

多语言文本生成

java
public String translateToMultipleLanguages(String text, List<String> targetLanguages) {
    StringBuilder promptBuilder = new StringBuilder();
    promptBuilder.append("请将以下文本翻译成以下语言:\n\n");
    promptBuilder.append("原文:").append(text).append("\n\n");
    
    for (String language : targetLanguages) {
        promptBuilder.append(language).append("翻译:\n");
    }
    
    return chatClient.call(new Prompt(promptBuilder.toString()))
            .getResult().getOutput().getContent();
}

不同风格的内容生成

java
public String rewriteInStyle(String text, String style) {
    String prompt = String.format("""
        以%s的风格改写以下文本:
        
        %s
        """, style, text);
    
    return chatClient.call(new Prompt(prompt))
            .getResult().getOutput().getContent();
}

文本后处理

有时生成的文本需要进一步处理:

java
@Service
public class TextPostProcessingService {
    
    private final ChatClient chatClient;
    
    public String generateAndFormat(String topic) {
        // 生成原始文本
        String rawText = chatClient.call(new Prompt("写一篇关于" + topic + "的文章"))
                .getResult().getOutput().getContent();
        
        // 后处理:提取重点并格式化
        String processPrompt = "从以下文章中提取5个关键点,并以markdown格式的无序列表返回:\n\n" + rawText;
        
        return chatClient.call(new Prompt(processPrompt))
                .getResult().getOutput().getContent();
    }
}

生成文本的评估与改进

Spring AI 支持对生成文本进行评估和改进:

java
@Service
public class ContentEvaluationService {
    
    private final ChatClient chatClient;
    
    public String improveContent(String content, String criteria) {
        String prompt = String.format("""
            请评估并改进以下内容,重点关注%s:
            
            %s
            
            先给出评估,然后提供改进后的版本。
            """, criteria, content);
        
        return chatClient.call(new Prompt(prompt))
                .getResult().getOutput().getContent();
    }
}

文本生成的最佳实践

  1. 明确指定输出格式:在提示中明确要求模型以特定格式返回结果
  2. 控制生成参数:根据任务调整温度、top-p等参数
  3. 分步生成:复杂任务分解为多个步骤,逐步生成和优化
  4. 使用流式响应:对于长文本生成,提供实时反馈
  5. 验证输出:设计系统验证和清理模型输出,确保符合预期
  6. 使用思维链提示:引导模型逐步思考,提高复杂生成任务的质量

总结

Spring AI 提供了丰富的工具和抽象,使开发人员能够轻松实现各种文本生成功能。通过合理设计提示、控制生成参数和实施后处理,可以创建出高质量、符合特定需求的文本生成应用。无论是简单的文本补全还是复杂的创意写作,Spring AI 都提供了统一、灵活的接口,使文本生成任务变得简单而可控。