Maison  >  Article  >  interface Web  >  Chunking in AI - La sauce secrète qui vous manque

Chunking in AI - La sauce secrète qui vous manque

Patricia Arquette
Patricia Arquetteoriginal
2024-10-10 11:10:30630parcourir

Chunking in AI - The Secret Sauce You

Hé les amis ! ?

Vous savez ce qui m'empêche de dormir la nuit ? Réfléchir à la manière de rendre nos systèmes d’IA plus intelligents et plus efficaces. Aujourd'hui, je veux parler de quelque chose qui peut sembler basique mais qui est crucial lors de la création d'applications d'IA géniales : chunking ✨.

Qu'est-ce qui se passe de toute façon ? ?

Considérez le chunking comme le moyen utilisé par votre IA pour décomposer un énorme buffet d'informations en portions gérables et de la taille d'une bouchée. Tout comme vous n'essaieriez pas de mettre une pizza entière dans votre bouche d'un coup (ou peut-être que vous le feriez, sans jugement ici !), votre IA doit diviser les gros textes en morceaux plus petits pour les traiter efficacement.

Ceci est particulièrement important pour ce que nous appelons les modèles RAG (Retrieval-Augmented Generation). Ces mauvais garçons ne se contentent pas d'inventer des trucs : ils vont en fait chercher de vraies informations auprès de sources externes. Plutôt sympa, non ?

Pourquoi devriez-vous vous en soucier ? ?

Écoutez, si vous créez quelque chose qui traite du texte - qu'il s'agisse d'un chatbot de support client ou d'une recherche sophistiquée dans une base de connaissances - une bonne décomposition est la différence entre une IA qui donne des réponses précises et une qui est juste... . meh.

Des morceaux trop gros ? Votre modèle passe à côté de l'essentiel.
Des morceaux trop petits ? On se perd dans les détails.

Mettons-nous les mains dans le cambouis : exemples concrets ?

Exemple Python : regroupement sémantique

Tout d'abord, regardons un exemple Python utilisant LangChain pour le chunking sémantique :

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]}...")

Exemple Node.js et CDK : création d'une base de connaissances

Maintenant, construisons quelque chose de réel : une base de connaissances sans serveur utilisant AWS CDK et Node.js ! ?

Tout d'abord, l'infrastructure CDK (c'est là que la magie opère) :

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);
  }
}

Et maintenant, la fonction Lambda qui effectue le chunking et l'indexation :

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;
}

Comment tout cela fonctionne ensemble ?

  1. Téléchargement de documents : lorsque vous téléchargez un document dans le compartiment S3, cela déclenche notre fonction Lambda.
  2. Traitement : La fonction Lambda :
    • Récupère le document de S3
    • Le coupe en morceaux à l'aide de notre algorithme de segmentation intelligent
    • Indexe chaque morceau dans OpenSearch avec des métadonnées
  3. Récupération : plus tard, lorsque votre application a besoin de trouver des informations, elle peut interroger OpenSearch pour trouver les morceaux les plus pertinents.

Voici un exemple rapide de la façon dont vous pouvez interroger cette base de connaissances :

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,
  }));
}

L'avantage AWS ?️

L'utilisation des services AWS comme S3, Lambda et OpenSearch nous donne :

  • Évolutivité sans serveur (pas de serveur à gérer !)
  • Tarif à l'utilisation (votre portefeuille vous remerciera)
  • Services gérés (moins de travail opérationnel = plus de plaisir de codage)

Pensées finales ?

Voilà, les amis ! Un exemple concret de la façon d'implémenter le chunking dans une base de connaissances sans serveur. La meilleure partie ? Celui-ci évolue automatiquement et peut gérer des documents de n'importe quelle taille.

N'oubliez pas que la clé d'un bon chunking est :

  1. Choisissez la taille de morceau adaptée à votre cas d'utilisation
  2. Envisagez les chevauchements pour maintenir le contexte
  3. Utilisez des limites naturelles lorsque cela est possible (comme des phrases ou des paragraphes)

Quelle est votre expérience en matière de création de bases de connaissances ? Avez-vous essayé différentes stratégies de segmentation ? Faites-le moi savoir dans les commentaires ci-dessous ! ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn