En esta página, se muestra cómo desarrollar un agente con la plantilla de canalizaciones de consulta de LlamaIndex (la clase LlamaIndexQueryPipelineAgent
en el SDK de Vertex AI para Python). Este agente está diseñado para responder preguntas con la generación de aumento de recuperación (RAG), como la siguiente consulta: "¿Cómo es la vida de Paul Graham en la universidad?".
Sigue estos pasos para desarrollar un agente con las canalizaciones de consulta de LlamaIndex:
- Define y configura un modelo
- Define y usa un recuperador
- Define y usa un sintetizador de respuestas
- (Opcional) Personaliza la plantilla de instrucciones
- (Opcional) Cómo personalizar la organización
Antes de comenzar
Asegúrate de que tu entorno esté configurado con los pasos que se indican en Configura tu entorno.
Define y configura un modelo
Define y configura un modelo para que lo use tu agente de LlamaIndex Query Pipelines.
Define la versión del modelo:
model = "gemini-1.5-flash-001"
(Opcional) Especifica los parámetros del modelo:
model_kwargs = { # vertexai_config (dict): By providing the region and project_id parameters, # you can enable model usage through Vertex AI. "vertexai_config": { "project": "PROJECT_ID", "location": "LOCATION" }, # temperature (float): The sampling temperature controls the degree of # randomness in token selection. "temperature": 0.28, # context_window (int): The context window of the model. # If not provided, the default context window is 200000. "context_window": 200000, # max_tokens (int): Token limit determines the maximum # amount of text output from one prompt. If not provided, # the default max_tokens is 256. "max_tokens": 256, }
Crea un
LlamaIndexQueryPipelineAgent
con las siguientes configuraciones de modelos:from vertexai.preview import reasoning_engines agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model=model, # Required. model_kwargs=model_kwargs, # Optional. )
Si ejecutas el código en un entorno interactivo (como la terminal o el notebook de Colab), puedes consultar al agente:
response = agent.query(input="What is Paul Graham's life in college?") print(response)
Deberías recibir una respuesta similar a la que figura a continuación:
{'message': {'role': 'assistant', 'additional_kwargs': {}, 'blocks': [{'block_type': 'text', 'text': "Unfortunately, there's not a lot of publicly available information about Paul Graham's personal life in college. ..."}]}, 'raw': {'content': {'parts': [{'video_metadata': None, 'thought': None, 'code_execution_result': None, 'executable_code': None, 'file_data': None, 'function_call': None, 'function_response': None, 'inline_data': None, 'text': "Unfortunately, there's not a lot of publicly available information about Paul Graham's personal life in college. ..."}], 'role': 'model'}, 'citation_metadata': None, 'finish_message': None, 'token_count': None, 'avg_logprobs': -0.1468650027438327, 'finish_reason': 'STOP', 'grounding_metadata': None, 'index': None, 'logprobs_result': None, 'safety_ratings': [{'blocked': None, 'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability': 'NEGLIGIBLE', 'probability_score': 0.022949219, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.014038086}, {'blocked': None, 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability': 'NEGLIGIBLE', 'probability_score': 0.056640625, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.029296875}, {'blocked': None, 'category': 'HARM_CATEGORY_HARASSMENT', 'probability': 'NEGLIGIBLE', 'probability_score': 0.071777344, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.024047852}, {'blocked': None, 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability': 'NEGLIGIBLE', 'probability_score': 0.103515625, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.05102539}], 'usage_metadata': {'cached_content_token_count': None, 'candidates_token_count': 222, 'prompt_token_count': 10, 'total_token_count': 232}}, 'delta': None, 'logprobs': None, 'additional_kwargs': {}}
Personaliza tu modelo (opcional)
La plantilla LlamaIndexQueryPipelineAgent
usa Google GenAI
de forma predeterminada para proporcionar acceso a todos los modelos fundamentales disponibles en Google Cloud. Para usar un modelo que no está disponible a través de Google GenAI
, define model_builder=
de la siguiente manera:
from typing import Optional
def model_builder(
*,
model_name: str, # Required. The name of the model
model_kwargs: Optional[dict] = None, # Optional. The model keyword arguments.
**kwargs, # Optional. The remaining keyword arguments to be ignored.
):
Para obtener una lista de los modelos de chat compatibles con LlamaIndexQueryPipeline
y sus capacidades, consulta
Integraciones de LLM disponibles.
Cada modelo de chat usa su propio conjunto de valores admitidos para model=
y model_kwargs=
.
Google GenAI
La IA generativa de Google se instala de forma predeterminada cuando configuras tu entorno y se usa automáticamente en la plantilla LlamaIndexQueryPipelineAgent
cuando omites model_builder
.
from vertexai.preview import reasoning_engines
agent = reasoning_engines.LlamaIndexQueryPipelineAgent(
model=model, # Required.
model_kwargs=model_kwargs, # Optional.
)
Anthropic
Sigue la documentación de Anthroponic para configurar una cuenta e instalar el paquete
llama-index-llms-anthropic
.Define
model_builder
para mostrar el modeloAnthropic
:def model_builder(*, model_name: str, model_kwargs = None, **kwargs): from llama_index.llms.anthropic import Anthropic return Anthropic(model=model_name, **model_kwargs)
Usa el modelo Anthropic en la plantilla
LlamaIndexQueryPipelineAgent
:from vertexai.preview import reasoning_engines agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model="claude-3-opus-20240229", # Required. model_builder=model_builder, # Required. model_kwargs={ "api_key": "ANTHROPIC_API_KEY", # Required. "temperature": 0.28, # Optional. }, )
OpenAILike
Puedes usar OpenAILike
con la API de ChatCompletions
de Gemini.
Sigue la documentación de
OpenAILike
para instalar el paquete:pip install llama-index-llms-openai-like
Define un
model_builder
que muestre el modeloOpenAILike
:def model_builder( *, model_name: str, model_kwargs = None, project: str, # Specified via vertexai.init location: str, # Specified via vertexai.init **kwargs, ): import google.auth from llama_index.llms.openai_like import OpenAILike # Note: the credential lives for 1 hour by default. # After expiration, it must be refreshed. creds, _ = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"]) auth_req = google.auth.transport.requests.Request() creds.refresh(auth_req) if model_kwargs is None: model_kwargs = {} endpoint = f"https://{location}-aiplatform.googleapis.com" api_base = f'{endpoint}/v1beta1/projects/{project}/locations/{location}/endpoints/openapi' return OpenAILike( model=model_name, api_base=api_base, api_key=creds.token, **model_kwargs, )
Usa el modelo en la plantilla
LlamaIndexQueryPipelineAgent
:from vertexai.preview import reasoning_engines agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model="google/gemini-1.5-pro-001", # Or "meta/llama3-405b-instruct-maas" model_builder=model_builder, # Required. model_kwargs={ "temperature": 0, # Optional. "max_retries": 2, # Optional. }, )
Define y usa un recuperador
Después de definir el modelo, define el recuperador que este usa para el razonamiento. Un recuperador se puede compilar sobre índices, pero también se puede definir de forma completa. Deberías probar el recuperador de forma local.
Define un recuperador que devuelva documentos relevantes y puntuaciones de similitud:
def retriever_builder(model, retriever_kwargs=None): import os import requests from llama_index.core import ( StorageContext, VectorStoreIndex, load_index_from_storage, ) from llama_index.core import SimpleDirectoryReader from llama_index.embeddings.vertex import VertexTextEmbedding import google.auth credentials, _ = google.auth.default() embed_model = VertexTextEmbedding( model_name="textembedding-gecko@003", project="PROJECT_ID", credentials=credentials ) data_dir = "data/paul_graham" essay_file = os.path.join(data_dir, "paul_graham_essay.txt") storage_dir = "storage" # --- Simple Download (if needed) --- if not os.path.exists(essay_file): os.makedirs(data_dir, exist_ok=True) # Make sure the directory exists essay_url = "https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt" try: response = requests.get(essay_url) response.raise_for_status() # Check for download errors with open(essay_file, "wb") as f: f.write(response.content) print("Essay downloaded.") except requests.exceptions.RequestException as e: print(f"Download failed: {e}") # --- Build/Load Index --- if not os.path.exists(storage_dir): print("Creating new index...") # --- Load Data --- reader = SimpleDirectoryReader(data_dir) docs = reader.load_data() index = VectorStoreIndex.from_documents(docs, model=model, embed_model=embed_model) index.storage_context.persist(persist_dir=storage_dir) else: print("Loading existing index...") storage_context = StorageContext.from_defaults(persist_dir=storage_dir) index = load_index_from_storage(storage_context, embed_model=embed_model) return index.as_retriever()
Prueba el recuperador:
from llama_index.llms.google_genai import GoogleGenAI model = GoogleGenAI( model=model, **model_kwargs ) retriever = retriever_builder(model) retrieved_response = retriever.retrieve("What is Paul Graham's life in College?")
La respuesta recuperada debería ser similar a la siguiente:
[ NodeWithScore( node=TextNode( id_='692a5d5c-cd56-4ed0-8e29-ecadf6eb9933', embedding=None, metadata={'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-24', 'last_modified_date': '2025-03-24'}, excluded_embed_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], excluded_llm_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], relationships={ <NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='3e1c4d73-1e1d-4e83-bd16-2dae24abb231', node_type='4', metadata={'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-24', 'last_modified_date': '2025-03-24'}, hash='0c3c3f46cac874b495d944dfc4b920f6b68817dbbb1699ecc955d1fafb2bf87b'), <NodeRelationship.PREVIOUS: '2'>: RelatedNodeInfo(node_id='782c5787-8753-4f65-85ed-c2833ea6d4d8', node_type='1', metadata={'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-24', 'last_modified_date': '2025-03-24'}, hash='b8e6463833887a8a2b13f1b5a623672819faedc1b725d9565ba003223628db0e'), <NodeRelationship.NEXT: '3'>: RelatedNodeInfo(node_id='f7d2cb7e-fa0c-40bf-b8e7-b888e36b87f9', node_type='1', metadata={}, hash='db7cc1a67fa3afd1e5f24c8c61583781ce6a00c444da8f25a5374468c17b7de0') }, metadata_template='{key}: {value}', metadata_separator='\n', text='So I looked around to see what I could salvage from the wreckage of my plans, and there was Lisp...', mimetype='text/plain', start_char_idx=7166, end_char_idx=11549, metadata_separator='\n', text_template='{metadata_str}\n\n{content}' ), score=0.7403571819090398 ) ]
Para usar el recuperador dentro de la plantilla
LlamaIndexQueryPipelineAgent
, agrégalo debajo del argumentoretriever_builder=
:from vertexai.preview import reasoning_engines agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model=model, # Required. model_kwargs=model_kwargs, # Optional. retriever_builder=retriever_builder, # Optional. )
Para probar el agente de forma local, realiza consultas de prueba:
response = agent.query( input="What is Paul Graham's life in College?" )
La respuesta es una lista serializable JSON de nodos con puntuaciones.
[{'node': {'id_': '692a5d5c-cd56-4ed0-8e29-ecadf6eb9933', 'embedding': None, 'metadata': {'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-12', 'last_modified_date': '2025-03-12'}, 'excluded_embed_metadata_keys': ['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], 'excluded_llm_metadata_keys': ['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], 'relationships': {'1': {'node_id': '07ee9574-04c8-46c7-b023-b22ba9558a1f', 'node_type': '1', 'metadata': {}, 'hash': '44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a', 'class_name': 'RelatedNodeInfo'}, '2': {'node_id': 'ac7e54aa-6fff-40b5-a15e-89c5eb234936', 'node_type': '1', 'metadata': {'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-12', 'last_modified_date': '2025-03-12'}, 'hash': '755327a01efe7104db771e4e6f9683417884ea6895d878da882d2b21a6b66442', 'class_name': 'RelatedNodeInfo'}, '3': {'node_id': '3a04be27-ac46-4acd-a8c6-031689508982', 'node_type': '1', 'metadata': {}, 'hash': 'db7cc1a67fa3afd1e5f24c8c61583781ce6a00c444da8f25a5374468c17b7de0', 'class_name': 'RelatedNodeInfo'}}, 'metadata_template': '{key}: {value}', 'metadata_separator': '\n', 'text': 'So I looked around to see what I could salvage from the wreckage of my plans, and there was Lisp...', 'mimetype': 'text/plain', 'start_char_idx': 7164, 'end_char_idx': 11547, 'metadata_separator': '\n', 'text_template': '{metadata_str}\n\n{content}', 'class_name': 'TextNode'}, 'score': 0.25325886336265013, 'class_name': 'NodeWithScore'} ]
Define y usa un sintetizador de respuestas
Después de definir tu modelo y recuperador, define el sintetizador de respuestas que genera una respuesta de un LLM con una consulta del usuario y un conjunto determinado de fragmentos de texto. Puedes usar el get_response_synthesizer predeterminada o configurar el modo de respuesta.
Define un sintetizador de respuestas que muestre la respuesta:
def response_synthesizer_builder(model, response_synthesizer_kwargs=None): from llama_index.core.response_synthesizers import SimpleSummarize return SimpleSummarize(llm=model)
Sigue estos pasos para probar la función:
response_synthesizer = response_synthesizer_builder(model=model) response = response_synthesizer.get_response( "What is Paul Graham's life in College?", [node.model_dump_json() for node in retrieved_response], )
La respuesta podría ser similar a la siguiente:
"While in a PhD program for computer science, he took art classes and worked on a book about Lisp hacking. He applied to art schools, got accepted to RISD, and later got an invitation to take the entrance exam at the Accademia di Belli Arti in Florence. He was accepted to both. He attended the Accademia, but was disappointed by the lack of instruction."
Para usar el sintetizador de respuestas dentro de la plantilla
LlamaIndexQueryPipeline
, agrégalo debajo del argumentoresponse_synthesizer_builder=
:from vertexai.preview import reasoning_engines agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model=model, # Required. model_kwargs=model_kwargs, # Optional. retriever_builder=retriever_builder, # Optional. response_synthesizer_builder=response_synthesizer_builder, # Optional. )
Ejecuta consultas de prueba para probar la canalización de consultas de RAG completa de forma local:
response = agent.query( input="What is Paul Graham's life in College?" )
La respuesta es un diccionario similar al siguiente:
{ 'response': "While in college, he was drawn to McCarthy's 1960 Lisp, although he didn't fully grasp the reasons for his interest at the time. He also had a brief encounter with surplus Xerox Dandelions in the computer lab but found them too slow for his liking. \n", 'source_nodes': [ '{"node":{"id_":"95889c30-53c7-43d0-bf91-930dbb23bde6"...,"score":0.7077213268404997,"class_name":"NodeWithScore"}' ], 'metadata': { '95889c30-53c7-43d0-bf91-930dbb23bde6': { 'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-25', 'last_modified_date': '2025-03-25' } } }
(Opcional) Personaliza la plantilla de instrucciones
Las plantillas de instrucciones traducen la entrada del usuario en instrucciones del modelo y guían las respuestas para obtener un resultado contextualmente relevante y coherente. Consulta Instrucciones para obtener más información.
La plantilla de instrucciones predeterminada se organiza de forma secuencial en las siguientes secciones:
Sección | Descripción |
---|---|
(Opcional) Instrucción del sistema | Son instrucciones para que el agente se aplique en todas las consultas. |
Entrada del usuario | Es la consulta del usuario que el agente debe responder. |
La plantilla de instrucciones predeterminada se genera si creas el agente sin especificar tu propia plantilla de instrucciones y se verá de la siguiente manera:
from llama_index.core import prompts
from llama_index.core.base.llms import types
message_templates = [
types.ChatMessage(role=types.MessageRole.SYSTEM, content=system_instruction),
types.ChatMessage(role=types.MessageRole.USER, content="{input}"),
]
prompts.ChatPromptTemplate(message_templates=message_templates)
Puedes usar la plantilla de instrucciones completa cuando crees una instancia del agente en el siguiente ejemplo:
from vertexai.preview import reasoning_engines
system_instruction = "I help to find what is Paul Graham's life in College"
agent = reasoning_engines.LlamaIndexQueryPipelineAgent(
model=model,
system_instruction=system_instruction,
)
Puedes anular la plantilla de instrucciones predeterminada con tu propia plantilla de instrucciones y usarla cuando construyas el agente:
prompt_str = "Please answer {question} about {name}"
prompt_tmpl = PromptTemplate(prompt_str)
from vertexai.preview import reasoning_engines
agent = reasoning_engines.LlamaIndexQueryPipelineAgent(
model = model,
prompt = prompt_tmpl,
)
agent.query(
input={
"name": "Paul Graham",
"question": "What is the life in college?",
}
)
(Opcional) Cómo personalizar la organización
Todos los componentes LlamaIndexQueryPipeline
implementan la interfaz de Query Component, que proporciona esquemas de entrada y salida para la organización. LlamaIndexQueryPipelineAgent
requiere que se compile un elemento ejecutable para que responda a las consultas. De forma predeterminada,
LlamaIndexQueryPipelineAgent
compila una cadena secuencial o un grafo acíclico dirigido (DAG) con Query Pipeline
.
Te recomendamos que personalices la orquestación si quieres hacer alguna de las siguientes acciones:
Implementa un agente que extienda la canalización de RAG (como extender un módulo existente de instrucción, modelo, recuperador o sintetizador de respuestas al motor de consulta, al transformador de consultas, a los analizadores de salida, a los procesadores posteriores o a los reclasificadores o al componente de consulta personalizado).
Solicita al agente con ReAct que ejecute herramientas y annote cada paso con comentarios sobre por qué lo realizó. Para ello, anula el ejecutable predeterminado cuando crees el
LlamaIndexQueryPipelineAgent
especificando el argumentorunnable_builder=
:from typing import Optional from llama_index.core.llms import function_calling def runnable_builder( model: function_calling.FunctionCallingLLM, *, system_instruction: Optional[str] = None, prompt: Optional[query.QUERY_COMPONENT_TYPE] = None, retriever: Optional[query.QUERY_COMPONENT_TYPE] = None, response_synthesizer: Optional[query.QUERY_COMPONENT_TYPE] = None, runnable_kwargs: Optional[Mapping[str, Any]] = None, ):
Aquí:
model
corresponde al modelo de chat que se muestra desdemodel_builder
(consulta Define y configura un modelo).retriever
yretriever_kwargs
corresponden al recuperador y a las configuraciones que se usarán (consulta Define un recuperador).response_synthesizer
yresponse_synthesizer_kwargs
corresponden al sintetizador de respuestas y a las configuraciones que se usarán (consulta Define un sintetizador de respuestas).system_instruction
yprompt
corresponden a la configuración de la instrucción (consulta Cómo personalizar la plantilla de instrucciones).agent_executor_kwargs
yrunnable_kwargs
son los argumentos de palabra clave que puedes usar para personalizar el elemento ejecutable.
Puedes personalizar la lógica de orquestación con una canalización personalizada o ReAct:
Canalización personalizada
Para proporcionar un módulo adicional (como un postprocesador) al agente, anula runnable_builder
por LlamaIndexQueryPipelineAgent
.
Define un postprocesador:
def post_processor_builder(): from llama_index.core.postprocessor import SimilarityPostprocessor # similarity postprocessor: filter nodes below 0.7 similarity score return SimilarityPostprocessor(similarity_cutoff=0.7) def runnable_with_postprocessor_builder( model, runnable_kwargs, **kwargs ): from llama_index.core.query_pipeline import QueryPipeline pipeline = QueryPipeline(**runnable_kwargs) pipeline_modules = { "retriever": retriever_builder(model), "postprocessor": post_processor_builder(), } pipeline.add_modules(pipeline_modules) pipeline.add_link("retriever", "postprocessor") return pipeline agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model=model, runnable_builder=runnable_with_postprocessor_builder, )
Consulta al agente:
result = agent.query(input="What is Paul Graham's life in College?")
El resultado debería ser similar al siguiente ejemplo:
[ { 'node': {'id_': 'bb7d2942-213d-4fb3-a7cb-1a664642a7ff', 'embedding': None, 'metadata': { 'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-25', 'last_modified_date': '2025-03-25' }, 'excluded_embed_metadata_keys': [ 'file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date' ], 'excluded_llm_metadata_keys': [ 'file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date' ], 'relationships': {'1': {'node_id': 'c508cee5-5ef2-4fdf-a33d-0427dcb78b5c', 'node_type': '4', 'metadata': {'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-25', 'last_modified_date': '2025-03-25'}, 'hash': '0c3c3f46cac874b495d944dfc4b920f6b68817dbbb1699ecc955d1fafb2bf87b', 'class_name': 'RelatedNodeInfo'}, '2': {'node_id': '97a84b41-62bf-4959-acae-cfd4bdfbd4d9', 'node_type': '1', 'metadata': {'file_path': '/content/data/paul_graham/paul_graham_essay.txt', 'file_name': 'paul_graham_essay.txt', 'file_type': 'text/plain', 'file_size': 75042, 'creation_date': '2025-03-25', 'last_modified_date': '2025-03-25'}, 'hash': 'a7dd352be97e47e8e553ceda3d2d2c9e9d5c54adb298063c94da06167938d583', 'class_name': 'RelatedNodeInfo'}, '3': {'node_id': 'b984eea1-f0bc-4880-812e-3f49f1e304b8', 'node_type': '1', 'metadata': {}, 'hash': 'db7cc1a67fa3afd1e5f24c8c61583781ce6a00c444da8f25a5374468c17b7de0', 'class_name': 'RelatedNodeInfo'}}, 'metadata_template': '{key}: {value}', 'metadata_separator': '\n', 'text': 'So I looked around to see what I could salvage from the wreckage of my plans, and there was Lisp...', 'mimetype': 'text/plain', 'start_char_idx': 7166, 'end_char_idx': 11549, 'metadata_separator': '\n', 'text_template': '{metadata_str}\n\n{content}', 'class_name': 'TextNode'}, 'score': 0.7403571819090398, 'class_name': 'NodeWithScore' }, { 'node': {'id_': 'b984eea1-f0bc-4880-812e-3f49f1e304b8...'} 'score': 0.7297395567513889, 'class_name': 'NodeWithScore' } ]
Agente de ReAct
Para proporcionar un comportamiento de llamada de herramientas con tu propio agente de ReAct, anula runnable_builder
para LlamaIndexQueryPipelineAgent
.
Define una función de ejemplo que muestre un tipo de cambio:
def get_exchange_rate( currency_from: str = "USD", currency_to: str = "EUR", currency_date: str = "latest", ): """Retrieves the exchange rate between two currencies on a specified date. Uses the Frankfurter API (https://api.frankfurter.app/) to obtain exchange rate data. Args: currency_from: The base currency (3-letter currency code). Defaults to "USD" (US Dollar). currency_to: The target currency (3-letter currency code). Defaults to "EUR" (Euro). currency_date: The date for which to retrieve the exchange rate. Defaults to "latest" for the most recent exchange rate data. Can be specified in YYYY-MM-DD format for historical rates. Returns: dict: A dictionary containing the exchange rate information. Example: {"amount": 1.0, "base": "USD", "date": "2023-11-24", "rates": {"EUR": 0.95534}} """ import requests response = requests.get( f"https://api.frankfurter.app/{currency_date}", params={"from": currency_from, "to": currency_to}, ) return response.json()
Crea un agente de ReAct personalizado con las siguientes herramientas:
def runnable_with_tools_builder(model, runnable_kwargs=None, **kwargs): from llama_index.core.query_pipeline import QueryPipeline from llama_index.core.tools import FunctionTool from llama_index.core.agent import ReActAgent llama_index_tools = [] for tool in runnable_kwargs.get("tools"): llama_index_tools.append(FunctionTool.from_defaults(tool)) agent = ReActAgent.from_tools(llama_index_tools, llm=model, verbose=True) return QueryPipeline(modules = {"agent": agent}) agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model="gemini-1.5-pro-001", runnable_kwargs={"tools": [get_exchange_rate]}, runnable_builder=runnable_with_tools_builder, )
Consulta al agente:
result = agent.query(input="What is the exchange rate between US and EURO today?")
El resultado debe verse de la siguiente manera:
{ 'response': 'The exchange rate between US and EURO today, 2025-03-19, is 1 USD to 0.91768 EUR.', 'source_nodes': [], 'metadata': None }
¿Qué sigue?
- Evalúa un agente.
- Implementa un agente.
- Soluciona problemas de desarrollo de un agente.
- Obtén asistencia.