Elysia Documentation

repository·main·Indexed 23 days ago

https://github.com/weaviate/elysia

Elysia (elysia-ai) is an open-source agentic decision tree framework for searching data, designed to build agents and tools tailored to specific use cases. It uses Weaviate as the default retrieval tool for RAG (Retrieval-Augmented Generation) and custom tool workflows. The platform allows developers to define a Tree, create custom tools via the Tool class or @tool decorator, and manage agent behavior through style, identity, and end-goal parameters. It includes a web application for configuration and supports persisting tree states via JSON or Weaviate.

Tokens
24.1K
Snippets
57
Records
104
Agent score
83%

What's inside Elysia

  1. What is Elysia?

    main
    Elysia is an agentic platform that uses a decision tree to dynamically select and use tools based on environment and context. A decision agent evaluates the input and determines which tools (either pre-built for Weaviate or custom-defined) are required to fulfill a request.
  2. Control tool outputs using async generators

    main

    Elysia tools can return or yield objects to the decision tree.

    • Strings: When a tool yields or returns a string, it is treated as a direct response to the user (the agent's speech).
    • Other Types (Result objects): Any other type (like a dictionary or list) is treated as a Result object and added to the tree's environment.
    • Customizing Environment Objects: Yielding a dictionary allows you to control the keys added to the environment. Yielding a list of dictionaries adds multiple objects to the Result.

    You can use an async generator to yield multiple items (e.g., a data dictionary for the environment and a string for the user response).

    @tool
    async def calculate_two_numbers(x: int, y: int):
        """
        This function calculates the sum, product, and difference of two numbers.
        """
        yield {
            "sum": x + y,
            "product": x * y,
            "difference": x - y,
        }
        yield f"I just performed some calculations on {x} and {y}."
  3. How the Elysia Decision Agent works

    main

    The Decision Agent (run from the base_model) manages the execution of the decision tree by selecting tools or nodes for each step.

    Core Components:

    • Branches: Subcategories used to organize tools when many are available.
    • Tools: Specific actions that perform tasks and add information to the Elysia environment.
    • Environment: A shared state used by both the decision agent and tools to track retrieved or collected data.

    Decision Agent Inputs:

    • Tree Data: The current state of the process (see Tree Data).
    • Tool Descriptions: Definitions of available actions.
    • Branch Instructions: Guidance on how to choose between available tools within a specific branch.
    • Metadata: Information including the current loop count and available future tools within a branch.

    Decision Agent Outputs:

    • The selected Tool to use.
    • Inputs for the tool (if required).
    • A flag indicating if the tree should end after this tool call (conditional on tool capability).
    • A message update for the user.
    • A flag indicating if the task is impossible based on current information.
  4. Understanding Tree Data and the Atlas

    main

    Tree Data is the central state object used by the decision agent and tools to interact with Elysia. It allows tools to access the current state and update it for subsequent iterations.

    Key elements within Tree Data include:

    • User Prompt: The original request.
    • Conversation History: The record of interactions.
    • Atlas: An alias representing the agent's style, description, and end goal that the agent must adhere to.
    • Environment: A collection of all data retrieved or collected during tool evaluations.
    • Task History: A record of completed tasks and custom formatted text from tools.
    • Error Logs: Manually caught and yielded errors from tool evaluations, allowing the agent to learn from and react to previous failures.

    For a full technical breakdown, refer to the TreeData class documentation.

  5. Understand how Result and Update objects yield payloads

    main

    When an Elysia tool or decision agent yields a Result or Update object, they behave differently regarding the Elysia Environment:

    1. Result: Automatically adds all objects and metadata contained within the Result to the Elysia Environment for use in subsequent steps of the decision tree. It also provides a .to_frontend() method which parses the content into a format suitable for sending to a connected frontend.
    2. Update: Yields a payload to the frontend outside of the decision tree, but does not add any objects to the environment.

    Use Result when you want the data to persist and be accessible to later nodes in your decision tree. Use Update when you only want to send information to the user interface without affecting the internal state of the agent.

  6. Understanding the Elysia Environment

    main

    The Environment is a persistent object used across all actions, tools, and decisions within an Elysia decision tree. It acts as a global store for information (like retrieved objects) that needs to be accessible across different tools and actions.

    Data Structure

    The environment is a nested dictionary structured as follows:

    1. tool_name (str): The name of the tool that added the data.
    2. name (str): A unique subkey associated with the specific result (e.g., a collection name).
    3. List of Results: A list where each element is a dictionary containing:
      • objects (list[dict]): The actual data retrieved.
      • metadata (dict): Metadata shared among all objects in that specific result entry.

    Automatic Assignment

    When a Tool yields a Result object, Elysia automatically calls .add() on the environment. The Result.to_json() method is used to populate the objects and metadata fields under environment[tool_name][name]. If the tool_name and name already exist, the new result is appended to the existing list.

  7. Understand the output of the Elysia decision tree

    main

    When running the tree function, the output provides both the conversational flow and the raw data retrieved from Weaviate.

    Response String

    The response variable is a single string that concatenates all assistant responses and decision-making outputs. For example:

    # Example output
    'I will now search for a science question... Here\'s a science question for you: "This organ removes excess glucose..."'

    Retrieved Objects

    The objects variable is a list of lists containing the dictionaries representing the objects found in Weaviate. Each dictionary includes the object's properties and metadata (like uuid and collection_name).

    Example structure:

    [
        [
            {
                'category': 'SCIENCE',
                'question': 'This organ removes excess glucose from the blood & stores it as glycogen',
                'answer': 'Liver',
                'uuid': 'b28ca48a-9a8d-417c-9ed1-e487132740ed',
                'collection_name': 'JeopardyQuestion',
                'chunk_spans': [],
                '_REF_ID': 'query_JeopardyQuestion_0_0'
            }
        ]
    ]
  8. Map custom object fields to frontend expectations using mapping

    main

    If your data objects use different field names than what an Elysia-aware frontend expects, use the mapping parameter in the Result class. This allows you to translate your internal keys to the keys the frontend uses for rendering.

    For example, if your object uses document_header but the frontend expects title, define the mapping accordingly.

  9. Return results and status updates from tools

    main

    Tools can interact with the decision tree and frontend by yield-ing specific objects:

    Status Updates

    Yield any class inheriting from Update to send messages to the frontend/progress bar. A Status message is a common implementation:

    yield Status("Processing data...")

    Adding Results to Environment

    Yield any class inheriting from Result to add objects to the tree's environment. This allows the LLM to 'see' the output and make subsequent decisions.

    Result arguments:

    • objects: A list of dictionaries containing your data.
    • metadata: A dictionary for global/object-specific metadata.
    • payload_type: A string describing the object type (e.g., table).
    • mapping: A dictionary mapping frontend-aware fields to your object fields.

    Note: If you manually call tree_data.add() and also yield Result(...) with the same items, you may create duplicates in the environment.

    yield Result(
        objects = [
            {
                "title": "Example Result",
                "content": "This is just an example of a result"
            }
        ]
    )
  10. Understand Weaviate connection priority

    main

    If multiple connection methods are configured simultaneously, Elysia resolves the connection using the following priority order:

    1. Custom Connections (weaviate_is_custom=True)
    2. Local Connections (weaviate_is_local=True)
    3. Cloud Connections (using wcd_url and wcd_api_key)

    It is recommended to use only one method to avoid configuration confusion.

  11. How TreeManager and UserManager work together

    main

    Elysia uses two primary manager classes to handle multi-user environments with multiple decision trees:

    1. TreeManager: Responsible for a single user. It tracks and stores multiple decision trees for that specific user. It holds default configuration options (like style, agent_description, and end_goal) that apply to all trees created within it unless overridden.
    2. UserManager: The top-level orchestrator. It manages multiple users by maintaining a dictionary of user_ids, where each entry contains a dedicated TreeManager and a ClientManager for that user.

    Use UserManager when you need to scale your application to handle many different users, each with their own independent conversation histories and client connections.

  12. Use the Hidden Environment for private data

    main

    The environment.hidden_environment is a dictionary designed to store data that should not be shown to the LLM.

    Unlike the standard environment, you can store any type of Python object here without converting it to a string. This is useful for saving raw retrieval objects or complex metadata that you need to access later in the decision tree but don't want to expose in the LLM's context or the frontend.