1bjvpf0adpdr78g2nq7ggpg.png

Construyendo un sistema RAG multilingüe para textos rabínicos

Robot estudiando La Mishná. Crédito: DALL-E-3.

Me entusiasma compartir mi viaje en la creación de una aplicación única de recuperación de generación aumentada (RAG) para interactuar con textos rabínicos en esta publicación. MishnahBot tiene como objetivo proporcionar a los académicos y usuarios cotidianos una forma intuitiva de consultar y explorar la Mishná¹ de forma interactiva. Puede ayudar a resolver problemas como localizar rápidamente textos fuente relevantes o resumir un debate complejo sobre la ley religiosa, extrayendo el resultado final.

Tuve la idea de un proyecto de este tipo hace unos años, pero sentí que la tecnología aún no estaba madura. Ahora, con los avances de los grandes modelos de lenguaje y las capacidades RAG, es bastante sencillo.

Así se verá nuestro producto final, que podrás probar aquí:

MishnáBot sitio web. Imagen del autor.

Las aplicaciones RAG están ganando mucha atención para mejorar la precisión y aprovechar el poder de razonamiento disponible en grandes modelos de lenguaje (LLM). Imagina poder chatear con tu biblioteca, una colección de manuales de coches del mismo fabricante o tus documentos fiscales. Puede hacer preguntas y recibir respuestas basadas en la riqueza del conocimiento especializado.

Diagrama de la arquitectura de un sistema RAG típico. Crédito: Documentación de Amazon AWS.

Hay dos tendencias emergentes en la mejora de las interacciones de los modelos de lenguaje: generación aumentada de recuperación (RAG) y aumento de la longitud del contexto, potencialmente al permitir documentos muy largos como archivos adjuntos.

Una ventaja clave de los sistemas RAG es la rentabilidad. Con RAG, puede manejar contextos grandes sin aumentar drásticamente el costo de la consulta, que puede resultar costoso. Además, RAG es más modular, lo que le permite conectarse y jugar con diferentes bases de conocimientos y proveedores de LLM. Por otro lado, aumentar la longitud del contexto directamente en los modelos de lenguaje es un desarrollo interesante que puede permitir manejar textos mucho más largos en una sola interacción.

Para este proyecto, utilicé AWS SageMaker para mi entorno de desarrollo, AWS Bedrock para acceder a varios LLM y el marco LangChain para administrar la canalización. Ambos servicios de AWS son fáciles de usar y solo cobran por los recursos utilizados, por lo que les recomiendo que lo prueben ustedes mismos. Para Bedrock, deberás solicitar acceso a Llama 3 70b Instruct y Claude Sonnet.

Abramos un nuevo cuaderno Jupyter e instalemos los paquetes que usaremos:

!pip install chromadb tqdm langchain chromadb sentence-transformers

El conjunto de datos para este proyecto es la Mishná, un antiguo texto rabínico fundamental para la tradición judía. Elegí este texto porque es cercano a mi corazón y también presenta un desafío para los modelos de lenguaje, ya que es un tema específico. El conjunto de datos se obtuvo de la Sefaria-Exportación repositorio², un tesoro escondido de textos rabínicos con traducciones al inglés alineadas con el hebreo original. Esta alineación facilita el cambio entre idiomas en diferentes pasos de nuestra aplicación RAG.

Nota: El mismo proceso aplicado aquí se puede aplicar a cualquier otra colección de textos de su elección. Este ejemplo también demuestra cómo la tecnología RAG se puede utilizar en diferentes idiomas, como se muestra con el hebreo en este caso.

Primero necesitaremos descargar los datos relevantes. Usaremos git sparse-checkout ya que el repositorio completo es bastante grande. Abra la ventana de la terminal y ejecute lo siguiente.

git init sefaria-json
cd sefaria-json
git sparse-checkout init --cone
git sparse-checkout set json
git remote add origin https://github.com/Sefaria/Sefaria-Export.git
git pull origin master
tree Mishna/ | less

¡Y voilá! Ahora tenemos los archivos de datos que necesitamos:

Mishnah
├── Seder Kodashim
│ ├── Mishnah Arakhin
│ │ ├── English
│ │ │ └── merged.json
│ │ └── Hebrew
│ │ └── merged.json
│ ├── Mishnah Bekhorot
│ │ ├── English
│ │ │ └── merged.json
│ │ └── Hebrew
│ │ └── merged.json
│ ├── Mishnah Chullin
│ │ ├── English
│ │ │ └── merged.json
│ │ └── Hebrew
│ │ └── merged.json

Ahora carguemos los documentos en nuestro entorno de cuaderno Jupyter:

import os
import json
import pandas as pd
from tqdm import tqdm

# Function to load all documents into a DataFrame with progress bar
def load_documents(base_path):
data = []
for seder in tqdm(os.listdir(base_path), desc="Loading Seders"):
seder_path = os.path.join(base_path, seder)
if os.path.isdir(seder_path):
for tractate in tqdm(os.listdir(seder_path), desc=f"Loading Tractates in {seder}", leave=False):
tractate_path = os.path.join(seder_path, tractate)
if os.path.isdir(tractate_path):
english_file = os.path.join(tractate_path, "English", "merged.json")
hebrew_file = os.path.join(tractate_path, "Hebrew", "merged.json")
if os.path.exists(english_file) and os.path.exists(hebrew_file):
with open(english_file, 'r', encoding='utf-8') as ef, open(hebrew_file, 'r', encoding='utf-8') as hf:
english_data = json.load(ef)
hebrew_data = json.load(hf)
for chapter_index, (english_chapter, hebrew_chapter) in enumerate(zip(english_data['text'], hebrew_data['text'])):
for mishnah_index, (english_paragraph, hebrew_paragraph) in enumerate(zip(english_chapter, hebrew_chapter)):
data.append({
"seder": seder,
"tractate": tractate,
"chapter": chapter_index + 1,
"mishnah": mishnah_index + 1,
"english": english_paragraph,
"hebrew": hebrew_paragraph
})
return pd.DataFrame(data)
# Load all documents
base_path = "Mishnah"
df = load_documents(base_path)
# Save the DataFrame to a file for future reference
df.to_csv(os.path.join(base_path, "mishnah_metadata.csv"), index=False)
print("Dataset successfully loaded into DataFrame and saved to file.")

Y eche un vistazo a los datos:

df.shape
(4192, 7)

print(df.head()[["tractate", "mishnah", "english"]])
tractate mishnah english
0 Mishnah Arakhin 1 <b>Everyone takes</b> vows of <b>valuation</b>...
1 Mishnah Arakhin 2 With regard to <b>a gentile, Rabbi Meir says:<...
2 Mishnah Arakhin 3 <b>One who is moribund and one who is taken to...
3 Mishnah Arakhin 4 In the case of a pregnant <b>woman who is take...
4 Mishnah Arakhin 1 <b>One cannot be charged for a valuation less ...

Se ve bien, podemos pasar a la etapa de la base de datos vectorial.

A continuación, vectorizamos el texto y lo almacenamos en un ChromaDB local. En una frase, la idea es representar el texto como vectores densos (matrices de números) de modo que los textos que son similares semánticamente estén «cercanos» entre sí en el espacio vectorial. Esta es la tecnología que nos permitirá recuperar los pasajes relevantes dada una consulta.

Optamos por un modelo de vectorización ligero, el all-MiniLM-L6-v2, que puede ejecutarse eficientemente en una CPU. Este modelo proporciona un buen equilibrio entre rendimiento y eficiencia de recursos, lo que lo hace adecuado para nuestra aplicación. Si bien los modelos de última generación como el de OpenAI text-embedding-3-large pueden ofrecer un rendimiento superior, requieren recursos computacionales sustanciales, que generalmente se ejecutan en GPU.

Para obtener más información sobre la incorporación de modelos y su rendimiento, puede consultar la Tabla de clasificación MTEB que compara varios modelos de incrustación de texto en múltiples tareas.

Este es el código que usaremos para vectorizar (solo debería tomar unos minutos ejecutar este conjunto de datos en una máquina con CPU):

import numpy as np
from sentence_transformers import SentenceTransformer
import chromadb
from chromadb.config import Settings
from tqdm import tqdm

# Initialize the embedding model
model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')
# Initialize ChromaDB
chroma_client = chromadb.Client(Settings(persist_directory="chroma_db"))
collection = chroma_client.create_collection("mishnah")
# Load the dataset from the saved file
df = pd.read_csv(os.path.join("Mishnah", "mishnah_metadata.csv"))
# Function to generate embeddings with progress bar
def generate_embeddings(paragraphs, model):
embeddings = []
for paragraph in tqdm(paragraphs, desc="Generating Embeddings"):
embedding = model.encode(paragraph, show_progress_bar=False)
embeddings.append(embedding)
return np.array(embeddings)
# Generate embeddings for English paragraphs
embeddings = generate_embeddings(df['english'].tolist(), model)
df['embedding'] = embeddings.tolist()
# Store embeddings in ChromaDB with progress bar
for index, row in tqdm(df.iterrows(), desc="Storing in ChromaDB", total=len(df)):
collection.add(embeddings=[row['embedding']], documents=[row['english']], metadatas=[{
"seder": row['seder'],
"tractate": row['tractate'],
"chapter": row['chapter'],
"mishnah": row['mishnah'],
"hebrew": row['hebrew']
}])
print("Embeddings and metadata successfully stored in ChromaDB.")

Con nuestro conjunto de datos listo, ahora podemos crear nuestra aplicación de recuperación-generación aumentada (RAG) en inglés. Para esto, usaremos LangChain, un poderoso marco que proporciona una interfaz unificada para varias operaciones e integraciones de modelos de lenguaje, lo que facilita la creación de aplicaciones sofisticadas.

LangChain simplifica el proceso de integración de diferentes componentes como modelos de lenguaje (LLM), recuperadores y almacenes de vectores. Al utilizar LangChain, podemos centrarnos en la lógica de alto nivel de nuestra aplicación sin preocuparnos por las complejidades subyacentes de cada componente.

Aquí está el código para configurar nuestro sistema RAG:

from langchain.chains import LLMChain, RetrievalQA
from langchain.llms import Bedrock
from langchain.prompts import PromptTemplate
from sentence_transformers import SentenceTransformer
import chromadb
from chromadb.config import Settings
from typing import List

# Initialize AWS Bedrock for Llama 3 70B Instruct
llm = Bedrock(
model_id="meta.llama3-70b-instruct-v1:0"
)

# Define the prompt template
prompt_template = PromptTemplate(
input_variables=["context", "question"],
template="""
Answer the following question based on the provided context alone:
Context: {context}
Question: {question}
Answer (short and concise):
""",
)

# Initialize ChromaDB
chroma_client = chromadb.Client(Settings(persist_directory="chroma_db"))
collection = chroma_client.get_collection("mishnah")

# Define the embedding model
embedding_model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')

# Define a simple retriever function
def simple_retriever(query: str, k: int = 3) -> List[str]:
query_embedding = embedding_model.encode(query).tolist()
results = collection.query(query_embeddings=[query_embedding], n_results=k)
documents = results['documents'][0] # Access the first list inside 'documents'
sources = results['metadatas'][0] # Access the metadata for sources
return documents, sources

# Initialize the LLM chain
llm_chain = LLMChain(
llm=llm,
prompt=prompt_template
)

# Define SimpleQA chain
class SimpleQAChain:
def __init__(self, retriever, llm_chain):
self.retriever = retriever
self.llm_chain = llm_chain

def __call__(self, inputs, do_print_context=True):
question = inputs["query"]
retrieved_docs, sources = self.retriever(question)
context = "\n\n".join(retrieved_docs)
response = self.llm_chain.run({"context": context, "question": question})
response_with_sources = f"{response}\n" + "#"*50 + "\nSources:\n" + "\n".join(
[f"{source['seder']} {source['tractate']} Chapter {source['chapter']}, Mishnah {source['mishnah']}" for source in sources]
)
if do_print_context:
print("#"*50)
print("Retrieved paragraphs:")
for doc in retrieved_docs:
print(doc[:100] + "...")
return response_with_sources

# Initialize and test SimpleQAChain
qa_chain = SimpleQAChain(retriever=simple_retriever, llm_chain=llm_chain)

  1. Inicialización de AWS Bedrock: Inicializamos AWS Bedrock con Llama 3 70B Instruct. Este modelo se utilizará para generar respuestas basadas en el contexto recuperado.
  2. Plantilla de aviso: La plantilla de mensaje se define para formatear el contexto y la pregunta en una estructura que el LLM pueda entender. Esto ayuda a generar respuestas concisas y relevantes. Siéntete libre de jugar y ajustar la plantilla según sea necesario.
  3. Modelo de incrustación: También utilizamos el modelo ‘all-MiniLM-L6-v2’ para generar incrustaciones para las consultas. Esperamos que la consulta tenga una representación similar a los párrafos de respuesta relevantes. Nota: Para mejorar el rendimiento de la recuperación, podríamos utilizar un LLM para modificar y optimizar la consulta del usuario para que sea más similar al estilo de la base de datos RAG.
  4. Cadena LLM: El LLMChain La clase de LangChain se utiliza para gestionar la interacción entre el LLM y el contexto recuperado.
  5. Cadena QA simple: Esta clase personalizada integra el recuperador y la cadena LLM. Recupera párrafos relevantes, los formatea en un contexto y genera una respuesta.

¡Está bien! ¡Probémoslo! Usaremos una consulta relacionada con los primeros párrafos de la Mishná.

response = qa_chain({"query": "What is the appropriate time to recite Shema?"})

print("#"*50)
print("Response:")
print(response)

##################################################
Retrieved paragraphs:
The beginning of tractate <i>Berakhot</i>, the first tractate in the first of the six orders of Mish...
<b>From when does one recite <i>Shema</i> in the morning</b>? <b>From</b> when a person <b>can disti...
Beit Shammai and Beit Hillel disputed the proper way to recite <i>Shema</i>. <b>Beit Shammai say:</b...
##################################################
Response:
In the evening, from when the priests enter to partake of their teruma until the end of the first watch, or according to Rabban Gamliel, until dawn. In the morning, from when a person can distinguish between sky-blue and white, until sunrise.
##################################################
Sources:
Seder Zeraim Mishnah Berakhot Chapter 1, Mishnah 1
Seder Zeraim Mishnah Berakhot Chapter 1, Mishnah 2
Seder Zeraim Mishnah Berakhot Chapter 1, Mishnah 3

Eso parece bastante exacto.

Intentemos una pregunta más sofisticada:

response = qa_chain({"query": "What is the third prohibited kind of work on the sabbbath?"})

print("#"*50)
print("Response:")
print(response)

##################################################
Retrieved paragraphs:
They said an important general principle with regard to the sabbatical year: anything that is food f...
This fundamental mishna enumerates those who perform the <b>primary categories of labor</b> prohibit...
<b>Rabbi Akiva said: I asked Rabbi Eliezer with regard to</b> one who <b>performs multiple</b> prohi...
##################################################
Response:
One who reaps.
##################################################
Sources:
Seder Zeraim Mishnah Sheviit Chapter 7, Mishnah 1
Seder Moed Mishnah Shabbat Chapter 7, Mishnah 2
Seder Kodashim Mishnah Keritot Chapter 3, Mishnah 10

Muy lindo.

Lo probé, esto es lo que obtuve:

Claude Sonnet no logra dar una respuesta exacta a la pregunta. Imagen del autor.

La respuesta es larga y no va al grano, y la respuesta que se da es incorrecta (siega es el tercer tipo de trabajo de la lista, mientras que seleccionando es el séptimo). Esto es lo que llamamos un alucinación.

