Skip to main content
This quickstart will guide you through building a simple program using Agentica. We’ll build a simple note-taking assistant that can manage and search your notes.
1

Installation

Setup your project in a new directory called note-assistant.
2

Your First Magic Function

Write your first AI primitive using Agentica.
3

Adding Tools

Start sharing your code with the AI over RPC.
4

Putting it together

Bundle up your first AI application.
5

Using Agents

How you could extend your application using agents.

Installation

We’ll setup our project in a new directory called note-assistant.
Get your API key & wheel/package URLs from the login page.
  • Python+uv
  • Python+pip
  • TypeScript+Node
  • TypeScript+Bun
Prerequisites:
  • Python version 3.12.*
  • uv package manager
  • Your Agentica API key from the login page
Setup your virtual environment
uv init note-assistant --python '==3.12.*'
cd note-assistant
uv sync
source .venv/bin/activate
uv add 'https://agentica.symbolica.ai/api/pip/...' # get your wheel from the login page
Export your API key under the AGENTICA_API_KEY environment variable.
export AGENTICA_API_KEY="your-key-here"
Then, start editing your main.py file.

Your First Magic Function

Our note assistant will need the ability to search notes. Let’s start by adding a magic function which is capable of summarizing the content of a note.
  • Python
  • TypeScript
main.py
from agentica import magic

@magic()
def summarize_note(note: str) -> str:
    """
    Summarize the content of the note in 5 words or fewer.
    """
    ...

result = summarize_note("Jellyfish have been around for more than 500 million years, making them one of the oldest living creatures on Earth.")
print(result)  # e.g. "Ancient existence of jellyfish"
Now, run your script:
uv run main.py
What just happened?
  • The @magic decorator turned a function into an AI-powered function which can be called like a normal function.
  • The arguments to the magic function became available to the AI per call.
  • The docstring in the function body told the AI what it should do.
  • The function body was otherwise empty, since the AI dynamically generates the return value per call.

Adding Tools

Create a magic function which can search for a specific note in a list of notes.
  • Python
  • TypeScript
Say our note-store is a list of strings. Our intelligent magic function will get a query for a note and return the index of the most relevant note in the list.Let’s first define a helper resource (in this case, a function) which will show the notes with their indices.
main.py
def print_list_with_indices(notes: list[str]) -> None:
    for i, note in enumerate(notes):
        print(f"[{i}]: {note}")
We can give the magic function access to this resource by passing it as an argument to the @magic decorator.
main.py
@magic(print_list_with_indices)
def search_notes(notes: list[str], query: str) -> int:
    """
    Search the notes for the note matching the query.
    Return the note index in the list.
    """
    ...
Now let’s use it to search for a note.
main.py
notes = [
  "Jellyfish have been around for more than 500 million years, making them one of the oldest living creatures on Earth.",
  "The mollusc usually has an egg stage and an adult stage. Many aquatic species also have a larval stage.",
  "Cuttlefish can change their skin color and texture in less than a second to blend into their surroundings."
]
result = search_notes(notes, "What did I write about the life cycle of mollusca?")
print(notes[result])  # note at index `1`
In this example, print_list_with_indices was a function that might have been helpful for the AI to accurately implement the magic function. In general, you can pass in any function, class, object or other Python value that you want the AI to use or have access to.

Putting it together

We have summarization, and searching for notes. To avoid overwhelming our AI, we can have it search through summarized notes instead of the raw notes. Let’s also cache the summarized notes so we don’t re-summarize them each time.
  • Python
  • TypeScript
main.py
from functools import cache 

# Redefine `summarize_note` with cached responses.
@cache
@magic()
def summarize_note(note: str) -> str:
  """
  Summarize the content of the note in 5 words or fewer.
  """
  ...

# Our intelligent note-retrieval is powered by two magic functions.
def retrieve_note(notes: list[str], query: str) -> str:
  short_notes = [summarize_note(note) for note in notes]
  result = search_notes(short_notes, query)
  return notes[result]
In this example, we orchestrated two AIs to complete single, simple tasks to power behaviors in our program that required an amount of intelligence.

Using Agents

Now we could extend our application to include a chat-with-notes feature. This requires a stateful context of that potentially includes retrieving many related notes.
  • Python
  • TypeScript
main.py
from agentica import spawn

# Create an agent that always has access to our retrieve_note tool
agent = await spawn(
  premise="You are a helpful assistant that can answer questions about notes.",
  scope={'retrieve_note': retrieve_note},
)

# First question: provide the notes on the first call
answer1: str = await agent.call(
  str,
  "What did I write about the life cycle of mollusca?",
  notes=notes,
)

# Follow‑up: agent remembers context, no need to pass notes again
answer2: str = await agent.call(
  None,
  "Extend that note to include some examples",
  notes=notes,
)

print("Answer 1:", answer1)
print("Answer 2:", notes[answer2])
Now it’s your turn to turn this example into a real chat feature. Build a UI on top of it or integrate it into an existing application!

What’s Next?