Spring AI 对接Gemini实践
准备工作
了解Gemini
Gemini 是谷歌提供的人工智能大模型。
Gemini 提供的模型列表:https://ai.google.dev/gemini-api/docs/models?hl=zh-cn, 本案例使用的是gemini-2.5-flash-preview-05-20
获取秘钥和请求配置示例
注
秘钥获取过程 - 参考官网教程
https://ai.google.dev/gemini-api/docs?hl=zh-cn
官网示例:
科学网络代理
测试连通性
curl --socks5 127.0.0.1:10886 "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Gemini_API_KEY(replace your key)" \
-d '{
"model": "gemini-2.5-flash-preview-05-20",
"messages": [
{"role": "user", "content": "Explain to me how AI works"}
]
}'
注
curl,要配置代理 此处使用socks 代理。
请求结果:
(base) dftshine@192 ~ % curl --socks5 127.0.0.1:10886 "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Gemini_API_KEY(replace your key)" \
-d '{
"model": "gemini-2.5-flash-preview-05-20",
"messages": [
{"role": "user", "content": "Explain to me how AI works"}
]
}'
{"choices":[{"finish_reason":"stop","index":0,"message":{"content":"Imagine AI not as a thinking brain, but as an incredibly sophisticated .... **Magic:** It's all built on mathematics, statistics, and computer science.\n\nIn essence, AI works by}}],"created":1748739268,"id":"xKQ7aP3GCfe41MkPsb-mwAg","model":"gemini-2.5-flash-preview-05-20","object":"chat.completion","usage":{"completion_tokens":1574,"prompt_tokens":7,"total_tokens":2878}}%
工程实践
配置Idea 代理
注
可能与代码访问网络无关
配置代码代理
配置文件 application.yml
gemini:
base-url: https://generativelanguage.googleapis.com/v1beta/openai/
api-key: Gemini_API_KEY(replace your key)
model: gemini-2.5-flash-preview-05-20
spring:
ai:
name: ai-demo
proxy:
enabled: true
host: 127.0.0.1
port: 10887
client:
connection-timeout: 100000
read-timeout: 200000
openai:
base-url: ${gemini.base-url}
api-key: ${gemini.api-key}
chat:
options:
model: ${gemini.model}
temperature: 0.3F
completions-path: chat/completions
gemini的配置与deepseek类似,均通过openai库进行访问,只替换了base-url、api-key、model
spring.ai.proxy 下配置了是否启用代理、代理host和 代理的端口
最关键的spring.ai.openai.chat.completions-path 需要指定,否则发出的请求访问的接口地址多了路径**/v1**
代理逻辑
@Configuration
class ChatClientConfig {
@Autowired
private ChatModel chatModel;
@Value("${spring.ai.proxy.enabled}")
private boolean enabled;
@Value("${spring.ai.proxy.host}")
private String host;
@Value("${spring.ai.proxy.port}")
private String port;
/**
* 初始化代理
*/
private void initProxy(){
System.setProperty("proxyHost", host); // 代理的IP地址
System.setProperty("proxyPort", port); // 代理的端口号
// 验证代理是否生效
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress("www.google.com", 443), 5000);
System.out.println("代理连接成功");
} catch (IOException e) {
System.err.println("代理连接失败: " + e.getMessage());
}
}
@Bean
ChatClient chatClient() {
if (enabled) {
initProxy();
}
return ChatClient.create(chatModel);
}
}
**暂时放在初始化模型客户端的位置。**增加初始化代理的方法,并提供访问验证。
验证过程
注
因本地有完整前后端对话程序,所以此处略。
过程经验
科学网络代理使用经验
使用科学网络工具后,虽然选择了全局模式,但是只是针对配置了代理的软件,提供全局访问,因为浏览器是默认配置了代理,所以可以直接访问。 使用终端或者Iterm2,执行curl 命令时,还是需要配置代理,否则依然无法访问。
科学网络代理按需使用分类
代理也是分为,socks 代理和 http代理,之前代码配置了socks代理,但是无法访问成功,原因是spring ai 访问大模型使用的是rest http方式,所以需要配置 http代理。
请求端点(接口)配置
命令行示例使用的api- url 和 spring AI 配置 base-url 生成的url 中 , completionsPath 部分不同, spring ai 默认配置中, 多了一个/v1 , 尝试了很多方法
..找到completionsPath 这个是在 chatModel 中的 openAiApi 中定义的,想通过反射直接修改,没有成功
..定义拦截器,没有配置成功
.. 通过yaml中的提示,发现有spring.ai.openai.chat.completions-path 配置,直接配置了没有/v1 的路径,成功