Introducción
Muchos de nosotros podríamos haber tratado de construir una aplicación de trapo y notamos que no se puede abordar las necesidades de la vida real. ¿Porqué es eso? Es porque muchos problemas del mundo real requieren múltiples pasos de recuperación de información y razonamiento. Necesitamos que nuestro agente los realice como lo hacen normalmente los humanos, sin embargo, la mayoría de las aplicaciones de trapo no alcanzan esto.
Este artículo explora cómo sobrealimentar su aplicación RAG haciendo su proceso de recuperación de datos y razonamiento similar a cómo un humano, bajo un marco de múltiples agentes. El marco presentado aquí se basa en el Estrategia de auto-rag pero se ha modificado significativamente para mejorar sus capacidades. El conocimiento previo de la estrategia original no es necesario para leer este artículo.
Caso de la vida real
Considere esto: iba a volar de Delhi a Munich (supongamos que estoy tomando el vuelo de una aerolínea de la UE), pero de alguna manera me negaron abordar de alguna manera. Ahora quiero saber cuál debería ser la compensación.
Estas dos páginas web contienen información relevante, continúo agregándolos a mi tienda vectorial, tratando de que mi agente respondiera esto por recuperar la información correcta.
Ahora, paso esta pregunta a la tienda Vector: “¿Cuánto puedo recibir si se me niega el embarque, para vuelos desde Delhi a Munich?”.
– – – – – – – – – – – – – – – – – – – – – – – – –
Overview of US Flight Compensation Policies To get compensation for delayed flights, you should contact your airline via their customer service or go to the customer service desk. At the same time, you should bear in mind that you will only receive compensation if the delay is not weather-related and is within the carrier`s control. According to the US Department of Transportation, US airlines are not required to compensate you if a flight is cancelled or delayed. You can be compensated if you are bumped or moved from an overbooked flight. If your provider cancels your flight less than two weeks before departure and you decide to cancel your trip entirely, you can receive a refund of both pre-paid baggage fees and your plane ticket. There will be no refund if you choose to continue your journey. In the case of a delayed flight, the airline will rebook you on a different flight. According to federal law, you will not be provided with money or other compensation. Comparative Analysis of EU vs. US Flight Compensation Policies
– – – – – – – – – – – – – – – – – – – – – – – – –
(AUTHOR-ADDED NOTE: IMPORTANT, PAY ATTENTION TO THIS)
Short-distance flight delays – if it is up to 1,500 km, you are due 250 Euro compensation.
Medium distance flight delays – for all the flights between 1,500 and 3,500 km, the compensation should be 400 Euro.
Long-distance flight delays – if it is over 3,500 km, you are due 600 Euro compensation. To receive this kind of compensation, the following conditions must be met; Your flight starts in a non-EU member state or in an EU member state and finishes in an EU member state and is organised by an EU airline. Your flight reaches the final destination with a delay that exceeds three hours. There is no force majeure.
– – – – – – – – – – – – – – – – – – – – – – – – –
Compensation policies in the EU and US are not the same, which implies that it is worth knowing more about them. While you can always count on Skycop flight cancellation compensation, you should still get acquainted with the information below.
– – – – – – – – – – – – – – – – – – – – – – – – –
Compensation for flight regulations EU: The EU does regulate flight delay compensation, which is known as EU261. US: According to the US Department of Transportation, every airline has its own policies about what should be done for delayed passengers. Compensation for flight delays EU: Just like in the United States, compensation is not provided when the flight is delayed due to uncontrollable reasons. However, there is a clear approach to compensation calculation based on distance. For example, if your flight was up to 1,500 km, you can receive 250 euros. US: There are no federal requirements. That is why every airline sets its own limits for compensation in terms of length. However, it is usually set at three hours. Overbooking EU: In the EU, they call for volunteers if the flight is overbooked. These people are entitled to a choice of: Re-routing to their final destination at the earliest opportunity. Refund of their ticket cost within a week if not travelling. Re-routing at a later date at the person`s convenience.
Desafortunadamente, contienen solo políticas genéricas de compensación de vuelo, sin decirme cuánto puedo esperar cuando se les niega el abordaje de Delhi a Munich específicamente. Si el agente de RAG los toma como el único contexto, solo puede proporcionar una respuesta genérica sobre la política de compensación de vuelo, sin dar la respuesta que queremos.
Sin embargo, si bien los documentos no son inmediatamente útiles, hay una visión importante contenida en la segunda pieza de contexto: La compensación varía según la distancia de vuelo. Si el agente de Rag piensa más como humano, debe seguir estos pasos para proporcionar una respuesta:
- Basado en el contexto recuperado, la razón por la que la compensación varía con la distancia de vuelo
- A continuación, recupere la distancia de vuelo entre Delhi y Munich
- Dada la distancia (que es de alrededor de 5900 km), clasifique el vuelo como una larga distancia
- Combinado con el contexto previamente recuperado, descubra que tengo 600 EUR, suponiendo que se cumplan otras condiciones
Este ejemplo demuestra cómo se hace un trapo simple, en el que se realiza una sola recuperación, queda corto por varias razones:
- Consultas complejas: Los usuarios a menudo tienen preguntas que una búsqueda simple no puede abordar completamente. Por ejemplo, “¿Cuál es el mejor teléfono inteligente para jugar con menos de $ 500?” Requiere la consideración de múltiples factores como el rendimiento, el precio y las características, que un solo paso de recuperación podría perderse.
- Información profunda: Alguna información se encuentra entre los documentos. Por ejemplo, los documentos de investigación, los registros médicos o los documentos legales a menudo incluyen referencias que deben tener sentido, antes de que uno pueda comprender completamente el contenido de un artículo determinado. Múltiples pasos de recuperación ayudan a profundizar en el contenido.
Las recuperaciones múltiples complementadas con un razonamiento humano permiten una respuesta más matizada, integral y precisa, adaptándose a la complejidad y la profundidad de las consultas de los usuarios.
Auto-rag de múltiples agentes
Aquí explico el proceso de razonamiento detrás de esta estrategia, luego proporcionaré el código para mostrarle cómo lograr esto.
Nota: Para los lectores interesados en saber cómo mi enfoque difiere del auto-arrebato originalDescribiré las discrepancias entre citas como este. Pero los lectores generales que no están familiarizados con el auto-rag original pueden omitirlos.
En los gráficos a continuación, cada círculo representa un paso (también conocido como Nodo), que realiza un agente dedicado que trabaja en el problema específico. Los orquestamos para formar una aplicación de trapo de múltiples agentes.
Primera iteración: trapo simple
Este es solo el enfoque de Vanilla Rag que describí en el “caso de la vida real”, representado como un gráfico. Después Retrieve documentsel new_documents se utilizará como entrada para Generate Answer. Nada especial, pero sirve como nuestro punto de partida.
2da iteración: Digrest documentos con “documentos de calificación”

