【Templater】问问 AI

AI 是个好东西,但是找个合适的插件,学习用法,然后设置……也挺劝退的。如果需求很低,其实可以用非常简单的方法来实现,创建如下模板,填入你的 API Key,就可以使用了。

缺点是有的,虽然也采用了流式输出(stream),但是可能还是会一坨内容一起出来(应该是 Templater 的插入逻辑),但问题不大。回答结束或者出错会弹出通知。下面某一行的 console.log 前面注释取消可以在控制台实时输出接收到的回复片段。

完全可以建立多个模板,应用不同的提示词。

如果你没有 API Key,可以使用各种第三方代理服务,比如:

这种第三方服务非常多,选择你觉得可以信任的即可,然后根据他们的文档修改下方的 baseUrlApiKey 即可。

<%*
  /**
   * 快问问 AI
   * @author: 稻米鼠
   * @description: 简单地向 AI 提问
   * @created: 2024-05-11
   * @updated: 2024-05-11
   * @version: 0.0.1
   */
  /* ======== 修改下方内容进行基本设置 ======== */
  const opt = {
    /** 预设提示词 **/
    prompt: `您作为一名优秀的知识管理专家,具有强迫症的资料管理员,请对如下内容的格式进行整理:`,
      /** API 服务的地址 */
    baseUrl: "https://api.openai.com/v1/chat/completions",
    /** 您的 API key */
    ApiKey: "sk-xxxxxxxxxxx",
    /** 模型,一般使用也不需要修改 */
    model: "gpt-3.5-turbo",
  }
  /* ======== 下面内容就不要修改了哦 ======== */
  let content = tp.file.selection()
  if(!(content && content.length)) content = await tp.system.prompt("请输入你的问题", '', false, true)
  if(!(content && content.length)) return
  content = opt.prompt + content
  const response = await fetch(opt.baseUrl, {
    method: "POST",
    headers: {
      "Authorization": opt.ApiKey,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: opt.model,
      stream: false,
      messages: [
        {
          role: "user",
          content,
        },
      ],
    }),
  })

  const reader = response.body?.pipeThrough(new TextDecoderStream()).getReader();
  if (!reader){
    new Notice("看起来什么地方出了问题?!")
    return
  };

  while (true) {
    const { value, done } = await reader.read();
    if (done) {
      new Notice("Over~")
      break
    };

    let dataDone = false;
    const arr = value.split('\n');
    arr.forEach((data) => {
        if (data.length === 0) return; // 忽略空消息
        if (data.startsWith(':')) return; // 忽略SSE注释消息
        if (data === 'data: [DONE]') {
            dataDone = true;
            return;
        }
        const json = JSON.parse(data.substring(6));
        const replayContent = json?.choices[0]?.delta?.content || ''
        /** 取消下一行的注释则会在控制台实时输出回复的内容 */
        // console.log(replayContent)
        tR += replayContent
    });

    if (dataDone){
      new Notice("Over~")
      break
    };
  }
%>
©2022~2024 稻米鼠. Last build at 2024-10-12 00:00:34