亲测AI智能小助手-IDEA中使用腾讯混元大模型
已完成AI真实模型的集成,支持多种AI服务提供商,并具备自动降级机制。
功能概述
已完成AI真实模型的集成,支持多种AI服务提供商,并具备自动降级机制。
技术实现
1. 配置文件
位置 : src/main/resources/application-ai.yml
配置项说明:
-
provider: AI服务提供商,可选值
tencent: 腾讯混元baidu: 百度文心一言alibaba: 阿里通义千问openai: OpenAIrule: 规则匹配(降级方案)
-
fallback-enabled: 是否启用降级
true: 当AI服务不可用时,自动降级到规则匹配false: AI服务失败时返回错误
-
timeout: 超时时间(秒)
-
max-retry: 最大重试次数
-
system-prompt: 系统提示词,定义AI助手的角色和职责
2. 服务架构
AIController
↓
AIServiceProxy (代理层)
↓ 根据配置选择
├── TencentHunyuanAIService (腾讯混元)
├── BaiduAIService (文心一言,待实现)
├── AlibabaAIService (通义千问,待实现)
├── OpenAIService (OpenAI,待实现)
└── RuleBasedAIService (规则匹配,降级)
3. 核心文件
配置类:
AIConfig.java: AI配置管理YamlPropertySourceFactory.java: YAML配置加载器
服务接口:
AIService.java: AI服务接口,定义聊天和流式聊天方法
服务实现:
TencentHunyuanAIService.java: 腾讯混元实现RuleBasedAIService.java: 规则匹配实现AIServiceProxy.java: 服务代理,负责选择服务和降级
控制器:
AIController.java: AI接口控制器
使用方法
方式一: 使用腾讯混元(推荐)
-
在腾讯云控制台开通混元服务: https://console.cloud.tencent.com/hunyuan
-
获取API密钥:
- Secret ID
- Secret Key
-
修改配置文件
application-ai.yml:
yaml
ai:
provider: tencent
fallback-enabled: true
tencent:
secret-id: your_secret_id # 替换为实际密钥
secret-key: your_secret_key # 替换为实际密钥
model: hunyuan-lite # 可选: hunyuan-lite, hunyuan-standard, hunyuan-pro
- 重启应用,即可使用腾讯混元AI
项目案例