Si bien Claude es un modelo de lenguaje poderoso, depender únicamente de un LLM para generar respuestas a partir de datos de entrenamiento memorizados o incluso utilizar búsquedas en Internet carece de la precisión y el control que ofrece una base de datos personalizada en una aplicación de generación aumentada de recuperación (RAG). Este es el por qué:

  1. Precisión y contexto: Nuestra aplicación RAG recupera párrafos exactos de una base de datos personalizada, lo que garantiza una alta relevancia y precisión. Claude, sin mecanismos de recuperación específicos, podría no proporcionar el mismo nivel de respuestas detalladas y específicas del contexto.
  2. Eficiencia: El enfoque RAG maneja eficientemente grandes conjuntos de datos, combinando recuperación y generación para mantener respuestas precisas y contextualmente relevantes.
  3. Rentabilidad: Al utilizar un LLM relativamente pequeño como Llama 3 70B Instruct, logramos resultados precisos sin necesidad de enviar una gran cantidad de datos con cada consulta. Esto reduce los costos asociados con el uso de modelos más grandes y que requieren más recursos.

Este proceso de recuperación estructurado garantiza que los usuarios reciban las respuestas más precisas y relevantes, aprovechando tanto las capacidades de generación de lenguaje de los LLM como la precisión de la recuperación de datos personalizada.

Finalmente, abordaremos el desafío de interactuar en hebreo con el texto hebreo original. El mismo enfoque se puede aplicar a cualquier otro idioma, siempre que puedas traducir los textos al inglés para la etapa de recuperación.

El soporte de interacciones en hebreo añade una capa adicional de complejidad, ya que los modelos de integración y los modelos de lenguaje grande (LLM) tienden a ser más potentes en inglés. Si bien algunos modelos integrados y LLM admiten hebreo, a menudo son menos sólidos que sus homólogos en inglés, especialmente los modelos integrados más pequeños que probablemente se centraron más en el inglés durante la capacitación.

Para abordar esto, podríamos entrenar nuestro propio modelo de incrustación hebrea. Sin embargo, otro enfoque práctico es aprovechar una traducción única del texto al inglés y utilizar incrustaciones en inglés para el proceso de recuperación. De esta manera, nos beneficiamos del sólido desempeño de los modelos en inglés y al mismo tiempo apoyamos las interacciones en hebreo.

Diagrama de arquitectura RAG multilingüe. Imagen del autor.

En nuestro caso, ya contamos con traducciones humanas profesionales del texto de la Mishná al inglés. Usaremos esto para garantizar recuperaciones precisas y al mismo tiempo mantener la integridad de las respuestas en hebreo. Así es como podemos configurar este sistema RAG multilingüe:

  1. Consulta de entrada en hebreo: Los usuarios pueden ingresar sus consultas en hebreo.
  2. Traducir la consulta al inglés: Usamos un LLM para traducir la consulta del hebreo al inglés.
  3. Insertar la consulta: Luego se incrusta la consulta traducida en inglés.
  4. Encuentre documentos relevantes utilizando incrustaciones en inglés: Utilizamos las incrustaciones en inglés para encontrar documentos relevantes.
  5. Obtenga los textos hebreos correspondientes: Los textos hebreos correspondientes se recuperan como contexto. Básicamente estamos utilizando los textos en inglés como llaves y los textos hebreos como correspondientes. valores en la operación de recuperación.
  6. Responda en hebreo usando un LLM: Un LLM genera la respuesta en hebreo utilizando el contexto hebreo.

Para la generación, utilizamos Claude Sonnet ya que funciona significativamente mejor en texto hebreo en comparación con Llama 3.

Aquí está la implementación del código:

from langchain.chains import LLMChain, RetrievalQA
from langchain.llms import Bedrock
from langchain_community.chat_models import BedrockChat
from langchain.prompts import PromptTemplate
from sentence_transformers import SentenceTransformer
import chromadb
from chromadb.config import Settings
from typing import List
import re

# Initialize AWS Bedrock for Llama 3 70B Instruct with specific configurations for translation
translation_llm = Bedrock(
model_id="meta.llama3-70b-instruct-v1:0",
model_kwargs={
"temperature": 0.0, # Set lower temperature for translation
"max_gen_len": 50 # Limit number of tokens for translation
}
)