Recuerde que dije en la sección del “caso de la vida real”, que como siguiente paso, el agente debería “Razón que la compensación varía con la distancia de vuelo”? El Grade documents El paso es exactamente para este propósito.
Dado que new_documentsel agente intentará emitir dos elementos:
useful_documents: Comparando la pregunta formulada, determina si los documentos son útiles y retienen una memoria para aquellos considerados útiles para referencia futura. Como ejemplo, dado que nuestra pregunta no se refiere a las políticas de compensación para nosotros, los documentos que describen ellas se descartan, dejando solo aquellos para la UEhypothesis: Según los documentos, el agente forma una hipótesis sobre cómo se puede responder la pregunta, es decir, la distancia de vuelo debe identificarse
¡Observe cómo el razonamiento anterior se asemeja al pensamiento humano! Pero aún así, si bien estas salidas son útiles, necesitamos instruir al agente que las use como entrada para realizar la próxima recuperación de documentos. Sin esto, la respuesta proporcionada en Generate answer todavía no es útil.
useful_documentsse agregan para cada bucle de recuperación de documentos, en lugar de sobrescribirse, para mantener un recuerdo de los documentos que previamente se consideran útiles.hypothesisse forma a partir deuseful_documentsynew_documentsProporcionar un “razonamiento abstracto” para informar cómo la consulta se transformará posteriormente.El
hypothesises especialmente útil cuando no se pueden identificar documentos útiles inicialmente, ya que el agente aún puede formar hipótesis de los documentos que no se consideran inmediatamente como útiles / solo con relación indirecta con la pregunta en cuestión, para informar qué preguntas hacer a continuación
3ra iteración: lluvia de ideas sobre nuevas preguntas para hacer

