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