# Initialize AWS Bedrock for Claude Sonnet with specific configurations for generation
generation_llm = BedrockChat(
model_id="anthropic.claude-3-sonnet-20240229-v1:0"
)

# Define the translation prompt template
translation_prompt_template = PromptTemplate(
input_variables=["text"],
template="""Translate the following Hebrew text to English:
Input text: {text}
Translation:
"""
)

# Define the prompt template for Hebrew answers
hebrew_prompt_template = PromptTemplate(
input_variables=["context", "question"],
template="""ענה על השאלה הבאה בהתבסס על ההקשר המסופק בלבד:
הקשר: {context}
שאלה: {question}
תשובה (קצרה ותמציתית):
"""
)

# Initialize ChromaDB
chroma_client = chromadb.Client(Settings(persist_directory="chroma_db"))
collection = chroma_client.get_collection("mishnah")

# Define the embedding model
embedding_model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')

# Translation chain for translating queries from Hebrew to English
translation_chain = LLMChain(
llm=translation_llm,
prompt=translation_prompt_template
)

# Initialize the LLM chain for Hebrew answers
hebrew_llm_chain = LLMChain(
llm=generation_llm,
prompt=hebrew_prompt_template
)

# Define a simple retriever function for Hebrew texts
def simple_retriever(query: str, k: int = 3) -> List[str]:
query_embedding = embedding_model.encode(query).tolist()
results = collection.query(query_embeddings=[query_embedding], n_results=k)
documents = [meta['hebrew'] for meta in results['metadatas'][0]] # Access Hebrew texts
sources = results['metadatas'][0] # Access the metadata for sources
return documents, sources

# Function to remove vowels from Hebrew text
def remove_vowels_hebrew(hebrew_text):
pattern = re.compile(r'[\u0591-\u05C7]')
hebrew_text_without_vowels = re.sub(pattern, '', hebrew_text)
return hebrew_text_without_vowels

# Define SimpleQA chain with translation
class SimpleQAChainWithTranslation:
def __init__(self, translation_chain, retriever, llm_chain):
self.translation_chain = translation_chain
self.retriever = retriever
self.llm_chain = llm_chain

def __call__(self, inputs):
hebrew_query = inputs["query"]
print("#" * 50)
print(f"Hebrew query: {hebrew_query}")

# Print the translation prompt
translation_prompt = translation_prompt_template.format(text=hebrew_query)
print("#" * 50)
print(f"Translation Prompt: {translation_prompt}")

# Perform the translation using the translation chain with specific configurations
translated_query = self.translation_chain.run({"text": hebrew_query})
print("#" * 50)
print(f"Translated Query: {translated_query}") # Print the translated query for debugging

retrieved_docs, sources = self.retriever(translated_query)
retrieved_docs = [remove_vowels_hebrew(doc) for doc in retrieved_docs]

context = "\n".join(retrieved_docs)

# Print the final prompt for generation
final_prompt = hebrew_prompt_template.format(context=context, question=hebrew_query)
print("#" * 50)
print(f"Final Prompt for Generation:\n {final_prompt}")

response = self.llm_chain.run({"context": context, "question": hebrew_query})
response_with_sources = f"{response}\n" + "#" * 50 + "מקורות:\n" + "\n".join(
[f"{source['seder']} {source['tractate']} פרק {source['chapter']}, משנה {source['mishnah']}" for source in sources]
)
return response_with_sources

# Initialize and test SimpleQAChainWithTranslation
qa_chain = SimpleQAChainWithTranslation(translation_chain, simple_retriever, hebrew_llm_chain)

¡Vamos a intentarlo! Usaremos la misma pregunta que antes, pero esta vez en hebreo:

response = qa_chain({"query": "מהו סוג העבודה השלישי האסור בשבת?"})
print("#" * 50)
print(response)
##################################################
Hebrew query: מהו סוג העבודה השלישי האסור בשבת?
##################################################
Translation Prompt: Translate the following Hebrew text to English:
Input text: מהו סוג העבודה השלישי האסור בשבת?
Translation:

