Electron Forge【实战】百度智能云千帆大模子 —— AI聊天 ...

打印 上一主题 下一主题

主题 1969|帖子 1969|积分 5907

1. 获取 Access Key 与 Secret Key

  登录百度智能云
https://login.bce.baidu.com/



   2. 安装node.js sdk

  1. npm install @baiducloud/qianfan
复制代码
  3. src/main.ts

  1. import { setupIPC } from "./ipc";
复制代码
在 const mainWindow 之后
  1. setupIPC(mainWindow);
复制代码
  4. src/ipc.ts

  1. import { ipcMain, BrowserWindow } from "electron";
  2. import { createProvider } from "./providers/createProvider";
  3. interface CreateChatProps {
  4.   messages: {
  5.     role: string;
  6.     content: string;
  7.     imagePath?: string;
  8.   }[];
  9.   providerName: string;
  10.   selectedModel: string;
  11.   messageId: number;
  12. }
  13. export function setupIPC(mainWindow: BrowserWindow) {
  14.   ipcMain.on("start-chat", async (event, data: CreateChatProps) => {
  15.     const { providerName, messages, messageId, selectedModel } = data;
  16.     try {
  17.       const provider = createProvider(providerName);
  18.       const stream = await provider.chat(messages, selectedModel);
  19.       for await (const chunk of stream) {
  20.         const content = {
  21.           messageId,
  22.           data: chunk,
  23.         };
  24.         mainWindow.webContents.send("update-message", content);
  25.       }
  26.     } catch (error) {
  27.       const errorContent = {
  28.         messageId,
  29.         data: {
  30.           is_end: true,
  31.           result:
  32.             error instanceof Error ? error.message : "与AI服务通信时发生错误",
  33.           is_error: true,
  34.         },
  35.       };
  36.       mainWindow.webContents.send("update-message", errorContent);
  37.     }
  38.   });
  39. }
复制代码
  5. src/providers/createProvider.ts

  下方代码中,留意更改为第1步得到的 accessKey 和 secretKey
  1. import { QianfanProvider } from "./QianfanProvider";
  2. export function createProvider(providerName: string) {
  3.   // 定义 QianfanConfig 接口
  4.   interface QianfanConfig {
  5.     accessKey: string;
  6.     secretKey: string;
  7.   }
  8.   // 定义完整的配置接口
  9.   interface Config {
  10.     qianfan: QianfanConfig;
  11.   }
  12.   const providerConfigs: Config = {
  13.     qianfan: {
  14.       accessKey: "填第1步获取的accessKey",
  15.       secretKey: "填第1步获取的secretKey",
  16.     },
  17.   };
  18.   const providerConfig = providerConfigs[providerName as keyof Config] || {};
  19.   switch (providerName) {
  20.     case "qianfan":
  21.       if (!providerConfig.accessKey || !providerConfig.secretKey) {
  22.         throw new Error(
  23.           "缺少千帆API配置:请在设置中配置 accessKey 和 secretKey"
  24.         );
  25.       }
  26.       return new QianfanProvider(
  27.         providerConfig.accessKey,
  28.         providerConfig.secretKey
  29.       );
  30.     default:
  31.       throw new Error(`不支持的AI服务提供商: ${providerName}`);
  32.   }
  33. }
复制代码
  6. src/providers/QianfanProvider.ts

  1. import { ChatCompletion } from "@baiducloud/qianfan";
  2. interface ChatMessageProps {
  3.   role: string;
  4.   content: string;
  5.   imagePath?: string;
  6. }
  7. export class QianfanProvider {
  8.   // eslint-disable-next-line @typescript-eslint/no-explicit-any
  9.   private client: any;
  10.   constructor(accessKey: string, secretKey: string) {
  11.     this.client = new ChatCompletion({
  12.       QIANFAN_ACCESS_KEY: accessKey,
  13.       QIANFAN_SECRET_KEY: secretKey,
  14.       ENABLE_OAUTH: true,
  15.     });
  16.   }
  17.   async chat(messages: ChatMessageProps[], model: string) {
  18.     const stream = await this.client.chat(
  19.       {
  20.         messages,
  21.         stream: true,
  22.       },
  23.       model
  24.     );
  25.     return {
  26.       async *[Symbol.asyncIterator]() {
  27.         for await (const chunk of stream) {
  28.           yield chunk;
  29.         }
  30.       },
  31.     };
  32.   }
  33. }
复制代码
  7. src/preload.ts

  1. import { ipcRenderer, contextBridge } from "electron";
  2. contextBridge.exposeInMainWorld("electronAPI", {
  3.   startChat: (data: CreateChatProps) => ipcRenderer.send("start-chat", data),
  4.   onUpdateMessage: (callback: OnUpdatedCallback) =>
  5.     ipcRenderer.on("update-message", (_event, value) => callback(value)),
  6. });
  7. interface CreateChatProps {
  8.   messages: {
  9.     role: string;
  10.     content: string;
  11.     imagePath?: string;
  12.   }[];
  13.   providerName: string;
  14.   selectedModel: string;
  15.   messageId: number;
  16. }
  17. interface UpdatgedStreamData {
  18.   messageId: number;
  19.   data: {
  20.     is_end: boolean;
  21.     result: string;
  22.     is_error?: boolean;
  23.   };
  24. }
  25. type OnUpdatedCallback = (data: UpdatgedStreamData) => void;
复制代码
  8. 页面中利用

  1. // 访问 AI 模型,获取答案
  2. const get_AI_answer = async (answerIndex: number) => {
  3.   await (window as any).electronAPI.startChat({
  4.     messageId: answerIndex,
  5.     providerName: convsersation.value!.AI_providerName,
  6.     selectedModel: convsersation.value!.AI_modelName,
  7.     // 发给AI模型的消息需移除最后一条加载状态的消息,使最后一条消息为用户的提问
  8.     messages: convsersation
  9.       .value!.msgList.map((message) => ({
  10.         role: message.type === "question" ? "user" : "assistant",
  11.         content: message.content,
  12.       }))
  13.       .slice(0, -1),
  14.   });
  15. };
复制代码
完备利用范例见
https://blog.csdn.net/weixin_41192489/article/details/146472170

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表