AI のチャンク化 - あなたに欠けている秘密のソース

Patricia Arquette
リリース: 2024-10-10 11:10:30
オリジナル
629 人が閲覧しました

Chunking in AI - The Secret Sauce You

皆さん! ?

何が私を夜眠れなくさせるか知っていますか? AI システムをよりスマートかつ効率的にする方法を考えています。今日は、基本的なことのように聞こえるかもしれませんが、強力な AI アプリケーションを構築する際に重要なことについて話したいと思います。それは、チャンク ✨.

そもそもチャンク化とは一体何なのでしょうか? ?

チャンク化とは、大量の情報を管理しやすい一口サイズの部分に分割する AI の方法であると考えてください。一度にピザ全体を口の中に詰め込もうとしないのと同じように (あるいは、そうするかもしれませんが、ここで判断する必要はありません!)、AI は大きなテキストを効果的に処理するために小さな部分に分割する必要があります。

これは、いわゆる RAG (検索拡張生成) モデルにとって特に重要です。これらの悪い奴らはただでっち上げているだけではなく、実際に外部ソースから本物の情報を入手しに行きます。かなりきれいですね?

なぜ気にする必要があるのでしょうか? ?

ほら、テキストを扱うものを構築している場合、それがカスタマー サポート チャットボットであれ、高度なナレッジ ベース検索であれ、正しくチャンク化するかどうかが、的確な回答を提供する AI と単なる AI の違いです。 .まあ

塊が大きすぎますか?あなたのモデルは要点を外しています。
塊が小さすぎますか?細部では迷ってしまいます。

手を汚しましょう: 実際の例 ?

Python の例: セマンティック チャンク化

まず、セマンティック チャンキングに LangChain を使用する Python の例を見てみましょう。

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import TextLoader

def semantic_chunk(file_path):
    # Load the document
    loader = TextLoader(file_path)
    document = loader.load()

    # Create a text splitter
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len,
        separators=["\n\n", "\n", " ", ""]
    )

    # Split the document into chunks
    chunks = text_splitter.split_documents(document)

    return chunks

# Example usage
chunks = semantic_chunk('knowledge_base.txt')
for i, chunk in enumerate(chunks):
    print(f"Chunk {i}: {chunk.page_content[:50]}...")
ログイン後にコピー

Node.js と CDK の例: ナレッジ ベースの構築

さあ、実際のもの、AWS CDK と Node.js を使用したサーバーレスのナレッジベースを構築しましょう! ?

まず、CDK インフラストラクチャ (ここで魔法が起こります):

import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as opensearch from 'aws-cdk-lib/aws-opensearch';
import * as iam from 'aws-cdk-lib/aws-iam';

export class KnowledgeBaseStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // S3 bucket to store our documents
    const documentBucket = new s3.Bucket(this, 'DocumentBucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    // OpenSearch domain for storing our chunks
    const openSearchDomain = new opensearch.Domain(this, 'DocumentSearch', {
      version: opensearch.EngineVersion.OPENSEARCH_2_5,
      capacity: {
        dataNodes: 1,
        dataNodeInstanceType: 't3.small.search',
      },
      ebs: {
        volumeSize: 10,
      },
    });

    // Lambda function for processing documents
    const processorFunction = new lambda.Function(this, 'ProcessorFunction', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
      environment: {
        OPENSEARCH_DOMAIN: openSearchDomain.domainEndpoint,
      },
      timeout: cdk.Duration.minutes(5),
    });

    // Grant permissions
    documentBucket.grantRead(processorFunction);
    openSearchDomain.grantWrite(processorFunction);
  }
}
ログイン後にコピー

そして、チャンク化とインデックス付けを行う Lambda 関数:

import { S3Event } from 'aws-lambda';
import { S3 } from 'aws-sdk';
import { Client } from '@opensearch-project/opensearch';
import { defaultProvider } from '@aws-sdk/credential-provider-node';
import { AwsSigv4Signer } from '@opensearch-project/opensearch/aws';

