柠裳 發表於 2025-9-23 11:23:00

2. Spring AI 快速入门使用

<h1 id="2-spring-ai-快速入门使用">2. Spring AI 快速入门使用</h1>
<p>@</p><div class="toc"><div class="toc-container-header">目录</div><ul><li>2. Spring AI 快速入门使用<ul><li>快速使用<ul><li>接入deepseek<ul><li>流式对话</li><li>options配置选项<ul><li>temperature(温度)<ul><li>建议</li></ul></li><li><font style="color: rgba(6, 8, 31, 0.88)">maxTokens </font></li><li>stop</li><li>模型推理</li></ul></li><li>原理:</li></ul></li><li>接入阿里百炼<ul><li>使用</li><li>文生图</li><li>文生语音text2audio</li><li>语音翻译audio2text</li><li>多模态</li><li>文生视频(更多功能)</li></ul></li></ul></li></ul></li><li>最后:</li></ul></div><p></p>
<h2 id="快速使用">快速使用</h2>
<ol>
<li>创建项目</li>
</ol>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310841-499614854.png" class="lazyload"></p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
      &lt;version&gt;3.4.5&lt;/version&gt;
      &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
    &lt;/parent&gt;
    &lt;groupId&gt;com.xs&lt;/groupId&gt;
    &lt;artifactId&gt;spring-ai-GA&lt;/artifactId&gt;
    &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
    &lt;name&gt;spring-ai-GA&lt;/name&gt;
    &lt;properties&gt;
      &lt;java.version&gt;17&lt;/java.version&gt;
      &lt;spring-ai.version&gt;1.0.0&lt;/spring-ai.version&gt;
    &lt;/properties&gt;
    &lt;dependencies&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
      &lt;/dependency&gt;

      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;
    &lt;dependencyManagement&gt;
      &lt;dependencies&gt;
          &lt;!-- Spring AI版本管理依赖,可以减少版本的冲突 --&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
                &lt;artifactId&gt;spring-ai-bom&lt;/artifactId&gt;
                &lt;version&gt;${spring-ai.version}&lt;/version&gt;
                &lt;type&gt;pom&lt;/type&gt;
                &lt;scope&gt;import&lt;/scope&gt;
            &lt;/dependency&gt;
      &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;

    &lt;build&gt;
      &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/build&gt;

&lt;/project&gt;
</code></pre>
<h3 id="接入deepseek">接入deepseek</h3>
<ol>
<li>依赖</li>
</ol>
<pre><code class="language-xml">      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
            &lt;artifactId&gt;spring-ai-starter-model-deepseek&lt;/artifactId&gt;
      &lt;/dependency&gt;
</code></pre>
<ol>
<li>获取deepseek api-key</li>
</ol>
<ul>
<li><strong><font style="color: rgba(6, 8, 31, 0.88)">API Key</font></strong><font style="color: rgba(6, 8, 31, 0.88)">:需从 DeepSeek 创建并获取 API 密钥:</font>https://platform.deepseek.com/api_keys</li>
</ul>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310963-1170423557.png" class="lazyload"></p>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310849-524647092.png" class="lazyload"></p>
<ol>
<li>配置</li>
</ol>
<pre><code class="language-yaml">spring:
ai:
    deepseek:
      api-key: ${DEEP_SEEK_KEY}
      chat:
      options:
          model: deepseek-chat
</code></pre>
<ol>
<li>测试</li>
</ol>
<p>spring-ai-starter-model-deepseek</artifactid> 会为你增加自动配置类, 其中DeepSeekChatModel这个就是专门负责智能对话的。</p>
<pre><code class="language-java">package com.xs.springaiga;

