Agent Runtime を使用すると、LlamaIndex Query Pipelines
テンプレートを使用してエージェントを開発してデプロイできます。Agent Platform SDK の LlamaIndexQueryPipelineAgent クラスを使用すると、検索拡張生成(RAG)用に設計されたエージェントを作成できます。
このドキュメントでは、モデルの定義、リトリーバーの設定、レスポンスの合成など、LlamaIndex Query Pipeline エージェントを開発する方法について説明します。
デプロイされたエージェントの管理の詳細については、 デプロイされたエージェントを管理するをご覧ください。
始める前に
環境の設定の手順に沿って環境が設定されていることを確認します。
モデルを定義して構成する
LlamaIndex Query Pipeline エージェントが使用するモデルを定義して構成します。
使用するモデルを指定します。
model = "gemini-3.5-flash"省略可: モデル パラメータを指定します。
model_kwargs = { # vertexai_config (dict): By providing the region and project_id parameters, # you can enable model usage through Agent Platform. "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 GenAI
Google GenAI は、環境を設定するときにデフォルトでインストールされ、LlamaIndexQueryPipelineAgent で model_builder を省略すると自動的に使用されます。
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
OpenAILike は、Gemini の ChatCompletions API で使用できます。
OpenAILikeドキュメント に沿ってパッケージをインストールします。pip install llama-index-llms-openai-likeOpenAILikeモデルを返す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-3.5-flash", # 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="text-embedding-005", 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."LlamaIndexQueryPipelineAgent内でレスポンス シンセサイザーを使用するには、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 コンポーネントは、オーケストレーション用の入力スキーマと出力スキーマを提供する Query Component
インターフェースを実装します。
LlamaIndexQueryPipelineAgent
クラスでは、クエリに応答するために実行可能ファイルをビルドする必要があります。デフォルトでは、
LlamaIndexQueryPipelineAgent
はシーケンシャル チェーンまたは有向非巡回グラフ
(DAG)
をQuery
Pipelineを使用して構築します。
次のいずれかを行う場合は、オーケストレーションをカスタマイズすることをおすすめします。
RAG パイプラインを拡張するエージェントを実装する(既存のプロンプト、モデル、リトリーバー、レスポンス シンセサイザー モジュールを Query Engine、 Query Transformer、 Output Parsers、 Postprocessor/Rerankers または Custom Query Component に拡張するなど)。
ReActこれを行うには、
LlamaIndexQueryPipelineAgentを作成するときに、runnable_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, ):ここで
modelは、model_builderから返されるチャットモデルに対応します(モデルを定義して構成するをご覧ください)。retrieverとretriever_kwargsは、使用するリトリーバーと 構成に対応します(リトリーバーを定義するをご覧ください)。response_synthesizerとresponse_synthesizer_kwargsは、使用するレスポンス シンセサイザーと構成に対応します(レスポンス シンセサイザーを定義するをご覧ください)。system_instructionとpromptは、プロンプト構成に対応しています (プロンプト テンプレートをカスタマイズするをご覧ください)。agent_executor_kwargsとrunnable_kwargsは、実行可能ファイルのカスタマイズに使用できるキーワード引数です。
カスタム パイプラインまたは ReAct を使用して、オーケストレーション ロジックをカスタマイズできます。
カスタム パイプライン
エージェントに追加のモジュール(Postprocessor など)を提供するには、runnable_builder を LlamaIndexQueryPipelineAgent オーバーライドします。
Postprocessor を定義します。
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 エージェントで ツール呼び出し動作 を提供するには、
runnable_builder を LlamaIndexQueryPipelineAgent に対してオーバーライドします。
為替レートを返すサンプル関数を定義します。
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-3.5-flash", 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 }
次のステップ
LlamaIndex Query Pipeline エージェントを使用する
Agent Platform Runtime で LlamaIndex Query Pipeline エージェントを使用します。