Skip to content

Autonomous Agent

Autonomous Agents

Autonomous agents represent a significant advancement in AI system design, combining the power of language models with the ability to perform tasks autonomously. This tutorial will guide you through building an autonomous agent using Synalinks, capable of processing mathematical queries and returning numerical answers.

Understanding the Foundation

Autonomous agents address a fundamental limitation of traditional systems by enabling them to perform tasks without constant human intervention. While language models excel at generating coherent text, they often require additional tools and logic to perform specific tasks autonomously. Autonomous agents bridge this gap by dynamically processing information and executing tasks based on predefined tools.

The architecture of an autonomous agent follows several core stages:

  • The input stage captures the user's query or command.
  • The processing stage uses predefined tools and logic to process the input and generate a response.
  • The output stage returns the result to the user.
graph LR
    A[Query] --> B[Agent]
    B --> C{Need Tool?}
    C -->|Yes| D[Tool Call]
    D --> E[Tool Result]
    E --> B
    C -->|No| F[Final Answer]

Synalinks streamlines this complex process through its modular architecture, allowing you to compose components with precision while maintaining flexibility for different use cases.

Creating an Autonomous Agent

Define tools as async functions with docstrings, then wrap them with synalinks.Tool:

@synalinks.utils.register_synalinks_serializable()
async def calculate(expression: str):
    """Calculate the result of a mathematical expression."""
    result = eval(expression)
    return {"result": result, "log": "Successfully executed"}

tools = [synalinks.Tool(calculate)]

Create the agent with FunctionCallingAgent in autonomous mode:

inputs = synalinks.Input(data_model=Query)
outputs = await synalinks.FunctionCallingAgent(
    data_model=NumericalFinalAnswer,
    tools=tools,
    language_model=language_model,
    max_iterations=5,
    return_inputs_with_trajectory=True,
    autonomous=True,  # Agent runs until completion
)(inputs)

Key Takeaways

  • Autonomous Task Execution: Autonomous agents solve the fundamental problem of performing tasks without constant human intervention.
  • Synalinks Modular Implementation: The framework simplifies the development of autonomous agents through composable components like FunctionCallingAgent.
  • Explicit Data Model Contracts: Using structured Query and output models ensures type safety and predictable behavior.
  • Tool Integration: Integrate tools like the calculate function into your autonomous agent for processing specific types of queries.
  • Dynamic Processing: Autonomous agents dynamically process information and execute tasks based on predefined tools and logic.

Program Visualization

math_agent

API References

calculate(expression) async

Calculate the result of a mathematical expression.

Parameters:

Name Type Description Default
expression str

The mathematical expression to calculate, such as '2 + 2'. The expression can contain numbers, operators (+, -, *, /), parentheses, and spaces.

required
Source code in examples/10_autonomous_agent.py
@synalinks.utils.register_synalinks_serializable()
async def calculate(expression: str):
    """Calculate the result of a mathematical expression.

    Args:
        expression (str): The mathematical expression to calculate, such as
            '2 + 2'. The expression can contain numbers, operators (+, -, *, /),
            parentheses, and spaces.
    """
    if not all(char in "0123456789+-*/(). " for char in expression):
        return {
            "result": None,
            "log": (
                "Error: invalid characters in expression. "
                "The expression can only contain numbers, operators (+, -, *, /),"
                " parentheses, and spaces NOT letters."
            ),
        }
    try:
        # Evaluate the mathematical expression safely
        result = round(float(eval(expression, {"__builtins__": None}, {})), 2)
        return {
            "result": result,
            "log": "Successfully executed",
        }
    except Exception as e:
        return {
            "result": None,
            "log": f"Error: {e}",
        }