yml文件配置
yaml
# AI配置
ai:
# AI服务提供商: tencent(腾讯混元), baidu(文心一言), alibaba(通义千问), openai
provider: tencent
# 启用降级: 当AI服务不可用时,自动降级到规则匹配
fallback-enabled: true
# 超时时间(秒)
timeout: 30
# 最大重试次数
max-retry: 2
# 腾讯混元配置
tencent:
# API密钥(在腾讯云控制台获取) SecretId:
#SecretKey:
secret-id: ${TENCENT_SECRET_ID:你的SecretId}
secret-key: ${TENCENT_SECRET_KEY:你的SecretKey}
# 模型版本: hunyuan-lite(轻量版), hunyuan-standard(标准版), hunyuan-pro(专业版)
model: hunyuan-lite
# API端点
endpoint: https://hunyuan.tencentcloudapi.com
# 请求超时(毫秒)
request-timeout: 30000
# 百度文心一言配置
baidu:
# API Key
api-key: ${BAIDU_API_KEY:your_api_key}
secret-key: ${BAIDU_SECRET_KEY:your_secret_key}
# 模型版本: ERNIE-Bot-turbo, ERNIE-Bot, ERNIE-Bot-4
model: ERNIE-Bot-turbo
# API端点
endpoint: https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat
# 阿里通义千问配置
alibaba:
# API Key
api-key: ${ALIBABA_API_KEY:your_api_key}
# 模型版本: qwen-turbo, qwen-plus, qwen-max
model: qwen-turbo
# API端点
endpoint: https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
# OpenAI配置
openai:
# API Key
api-key: ${OPENAI_API_KEY:your_api_key}
# 模型版本: gpt-3.5-turbo, gpt-4
model: gpt-3.5-turbo
# API端点
endpoint: https://api.openai.com/v1/chat/completions
# 组织ID(可选)
organization-id: ${OPENAI_ORGANIZATION_ID:}
# 系统提示词
system-prompt: |
你是智慧管理系统的AI助手,专门负责解答工作相关的各类问题。
你的回答需要:
1. 准确、专业,符合党的理论和政策
2. 语言简洁明了,条理清晰
3. 必要时引用相关法规和文件
4. 保持客观中立的立场
5. 对于不确定的问题,建议用户咨询相关部门
前端聊天界面设计
javascript
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>AI智能问答 - 智慧AI</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
height: 100vh;
display: flex;
flex-direction: column;
}
.chat-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
padding-top: env(safe-area-inset-top, 20px);
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header-top {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.header-title {
font-size: 20px;
font-weight: 600;
}
.header-back {
cursor: pointer;
padding: 5px;
}
.header-back svg {
width: 24px;
height: 24px;
}
.chat-container {
flex: 1;
overflow-y: auto;
padding: 20px;
padding-bottom: 80px;
background: #f5f7fa;
}
.message-item {
display: flex;
margin-bottom: 20px;
animation: fadeIn 0.3s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.message-user {
justify-content: flex-end;
}
.message-ai {
justify-content: flex-start;
}
.message-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 20px;
}
.user-avatar {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
margin-left: 10px;
}
.ai-avatar {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
margin-right: 10px;
}
.message-content {
max-width: 70%;
padding: 12px 16px;
border-radius: 18px;
position: relative;
line-height: 1.6;
}
.user-message {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-bottom-right-radius: 4px;
}
.ai-message {
background: white;
color: #333;
border-bottom-left-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.message-time {
font-size: 11px;
color: #999;
margin-top: 5px;
text-align: right;
}
.ai-message .message-time {
text-align: left;
}
.chat-input-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: white;
padding: 15px;
padding-bottom: calc(15px + env(safe-area-inset-bottom, 0px));
box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
}
.chat-input-wrapper {
display: flex;
gap: 10px;
max-width: 800px;
margin: 0 auto;
}
.chat-input {
flex: 1;
}
.chat-input .el-input__inner {
border-radius: 25px;
padding: 12px 20px;
height: 50px;
}
.send-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 25px;
padding: 0 25px;
height: 50px;
color: white;
font-size: 16px;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
transition: all 0.3s ease;
}
.send-btn:hover {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
.send-btn:active {
transform: scale(0.98);
}
.send-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.quick-questions {
padding: 15px;
background: white;
border-top: 1px solid #eee;
}
.quick-title {
font-size: 14px;
color: #666;
margin-bottom: 10px;
}
.quick-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.quick-item {
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
color: #333;
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid transparent;
}
.quick-item:hover {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
transform: translateY(-2px);
}
.loading-dots {
display: inline-flex;
gap: 4px;
align-items: center;
}
.loading-dots span {
width: 8px;
height: 8px;
background: #667eea;
border-radius: 50%;
animation: bounce 1.4s infinite ease-in-out both;
}
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
.loading-dots span:nth-child(3) { animation-delay: 0s; }
@keyframes bounce {
0%, 80%, 100% {
transform: scale(0);
}
40% {
transform: scale(1);
}
}
.typing-indicator {
font-size: 12px;
color: #999;
margin-top: 5px;
}
@media (max-width: 768px) {
.message-content {
max-width: 85%;
}
.chat-input-wrapper {
flex-direction: row;
}
}
</style>
</head>
<body>
<div id="app">
<div class="chat-header">
<div class="header-top">
<div class="header-back" @click="goBack">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M19 12H5M12 19l-7-7 7-7"/>
</svg>
</div>
<div class="header-title">AI智能问答</div>
<div style="width: 34px;"></div>
</div>
<div style="font-size: 12px; opacity: 0.9;">
<svg style="width: 16px; height: 16px; vertical-align: middle; margin-right: 4px;" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79.09-3.15 2.65-5.66 5.88-5.66.6 0 1.19.09 1.79.21 3.15-3.95 4.08-7.48 8.03-7.48 4.08 0 7.48 3.53 7.48 8.08zm6.88-2.57c-.67-2.65-2.67-4.97-5.37-5.76-.68-.2-1.38-.35-2.1-.45.58-1.62 1.58-3.29 1.58-3.29s-1 1.67-1.58 3.29c-.72.1-1.42.25-2.1.45-2.7.79-2.7 2.11-4.7 3.12-5.37 5.76zm1.63 4.37c-.91-1.84-2.28-3.25-3.89-4.14-.28.63-.53 1.27-.74 1.92.21.65.46 1.3.74 1.92 1.61.89 2.98 2.3 3.89 4.14-.91-.21-1.84-.48-2.76-.81-.21-.65-.46-1.3-.74-1.92-.23-.65-.46-1.29-.74-1.92.87.33 1.8.6 2.76.81z"/>
</svg>
智慧党建AI助手 · 24小时在线
</div>
</div>
<div class="chat-container" ref="chatContainer">
<div v-if="messages.length === 0" style="text-align: center; padding: 40px 20px;">
<div style="width: 100px; height: 100px; margin: 0 auto 20px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 48px;">
🤖
</div>
<div style="font-size: 18px; color: #333; margin-bottom: 10px;">欢迎来到智慧党建AI助手</div>
<div style="font-size: 14px; color: #666; margin-bottom: 30px;">我可以帮您解答党建工作相关问题</div>
</div>
<div v-for="(message, index) in messages" :key="index" :class="['message-item', message.role === 'user' ? 'message-user' : 'message-ai']">
<div v-if="message.role === 'ai'" class="message-avatar ai-avatar">
🤖
</div>
<div class="message-content" :class="message.role === 'user' ? 'user-message' : 'ai-message'">
<div v-html="message.content"></div>
<div class="message-time">{{ message.time }}</div>
</div>
<div v-if="message.role === 'user'" class="message-avatar user-avatar">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
</svg>
</div>
</div>
<div v-if="isTyping" class="message-item message-ai">
<div class="message-avatar ai-avatar">🤖</div>
<div class="message-content ai-message">
<div class="loading-dots">
<span></span>
<span></span>
<span></span>
</div>
<div class="typing-indicator">AI正在思考...</div>
</div>
</div>
</div>
<div class="quick-questions" v-if="messages.length === 0">
<div class="quick-title">常见问题:</div>
<div class="quick-list">
<div v-for="(question, index) in quickQuestions" :key="index" class="quick-item" @click="askQuestion(question)">
{{ question }}
</div>
</div>
</div>
<div class="chat-input-container">
<div class="chat-input-wrapper">
<el-input
ref="chatInput"
v-model="inputMessage"
placeholder="请输入您的问题..."
@keyup.enter.native="sendMessage"
:disabled="isTyping"
class="chat-input">
</el-input>
<button class="send-btn" @click="sendMessage" :disabled="isTyping || !inputMessage.trim()">
<svg v-if="!isTyping" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="22" y1="2" x2="11" y2="13"/>
<polygon points="22 2 15 22 11 13 2 9 22 2 22 2"/>
</svg>
<span v-else>发送中</span>
<span v-if="!isTyping">发送</span>
</button>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.24.0/dist/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
inputMessage: '',
messages: [],
isTyping: false,
quickQuestions: [
'如何申请入党?',
'党费如何缴纳?',
'党员发展流程是什么?',
'什么是三会一课?',
'党员的权利和义务有哪些?',
'如何转接党组织关系?'
],
currentUser: null
};
},
mounted() {
this.loadUserInfo();
},
methods: {
loadUserInfo() {
const userStr = localStorage.getItem('currentUser');
if (userStr) {
this.currentUser = JSON.parse(userStr);
}
},
goBack() {
if (this.currentUser) {
if (this.currentUser.role === 'student') {
window.location.href = '/student/mobile/submit';
} else {
window.location.href = '/index';
}
} else {
window.location.href = '/student/login';
}
},
sendMessage() {
if (!this.inputMessage.trim() || this.isTyping) return;
const userMessage = this.inputMessage.trim();
this.messages.push({
role: 'user',
content: this.escapeHtml(userMessage),
time: this.getCurrentTime()
});
this.inputMessage = '';
this.scrollToBottom();
// 模拟AI回复
this.getAIResponse(userMessage);
},
askQuestion(question) {
this.inputMessage = question;
this.sendMessage();
},
async getAIResponse(question) {
this.isTyping = true;
this.scrollToBottom();
try {
// 调用后端AI接口
const response = await axios.post('/api/ai/chat', {
question: question,
userId: this.currentUser?.id || null
});
if (response.data.code === 200) {
this.messages.push({
role: 'ai',
content: this.formatMessage(response.data.data.answer),
time: this.getCurrentTime()
});
} else {
// 如果后端接口不可用,使用模拟回复
this.addMockResponse(question);
}
} catch (error) {
console.log('AI接口调用失败,使用模拟回复');
this.addMockResponse(question);
}
this.isTyping = false;
this.scrollToBottom();
},
addMockResponse(question) {
const answer = this.getMockAnswer(question);
this.messages.push({
role: 'ai',
content: answer,
time: this.getCurrentTime()
});
},
getMockAnswer(question) {
const q = question.toLowerCase();
if (q.includes('入党') || q.includes('申请')) {
return `<strong>入党申请流程:</strong><br>
1. 向党组织递交入党申请书<br>
2. 确定入党积极分子<br>
3. 确定发展对象<br>
4. 接收预备党员<br>
5. 预备党员转正<br><br>
<em>具体流程请联系所在党支部获取详细指导。</em>`;
} else if (q.includes('党费')) {
return `<strong>党费缴纳说明:</strong><br>
• 党费按月缴纳,标准根据收入确定<br>
• 学生党员:每月0.2-1元<br>
• 职工党员:每月按收入比例缴纳<br>
• 可通过线上或线下方式缴纳<br><br>
<em>详细标准请咨询所在党组织。</em>`;
} else if (q.includes('流程') || q.includes('发展')) {
return `<strong>党员发展流程:</strong><br>
申请人 → 入党积极分子 → 发展对象 → 预备党员 → 正式党员<br>
每个阶段都有相应的时间要求和培养考察,总时长不少于2年。`;
} else if (q.includes('三会一课')) {
return `<strong>三会一课制度:</strong><br>
• <strong>三会:</strong>支部党员大会、支部委员会、党小组会<br>
• <strong>一课:</strong>党课<br><br>
这是党组织生活的基本制度,每月至少召开一次支部党员大会。`;
} else if (q.includes('权利') || q.includes('义务')) {
return `<strong>党员的权利和义务:</strong><br>
<strong>权利:</strong><br>
• 参加党的有关会议<br>
• 阅读党的有关文件<br>
• 在党的会议上参加讨论<br>
• 行使表决权、选举权<br><br>
<strong>义务:</strong><br>
• 认真学习党的理论<br>
• 坚决执行党的决定<br>
• 严守党的纪律<br>
• 密切联系群众<br>
• 发扬社会主义新风尚`;
} else if (q.includes('转接') || q.includes('关系')) {
return `<strong>党组织关系转接:</strong><br>
1. 在原党组织开具党组织关系介绍信<br>
2. 持介绍信到新单位报到<br>
3. 新单位党组织接收并办理转入手续<br><br>
<em>省内转接可通过网上办理,跨省需开具纸质介绍信。</em>`;
} else {
return `感谢您的问题:"${question}"<br><br>
我已经记录了您的问题,正在为您查找答案。<br><br>
如果需要更详细的解答,建议您:<br>
• 联系所在党支部<br>
• 咨询党务工作者<br>
• 拨打党建工作热线<br><br>
我会持续学习,为您提供更好的服务!`;
}
},
formatMessage(message) {
// 格式化AI返回的消息
return message;
},
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
},
getCurrentTime() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
return `${hours}:${minutes}`;
},
scrollToBottom() {
this.$nextTick(() => {
const container = this.$refs.chatContainer;
container.scrollTop = container.scrollHeight;
});
}
}
});
</script>
</body>
</html>
后端配置
java
package com.party.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* AI配置类
*/
@Configuration
@PropertySource(value = "classpath:application-ai.yml", factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "ai")
public class AIConfig {
/**
* AI服务提供商
*/
private String provider = "tencent";
/**
* 是否启用降级
*/
private boolean fallbackEnabled = true;
/**
* 超时时间(秒)
*/
private int timeout = 30;
/**
* 最大重试次数
*/
private int maxRetry = 2;
/**
* 系统提示词
*/
private String systemPrompt;
/**
* 腾讯混元配置
*/
private TencentConfig tencent = new TencentConfig();
/**
* 百度文心一言配置
*/
private BaiduConfig baidu = new BaiduConfig();
/**
* 阿里通义千问配置
*/
private AlibabaConfig alibaba = new AlibabaConfig();
/**
* OpenAI配置
*/
private OpenAIConfig openai = new OpenAIConfig();
// Getters and Setters
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
public boolean isFallbackEnabled() {
return fallbackEnabled;
}
public void setFallbackEnabled(boolean fallbackEnabled) {
this.fallbackEnabled = fallbackEnabled;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getMaxRetry() {
return maxRetry;
}
public void setMaxRetry(int maxRetry) {
this.maxRetry = maxRetry;
}
public String getSystemPrompt() {
return systemPrompt;
}
public void setSystemPrompt(String systemPrompt) {
this.systemPrompt = systemPrompt;
}
public TencentConfig getTencent() {
return tencent;
}
public void setTencent(TencentConfig tencent) {
this.tencent = tencent;
}
public BaiduConfig getBaidu() {
return baidu;
}
public void setBaidu(BaiduConfig baidu) {
this.baidu = baidu;
}
public AlibabaConfig getAlibaba() {
return alibaba;
}
public void setAlibaba(AlibabaConfig alibaba) {
this.alibaba = alibaba;
}
public OpenAIConfig getOpenai() {
return openai;
}
public void setOpenai(OpenAIConfig openai) {
this.openai = openai;
}
/**
* 腾讯混元配置
*/
public static class TencentConfig {
private String secretId;
private String secretKey;
private String model = "hunyuan-lite";
private String endpoint = "https://hunyuan.tencentcloudapi.com";
private int requestTimeout = 30000;
// Getters and Setters
public String getSecretId() {
return secretId;
}
public void setSecretId(String secretId) {
this.secretId = secretId;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public int getRequestTimeout() {
return requestTimeout;
}
public void setRequestTimeout(int requestTimeout) {
this.requestTimeout = requestTimeout;
}
}
/**
* 百度文心一言配置
*/
public static class BaiduConfig {
private String apiKey;
private String secretKey;
private String model = "ERNIE-Bot-turbo";
private String endpoint = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat";
// Getters and Setters
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
}
/**
* 阿里通义千问配置
*/
public static class AlibabaConfig {
private String apiKey;
private String model = "qwen-turbo";
private String endpoint = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";
// Getters and Setters
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
}
/**
* OpenAI配置
*/
public static class OpenAIConfig {
private String apiKey;
private String model = "gpt-3.5-turbo";
private String endpoint = "https://api.openai.com/v1/chat/completions";
private String organizationId;
// Getters and Setters
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getOrganizationId() {
return organizationId;
}
public void setOrganizationId(String organizationId) {
this.organizationId = organizationId;
}
}
}
java
package com.party.config;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
/**
* YAML配置源工厂
* 用于加载YAML格式的配置文件
*/
public class YamlPropertySourceFactory implements PropertySourceFactory {
private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null || resource.getResource() == null) {
throw new IllegalArgumentException("Resource must not be null");
}
List<PropertySource<?>> propertySources = loader.load(
name != null ? name : resource.getResource().getFilename(),
resource.getResource()
);
if (propertySources.isEmpty()) {
throw new IllegalStateException("Failed to load YAML property source");
}
return propertySources.get(0);
}
}
以上为部分实现代码,具体实现逻辑,自己可以根据任务来修改完成。有需要完整的AI智能集成服务的,留言。