Tenemos al agente reflexionar sobre si la respuesta es útil y basada en el contexto. Si no, debe proceder a Transform query para hacer más preguntas.
La salida new_queries Será una lista de nuevas preguntas que el agente considere útil para obtener información adicional. Dado que useful_documents (Políticas de compensación para la UE) y hypothesis (Necesita identificar la distancia de vuelo entre Delhi y Munich), hace preguntas como “¿Cuál es la distancia entre Delhi y Munich?”
Ahora estamos listos para usar el new_queries ¡Para más recuperación!
El
transform_queryEl nodo usaráuseful_documents(que se acumulan por iteración, en lugar de ser sobrescritos) yhypothesiscomo entrada para proporcionar las instrucciones del agente para hacer nuevas preguntas.Las nuevas preguntas serán una lista de preguntas (en lugar de una sola pregunta) separadas del original
questionpara que la pregunta original se mantenga en el estado, de lo contrario, el agente podría perder la rastro de la pregunta original después de múltiples iteraciones.
Iteración final: recuperación adicional con nuevas preguntas

La salida new_queries de Transform query se pasará al Retrieve documents paso, formando un bucle de recuperación.
Desde la pregunta “¿Cuál es la distancia entre Delhi y Munich?” se pregunta, podemos esperar que la distancia de vuelo se recupere como new_documentsy posteriormente calificado como useful_documentsutilizado aún más como entrada para Generate answer.
El
grade_documentsEl nodo comparará los documentos con ambosquestionynew_questionslista, de modo que los documentos que se consideran útiles paranew_questionsincluso si no es así para el originalquestionse guardan.Esto se debe a que esos documentos podrían ayudar a responder al original
questionindirectamente, por ser relevante paranew_questions(como “¿Cuál es la distancia entre Delhi y Munich? ”)