import org.junit.jupiter.api.Test;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class DeepseelTest {


    @Test
    public void testChat(@Autowired
                         DeepSeekChatModel chatModel) {
      String call = chatModel.call("你是谁");
      System.out.println(call);
    }
}
</code></pre>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310848-217712612.png" class="lazyload"></p>
<p>上述是一种阻塞输出方式,就是要等服务器全部处理完了,才会被响应出来。</p>
<h4 id="流式对话">流式对话</h4>
<pre><code class="language-java">@Test
    public void testChat2(@Autowired
                         DeepSeekChatModel chatModel) {

      Flux&lt;String&gt; stream = chatModel.stream("你是谁");
      // 流式输出
      stream.toIterable().forEach(System.out::print);
    }
</code></pre>
<p>流式输出,就是服务器接受到一点,就输出一点</p>
<h4 id="options配置选项">options配置选项</h4>
<h5 id="temperature温度">temperature(温度)</h5>
<p>0-2 浮点数值</p>
<p><strong><font style="color: rgba(223, 42, 63, 1)">数值越高</font></strong> 更有创造性 热情</p>
<p><font style="color: rgba(47, 142, 244, 1)">数值越低</font> 保守</p>
<pre><code class="language-java">@Test
public void testChatOptions(@Autowired
                            DeepSeekChatModel chatModel) {
    DeepSeekChatOptions options = DeepSeekChatOptions.builder()
                              .temperature(1.9d).build();
    ChatResponse res = chatModel.call(new Prompt("请写一句诗描述清晨。", options));
    System.out.println(res.getResult().getOutput().getText());
}
</code></pre>
<p>也可以通过配置文件配置</p>
<pre><code class="language-properties">spring.ai.deepseek.chat.options.temperature=0.8
</code></pre>
<p>temperature:0.2 规规矩矩,像是被应试教育出来的老实学生没有创造力</p>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310836-2061795658.png" class="lazyload"></p>
<p>temperature:1.9 可以看出来表现欲更强, 像是一个在领导面前想要表现的你.<img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310829-282140112.png" class="lazyload"></p>
<p>也可以通过提示词降低他的主观臆想:</p>
<ul>
<li><font style="color: rgba(6, 8, 31, 0.88); background-color: rgba(192, 221, 252, 0.5)">只引用可靠来源中的信息,不做任何假设或扩展描述。</font></li>
<li><font style="color: rgba(6, 8, 31, 0.88); background-color: rgba(192, 221, 252, 0.5)">请只基于已知事实回答,不要主观</font><font style="background-color: rgba(192, 221, 252, 0.5)">臆想</font><font style="color: rgba(6, 8, 31, 0.88); background-color: rgba(192, 221, 252, 0.5)">或添加额外内容。</font></li>
<li><font style="color: rgba(6, 8, 31, 0.88); background-color: rgba(192, 221, 252, 0.5)">请简明、客观地给出答案,不要进行修饰或补充未经请求的信息。</font></li>
</ul>
<h6 id="建议">建议</h6>
<table>
<thead>
<tr>
<th style="text-align: center"><strong><font style="color: rgba(6, 8, 31, 0.88)">temperature 范围</font></strong></th>
<th style="text-align: left"><strong><font style="color: rgba(6, 8, 31, 0.88)">建议业务场景</font></strong></th>
<th style="text-align: left"><strong><font style="color: rgba(6, 8, 31, 0.88)">输出风格</font></strong></th>
<th style="text-align: left"><strong><font style="color: rgba(6, 8, 31, 0.88)">说明/应用举例</font></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center"><font style="color: rgba(6, 8, 31, 0.88)">0.0 ~ 0.2</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">严谨问答、代码补全、数学答题</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">严格、确定、标准</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">法律/金融答题、接口返回模板、考试答卷等</font></td>
</tr>
<tr>
<td style="text-align: center"><font style="color: rgba(6, 8, 31, 0.88)">0.3 ~ 0.6</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">聊天机器人、日常摘要、辅助写作</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">稍有变化、较稳妥</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">公众号摘要、普通对话、邮件生成等</font></td>
</tr>
<tr>
<td style="text-align: center"><font style="color: rgba(6, 8, 31, 0.88)">0.7 ~ 1.0</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">创作内容、广告文案、标题生成</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">丰富、有创意、灵活</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">诗歌、短文案、趣味对话、产品描述等</font></td>
</tr>
<tr>
<td style="text-align: center"><font style="color: rgba(6, 8, 31, 0.88)">1.1 ~ 1.5</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">脑洞风格、头脑风暴、灵感碰撞场景</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">大开脑洞、变化极强</font></td>
<td style="text-align: left"><font style="color: rgba(6, 8, 31, 0.88)">故事创作、异想天开的推荐语、多样化内容</font></td>
</tr>
</tbody>
</table>
<hr>
<p><strong><font style="color: rgba(6, 8, 31, 0.88)">说明:</font></strong></p>
<ul>
<li><font style="color: rgba(6, 8, 31, 0.88)">温度越低,输出越收敛和中规中矩;</font></li>
<li><font style="color: rgba(6, 8, 31, 0.88)">温度越高,输出越多变、富有惊喜但有风险;</font></li>
<li><font style="color: rgba(6, 8, 31, 0.88)">实战用法一般建议选 </font><strong><font style="color: rgba(6, 8, 31, 0.88)">0.5~0.8</font></strong><font style="color: rgba(6, 8, 31, 0.88)"> 作为日常生产起点,需要根据业务不断测试调整。</font></li>
</ul>
<h5 id="maxtokens-"><font style="color: rgba(6, 8, 31, 0.88)">maxTokens </font></h5>
<p>默认低 token</p>
<p><code>maxTokens</code>: 限制AI模型生成的最大token数(近似理解为字数上限)。</p>
<ul>
<li><font style="color: rgba(6, 8, 31, 0.88)">需要简洁回复、打分、列表、短摘要等,建议小值(如10~50)。</font></li>
<li><font style="color: rgba(6, 8, 31, 0.88)">防止用户跑长对话导致无关内容或花费过多token费用。</font></li>
<li><font style="color: rgba(6, 8, 31, 0.88)">如果遇到生成内容经常被截断,可以适当配置更大maxTokens。</font></li>
</ul>
<h5 id="stop">stop</h5>
<p>截断你不想输出的内容 比如:</p>
<pre><code class="language-yaml">spring:
ai:
    deepseek:
      api-key: ${DEEP_SEEK_KEY}
      chat:
      options:
          model: deepseek-chat
          max-tokens: 20
          stop:
            - "\n"    #只想一行
            - "。"    #只想一句话
            - "政治"#敏感词
            - "最后最总结一下"#这种AI惯用的模板词, 减少AI词汇, 让文章更拟人
