😎

Langchain.jsのツールレシピ集 ページ取得、YouTube文字起こしなど

2023/03/21に公開

今回はLangchain.jsですぐに使えるいくつかのツールをコード付きでサクッと紹介してきます。
サクサク行くので飛ばし気味で行きます。

1. ReadPageTool

必須パッケージ:@mozilla/readability,jsdom
推奨パッケージ:deepl

URLからページを取得して、本文を取得して返却するツールです。
本文の取得には@mozilla/readabilityを使用しています。
日本語のページなどでトークンオーバーする際はdeeplなどの翻訳を挟むとましになります。

import { JSDOM } from "jsdom";
import { Readability } from "@mozilla/readability";

class ReadPageTool extends Tool {
  name = "read-page-tool";
  description = `Reads the content of the entered URL and returns the content`;
  call(input) {
    console.log("Fetch:", input);
    const nhm = new NodeHtmlMarkdown();
    return fetch(input, FETCH_OPTION)
      .then((res) => res.text())
      .then((html) => new JSDOM(html))
      .then((dom) => new Readability(dom.window.document).parse())
      .then((html) => html.textContent)
      .catch((e) => "Sorry, I couldn't fetch the content.");
  }
}

2. GPTTool

本体の秘書として与えることで処理性能の向上を、試みるツールです。
正直効果のほどはわかりませんが、GPT同士の会話がみられます。
トークンオーバーになりがちなタスクなどは一定効果があった気がします。

import { ChatOpenAI } from "langchain/chat_models";
import { initializeAgentExecutor } from "langchain/agents";
import { Tool } from "langchain/tools";

export class GPTTool extends Tool {
  name = "secretary-tool";
  description = `I am your secretary. Convenient but not complicated.`;

  async call(input) {
    const llms = new ChatOpenAI({ temperature: 0.2 });
    const tools = [YOUR_TOOLS];
    const executor = await initializeAgentExecutor(tools, llms, "zero-shot-react-description");
    const result = await executor.call({ input });
    return result.output;
  }
}

3. YoutubeTranscriptionTool

必須パッケージ:ytdl-core,axios

Youtubeから動画をダウンロードしてWhisperを使って文字起こしを行うツールです。
僕の環境ではfetchFormDataをPOSTできなかったので、axiosを使っています。
トークンオーバーする際は要約してから返却するようにすればましになります。

import ytdl from "ytdl-core";
import axios from "axios";

const streamToBlob = (readable, type) =>
  new Promise((resolve, reject) => {
    const data = [];
    readable.on("data", (chunk) => {
      data.push(chunk);
    });
    readable.on("end", () => {
      const blob = new Blob(data, { type });
      resolve(blob);
    });
    readable.on("error", reject);
  });

class YoutubeTranscriptionTool extends Tool {
  name = "youtube-transcription-tool";
  description = `Give me the Youtube link and we will transcribe it into text and return it to you. Search is not available.`;

  constructor(opt) {
    super();
    this.opt = opt;
  }

  async call(input) {
    try {
      const audioStream = await ytdl(input, { quality: this.opt || "lowestaudio" });
      const audio = await streamToBlob(audioStream, "audio/mpeg");
      const formData = new FormData();
      formData.append("file", audio, "audio.mp3");
      formData.append("model", "whisper-1");

      const endpoint =
        this.opt?.translate == false ? "/audio/transcriptions" : "/audio/translations";
      const res = await axios({
        method: "POST",
        url: `https://api.openai.com/v1${endpoint}`,
        headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
        data: formData,
      });

      return res.data.text;
    } catch (e) {
      return "Video not found";
    }
  }
}

おわりに

これらのツールが何かの役に立てば幸いです。
こういったツールを共有できるサイトがあるといいかもしれませんね。(作るかも)
レッツChatGPTライフ!!!

Discussion