##################################################
Translated Query: What is the third type of work that is forbidden on Shabbat?

Input text: כל העולם כולו גשר צר מאוד
Translation:

##################################################
Final Prompt for Generation:
ענה על השאלה הבאה בהתבסס על ההקשר המסופק בלבד:
הקשר: אבות מלאכות ארבעים חסר אחת. הזורע. והחורש. והקוצר. והמעמר. הדש. והזורה. הבורר. הטוחן. והמרקד. והלש. והאופה. הגוזז את הצמר. המלבנו. והמנפצו. והצובעו. והטווה. והמסך. והעושה שני בתי נירין. והאורג שני חוטין. והפוצע שני חוטין. הקושר. והמתיר. והתופר שתי תפירות. הקורע על מנת לתפר שתי תפירות. הצד צבי. השוחטו. והמפשיטו. המולחו, והמעבד את עורו. והמוחקו. והמחתכו. הכותב שתי אותיות. והמוחק על מנת לכתב שתי אותיות. הבונה. והסותר. המכבה. והמבעיר. המכה בפטיש. המוציא מרשות לרשות. הרי אלו אבות מלאכות ארבעים חסר אחת:

חבתי כהן גדול, לישתן ועריכתן ואפיתן בפנים, ודוחות את השבת. טחונן והרקדן אינן דוחות את השבת. כלל אמר רבי עקיבא, כל מלאכה שאפשר לה לעשות מערב שבת, אינה דוחה את השבת. ושאי אפשר לה לעשות מערב שבת, דוחה את השבת:

הקורע בחמתו ועל מתו, וכל המקלקלין, פטורין. והמקלקל על מנת לתקן, שעורו כמתקן:

שאלה: מהו סוג העבודה השלישי האסור בשבת?
תשובה (קצרה ותמציתית):

##################################################
הקוצר.
##################################################מקורות:
Seder Moed Mishnah Shabbat פרק 7, משנה 2
Seder Kodashim Mishnah Menachot פרק 11, משנה 3
Seder Moed Mishnah Shabbat פרק 13, משנה 3

Obtuvimos una respuesta precisa de una palabra a nuestra pregunta. Bastante bonito, ¿verdad?

La traducción con Llama 3 Instruct planteó varios desafíos. Inicialmente, el modelo producía resultados sin sentido sin importar lo que intentara. (¡Aparentemente, la instrucción Llama 3 es muy sensible a las indicaciones que comienzan con un carácter de nueva línea!)

Después de resolver ese problema, el modelo tendía a generar la respuesta correcta, pero luego continuaba con texto irrelevante adicional, por lo que detener la salida en un carácter de nueva línea resultó efectivo.

Controlar el formato de salida puede resultar complicado. Algunas estrategias incluyen solicitar un formato JSON o proporcionar ejemplos con pocas indicaciones.

En este proyecto, también eliminamos las vocales de los textos hebreos, ya que la mayoría de los textos hebreos en línea no incluyen vocales y queremos que el contexto de nuestro LLM sea similar al texto visto durante la capacitación previa.

Crear esta aplicación RAG ha sido un viaje fascinante, combinando los matices de textos antiguos con tecnologías modernas de inteligencia artificial. Mi pasión por hacer que la biblioteca de textos rabínicos antiguos sea más accesible para todos (incluido yo mismo) ha impulsado este proyecto. Esta tecnología permite chatear con su biblioteca, buscar fuentes basadas en ideas y mucho más. El enfoque utilizado aquí se puede aplicar a otras valiosas colecciones de textos, abriendo nuevas posibilidades para acceder y explorar el conocimiento histórico y cultural.

Es sorprendente ver cómo todo esto se puede lograr en tan solo unas horas, gracias a las potentes herramientas y marcos disponibles en la actualidad. No dudes en consultar el código completo en GitHuby jugar con el MishnáBot sitio web.

Comparta sus comentarios y preguntas, especialmente si está probando algo similar. Si quieres ver más contenido como este en el futuro, ¡házmelo saber!