Equipado con este nuevo contexto sobre la distancia de vuelo, el agente ahora está listo para proporcionar la respuesta correcta: 600 EUR!
A continuación, hemos sumergido ahora en el código para ver cómo se crea esta aplicación de trapo de múltiples agentes.
Implementación
El código fuente se puede encontrar aquí. Nuestra aplicación de trapo de múltiples agentes involucra iteraciones y bucles, y Langgraph es una gran biblioteca para construir una aplicación tan compleja de múltiples agentes. Si no está familiarizado con Langgraph, se le sugiere que eche un vistazo a Guía QuickStart de Langgraph ¡Para entender más al respecto!
Para mantener este artículo conciso, me centraré solo en los fragmentos de código clave.
Nota importante: Estoy usando OpenRouter como el LLM interfaz, pero el código se puede adaptar fácilmente para otras interfaces LLM. Además, mientras que en mi código estoy usando el soneto Claude 3.5 como modelo, puede usar cualquier LLM siempre que soporte tools como parámetro (verifique esta lista aquí), ¡también puedes ejecutar esto con otros modelos, como Deepseek V3 y OpenAi O1!
Definición estatal
En la sección anterior, he definido varios elementos, por ejemplo, new_documents, hypothesis que se pasarán a cada paso (también conocido como Nodos), en la terminología de Langgraph, estos elementos se llaman Estado.
Definimos el estado formalmente con el siguiente fragmento.
from typing import List, Annotated
from typing_extensions import TypedDictdef append_to_list(original: list, new: list) -> list:
original.append(new)
return original
def combine_list(original: list, new: list) -> list:
return original + new
class GraphState(TypedDict):
"""
Represents the state of our graph.
Attributes:
question: question
generation: LLM generation
new_documents: newly retrieved documents for the current iteration
useful_documents: documents that are considered useful
graded_documents: documents that have been graded
new_queries: newly generated questions
hypothesis: hypothesis
"""
question: str
generation: str
new_documents: List[str]
useful_documents: Annotated[List[str], combine_list]
graded_documents: List[str]
new_queries: Annotated[List[str], append_to_list]
hypothesis: str
Definición de gráficos
Aquí es donde combinamos los diferentes pasos para formar un “Gráfico”, Que es una representación de nuestra aplicación de agente múltiple. Las definiciones de varios pasos (por ejemplo grade_documents) están representados por sus respectivas funciones.
from langgraph.graph import END, StateGraph, START
from langgraph.checkpoint.memory import MemorySaver
from IPython.display import Image, displayworkflow = StateGraph(GraphState)
# Define the nodes
workflow.add_node("retrieve", retrieve) # retrieve
workflow.add_node("grade_documents", grade_documents) # grade documents
workflow.add_node("generate", generate) # generatae
workflow.add_node("transform_query", transform_query) # transform_query
# Build graph
workflow.add_edge(START, "retrieve")
workflow.add_edge("retrieve", "grade_documents")
workflow.add_conditional_edges(
"grade_documents",
decide_to_generate,
{
"transform_query": "transform_query",
"generate": "generate",
},
)
workflow.add_edge("transform_query", "retrieve")
workflow.add_conditional_edges(
"generate",
grade_generation_v_documents_and_question,
{
"useful": END,
"not supported": "transform_query",
"not useful": "transform_query",
},
)
# Compile
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)
display(Image(app.get_graph(xray=True).draw_mermaid_png()))
Ejecutando el código anterior, debería ver esta representación gráfica de nuestra aplicación RAG. ¡Observe cómo es esencialmente equivalente al gráfico que he demostrado en la iteración final de la “estrategia mejorada de auto-rag”!