</code></pre>
<h5 id="模型推理">模型推理</h5>
<p>设置深度思考, 思考的内容有个专业名词叫:<font style="color: rgba(25, 30, 30, 1)">Chain of Thought (CoT)</font></p>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310860-656421391.png" class="lazyload"></p>
<p>在deepseek中, deepseek-reasoner模型是深度思考模型:</p>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310883-965329067.png" class="lazyload"></p>
<pre><code class="language-java">@Test
    public void deepSeekReasonerExample(@Autowired DeepSeekChatModel deepSeekChatModel) {
      DeepSeekChatOptions options = DeepSeekChatOptions.builder()
                .model("deepseek-reasoner").build();


      Prompt prompt = new Prompt("请写一句诗描述清晨。", options);
      ChatResponse res = deepSeekChatModel.call(prompt);

      DeepSeekAssistantMessage assistantMessage =(DeepSeekAssistantMessage)res.getResult().getOutput();

      String reasoningContent = assistantMessage.getReasoningContent();
      String content = assistantMessage.getText();

      System.out.println(reasoningContent);
      System.out.println("--------------------------------------------");
      System.out.println(content);


    }


    @Test
    public void deepSeekReasonerStreamExample(@Autowired DeepSeekChatModel deepSeekChatModel) {
      DeepSeekChatOptions options = DeepSeekChatOptions.builder()
                .model("deepseek-reasoner").build();


      Prompt prompt = new Prompt("请写一句诗描述清晨。", options);
      Flux&lt;ChatResponse&gt; stream = deepSeekChatModel.stream(prompt);

      stream.toIterable().forEach(res -&gt; {
            DeepSeekAssistantMessage assistantMessage =(DeepSeekAssistantMessage)res.getResult().getOutput();
            String reasoningContent = assistantMessage.getReasoningContent();
            System.out.print(reasoningContent);
      });
      System.out.println("--------------------------------------------");
      stream.toIterable().forEach(res -&gt; {
            DeepSeekAssistantMessage assistantMessage =(DeepSeekAssistantMessage)res.getResult().getOutput();
            String content = assistantMessage.getText();
            System.out.print(content);
      });

    }
