יצירת סוכן LlamaIndex Query Pipeline

‫Agent Runtime מאפשר לפתח ולפרוס סוכנים באמצעות תבנית Query Pipelines של LlamaIndex. באמצעות המחלקה LlamaIndexQueryPipelineAgent ב-Agent Platform SDK, אפשר ליצור סוכנים שמיועדים ל-Retrieval-Augmented Generation (יצירה משולבת-אחזור, RAG).

במאמר הזה מוסבר איך לפתח סוכן של צינור שאילתות LlamaIndex, כולל הגדרת המודל, הגדרת כלי לאחזור מידע וסינתוז של תשובות.

מידע נוסף על ניהול הסוכנים שהופעלו זמין במאמר ניהול סוכנים שהופעלו.

לפני שמתחילים

פועלים לפי השלבים שמפורטים במאמר הגדרת הסביבה כדי לוודא שהסביבה מוגדרת.

הגדרה והגדרה של מודל

הגדרת מודל לשימוש על ידי סוכן LlamaIndex Query Pipeline:

  1. מציינים את המודל שרוצים להשתמש בו:

    model = "gemini-3.5-flash"
    
  2. אופציונלי: מציינים פרמטרים של המודל:

    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,
    }
    
  3. יוצרים LlamaIndexQueryPipelineAgent באמצעות הגדרות המודל הבאות:

    from vertexai.preview import reasoning_engines
    
    agent = reasoning_engines.LlamaIndexQueryPipelineAgent(
        model=model,                # Required.
        model_kwargs=model_kwargs,  # Optional.
    )
    
  4. אם אתם מריצים בסביבה אינטראקטיבית (כמו הטרמינל או נוטבוק של 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.
):

במאמר שילובים זמינים של מודלים גדולים של שפה (LLM) מפורטת רשימה של מודלים לשיחה שנתמכים ב-LlamaIndexQueryPipeline והיכולות שלהם. כל מודל צ'אט משתמש בקבוצה משלו של ערכים נתמכים לפרמטרים model= ו-model_kwargs=.

Google GenAI

ה-AI הגנרטיבי של Google מותקן כברירת מחדל כשמגדירים את הסביבה, והוא נמצא בשימוש אוטומטי ב-LlamaIndexQueryPipelineAgent כשמשמיטים את model_builder.

from vertexai.preview import reasoning_engines

agent = reasoning_engines.LlamaIndexQueryPipelineAgent(
    model=model,                # Required.
    model_kwargs=model_kwargs,  # Optional.
)

Anthropic

  1. פועלים לפי המסמכים של Anthropic כדי להגדיר חשבון ולהתקין את חבילת llama-index-llms-anthropic.

  2. מגדירים את model_builder כדי להחזיר את המודל Anthropic:

    def model_builder(*, model_name: str, model_kwargs = None, **kwargs):
        from llama_index.llms.anthropic import Anthropic
    
        return Anthropic(model=model_name, **model_kwargs)
    
  3. שימוש במודל Anthropic ב-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

אפשר להשתמש ב-OpenAILike עם ChatCompletions API של Gemini.

  1. פועלים לפי ההוראות בתיעוד של OpenAILike כדי להתקין את החבילה:

    pip install llama-index-llms-openai-like
    
  2. הגדרת model_builder שמחזירה את המודל OpenAILike:

    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,
        )
    
  3. שימוש במודל ב-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.
        },
    )
    

הגדרה ושימוש בכלי לאחזור מידע

אחרי שמגדירים את המודל, מגדירים את מנגנון האחזור שהמודל משתמש בו כדי להסיק מסקנות. אפשר לבנות רכיב מאחזר על בסיס אינדקסים, אבל אפשר גם להגדיר אותו באופן מקיף. מומלץ לבדוק את כלי האחזור באופן מקומי.

  1. מגדירים מאחזר שמחזיר מסמכים רלוונטיים וציוני דמיון:

    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()
    
  2. בודקים את מאחזר המידע:

    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
      )
    ]
    
  3. כדי להשתמש בכלי לאחזור מידע בתוך 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.
    )
    
  4. כדי לבדוק את הסוכן באופן מקומי, מריצים שאילתות בדיקה:

    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'}
    ]
    

הגדרה ושימוש בסינתזת תשובות

אחרי שמגדירים את המודל ואת כלי האחזור, מגדירים את response-synthesizer שיוצר תשובה מ-LLM באמצעות שאילתת משתמש וקבוצה נתונה של מקטעי טקסט. אפשר להשתמש ב-get_response_synthesizer כברירת מחדל או להגדיר את מצב התגובה.

  1. מגדירים סינתזת תשובות שמחזירה את התשובה:

    def response_synthesizer_builder(model, response_synthesizer_kwargs=None):
        from llama_index.core.response_synthesizers import SimpleSummarize
    
        return SimpleSummarize(llm=model)
    
  2. בודקים את הפונקציה:

    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."
    
  3. כדי להשתמש בכלי לסינתזת תשובות בתוך 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.
    )
    
  4. בודקים את צינור השאילתות המלא של 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 יוצרת שרשרת רציפה או גרף אציקלי מכוון (DAG) באמצעות Query Pipeline.

יכול להיות שתרצו להתאים אישית את התזמור אם אתם מתכוונים לבצע אחת מהפעולות הבאות:

  • מטמיעים סוכן שמרחיב את צינור ה-RAG (למשל, הרחבה של מודול קיים של Prompt, ‏ Model, ‏ Retriever או Response Synthesizer ל-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.

  1. הגדרת מעבד פוסט:

    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,
    )
    
  2. שליחת שאילתה לסוכן:

    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.

  1. מגדירים פונקציה לדוגמה שמחזירה שער חליפין:

    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()
    
  2. יצירת סוכן 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,
    )
    
  3. שליחת שאילתה לסוכן:

    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
    }
    

המאמרים הבאים

מדריך

במאמר הזה מוסבר על חמש דרכים לפריסת סוכן ב-Agent Platform Runtime, בהתאם לצרכי הפיתוח שלכם.

מדריך

שימוש בסוכן LlamaIndex Query Pipeline עם Agent Platform Runtime.

מדריך

יצירה ופריסה של סוכן בסיסי ושימוש בשירות ההערכה של AI גנרטיבי כדי להעריך את הסוכן

פתרון בעיות

איך פותרים שגיאות נפוצות כשיוצרים סוכנים מותאמים אישית

Resource

מקורות מידע ותמיכה ב-Google Agent Platform