Después
generatesi la respuesta se considera “no compatible”, el agente procederá atransform_queryen caso degenerateUna vez más, para que el agente busque información adicional en lugar de tratar de regenerar las respuestas basadas en el contexto existente, lo que podría no ser suficiente para proporcionar una respuesta “apoyada”
¡Ahora estamos listos para poner a prueba la aplicación de múltiples agentes! Con el siguiente fragmento del código, hacemos esta pregunta how much can I receive if I am denied boarding, for flights from Delhi to Munich?
from pprint import pprint
config = {"configurable": {"thread_id": str(uuid4())}}# Run
inputs = {
"question": "how much can I receive if I am denied boarding, for flights from Delhi to Munich?",
}
for output in app.stream(inputs, config):
for key, value in output.items():
# Node
pprint(f"Node '{key}':")
# Optional: print full state at each node
# print(app.get_state(config).values)
pprint("\n---\n")
# Final generation
pprint(value["generation"])
Si bien la salida puede variar (a veces la aplicación proporciona la respuesta sin iteraciones, ya que “adivinó” la distancia entre Delhi y Munich), debería verse algo así, que muestra que la aplicación pasó por múltiples rondas de recuperación de datos para RAG.
---RETRIEVE---
"Node 'retrieve':"
'\n---\n'
---CHECK DOCUMENT RELEVANCE TO QUESTION---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---ASSESS GRADED DOCUMENTS---
---DECISION: GENERATE---
"Node 'grade_documents':"
'\n---\n'
---GENERATE---
---CHECK HALLUCINATIONS---
'---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---'
"Node 'generate':"
'\n---\n'
---TRANSFORM QUERY---
"Node 'transform_query':"
'\n---\n'
---RETRIEVE---
"Node 'retrieve':"
'\n---\n'
---CHECK DOCUMENT RELEVANCE TO QUESTION---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---GRADE: DOCUMENT NOT RELEVANT---
---ASSESS GRADED DOCUMENTS---
---DECISION: GENERATE---
"Node 'grade_documents':"
'\n---\n'
---GENERATE---
---CHECK HALLUCINATIONS---
---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---
---GRADE GENERATION vs QUESTION---
---DECISION: GENERATION ADDRESSES QUESTION---
"Node 'generate':"
'\n---\n'
('Based on the context provided, the flight distance from Munich to Delhi is '
'5,931 km, which falls into the long-distance category (over 3,500 km). '
'Therefore, if you are denied boarding on a flight from Delhi to Munich '
'operated by an EU airline, you would be eligible for 600 Euro compensation, '
'provided that:\n'
'1. The flight is operated by an EU airline\n'
'2. There is no force majeure\n'
'3. Other applicable conditions are met\n'
'\n'
"However, it's important to note that this compensation amount is only valid "
'if all the required conditions are met as specified in the regulations.')
¡Y la respuesta final es lo que apuntamos!
Based on the context provided, the flight distance from Munich to Delhi is
5,931 km, which falls into the long-distance category (over 3,500 km).
Therefore, if you are denied boarding on a flight from Delhi to Munich
operated by an EU airline, you would be eligible for 600 Euro compensation,
provided that:
1. The flight is operated by an EU airline
2. There is no force majeure
3. Other applicable conditions are metHowever, it's important to note that this compensation amount is only valid
if all the required conditions are met as specified in the regulations.
Inspeccionando el estado, vemos cómo el hypothesis y new_queries Mejore la efectividad de nuestra aplicación de RAG de múltiples agentes imitando el proceso de pensamiento humano.
Hipótesis
print(app.get_state(config).values.get('hypothesis',""))
--- Output ---
To answer this question accurately, I need to determine:1. Is this flight operated by an EU airline? (Since Delhi is non-EU and Munich is EU)
2. What is the flight distance between Delhi and Munich? (To determine compensation amount)
3. Are we dealing with a denied boarding situation due to overbooking? (As opposed to delay/cancellation)
From the context, I can find information about compensation amounts based on distance, but I need to verify:
- If the flight meets EU compensation eligibility criteria
- The exact distance between Delhi and Munich to determine which compensation tier applies (250€, 400€, or 600€)
- If denied boarding compensation follows the same amounts as delay compensation
The context doesn't explicitly state compensation amounts specifically for denied boarding, though it mentions overbooking situations in the EU require offering volunteers re-routing or refund options.
Would you like me to proceed with the information available, or would you need additional context about denied boarding compensation specifically?
Nuevas consultas
for questions_batch in app.get_state(config).values.get('new_queries',""):
for q in questions_batch:
print(q)
--- Output ---
What is the flight distance between Delhi and Munich?
Does EU denied boarding compensation follow the same amounts as flight delay compensation?
Are there specific compensation rules for denied boarding versus flight delays for flights from non-EU to EU destinations?
What are the compensation rules when flying with non-EU airlines from Delhi to Munich?
What are the specific conditions that qualify as denied boarding under EU regulations?
Conclusión
El trapo simple, aunque fácil de construir, podría quedarse corto para abordar las preguntas de la vida real. Al incorporar el proceso de pensamiento humano en un marco de trapo de múltiples agentes, estamos haciendo que las aplicaciones de trapo sean mucho más prácticas.
*A menos que se indique lo contrario, todas las imágenes son del autor