</code></pre>
<p>也可以在配置文件中配置</p>
<pre><code class="language-properties">spring.ai.deepseek.chat.options.model= deepseek-reasoner
</code></pre>
<h4 id="原理">原理:</h4>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310829-1111134963.png" class="lazyload"></p>
<ol>
<li>当调用chatModel.call</li>
</ol>
<pre><code class="language-java">default String call(String message) {
    Prompt prompt = new Prompt(new UserMessage(message));
    Generation generation = call(prompt).getResult();
    return (generation != null) ? generation.getOutput().getText() : "";
}
</code></pre>
<pre><code>1. 首先会将提示词解析到Prompt对象中 (用于远程请求的messages)
</code></pre>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310816-235675555.png" class="lazyload"></p>
<ol>
<li>调用deepseekModel#call---&gt; internalCall方法</li>
</ol>
<pre><code class="language-java">public ChatResponse internalCall(Prompt prompt, ChatResponse previousChatResponse) {

    // a
    ChatCompletionRequest request = createRequest(prompt, false);

    //..省略   
    ResponseEntity&lt;ChatCompletion&gt; completionEntity = this.retryTemplate
    // b
    .execute(ctx -&gt; this.deepSeekApi.chatCompletionEntity(request));

    var chatCompletion = completionEntity.getBody();
    //..省略
    ChatResponse chatResponse = new ChatResponse(generations,
                                                 from(completionEntity.getBody(), accumulatedUsage));

    observationContext.setResponse(chatResponse);

    return chatResponse;
    //.. 省略
    return response;
}
</code></pre>
<pre><code>1. 通过createRequest封装为远程请求所需的json对象
2. 通过spring retry 重试机制去远程请求
</code></pre>
<p>deepseekthis.deepSeekApi.chatCompletionEntity(request)</p>
<pre><code class="language-java">// 通过restClient 进行远程请求
public ResponseEntity&lt;ChatCompletion&gt; chatCompletionEntity(ChatCompletionRequest chatRequest) {

                return this.restClient.post()
                        .uri(this.getEndpoint(chatRequest))
                        .body(chatRequest)
                        .retrieve()
                        .toEntity(ChatCompletion.class);
        }
</code></pre>
<pre><code>1. 封装响应数据
</code></pre>
<h3 id="接入阿里百炼">接入阿里百炼</h3>
<p>https://bailian.console.aliyun.com/?tab=home#/home</p>
<p><img alt="" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310893-283496480.png" class="lazyload"></p>
<p>阿里自己的团队维护spring-ai-alibaba. 但是也必须依赖spring-ai 。 好处是扩展度更高,坏处是必须是springai先出来, spring-ai-alibaba.延迟几天出来。</p>
<p>如果需要接入阿里的百炼平台, 就必须用该组件</p>
<h4 id="使用">使用</h4>
<ol>
<li>申请api-key</li>
</ol>
<p><font style="color: rgba(24, 24, 24, 1)">在调用前,您需要</font>开通模型服务并获取API Key<font style="color: rgba(24, 24, 24, 1)">,再</font>配置API Key到环境变量<font style="color: rgba(24, 24, 24, 1)">。</font></p>
<ol>
<li>依赖</li>
</ol>
<pre><code class="language-xml">&lt;dependencyManagement&gt;
&lt;dependencies&gt;
    &lt;!-- 版本管理依赖 --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.alibaba.cloud.ai&lt;/groupId&gt;
      &lt;artifactId&gt;spring-ai-alibaba-bom&lt;/artifactId&gt;
      &lt;version&gt;1.0.0.2&lt;/version&gt;
      &lt;type&gt;pom&lt;/type&gt;
      &lt;scope&gt;import&lt;/scope&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/dependencyManagement&gt;

