FastGPT 大模型對接核心代碼分析
核心架構概覽
FastGPT 采用統一模型抽象層設計,通過標準化接口對接多種大模型,支持 LLM、Embedding、ReRank、TTS、STT 等多種 AI 能力。
支持各種大模型能力的配置,包括本地ollama、各個AI云廠商的API接入配置,支持知識庫的分詞、排序、向量化處理,支持Agent的對話和業務邏輯處理,完成完整的Agent可視化配置支撐。
核心文件主要主要在packages/global/core/ai/目錄,有model.ts、model.d.ts、config.ts、index.ts、ReRank.ts等
1. 模型管理架構
全局模型映射
// 全局模型存儲結構
declare global {var llmModelMap: Map<string, LLMModelItemType>;var embeddingModelMap: Map<string, EmbeddingModelItemType>;var reRankModelMap: Map<string, ReRankModelItemType>;var ttsModelMap: Map<string, TTSModelType>;var sttModelMap: Map<string, STTModelType>;var systemDefaultModel: {llm: LLMModelItemType;embedding: EmbeddingModelItemType;rerank?: ReRankModelItemType;tts?: TTSModelType;stt?: STTModelType;};
}
模型獲取接口
// 統一的模型獲取接口
export const getLLMModel = (model?: string) => {if (!model) return getDefaultLLMModel();return global.llmModelMap.get(model) || getDefaultLLMModel();
};export const getEmbeddingModel = (model?: string) => {if (!model) return getDefaultEmbeddingModel();return global.embeddingModelMap.get(model) || getDefaultEmbeddingModel();
};export const getReRankModel = (model?: string) => {if (!model) return getDefaultRerankModel();return global.reRankModelMap.get(model) || getDefaultRerankModel();
};// 通用模型查找
export const findAIModel = (model: string) => {return (global.llmModelMap.get(model) ||global.embeddingModelMap.get(model) ||global.ttsModelMap.get(model) ||global.sttModelMap.get(model) ||global.reRankModelMap.get(model));
};
2. LLM 模型對接
模型配置結構
export type LLMModelItemType = {provider: ModelProviderIdType; // 提供商: OpenAI/Claude/GLM等model: string; // 模型名稱name: string; // 顯示名稱// 能力參數maxContext: number; // 最大上下文長度maxResponse: number; // 最大響應長度quoteMaxToken: number; // 最大引用TokenmaxTemperature?: number; // 最大溫度值// 功能支持vision?: boolean; // 視覺能力reasoning?: boolean; // 推理能力functionCall: boolean; // 函數調用toolChoice: boolean; // 工具選擇// 專用功能datasetProcess?: boolean; // 知識庫處理usedInClassify?: boolean; // 問題分類usedInExtractFields?: boolean; // 內容提取usedInToolCall?: boolean; // 工具調用// 自定義配置defaultSystemChatPrompt?: string; // 默認系統提示詞defaultConfig?: Record<string, any>; // 默認請求配置fieldMap?: Record<string, string>; // 字段映射// 直連配置requestUrl?: string; // 自定義請求URLrequestAuth?: string; // 自定義認證
};
統一 API 客戶端
export const getAIApi = (props?: { userKey?: OpenaiAccountType; timeout?: number
}) => {const { userKey, timeout } = props || {};// 優先級: 用戶配置 > 全局配置 > 環境變量const baseUrl = userKey?.baseUrl || global?.systemEnv?.oneapiUrl || openaiBaseUrl;const apiKey = userKey?.key || global?.systemEnv?.chatApiKey || openaiBaseKey;return new OpenAI({baseURL: baseUrl,apiKey,httpAgent: global.httpsAgent,timeout,maxRetries: 2});
};
聊天完成接口
export const createChatCompletion = async ({body, userKey, timeout, options
}) => {const modelConstantsData = getLLMModel(body.model);const ai = getAIApi({ userKey, timeout });// 支持自定義請求路徑和認證const response = await ai.chat.completions.create(body, {...options,...(modelConstantsData.requestUrl ? { path: modelConstantsData.requestUrl } : {}),headers: {...options?.headers,...(modelConstantsData.requestAuth ? { Authorization: `Bearer ${modelConstantsData.requestAuth}` } : {})}});// 判斷響應類型const isStreamResponse = typeof response === 'object' && response !== null && ('iterator' in response || 'controller' in response);return { response, isStreamResponse };
};
3. Embedding 模型對接
Embedding 配置
export type EmbeddingModelItemType = {provider: ModelProviderIdType;model: string;name: string;// Token 配置defaultToken: number; // 默認分塊TokenmaxToken: number; // 最大Tokenweight: number; // 訓練權重// 處理配置normalization?: boolean; // 歸一化處理hidden?: boolean; // 是否隱藏// 自定義配置defaultConfig?: Record<string, any>; // 通用配置dbConfig?: Record<string, any>; // 存儲配置queryConfig?: Record<string, any>; // 查詢配置
};
向量化實現
export async function getVectorsByText({ model, input, type
}: GetVectorProps) {const ai = getAIApi();// 根據類型選擇配置const config = {...model.defaultConfig,...(type === EmbeddingTypeEnm.db && model.dbConfig),...(type === EmbeddingTypeEnm.query && model.queryConfig),model: model.model,input: [input]};const result = await ai.embeddings.create(config,model.requestUrl ? {path: model.requestUrl,headers: model.requestAuth ? {Authorization: `Bearer ${model.requestAuth}`} : undefined} : {});// 處理向量數據const vectors = await Promise.all(result.data.map(item => unityDimensional(item.embedding)) // 統一維度.map(item => {if (model.normalization) return normalization(item); // 歸一化return item;}));return { tokens: await countPromptTokens(input), vectors };
}// 統一向量維度到1536
function unityDimensional(vector: number[]) {if (vector.length > 1536) {return vector.slice(0, 1536);}const zeroVector = new Array(1536 - vector.length).fill(0);return vector.concat(zeroVector);
}// L2歸一化處理
function normalization(vector: number[]) {if (vector.some(item => item > 1)) {const norm = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));return vector.map(val => val / norm);}return vector;
}
4. ReRank 模型對接
ReRank 實現
export function reRankRecall({model = getDefaultRerankModel(),query,documents
}: {model?: ReRankModelItemType;query: string;documents: { id: string; text: string }[];
}): Promise<ReRankCallResult> {const { baseUrl, authorization } = getAxiosConfig();return POST<PostReRankResponse>(model.requestUrl ? model.requestUrl : `${baseUrl}/rerank`,{model: model.model,query,documents: documents.map(doc => doc.text)},{headers: {Authorization: model.requestAuth ? `Bearer ${model.requestAuth}` : authorization},timeout: 30000}).then(data => {return data?.results?.map(item => ({id: documents[item.index].id,score: item.relevance_score}));});
}
5. 模型配置管理
配置文件結構
{"llmModels": [{"provider": "OpenAI","model": "gpt-4o-mini","name": "gpt-4o-mini","maxContext": 128000,"maxResponse": 16000,"quoteMaxToken": 120000,"vision": true,"datasetProcess": true,"usedInClassify": true,"usedInExtractFields": true,"usedInToolCall": true,"toolChoice": true,"functionCall": false,"defaultConfig": {},"fieldMap": {}}],"vectorModels": [{"provider": "OpenAI","model": "text-embedding-3-small","name": "text-embedding-3-small","defaultToken": 512,"maxToken": 3000,"weight": 100}],"reRankModels": [],"audioSpeechModels": [{"provider": "OpenAI","model": "tts-1","name": "OpenAI TTS1","voices": [{ "label": "Alloy", "value": "alloy" },{ "label": "Echo", "value": "echo" }]}],"whisperModel": {"provider": "OpenAI","model": "whisper-1","name": "Whisper1"}
}
動態模型管理
// 模型配置更新
export const updateModelConfig = async (modelData: any) => {// 驗證模型配置const validatedModel = validateModelConfig(modelData);// 更新全局映射if (validatedModel.type === 'llm') {global.llmModelMap.set(validatedModel.model, validatedModel);} else if (validatedModel.type === 'embedding') {global.embeddingModelMap.set(validatedModel.model, validatedModel);}// 持久化配置await saveModelConfig(validatedModel);
};// 模型測試
export const testModel = async (modelConfig: any) => {try {if (modelConfig.type === 'llm') {const response = await createChatCompletion({body: {model: modelConfig.model,messages: [{ role: 'user', content: 'Hello' }],max_tokens: 10}});return { success: true, response };}if (modelConfig.type === 'embedding') {const result = await getVectorsByText({model: modelConfig,input: 'test text'});return { success: true, vectors: result.vectors };}} catch (error) {return { success: false, error: error.message };}
};
6. 多提供商支持
提供商適配
// 支持的模型提供商
export enum ModelProviderIdType {OpenAI = 'OpenAI',Anthropic = 'Anthropic',Google = 'Google',Baidu = 'Baidu',ByteDance = 'ByteDance',Moonshot = 'Moonshot',DeepSeek = 'DeepSeek',Other = 'Other'
}// 提供商特殊處理
const providerAdapters = {[ModelProviderIdType.OpenAI]: {formatRequest: (body) => body,formatResponse: (response) => response},[ModelProviderIdType.Anthropic]: {formatRequest: (body) => ({...body,// Claude 特殊格式轉換}),formatResponse: (response) => ({// 響應格式標準化})}
};
字段映射處理
// 處理不同模型的字段差異
const applyFieldMapping = (body: any, fieldMap: Record<string, string>) => {const mappedBody = { ...body };Object.entries(fieldMap).forEach(([from, to]) => {if (mappedBody[from] !== undefined) {mappedBody[to] = mappedBody[from];delete mappedBody[from];}});return mappedBody;
};// 示例: o1 模型字段映射
const o1FieldMap = {"max_tokens": "max_completion_tokens"
};
7. 錯誤處理與監控
統一錯誤處理
const handleModelError = (error: any, modelConfig: any) => {addLog.error(`Model ${modelConfig.model} error`, {error: error.message,provider: modelConfig.provider,requestUrl: modelConfig.requestUrl});// 根據錯誤類型返回友好提示if (error.code === 'insufficient_quota') {return '模型配額不足,請檢查賬戶余額';}if (error.code === 'model_not_found') {return '模型不存在,請檢查模型配置';}return `模型調用失敗: ${error.message}`;
};
性能監控
const monitorModelPerformance = async (modelCall: () => Promise<any>) => {const startTime = Date.now();try {const result = await modelCall();const duration = Date.now() - startTime;addLog.info('Model call success', {duration,tokens: result.tokens,cost: result.cost});return result;} catch (error) {const duration = Date.now() - startTime;addLog.error('Model call failed', {duration,error: error.message});throw error;}
};
總結
FastGPT 大模型對接核心實現了統一、靈活、可擴展的模型管理架構:
- 統一抽象: 通過標準化接口屏蔽不同模型的差異
- 多模型支持: LLM、Embedding、ReRank、TTS、STT 全覆蓋
- 靈活配置: 支持自定義請求路徑、認證、字段映射
- 動態管理: 運行時模型配置更新和測試
- 錯誤處理: 完善的錯誤處理和性能監控
- 提供商適配: 支持主流 AI 服務提供商
這套架構為 FastGPT 提供了強大的 AI 能力集成基礎,支持快速接入新的模型和提供商。