이 페이지에서는 LlamaIndex 쿼리 파이프라인 템플릿(Vertex AI SDK for Python의 LlamaIndexQueryPipelineAgent
클래스)을 사용하여 에이전트를 개발하는 방법을 보여줍니다. 이 에이전트는 "폴 그레이엄의 대학 생활은 어떠했는가?" 질문과 같은 검색 증강 생성(RAG)을 사용하여 질문에 답변하도록 디자인되었습니다.
다음 단계에 따라 LlamaIndex 쿼리 파이프라인을 사용하여 에이전트를 개발합니다.
- 모델 정의 및 구성
- 검색기 정의 및 사용
- 응답 합성기 정의 및 사용
- (선택사항) 프롬프트 템플릿 맞춤설정
- (선택사항) 조정 맞춤설정
시작하기 전에
환경 설정 단계에 따라 환경이 설정되었는지 확인합니다.
모델 정의 및 구성
사용할 LlamaIndex 쿼리 파이프라인 에이전트의 모델을 정의 및 구성합니다.
모델 버전을 정의합니다.
model = "gemini-1.5-flash-001"
(선택사항) 모델 파라미터를 지정합니다.
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, }
다음 모델 구성을 사용하여
LlamaIndexQueryPipelineAgent
를 만듭니다.from vertexai.preview import reasoning_engines agent = reasoning_engines.LlamaIndexQueryPipelineAgent( model=model, # Required. model_kwargs=model_kwargs, # Optional. )
터미널 또는 Colab 노트북과 같은 대화형 환경에서 실행 중이면 에이전트를 쿼리할 수 있습니다.
response = agent.query(input="What is Paul Graham's life in college?") print(response)
다음과 비슷한 응답이 표시됩니다.
{'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': {}}
(선택사항) 모델 맞춤설정
LlamaIndexQueryPipelineAgent
템플릿은 기본적으로 Google GenAI
를 사용하여 Google Cloud에서 사용 가능한 모든 파운데이션 모델에 대한 액세스를 제공합니다. Google GenAI
를 통해 제공되지 않는 모델을 사용하려면 model_builder=
를 다음과 같이 정의합니다.
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.
):
LlamaIndexQueryPipeline
에서 지원되는 채팅 모델 목록과 해당 기능을 보려면 사용 가능한 LLM 통합을 참조하세요.
각 채팅 모델은 model=
및 model_kwargs=
에 대해 지원되는 자체 값 집합을 사용합니다.
Google 생성형 AI
Google 생성형 AI는 환경을 설정할 때 기본적으로 설치되며 model_builder
를 생략할 때 LlamaIndexQueryPipelineAgent
템플릿에 자동으로 사용됩니다.
from vertexai.preview import reasoning_engines
agent = reasoning_engines.LlamaIndexQueryPipelineAgent(
model=model, # Required.
model_kwargs=model_kwargs, # Optional.
)
Anthropic
Anthropic 문서에 따라 계정을 설정하고
llama-index-llms-anthropic
패키지를 설치합니다.Anthropic
모델을 반환하도록model_builder
를 정의합니다.def model_builder(*, model_name: str, model_kwargs = None, **kwargs): from llama_index.llms.anthropic import Anthropic return Anthropic(model=model_name, **model_kwargs)
LlamaIndexQueryPipelineAgent
템플릿에서 Anthropic 모델을 사용합니다.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
Gemini의 ChatCompletions
API에서 OpenAILike
를 사용할 수 있습니다.
OpenAILike
문서에 따라 패키지를 설치합니다.pip install llama-index-llms-openai-like
OpenAILike
모델을 반환하는model_builder
를 정의합니다.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, )
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. }, )
검색기 정의 및 사용
모델을 정의한 후 추론을 위해 모델에 사용되는 검색기를 정의합니다. 검색기는 색인을 기반으로 빌드할 수 있지만 자세한 구성에 따라 독립적으로 정의할 수도 있습니다. 검색기를 로컬로 테스트해야 합니다.
관련 문서 및 유사성 점수를 반환하는 검색기를 정의합니다.
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()
검색기를 테스트합니다.
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?")
검색된 응답은 다음과 비슷하게 표시됩니다.
[ 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 ) ]
LlamaIndexQueryPipelineAgent
템플릿 내에서 검색기를 사용하려면retriever_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 = agent.query( input="What is Paul Graham's life in College?" )
응답은 점수와 함께 JSON으로 직렬화할 수 있는 노드 목록입니다.
[{'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'} ]
응답 합성기 정의 및 사용
모델 및 검색기를 정의한 후 사용자 쿼리 및 주어진 텍스트 청크 집합을 사용하여 LLM에서 응답을 생성하는 응답-합성기를 정의합니다. 기본 get_response_synthesizer를 사용하거나 응답 모드를 구성할 수 있습니다.
답변을 반환하는 응답 합성기를 정의합니다.
def response_synthesizer_builder(model, response_synthesizer_kwargs=None): from llama_index.core.response_synthesizers import SimpleSummarize return SimpleSummarize(llm=model)
다음과 같이 함수를 테스트합니다.
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], )
응답은 다음과 비슷하게 표시됩니다.
"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."
LlamaIndexQueryPipeline
템플릿 내에서 응답 합성기를 사용하려면response_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. )
테스트 쿼리를 실행하여 전체 RAG 쿼리 파이프라인을 로컬로 테스트합니다.
response = agent.query( input="What is Paul Graham's life in College?" )
응답은 다음과 유사한 사전입니다.
{ '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' } } }
(선택사항) 프롬프트 템플릿 맞춤설정
프롬프트 템플릿은 사용자 입력을 모델 명령으로 변환하며, 문맥적으로 관련성이 있고 일관성 있는 출력을 위한 응답을 안내합니다. 자세한 내용은 프롬프트를 참조하세요.
기본 프롬프트 템플릿은 다음 섹션으로 순차적으로 구성됩니다.
섹션 | 설명 |
---|---|
(선택사항) 시스템 안내 | 에이전트가 모든 쿼리에 적용할 안내입니다. |
사용자 입력 | 에이전트가 응답하는 데 사용하는 사용자의 쿼리입니다. |
기본 프롬프트 템플릿은 자체 프롬프트 템플릿을 지정하지 않고 에이전트를 만드는 경우에 생성되며 다음과 같이 표시됩니다.
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)
다음 예시에서 에이전트를 인스턴스화할 때 전체 프롬프트 템플릿을 사용할 수 있습니다.
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,
)
기본 프롬프트 템플릿을 자체 프롬프트 템플릿으로 재정의하고 에이전트를 구성할 때 사용할 수 있습니다.
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?",
}
)
(선택사항) 조정 맞춤설정
모든 LlamaIndexQueryPipeline
구성요소는 조정을 위한 입력 및 출력 스키마를 제공하는 쿼리 구성요소 인터페이스를 구현합니다. LlamaIndexQueryPipelineAgent
가 쿼리에 응답하면 실행 파일을 빌드해야 합니다. 기본적으로 LlamaIndexQueryPipelineAgent
는 Query Pipeline
을 사용하여 순차적 체인 또는 방향성 비순환 그래프(DAG)를 빌드합니다.
다음 중 하나를 수행하려는 경우 조정을 맞춤설정해야 할 수 있습니다.
RAG 파이프라인을 확장하는 에이전트를 구현합니다(예: 기존 프롬프트, 모델, 검색기, 응답 합성기 모듈을 쿼리 엔진, 쿼리 변환기, 출력 파서, 포스트프로세서/순위 재지정기, 커스텀 쿼리 구성요소로 확장).
ReAct를 사용하여 에이전트가 도구를 실행하고 해당 단계를 수행한 이유에 대한 설명을 각 단계에 주석으로 포함하도록 프롬프트합니다. 이렇게 하려면
runnable_builder=
인수를 지정하여LlamaIndexQueryPipelineAgent
를 만들 때 기본 실행 파일을 재정의합니다.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, ):
각 항목의 의미는 다음과 같습니다.
model
은model_builder
에서 반환되는 채팅 모델에 해당합니다(모델 정의 및 구성 참조).retriever
및retriever_kwargs
는 사용되는 검색기 및 구성에 해당합니다(검색기 정의 참조).response_synthesizer
및response_synthesizer_kwargs
는 사용되는 응답 합성기 및 구성에 해당합니다(응답 합성기 정의 참조).system_instruction
및prompt
는 프롬프트 구성에 해당합니다(프롬프트 템플릿 맞춤설정 참조).agent_executor_kwargs
및runnable_kwargs
는 실행 파일을 맞춤설정하는 데 사용할 수 있는 키워드 인수입니다.
커스텀 파이프라인 또는 ReAct를 사용하여 조정 로직을 맞춤설정할 수 있습니다.
커스텀 파이프라인
에이전트에 추가 모듈(예: 포스트프로세서)를 제공하려면 LlamaIndexQueryPipelineAgent
에 대해 runnable_builder
를 재정의합니다.
포스트프로세서를 정의합니다.
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, )
에이전트를 쿼리합니다.
result = agent.query(input="What is Paul Graham's life in College?")
출력은 다음과 비슷하게 표시됩니다.
[ { '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' } ]
ReAct 에이전트
자체 ReAct 에이전트를 도구 호출 동작기에 제공하려면 LlamaIndexQueryPipelineAgent
에 대해 runnable_builder
를 재정의합니다.
환율을 반환하는 예시 함수를 정의합니다.
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()
다음 도구를 사용하여 커스텀 ReAct 에이전트를 만듭니다.
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, )
에이전트를 쿼리합니다.
result = agent.query(input="What is the exchange rate between US and EURO today?")
다음과 유사하게 출력됩니다.
{ 'response': 'The exchange rate between US and EURO today, 2025-03-19, is 1 USD to 0.91768 EUR.', 'source_nodes': [], 'metadata': None }