&lt;dependencies&gt;
&lt;!--阿里的百炼依赖--&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.alibaba.cloud.ai&lt;/groupId&gt;
    &lt;artifactId&gt;spring-ai-alibaba-starter-dashscope&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre>
<ol>
<li>配置</li>
</ol>
<p>不配置指定通义千问的模型名的话,也是会自动配置一个默认模型名。</p>
<pre><code class="language-yaml">spring:
ai:
    dashscope:
      api-key: ${AI_DASHSCOPE_API_KEY}
</code></pre>
<ol>
<li>使用</li>
</ol>
<pre><code class="language-java">@Test
    public void testQwen(@Autowired DashScopeChatModel dashScopeChatModel) {

      String content = dashScopeChatModel.call("你好你是谁");
      System.out.println(content);
    }
</code></pre>
<h4 id="文生图">文生图</h4>
<pre><code class="language-java">@Test
    public void text2Img(
      // 注意:这里是图片生成使用的是 DashScopeImageModel 也是被自动装配了。
         @Autowired DashScopeImageModel imageModel) {
      DashScopeImageOptions imageOptions = DashScopeImageOptions.builder()
                .withModel("wanx2.1-t2i-turbo").build();// 构建配置项

      // 返回一个图片想 Response 返回类
      ImageResponse imageResponse = imageModel.call(
                new ImagePrompt("小兔子", imageOptions));
      String imageUrl = imageResponse.getResult().getOutput().getUrl();

      // 图片url
      System.out.println(imageUrl);

      // 图片base64
      // imageResponse.getResult().getOutput().getB64Json();

      /*
      按文件流相应
      InputStream in = url.openStream();

      response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);
      response.getOutputStream().write(in.readAllBytes());
      response.getOutputStream().flush();*/
    }
</code></pre>
<h4 id="文生语音text2audio">文生语音text2audio</h4>
<pre><code class="language-java">
// https://bailian.console.aliyun.com/?spm=5176.29619931.J__Z58Z6CX7MY__Ll8p1ZOR.1.74cd59fcXOTaDL&amp;tab=doc#/doc/?type=model&amp;url=https%3A%2F%2Fhelp.aliyun.com%2Fdocument_detail%2F2842586.html&amp;renderType=iframe
    @Test
    public void testText2Audio(
      //DashScopeSpeechSynthesisModel 自动装配生成 语言类
      @Autowired DashScopeSpeechSynthesisModel speechSynthesisModel) throws IOException {
      // 语言配置项,.出来
      DashScopeSpeechSynthesisOptions options = DashScopeSpeechSynthesisOptions.builder()
                //.voice()   // 人声
                //.speed()    // 语速
                //.model()    // 模型
                //.responseFormat(DashScopeSpeechSynthesisApi.ResponseFormat.MP3)
                .build();

      SpeechSynthesisResponse response = speechSynthesisModel.call(
                new SpeechSynthesisPrompt("大家好, 我是李华。",options)
      );

      File file = new File( System.getProperty("user.dir") + "/output.mp3");
      try (FileOutputStream fos = new FileOutputStream(file)) {
            // 响应的语言的二进制流
            ByteBuffer byteBuffer = response.getResult().getOutput().getAudio();
            // 保存到我们,根路径下
            fos.write(byteBuffer.array());
      }
      catch (IOException e) {
            throw new IOException(e.getMessage());
      }
    }
</code></pre>
<h4 id="语音翻译audio2text">语音翻译audio2text</h4>
<pre><code class="language-java">// 这个设置的是一个远程的 url 文本内容
private static final String AUDIO_RESOURCES_URL = "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav";


