Agents are the thinking component of an AI application: they parse user input, reason about it, potentially call external tools, and generate intelligent responses. In Galadriel, an Agent does all of that and more—it can be customized with different personalities, tools, and memory capabilities, and orchestrated via a runtime so it can operate continuously.

What Is a Galadriel Agent?

It’s an entire AI system that includes:

  1. Agent Interface (e.g., ToolCallingAgent, CodeAgent, or a custom interface you build),
  2. Tools it can call (e.g., a web search tool, a database query tool),
  3. Memory for context,
  4. Input/Output Clients that send user queries and receive responses,
  5. A Runtime that orchestrates continuous execution, communication and state persistence.

You can picture an Agent as follows:


What is autonomy?

Autonomy refers to how many decisions the Agent makes on its own to complete a task. This can range from simply choosing one of two routes (low autonomy) to a full multi-step, looped approach (high autonomy):

Agency LevelDescriptionExample Pattern
★☆☆ (Low)LLM output is used for simple decisions (like routing).if llm_decision(): path_a() else: path_b()
★★☆ (Medium)LLM decides which tool/function to call and its arguments.tool_name, args = llm_parse_output(); tool_name(args)
★★★ (High)LLM controls the entire multi-step loop and orchestrates calls.while llm_should_continue(): execute_next_step()

Galadriel empowers highly autonomous agents. Its Runtime ensures agents can operate continuously, while the Agent Interface acts as the agent’s “brain,” reasoning through a multi-step loop driven by LLM output and strategically using available tools. This design enables Galadriel agents to be fully autonomous, capable of running and performing tasks independently, without direct human intervention.

Tools, Loops, and Runtime

  • Tools provide real-world capabilities (e.g., searching the web, querying databases, etc.).
  • Loops enable iterative reasoning, via a ReAct-style approach:
    1. Observe the current situation,
    2. Think (“Thought”),
    3. Call a tool if needed (“Action”),
    4. Observe the result (“Observation”),
    5. Decide if another step is needed.
  • The Runtime connects all the dots by continuously feeding user requests to the Agent, capturing outputs, and optionally handling concurrency, logging, or multi-agent orchestration.

The Agent Interface

The Agent Interface is composed of the following interface: a class with an execute method that takes in a Message and returns a Message:

from abc import ABC, abstractmethod

class Agent(ABC):
    @abstractmethod
    async def execute(self, request: Message) -> Message:
        raise RuntimeError("Function not implemented")

Where Message is defined as:

class Message(BaseModel):
    content: str
    conversation_id: Optional[str] = None
    type: Optional[str] = None
    additional_kwargs: Optional[Dict] = None

Note: This is the bare-bones of an Agent Interface. However, when we refer to Agents, we mean the entire system which also includes tools, memory, runtime and clients.


Built-In Agent Interfaces

Galadriel provides two main interfaces you can use out of the box:

  1. ToolCallingAgent – Focuses on calling external functions (tools) to solve tasks.
  2. CodeAgent – Lets the LLM “write” Python code that is then executed, offering a powerful and flexible approach for certain use-cases.

You can also create custom agents for specific personalities or domain knowledge. For example, CharacterAgent shows how to craft an agent with a distinct persona (like a Discord bot with a particular style).


Sample Usage

Below is a quick demonstration of how to set up a CodeAgent with a web search tool, run it via the runtime, and communicate with a simple input/output client.

import asyncio
from galadriel import AgentRuntime, CodeAgent
from galadriel.clients import SimpleMessageClient
from galadriel.core_agent import LiteLLMModel, DuckDuckGoSearchTool

model = LiteLLMModel(model_id="gpt-4o", api_key="<ADD YOUR OPENAI KEY HERE>")

agent = CodeAgent(
    model=model,
    tools=[DuckDuckGoSearchTool()]
)

# Simple input/output client:
client = SimpleMessageClient("Explain the concept of blockchain")

# The runtime orchestrates continuous execution of the agent.
runtime = AgentRuntime(
    agent=agent,
    inputs=[client],
    outputs=[client],
)
asyncio.run(runtime.run())
  1. CodeAgent can “write” code to perform tasks.
  2. DuckDuckGoSearchTool provides a web search capability.
  3. SimpleMessageClient supplies the user’s query and will receive the final answer.
  4. AgentRuntime ties it all together, feeding data between the user, agent, and output.

Multi-Agents

Multi-agent systems enable several agents to work together on a task, often yielding better performance than a single monolithic agent. By dividing responsibilities among agents, you can achieve efficient specialization. For example, rather than filling the memory of a code-generating agent with the details of every webpage visited by a web search agent, you can separate these concerns by delegating tasks to specialized agents.

Key Concepts

  • Specialization: Each agent focuses on a specific sub-task, leveraging unique tool sets and memory.
  • Delegation: A manager agent can direct tasks to worker agents optimized for those tasks.

Implementation Example

import asyncio
from galadriel import AgentRuntime, CodeAgent
from galadriel.clients import SimpleMessageClient
from galadriel.core_agent import LiteLLMModel, DuckDuckGoSearchTool

model = LiteLLMModel(model_id="gpt-4o", api_key="<ADD YOUR OPENAI KEY HERE>")

managed_web_agent = CodeAgent(
    tools=[DuckDuckGoSearchTool()],
    model=model,
    name="web_search",
    description="Runs web searches for you. Give it your query as an argument.",
)

manager_agent = CodeAgent(tools=[], model=model, managed_agents=[managed_web_agent])

client = SimpleMessageClient("What's the most recent of Daige on X (twitter)?")

# Set up the runtime
runtime = AgentRuntime(
    agent=manager_agent,
    inputs=[client],
    outputs=[client],
)

# Run the agent
asyncio.run(runtime.run())

This example demonstrates a manager-worker pattern using multiple agents:

  • Manager Agent: A CodeAgent that receives user queries and coordinates with specialized worker agents.
  • Web Search Agent: A worker agent equipped with DuckDuckGoSearchTool to handle web search requests.
  • SimpleMessageClient: Implements input/output interfaces to send queries and display results.
  • AgentRuntime: Connects the manager and worker agents with the client, orchestrating continuous execution.

Conclusion

Agents in Galadriel empower you to build autonomous AI systems that:

  • Utilize state-of-the-art LLM Models.
  • Integrate seamlessly with Tools.
  • Maintain meaningful Memory.
  • Run continuously, responding to user requests in real time when combined with an AgentRuntime.

Next Steps

  • Learn how to integrate your agent into the AgentRuntime.
  • Examples - Check out our repository for real-world sample projects.