LangChainでファイルの拡張子ごとにSplitterを変える

LangChainのSplitterは、プログラム言語に対応したEmbedding生成ドキュメントの分割をサポートしています。GitHubから読み込んだファイルに対して、拡張子に基づいてSplitterを変更するコードが示されています。さらに、CartProviderをカスタマイズする方法も解説されています。プロパティを設定することで、CartProviderの動作をカスタマイズすることができます。ただし、いくつかの問題点も指摘されています。

広告ここから
広告ここまで

目次

    LangChainには、Embeddingを生成する際のドキュメントをいい感じに分割してくれるSplitterが用意されています。このSplitterには、プログラム言語に対応したものがありますが、通常のアプリケーションプロジェクトではMarkdownとJS / PHPファイルなど、複数のファイルが含まれています。と、いうことで動的に利用するSplitterを変えるコードを書いてみました。

    GitHubから読み込んだファイルを、拡張子ごとにSplitterを変更するサンプル

    RAG over codeを試したいので、GitHubから読んだコードで試してみます。LoaderからloadしたDocumentsには、metadata.sourceにファイル名が入っています。ここから拡張子をpickし、それによって利用する言語を変更させてみました。

        const loader = new GithubRepoLoader(
          "https://github.com/capacitor-community/stripe",
          {
            branch: "main",
            recursive: true,
            unknown: "warn",
            maxConcurrency: 2,
          }
        );
        const docs = await loader.load();
        const languages = ["cpp" , "go" , "java" , "js" , "php" , "proto" , "python" , "rst" , "ruby" , "rust" , "scala" , "swift" , "markdown" , "latex", "html", "sol"]
        const documents: Array<Document> = []
        for await (const doc of docs) {
            let fileExtensions = doc.metadata.source.split('.').pop()
            if (['jsx', 'tsx', 'ts', 'json'].includes(fileExtensions)) {
                fileExtensions = 'js'
            } else if (['md', 'mdx', 'mdoc'].includes(fileExtensions)) {
                fileExtensions = 'markdown'
            }
            if (!languages.includes(fileExtensions)) {
                continue
            }
            const splitter = RecursiveCharacterTextSplitter.fromLanguage(fileExtensions, {
                chunkSize: 2000,
                chunkOverlap: 200,
            })
            const splittedDocuments = await splitter.splitDocuments([doc])
            splittedDocuments.forEach(d => documents.push(d))
        }
        console.log("Loaded ", docs.length, " documents.");
        console.log("Loaded ", documents.length, " documents.");

    なお、Podfile, Dockerfileなどをどの分類に入れればよいか悩んだため、一旦拡張子なしのファイルは除外しています。

    これでもDocumentの数が5倍に増加しました。

    Loaded  357  documents.
    Loaded  1585  documents.

    use-shopping-cartで試してみた

    use-shopping-cartというOSSを、先ほどのコードで読み込み・Embedding化してみました。使い方の質問を投げたところ、体感ではかなり具体的な回答を得られるようになったかなと思っています。

    '{"question": "CartProviderのカスタマイズ方法をサンプルコード付きで教えてください。"}'
    [Start stream]
    CartProviderをカスタマイズするには、プロパティを設定することで可能です。以下にその手順を示します。
    
    まず、CartProviderを導入します:
    `import { CartProvider as USCProvider } from 'use-shopping-cart'`
    
    次に、CartProviderのプロパティを設定します。設定できるプロパティには次のものがあります:
    
    - mode: 'checkout-session'や'payment'など、支払いモードを設定します。
    - stripe: Stripeのキーを設定します。例: `stripe={process.env.NEXT_PUBLIC_STRIPE_KEY}`
    - currency: 通貨を設定します。例: `currency={'USD'}`
    - allowedCountries: 許可される国を設定します。例: `allowedCountries={['US', 'GB', 'CA']}`
    - billingAddressCollection: 請求先の住所の収集を設定します。例: `billingAddressCollection={true}`
    
    以下に、CartProviderをカスタマイズする実際のコード例を示します:
    
    ```
    function CartProvider({ children }) {
      return (
        <USCProvider
          mode="checkout-session"
          stripe={process.env.NEXT_PUBLIC_STRIPE_KEY}
          currency={'USD'}
          allowedCountries={['US', 'GB', 'CA']}
          billingAddressCollection={true}
        >
          {children}
        </USCProvider>
      )
    }
    ```
    
    このように、CartProviderへのプロパティの適用により、CartProviderの振る舞いをカスタマイズすることができます。
    [end stream]

    USCprefixは何者なのかや、Next.js前提のコードになっていないかなど、気になるところもありますが、例えば原稿生成や個人利用で使う分には許容できるかなと思います。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark