用 solon-ai 写个简单的 deepseek 程序(构建全国产 ai 智能体应用)
<p>用国产应用开发框架(及生态),对接国产 ai。构建全国产 ai 智能体应用。</p><h3 id="1先要申请个-apikey">1、先要申请个 apiKey</h3>
<p>打开 https://www.deepseek.com 官网,申请个 apiKey 。(一万字略过)</p>
<h3 id="2试试hello-deepseek">2、试试:Hello deepseek</h3>
<p>用 solon-initializr (https://solon.noear.org/start/),生成一个 solon-web 模板项目。之后:</p>
<ul>
<li>在应用属性里添加配置(app.yml)</li>
</ul>
<pre><code class="language-yaml">solon.ai.chat:
deepseek:
apiUrl: "https://api.deepseek.com/v1/chat/completions" # 使用完整地址(而不是 api_base)
apiKey: "sk-9f4415ddc57049658189************"# 填写自己申请的 apiKey
model: "deepseek-chat"
</code></pre>
<ul>
<li>用配置器类构建通用聊天模型</li>
</ul>
<pre><code class="language-java">@Configuration
public class DeepseekConfig {
@Bean
public ChatModel chatModel(@Inject("${solon.ai.chat.deepseek}") ChatConfig config) {
return ChatModel.of(config).build();
}
}
</code></pre>
<ul>
<li>添加测试用的控制器</li>
</ul>
<pre><code class="language-java">@Controller
public class DemoController {
@Inject
ChatModel chatModel;
@Mapping("hello")
public String hello(String message) throws IOException {
return chatModel.prompt(message).call().getMessage().getContent();
}
}
</code></pre>
<ul>
<li>测试一下</li>
</ul>
<p>启动项目。打开浏览器地址:<code>http://localhost:8080/hello?message=hello</code>。效果良好:</p>
<img src="https://teamx.noear.org/img/cb74771cb08d45469a5730b76271097e.png">
<h3 id="3尝试把输出改成-sse方便打字效果的聊天窗口开发">3、尝试把输出改成 sse,方便打字效果的聊天窗口开发</h3>
<p>这里需要添加两个插件依赖,协助流式输出 sse 数据。</p>
<table>
<thead>
<tr>
<th>插件</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>org.noear:solon-web-rx</code></td>
<td>提供响应式输出(就是流式输出)</td>
</tr>
<tr>
<td><code>org.noear:solon-web-sse</code></td>
<td>提供sse渲染支持</td>
</tr>
</tbody>
</table>
<p>加好依赖后,只需要改进下控制器的几行代码:</p>
<pre><code class="language-java">@Controller
public class DemoController {
@Inject
ChatModel chatModel;
@Produces(MimeType.TEXT_EVENT_STREAM_UTF8_VALUE) //这个很重要,申明用 sse 格式渲染
@Mapping("hello")
public Flux<String> hello(String message) throws IOException {
return Flux.from(chatModel.prompt(message).stream())
.filter(resp -> resp.hasChoices())
.map(resp -> resp.getMessage().getContent());
}
}
</code></pre>
<ul>
<li>测试一下</li>
</ul>
<p>启动项目。再次打开浏览器地址:<code>http://localhost:8080/hello?message=hello</code>。效果良好:</p>
<img src="https://teamx.noear.org/img/3ae3bc845c634cbea1f3258ce7b50c16.png">
<h3 id="4现在开始-rag以-联网搜索-作为知识库">4、现在开始 RAG,以 “联网搜索” 作为知识库</h3>
<p>这里把“联网搜索”,做为一个知识库使用(内部是动态搜索的)。用它作为 RAG 的外部检索支持。</p>
<ul>
<li>应用属性加一块配置</li>
</ul>
<pre><code class="language-yaml">solon.ai.chat:
deepseek:
apiUrl: "https://api.deepseek.com/v1/chat/completions" # 使用完整地址(而不是 api_base)
apiKey: "sk-9f4415ddc57049658189************"# 填写自己申明的 apiKey
model: "deepseek-chat"
solon.ai.repo:
websearch:
apiUrl: "https://api.bochaai.com/v1/web-search" # 使用完整地址(而不是 api_base)
apiKey: "sk-demo..."
</code></pre>
<ul>
<li>配置器类也调整下</li>
</ul>
<pre><code class="language-java">@Configuration
public class DeepseekConfig {
@Bean
public ChatModel chatModel(@Inject("${solon.ai.chat.deepseek}") ChatConfig config) {
return ChatModel.of(config).build();
}
@Bean
public Repository repository(@Inject("${solon.ai.repo.websearch}") AiConfig config) {
return new WebSearchRepository(null, config);
}
}
</code></pre>
<ul>
<li>再改改控制器(输出重新写回简单的方式,不然不好截图)</li>
</ul>
<pre><code class="language-java">@Controller
public class DemoController {
@Inject
ChatModel chatModel;
@Inject
Repository repository;
@Mapping("hello")
public String hello(String message) throws IOException {
//检索
List<Document> context = repository.search(new QueryCondition(message).limit(4));
//消息增强
ChatMessage chatMessage = UserMessage.augment(message, context);
//提交大模型并简单返回(不然,截图不好截)
return chatModel.prompt(chatMessage).call().getMessage().getContent();
}
}
</code></pre>
<ul>
<li>测试一下</li>
</ul>
<p>启动项目。打开浏览器地址:<code>http://localhost:8080/hello?message=solon%20%E6%98%AF%E8%B0%81%E5%BC%80%E5%8F%91%E7%9A%84%EF%BC%9F</code>。效果良好:</p>
<img src="https://teamx.noear.org/img/dedc8ee5c5844effaf363b0ea2546e41.png"><br><br>
来源:https://www.cnblogs.com/noear/p/18735473
頁:
[1]