> For the complete documentation index, see [llms.txt](https://axar-ai.gitbook.io/axar/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://axar-ai.gitbook.io/axar/basics/agent.md).

# Agent

Agents in AXAR AI are the primary building blocks. They represent a tightly coupled set of tasks. Agents can work independently in a developer-defined workflow or collaborate to build more complex autonomous workflows.

<figure><img src="/files/RklOp57KlYBOEN1OmeIE" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
Conceptually, an agent in AXAR AI is a container for:

* **LLM model:** The LLM the agent uses.
* **System prompts:** Instructions to guide the LLM.
* **Structured I/O:** Data structures defining the expected input and output of the agent.
* **Dependencies:** External objects passed to the agent, available across prompts, tools, and validators within the agent.
* **Tools:** Methods the agent can call to gather information or perform actions as needed.
  {% endhint %}

### **Creating an agent**

Here’s a simple example of creating an agent in AXAR AI. This agent greets the user by their name.

```typescript
import { model, systemPrompt, Agent } from "@axarai/axar";

// Specify the AI model used by the agent
@model('openai:gpt-4o-mini')
// Provide a system-level prompt to guide the agent's behavior
@systemPrompt(`Greet the user by their name in a friendly tone.`)
export class GreetingAgent extends Agent<string, string> {
  
}

// Instantiate and run the agent
(async () => {
  const response = await new GreetingAgent().run("My name is Alice.");
  console.log(response); // Output: "Hello, Alice! It's great to meet you! How are you doing today?"
})();
```

#### What just happened?

{% stepper %}
{% step %}
**Model**

The `@model` decorator sets the AI model to use. Here, it’s using `openai:gpt-4o-mini`.
{% endstep %}

{% step %}
**Prompt**

The `@systemPrompt` decorator defines the agent’s behavior. In this case, the agent greets users by their name in a friendly way.
{% endstep %}

{% step %}
**Agent**

The `GreetingAgent` class extends `Agent`, taking a `string` as input and returning a `string` as output.
{% endstep %}

{% step %}
**Run**

The agent runs with the input `"My name is Alice."` and generates a friendly greeting based on the system prompt.
{% endstep %}
{% endstepper %}

### Dynamic system prompts <a href="#runs-vs-conversations" id="runs-vs-conversations"></a>

In the previous example, the `run()` method assumes the user's name is included in the input. But what if the input doesn’t contain the name?

We can handle this by modifying the agent to accept the user's name as a parameter in its `constructor()`. We can then generate a dynamic system prompt using the provided name. This is done by combining the `@systemPrompt` annotation with an instance method inside the agent class.

With this setup, the username is passed during instantiation every time and also doesn't need to be included in every `run()` call.

{% hint style="success" %}
Dynamic system prompts let us change an agent's behavior in runtime based on external context. We can pass that context to the agent through its `constructor()` as a dependency, or the method defining the dynamic prompt can fetch the external context directly.
{% endhint %}

Here’s how it works:

```typescript
import { model, systemPrompt, Agent } from "@axarai/axar";

@model('openai:gpt-4o-mini')
@systemPrompt(`
  Greet the user by their name in a friendly tone.
`)
export class GreetingAgent extends Agent<string, string> {
  constructor(private userName: string) {
    super();
  }

  // A dynamic system prompt generated in runtime
  @systemPrompt()
  getUserName(): string {
    return `User's name is: ${this.userName}!`;
  }
}

// Instantiate and run the agent
(async () => {
  const response = await new GreetingAgent('Alice').run('Greet me.');
  console.log(response); // Output: "Hello, Alice! 😊 It's great to see you! How are you doing today?"
})();
```

{% hint style="info" %}
The above example also shows how to inject external dependencies to an agent. Anything passed into the agent's `constructor()` can be accessed within the agent throughout its lifetime.
{% endhint %}

### Structured I/O

So far, we’ve seen how to pass a string to an agent and get a string response. However, in many cases, we might want our agent to handle structured input and output for better control, validation, and clarity. AXAR makes this possible with schemas, allowing us to define structured data formats for both input and output.

{% hint style="success" %}
With structured I/O, we can:

* Validate input data before passing it to the agent.
* Ensure the output conforms to a predefined structure and validation rules.
* Handle complex use cases with multiple fields and specific data types.
  {% endhint %}

The following example demonstrates a `GreetingAgent` that takes structured input, including the user's name, mood, day of the week, and language preference. The agent then generates structured output with a greeting, a response to the user's mood, and an optional weekend message.

```typescript
import {
  model,
  systemPrompt,
  Agent,
  schema,
  property,
  output,
  input,
  optional,
} from '@axarai/axar';

@schema()
class GreetingAgentRequest {
  @property("User's full name")
  userName!: string;

  @property("User's current mood")
  userMood!: 'happy' | 'neutral' | 'sad';

  @property('Day of the week')
  dayOfWeek!: string;

  @property("User's language preference")
  language!: string;
}

@schema()
class GreetingAgentResponse {
  @property("A greeting message to cater to the user's mood")
  greeting!: string;

  @property("A line acknowledging the user's mood")
  moodResponse!: string;

  @property("A personalized message only if it's the weekend")
  @optional()
  weekendMessage?: string;
}


@model('openai:gpt-4o-mini')
@systemPrompt(`Greet the user by their name in a friendly tone in their preferred language.`)
@input(GreetingAgentRequest)
@output(GreetingAgentResponse)
export class GreetingAgent extends Agent<
  GreetingAgentRequest,
  GreetingAgentResponse
> {}

// Instantiate and run the agent
(async () => {
  const response = await new GreetingAgent().run({
    userName: 'Alice',
    userMood: 'happy',
    dayOfWeek: 'Saturday',
    language: 'English',
  });
  console.log(response);
})();

```

### **Running agents**

AXAR AI provides two methods for running agents:

#### agent.run()

The `run()` method is an asynchronous function that processes the input and returns the complete output in a single response.

```typescript
const greetingAgent = new GreetingAgent();
const response = await greetingAgent.run(input);
console.log(response);
```

#### agent.stream()

The `stream()` method provides a streaming interface that yields partial results as they become available, useful for real-time UI updates or processing long responses.

```typescript
const greetingAgent = new GreetingAgent();
const { stream } = await agent.stream(input);
for await (const chunk of stream) {
    // Process each chunk as it arrives
    console.log(chunk);
}
```

Both methods support the full range of AXAR AI features including:

* Input/output schema validation
* Tool execution
* Telemetry and monitoring
* Error handling
* Model configuration
