初始化:职引项目 v1.0
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import { Injectable, Logger } from '@nestjs/common'
|
||||
import axios from 'axios'
|
||||
|
||||
interface AiCallOptions {
|
||||
systemPrompt: string
|
||||
userMessage: string
|
||||
temperature?: number
|
||||
maxTokens?: number
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AiService {
|
||||
private readonly logger = new Logger(AiService.name)
|
||||
|
||||
private readonly primaryUrl = process.env.AI_PRIMARY_URL || 'https://token.sensenova.cn/v1'
|
||||
private readonly primaryKey = process.env.AI_PRIMARY_KEY || ''
|
||||
private readonly primaryModel = process.env.AI_PRIMARY_MODEL || 'deepseek-v4-flash'
|
||||
|
||||
private readonly backupUrl = process.env.AI_BACKUP_URL || 'https://integrate.api.nvidia.com/v1'
|
||||
private readonly backupKey = process.env.AI_BACKUP_KEY || ''
|
||||
private readonly backupModel = process.env.AI_BACKUP_MODEL || 'stepfun-ai/step-3.5-flash'
|
||||
|
||||
async call(options: AiCallOptions): Promise<string> {
|
||||
const { systemPrompt, userMessage, temperature = 0.7, maxTokens = 2048 } = options
|
||||
|
||||
// Try primary AI
|
||||
try {
|
||||
const result = await this.callApi(this.primaryUrl, this.primaryKey, this.primaryModel, systemPrompt, userMessage, temperature, maxTokens)
|
||||
if (result) return result
|
||||
} catch (e) {
|
||||
this.logger.warn(`Primary AI failed: ${(e as Error).message}, trying backup...`)
|
||||
}
|
||||
|
||||
// Try backup AI
|
||||
try {
|
||||
const result = await this.callApi(this.backupUrl, this.backupKey, this.backupModel, systemPrompt, userMessage, temperature, maxTokens)
|
||||
if (result) return result
|
||||
} catch (e) {
|
||||
this.logger.warn(`Backup AI also failed: ${(e as Error).message}`)
|
||||
}
|
||||
|
||||
// Final fallback
|
||||
throw new Error('AI 服务暂时不可用,请稍后重试')
|
||||
}
|
||||
|
||||
private async callApi(
|
||||
baseUrl: string, apiKey: string, model: string,
|
||||
systemPrompt: string, userMessage: string,
|
||||
temperature: number, maxTokens: number,
|
||||
): Promise<string | null> {
|
||||
const res = await axios.post(
|
||||
`${baseUrl}/chat/completions`,
|
||||
{
|
||||
model,
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userMessage },
|
||||
],
|
||||
temperature,
|
||||
max_tokens: maxTokens,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
timeout: 60000,
|
||||
},
|
||||
)
|
||||
return res.data?.choices?.[0]?.message?.content || null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user