Learn to create agents in RΞASON
Agents are an experimental feature in RΞASON. Their API is subject to change.
There are some different definitions people use to define “LLM agents”. This is confusing.
So we propose the following:
An agent is just a LLM that selects which action to take from predefined pool of actions in order to accomplish a certain objective.
Although people don’t think of it like it, we argue that ChatGPT is indeed an agent. (And probably the most popular in the world)
ChatGPT Plus lets users:
How does ChatGPT (the app, not the LLM) knows which action to take?
Because the LLM itself (GPT-4) decides which action to take — just respond to user, create an image using DALL·E, etc.
Its objective could be: “Your goal is to fulfill the user’s need — be that responding the message, creating a new image, web browsing, etc.”
And the actions available for the agent are:
The point here is not to discuss semantics but rather illustrate what RΞASON refers to as “agents”.
LLMs have strong reasoning capabilities and, because of that they are able to decide when to call an action (and which to call) pretty precisely.
For instance, LLMs are bad at math:
LLM failing at math
But if we give access to a “Sum” action that takes two numbers and outputs the sum of them, the LLM correctly calls the action and is able to get the answer:
LLM not failing at math
Let’s establish two definitions:
We’ll be creating a basic math agent that has access to: sum()
, subtract()
, multiply()
and divide()
actions.
To create an agent in RΞASON you’ll need to define its actions and then the agent itself.
Curious about RΞASON design philoshopy?
Our beliefs are:
And here’s their implications in the context of our agents API:
To create an action you need to:
.ts
file under src/actions
;Let’s create the SUM
action we mentioned previously:
Two things to notice:
sum
function in the form of JSDoc;return
something in the end.And that’s it! Pretty simple.
If you never heard of JSDoc before, go here to understand it a bit better.
JSDoc may seem strange & complicated, but what we recommend is the following:
/**
and your IDE will most-likely auto-complete for you.JSDoc autocompletion
To verify you’ve correctly wrote JSDoc, you can hover over the function:
Function & parameters description when you hover
Awesome! We now have a sum
action, however we still need the subtract
, multiply
and divide
actions:
With all four actions created, we now need to create the agent itself.
Before actually creating your first agent, we need to create the required mental model to understand how they work.
Agents mental model
Three important things to notice:
step
is cycle of:
step
the LLM can:
end()
action that the LLM must call when it wants to end;max_step
counter — where the LLM can run for at most n
number of steps.To create an agent in RΞASON:
.ts
file under src/agents
;const actions = []
containing the available actions for the agent;useAgent()
function.Let’s take a look at the MathAgent
:
Let’s break it down:
export const actions = [ ]
with the actions;const agent = await useAgent()
;agent.reason(initialPrompt)
.agent.reason(initialPrompt)
;
agent.reason()
is an async generator that you iterate using for await (const step of agent.reason()) {}
step
, you decide if you want to call agent.stop()
to stop the agent or not. In this case we’re stopping the agent if:
answer
action.Cool! Now we need an entrypoint in order to test our agent.
Let’s create a POST /math
entrypoint:
If we call the POST /math
entrypoint we get:
Response from POST /math
JSON response
A important thing to notice is that there was a lot of data that was streamed even though we only explictly set to stream the final answer in the JSON’s answer
property. Why?
But the cool thing is that if you leave the default streaming agent usage enabled, you can use RΞASON Playground’s chat mode:
RΞASON Playground's chat mode
Since most agents are chat-like, we thought it’d be cool to include a chat interface in the Playground to help test your agents.
For chat mode to work:
POST
request with a input
property in the body. That means your entrypoint needs to read it and pass it to your agent.Another cool thing that chat mode does is: it handles the memory_id
automatically.
But what is memory_id
?
memory_id
Some usecases, like creating a chat-like agent, requires persistance — i.e.: be able to restore previous messages in the chat.
RΞASON offers persistance by default:
useAgent()
a new memory_id
is created;useAgent(memory_id)
again you can pass a memory_id
and that agent will be continue where it left off.You can disable this.
Under the hood RΞASON uses a local SQLite database to store all the information needed. If you go to your project directory, you’ll see a database.sqlite
file.
Let’s test this out:
And in our agent:
Let’s try it on the Playground:
Using `memory_id`
In the demo above, we didn’t use chat mode just to illutrate how memory_id
works under the hood. However, as long as your entrypoint is expecting a memory_id
property inside the request’s body, chat mode will automatically send the memory_id
.
There are some options you can set to change the default behaviour of agents in RΞASON:
Although there is a bit more to learn about agents in RΞASON — such as how to deal with context length of the LLM — this page served as an introduction to them.
Next, we’ll be talking about the final piece of RΞASON puzzle: observability.
Learn to create agents in RΞASON
Agents are an experimental feature in RΞASON. Their API is subject to change.
There are some different definitions people use to define “LLM agents”. This is confusing.
So we propose the following:
An agent is just a LLM that selects which action to take from predefined pool of actions in order to accomplish a certain objective.
Although people don’t think of it like it, we argue that ChatGPT is indeed an agent. (And probably the most popular in the world)
ChatGPT Plus lets users:
How does ChatGPT (the app, not the LLM) knows which action to take?
Because the LLM itself (GPT-4) decides which action to take — just respond to user, create an image using DALL·E, etc.
Its objective could be: “Your goal is to fulfill the user’s need — be that responding the message, creating a new image, web browsing, etc.”
And the actions available for the agent are:
The point here is not to discuss semantics but rather illustrate what RΞASON refers to as “agents”.
LLMs have strong reasoning capabilities and, because of that they are able to decide when to call an action (and which to call) pretty precisely.
For instance, LLMs are bad at math:
LLM failing at math
But if we give access to a “Sum” action that takes two numbers and outputs the sum of them, the LLM correctly calls the action and is able to get the answer:
LLM not failing at math
Let’s establish two definitions:
We’ll be creating a basic math agent that has access to: sum()
, subtract()
, multiply()
and divide()
actions.
To create an agent in RΞASON you’ll need to define its actions and then the agent itself.
Curious about RΞASON design philoshopy?
Our beliefs are:
And here’s their implications in the context of our agents API:
To create an action you need to:
.ts
file under src/actions
;Let’s create the SUM
action we mentioned previously:
Two things to notice:
sum
function in the form of JSDoc;return
something in the end.And that’s it! Pretty simple.
If you never heard of JSDoc before, go here to understand it a bit better.
JSDoc may seem strange & complicated, but what we recommend is the following:
/**
and your IDE will most-likely auto-complete for you.JSDoc autocompletion
To verify you’ve correctly wrote JSDoc, you can hover over the function:
Function & parameters description when you hover
Awesome! We now have a sum
action, however we still need the subtract
, multiply
and divide
actions:
With all four actions created, we now need to create the agent itself.
Before actually creating your first agent, we need to create the required mental model to understand how they work.
Agents mental model
Three important things to notice:
step
is cycle of:
step
the LLM can:
end()
action that the LLM must call when it wants to end;max_step
counter — where the LLM can run for at most n
number of steps.To create an agent in RΞASON:
.ts
file under src/agents
;const actions = []
containing the available actions for the agent;useAgent()
function.Let’s take a look at the MathAgent
:
Let’s break it down:
export const actions = [ ]
with the actions;const agent = await useAgent()
;agent.reason(initialPrompt)
.agent.reason(initialPrompt)
;
agent.reason()
is an async generator that you iterate using for await (const step of agent.reason()) {}
step
, you decide if you want to call agent.stop()
to stop the agent or not. In this case we’re stopping the agent if:
answer
action.Cool! Now we need an entrypoint in order to test our agent.
Let’s create a POST /math
entrypoint:
If we call the POST /math
entrypoint we get:
Response from POST /math
JSON response
A important thing to notice is that there was a lot of data that was streamed even though we only explictly set to stream the final answer in the JSON’s answer
property. Why?
But the cool thing is that if you leave the default streaming agent usage enabled, you can use RΞASON Playground’s chat mode:
RΞASON Playground's chat mode
Since most agents are chat-like, we thought it’d be cool to include a chat interface in the Playground to help test your agents.
For chat mode to work:
POST
request with a input
property in the body. That means your entrypoint needs to read it and pass it to your agent.Another cool thing that chat mode does is: it handles the memory_id
automatically.
But what is memory_id
?
memory_id
Some usecases, like creating a chat-like agent, requires persistance — i.e.: be able to restore previous messages in the chat.
RΞASON offers persistance by default:
useAgent()
a new memory_id
is created;useAgent(memory_id)
again you can pass a memory_id
and that agent will be continue where it left off.You can disable this.
Under the hood RΞASON uses a local SQLite database to store all the information needed. If you go to your project directory, you’ll see a database.sqlite
file.
Let’s test this out:
And in our agent:
Let’s try it on the Playground:
Using `memory_id`
In the demo above, we didn’t use chat mode just to illutrate how memory_id
works under the hood. However, as long as your entrypoint is expecting a memory_id
property inside the request’s body, chat mode will automatically send the memory_id
.
There are some options you can set to change the default behaviour of agents in RΞASON:
Although there is a bit more to learn about agents in RΞASON — such as how to deal with context length of the LLM — this page served as an introduction to them.
Next, we’ll be talking about the final piece of RΞASON puzzle: observability.