@Test
    public void testAudio2Text(
            @Autowired
            DashScopeAudioTranscriptionModel transcriptionModel
    ) throws MalformedURLException {
      DashScopeAudioTranscriptionOptions transcriptionOptions = DashScopeAudioTranscriptionOptions.builder()
                //.withModel()   模型
                .build();
      AudioTranscriptionPrompt prompt = new AudioTranscriptionPrompt(
                new UrlResource(AUDIO_RESOURCES_URL),
                transcriptionOptions
      );
      AudioTranscriptionResponse response = transcriptionModel.call(
                prompt
      );

      System.out.println(response.getResult().getOutput());

    }
</code></pre>
<h4 id="多模态">多模态</h4>
<p>图片,语音,视频 传给大模型让大模型识别,理解其中的内容。</p>
<pre><code class="language-java">@Test
public void testMultimodal(@Autowired DashScopeChatModel dashScopeChatModel
                        ) throws MalformedURLException {
    // flac、mp3、mp4、mpeg、mpga、m4a、ogg、wav 或 webm。
    var audioFile = new ClassPathResource("/files/xushu.png");

// MimeTypeUtils.IMAGE_JPEG 表示我们传递的文件类型
    Media media = new Media(MimeTypeUtils.IMAGE_JPEG, audioFile);
    DashScopeChatOptions options = DashScopeChatOptions.builder()
    .withMultiModel(true)// 使用多模态要设置为 true
    .withModel("qwen-vl-max-latest").build();
   
    Promptprompt= Prompt.builder().chatOptions(options)
    .messages(UserMessage.builder().media(media)
            // 设置提示词 为“识别图片”
            .text("识别图片").build())
    .build();
    ChatResponse response = dashScopeChatModel.call(prompt);
   
    System.out.println(response.getResult().getOutput().getText());
}
</code></pre>
<h4 id="文生视频更多功能">文生视频(更多功能)</h4>
<p>因为这里的 Spring AI 目前并没有提供文生视频的 Modles 内容,需要接入第三方的依赖,使用第三方 API。</p>
<pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;com.alibaba&lt;/groupId&gt;
    &lt;artifactId&gt;dashscope-sdk-java&lt;/artifactId&gt;
    &lt;!-- 请将 'the-latest-version' 替换为最新版本号:https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --&gt;
    &lt;version&gt;the-latest-version&lt;/version&gt;
&lt;version&gt;2.20.6&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
<pre><code class="language-java">@Test
    public void text2Video() throws ApiException, NoApiKeyException, InputRequiredException {
      VideoSynthesis vs = new VideoSynthesis();
      VideoSynthesisParam param =
                VideoSynthesisParam.builder()
                        .model("wanx2.1-t2v-turbo")
                        .prompt("一只小猫在月光下奔跑")
                        .size("1280*720")
            // 因为这里我们接入的是第三方API,对应的key并没有采用application.yaml的配置
         // 所以需要我们手动,System.getenv() 获取到环境变量当中的key值
                        .apiKey(System.getenv("ALI_AI_KEY"))
                        .build();
      System.out.println("please wait...");
      VideoSynthesisResult result = vs.call(param);
      System.out.println(result.getOutput().getVideoUrl());
    }
</code></pre>
<p>更多的内容可以去参考阿里云百炼广场 https://bailian.console.aliyun.com/?tab=home#/home 当中的 SDK,以及提供的一些 Demo 进行配置操作。</p>
<h1 id="最后">最后:</h1>
<blockquote>
<p>“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”</p>
<p><img alt="在这里插入图片描述" loading="lazy" src="https://img2024.cnblogs.com/blog/3084824/202509/3084824-20250923112310849-921022573.gif" class="lazyload"></p>
</blockquote><br><br>
来源:https://www.cnblogs.com/TheMagicalRainbowSea/p/19106841
頁: [1]
查看完整版本: 2. Spring AI 快速入门使用