> ## Documentation Index
> Fetch the complete documentation index at: https://docs.symbolica.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agentic Functions

> Use agentic to execute any function with an agent.

export const TypeScript = props => {
  const getLang = () => {
    let lang = null;
    try {
      const raw = window.localStorage.getItem('code');
      lang = raw;
      try {
        lang = JSON.parse(raw);
      } catch (_err) {}
    } catch (_err) {}
    return (lang || '').toLowerCase();
  };
  const lang = getLang();
  return <span class="when-lang when-typescript" style={{
    display: lang.includes('typescript') ? 'inline' : 'none'
  }}>{props.children}</span>;
};

export const Python = props => {
  let lang = null;
  try {
    const raw = window.localStorage.getItem('code');
    lang = raw;
    try {
      lang = JSON.parse(raw);
    } catch (_err) {}
  } catch (_err) {}
  lang = (lang || 'Python').toLowerCase();
  if (!['python', 'typescript'].some(l => lang.includes(l))) {
    lang = 'python';
  }
  return <span class="when-lang when-python" style={{
    display: lang.includes('python') ? 'inline' : 'none'
  }}>{props.children}</span>;
};

<Note>
  **This is detailed usage documentation.** New to the Agentica SDK? Start with the [Quickstart](/quickstart) or learn [when to use agentic functions vs agents](/concepts/agentic-vs-agents).
</Note>

## Using agentic

**Agentic functions** are stateless, decorator‑based functions implemented by the model; each call is independent.
The de facto way to implement an agentic function is via the `@agentic` decorator.

### When to use agentic functions

Agentic functions work best for completing simple, well-defined tasks that **don't benefit from maintaining context** across multiple operations.

For longer-running, multi-task, contextual problem solving, see [Agents](/concepts/agent).

## The basics

The Agentica SDK's `agentic` decorator enables you to **turn regular Python or TypeScript functions into agent-backed functions**. Define a function with a descriptive prompt or docstring and simply call it like any other function.

<Tip>
  Function bodies in Python should contain a descriptive doc-string, but otherwise be empty (body contains `...`). See [here](/guides/prompting#writing-effective-prompts) for best practices on writing effective doc-strings.
</Tip>

<CodeGroup>
  ```python Python wrap theme={null}
  from agentica import agentic

  @agentic()
  async def rhymes(word_a: str, word_b: str) -> bool:
      """
      Returns whether `word_a` rhymes with `word_b`.
      """
      ...
  ```

  ```typescript TypeScript wrap theme={null}
  import { agentic } from '@symbolica/agentica';

  async function rhymes(wordA: string, wordB: string): Promise<boolean> {
    return await agentic(
      `Returns whether wordA rhymes with wordB`,
      { wordA, wordB }
    );
  }
  ```
</CodeGroup>

See the full API in the references: [Python](/references/python/agentic) | [TypeScript](/references/ts/agentic).

## Use your tools and types

Expose the full programmatic power of an SDK or API. No MCP server is required. Simply pass it into your agentic functions `scope`.

You can also **expose existing remote or local MCP tools** by passing an MCP configuration path. See [here](/concepts/unmcp) for more information.

<Info>
  **Prerequisites**:

  * **Python**: run `pip install art` or `uv add art`
  * **TypeScript**: run `npm install figlet` (or use `pnpm`, `bun`)
</Info>

<span id="art" />

<CodeGroup>
  ```python Python wrap theme={null}
  from agentica.logging import set_default_agent_listener
  set_default_agent_listener(None)

  from agentica import agentic
  from art import text2art

  @agentic(text2art)
  async def greet(name: str) -> str:
      """
      Use the provided function to create a fancy greeting.
      """
      ...

  print(await greet("agentica"))
  ```

  ```typescript TypeScript wrap theme={null}
  import { agentic } from '@symbolica/agentica';
  import figlet from 'figlet';

  async function greet(name: string): Promise<string> {
    return await agentic(
      `Use the provided function to create a fancy greeting`,
      { figletText: figlet.text, name },
    );
  }

  console.log(await greet("agentica"));
  ```
</CodeGroup>

<div class="compact">
  ```
      __  __     ____           ___                    __  _
     / / / /__  / / /___       /   | ____ ____  ____  / /_(_)________ _
    / /_/ / _ \/ / / __ \     / /| |/ __ `/ _ \/ __ \/ __/ / ___/ __ `/
   / __  /  __/ / / /_/ /    / ___ / /_/ /  __/ / / / /_/ / /__/ /_/ /
  /_/ /_/\___/_/_/\____( )  /_/  |_\__, /\___/_/ /_/\__/_/\___/\__,_/
                       |/         /____/
  ```
</div>

<Warning>
  * Objects passed to `scope` or as arguments are presented **without** private methods or field names (fields with a leading `_`).
  * Async functions in `scope` are exposed to the REPL as synchronous functions returning `Future[T]`. The REPL includes a top-level event loop, so agents can `await` these futures directly and use standard patterns like `asyncio.gather()`.
</Warning>

## Streaming

Stream responses as they are being generated.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from agentica import agentic
  from agentica.logging.loggers import StreamLogger


  @agentic(model='openai/gpt-5.2')
  async def word_counter(corpus: str) -> int:
      """Returns the number of words in the corpus."""
      ...

  stream = StreamLogger()
  with stream:
      res = asyncio.create_task(
        word_counter("True! -- nervous -- very, very dreadfully nervous I had been and am; but why will you say that I am mad? The disease had sharpened my senses -- not destroyed -- not dulled them. Above all was the sense of hearing acute. I heard all things in the heaven and in the earth. I heard many things in hell. How, then, am I mad? Hearken! and observe how healthily -- how calmly I can tell you the whole story.")
      )

  async for chunk in stream:
      if chunk.role == 'agent':
          print(chunk, end="", flush=True)
  print()

  print(await res)
  ```

  ```typescript TypeScript theme={null}
  import { agentic } from '@symbolica/agentica';

  async function summarize(text: string): Promise<string> {
    const result = await agentic<string>(
      `Summarize the following text in two sentences.`,
      { text },
      { listener: (iid, chunk) => process.stdout.write(chunk.content) }
    );

    return result;
  }

  const summary = await summarize(
    'True! -- nervous -- very, very dreadfully nervous I had been and am; but why will you say that I am mad? The disease had sharpened my senses -- not destroyed -- not dulled them. Above all was the sense of hearing acute. I heard all things in the heaven and in the earth. I heard many things in hell. How, then, am I mad? Hearken! and observe how healthily -- how calmly I can tell you the whole story.'
  );
  console.log('\nFinal summary:', summary);
  ```
</CodeGroup>

## Using MCP

<CodeGroup>
  ```python Python wrap theme={null}
  from dataclasses import dataclass

  from agentica import agentic

  @dataclass
  class Report:
      name: str
      blurb: str

  @agentic(mcp="./my-mcp.json")
  async def run_report(company: str) -> Report:
      """
      Create a brief company report for the given company name.

      Returns a report with:
      - name: The official company name
      - blurb: A 1-2 sentence description of the company's main business focus
      """
      ...
  ```

  ```typescript TypeScript wrap theme={null}
  // MCP support via unMCP coming soon for TypeScript
  ```
</CodeGroup>

## Advanced

You can expose custom exceptions in scope so they can be raised from within execution (see [here](/guides/agent-errors), including information on logging, retries, rate-limiting and prefix caching). For more examples, see [Examples](/guides/examples).