const s3 = new S3();
const CHUNK_SIZE = 1000;
const CHUNK_OVERLAP = 200;

// Create OpenSearch client
const client = new Client({
  ...AwsSigv4Signer({
    region: process.env.AWS_REGION,
    service: 'es',
    getCredentials: () => {
      const credentialsProvider = defaultProvider();
      return credentialsProvider();
    },
  }),
  node: `https://${process.env.OPENSEARCH_DOMAIN}`,
});

export const handler = async (event: S3Event) => {
  for (const record of event.Records) {
    const bucket = record.s3.bucket.name;
    const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));

    // Get the document from S3
    const { Body } = await s3.getObject({ Bucket: bucket, Key: key }).promise();
    const text = Body.toString('utf-8');

    // Chunk the document
    const chunks = chunkText(text);

    // Index chunks in OpenSearch
    for (const [index, chunk] of chunks.entries()) {
      await client.index({
        index: 'knowledge-base',
        body: {
          content: chunk,
          documentKey: key,
          chunkIndex: index,
          timestamp: new Date().toISOString(),
        },
      });
    }
  }
};

function chunkText(text: string): string[] {
  const chunks: string[] = [];
  let start = 0;

  while (start < text.length) {
    const end = Math.min(start + CHUNK_SIZE, text.length);
    let chunk = text.slice(start, end);

    // Try to break at a sentence boundary
    const lastPeriod = chunk.lastIndexOf('.');
    if (lastPeriod !== -1 && lastPeriod !== chunk.length - 1) {
      chunk = chunk.slice(0, lastPeriod + 1);
    }

    chunks.push(chunk);
    start = Math.max(start + chunk.length - CHUNK_OVERLAP, start + 1);
  }

  return chunks;
}
ログイン後にコピー

すべてはどのように連携して機能するのでしょうか?

  1. ドキュメントのアップロード: ドキュメントを S3 バケットにアップロードすると、Lambda 関数がトリガーされます。
  2. 処理: Lambda 関数:
    • S3 からドキュメントを取得します
    • スマートチャンクアルゴリズムを使用してチャンク化します
    • OpenSearch の各チャンクにメタデータをインデックス付けします
  3. 取得: 後でアプリケーションが情報を見つける必要がある場合、OpenSearch にクエリを実行して最も関連性の高いチャンクを見つけることができます。

このナレッジ ベースをクエリする方法の簡単な例を次に示します。

async function queryKnowledgeBase(query: string) {
  const response = await client.search({
    index: 'knowledge-base',
    body: {
      query: {
        multi_match: {
          query: query,
          fields: ['content'],
        },
      },
    },
  });

  return response.body.hits.hits.map(hit => ({
    content: hit._source.content,
    documentKey: hit._source.documentKey,
    score: hit._score,
  }));
}
ログイン後にコピー

AWS の利点 ?️

S3、Lambda、OpenSearch などの AWS サービスを使用すると、次のことが得られます。

  • サーバーレスのスケーラビリティ (サーバーを管理する必要はありません!)
  • 従量課金制の価格設定 (お財布に優しい)
  • マネージド サービス (運用作業が軽減される = コーディングがより楽しくなります)

最終的な考え?

これで完成です!サーバーレスナレッジベースにチャンキングを実装する方法の実例。一番いいところは?これは自動的に拡大縮小され、あらゆるサイズのドキュメントを処理できます。

適切なチャンク化の鍵は次のとおりであることを覚えておいてください。

  1. ユースケースに適したチャンク サイズを選択してください
  2. コンテキストを維持するために重複を考慮します
  3. 可能な限り自然な境界線を使用します (文や段落など)

知識ベースの構築に関するあなたの経験は何ですか?さまざまなチャンク化戦略を試してみましたか?以下のコメント欄でお知らせください。 ?

以上がAI のチャンク化 - あなたに欠けている秘密のソースの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!