Electron Forge【实战】百度智能云千帆大模型 —— AI聊天
1. 获取 Access Key 与 Secret Key
登录百度智能云
https://login.bce.baidu.com/
2. 安装node.js sdk
npm install @baiducloud/qianfan
3. src/main.ts
import { setupIPC } from "./ipc";
在 const mainWindow 之后
setupIPC(mainWindow);
4. src/ipc.ts
import { ipcMain, BrowserWindow } from "electron";
import { createProvider } from "./providers/createProvider";interface CreateChatProps {messages: {role: string;content: string;imagePath?: string;}[];providerName: string;selectedModel: string;messageId: number;
}export function setupIPC(mainWindow: BrowserWindow) {ipcMain.on("start-chat", async (event, data: CreateChatProps) => {const { providerName, messages, messageId, selectedModel } = data;try {const provider = createProvider(providerName);const stream = await provider.chat(messages, selectedModel);for await (const chunk of stream) {const content = {messageId,data: chunk,};mainWindow.webContents.send("update-message", content);}} catch (error) {const errorContent = {messageId,data: {is_end: true,result:error instanceof Error ? error.message : "与AI服务通信时发生错误",is_error: true,},};mainWindow.webContents.send("update-message", errorContent);}});
}
5. src/providers/createProvider.ts
下方代码中,留意更改为第1步得到的 accessKey 和 secretKey
import { QianfanProvider } from "./QianfanProvider";export function createProvider(providerName: string) {// 定义 QianfanConfig 接口interface QianfanConfig {accessKey: string;secretKey: string;}// 定义完整的配置接口interface Config {qianfan: QianfanConfig;}const providerConfigs: Config = {qianfan: {accessKey: "填第1步获取的accessKey",secretKey: "填第1步获取的secretKey",},};const providerConfig = providerConfigs[providerName as keyof Config] || {};switch (providerName) {case "qianfan":if (!providerConfig.accessKey || !providerConfig.secretKey) {throw new Error("缺少千帆API配置:请在设置中配置 accessKey 和 secretKey");}return new QianfanProvider(providerConfig.accessKey,providerConfig.secretKey);default:throw new Error(`不支持的AI服务提供商: ${providerName}`);}
}
6. src/providers/QianfanProvider.ts
import { ChatCompletion } from "@baiducloud/qianfan";interface ChatMessageProps {role: string;content: string;imagePath?: string;
}export class QianfanProvider {// eslint-disable-next-line @typescript-eslint/no-explicit-anyprivate client: any;constructor(accessKey: string, secretKey: string) {this.client = new ChatCompletion({QIANFAN_ACCESS_KEY: accessKey,QIANFAN_SECRET_KEY: secretKey,ENABLE_OAUTH: true,});}async chat(messages: ChatMessageProps[], model: string) {const stream = await this.client.chat({messages,stream: true,},model);return {async *[Symbol.asyncIterator]() {for await (const chunk of stream) {yield chunk;}},};}
}
7. src/preload.ts
import { ipcRenderer, contextBridge } from "electron";contextBridge.exposeInMainWorld("electronAPI", {startChat: (data: CreateChatProps) => ipcRenderer.send("start-chat", data),onUpdateMessage: (callback: OnUpdatedCallback) =>ipcRenderer.on("update-message", (_event, value) => callback(value)),
});interface CreateChatProps {messages: {role: string;content: string;imagePath?: string;}[];providerName: string;selectedModel: string;messageId: number;
}interface UpdatgedStreamData {messageId: number;data: {is_end: boolean;result: string;is_error?: boolean;};
}type OnUpdatedCallback = (data: UpdatgedStreamData) => void;
8. 页面中使用
// 访问 AI 模型,获取答案
const get_AI_answer = async (answerIndex: number) => {await (window as any).electronAPI.startChat({messageId: answerIndex,providerName: convsersation.value!.AI_providerName,selectedModel: convsersation.value!.AI_modelName,// 发给AI模型的消息需移除最后一条加载状态的消息,使最后一条消息为用户的提问messages: convsersation.value!.msgList.map((message) => ({role: message.type === "question" ? "user" : "assistant",content: message.content,})).slice(0, -1),});
};
完整使用范例见
https://blog.csdn.net/weixin_41192489/article/details/146472170