1. 获取 Access Key 与 Secret Key
登录百度智能云
https://login.bce.baidu.com/
2. 安装node.js sdk
ts
npm install @baiducloud/qianfan
3. src/main.ts
ts
import { setupIPC } from "./ipc";
在 const mainWindow 之后
ts
setupIPC(mainWindow);
4. src/ipc.ts
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
ts
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
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-any
private 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
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. 页面中使用
ts
// 访问 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