Informative Agent
This section describes how to build an Agent with Upstreet, with custom Components.
In this guide, we build an Informative Agent inspired by the Pokédex in the Pokémon franchise, an encyclopedia device capable of retrieving Pokémon information and having conversations with its user.
We define an Informative Agent as an Agent which can retrieve information from an API or the internet.
The source code for this example is available on GitHub.
Video Tutorial
You can follow along this example by watching the video below:
Guide
Step 1: Setup usdk
Follow Setup the SDK to set up NodeJS and usdk
.
Step 2: Create an Agent (shortcut)
We can skip the Interview process, and directly generate an Agent with a prompt, by running:
This will directly scaffold an Agent for you in <your-agent-directory>
. Learn more
Step 3: Create a PokeDexAssistant
Component
As of November 12, 2024, there are 1,025 Pokémon in the National Pokédex. That's a lot of Pokémon!
So instead of keeping the Pokédex database in memory, we'll use PokéAPI - an open-source (and free) Pokémon API - to retrieve Pokémon information at runtime.
We'll have to create a custom Component to retrieve Pokémon information from the PokéAPI. For the sake of this example, we'll keep it simple:
Now add a helper function to retrieve the Pokémon data, and also two more to filter them by abilities and moves:
Now comes the interesting part. We'll use the <Action>
tag to define how the Agent should respond to the default text perception.
To say that simply, we want the Agent to know that it can fetch Pokémon details whenever a user messages them.
Let's break down one of the Actions, and understand it.
Breakdown summary of the <Action>
Component
-
Purpose of the
<Action>
Component
<Action>
components define specific actions that your agent can perform in response to user inputs. In this case, the agent retrieves Pokémon-related details like abilities and moves from the PokéAPI. -
Defining Action Properties Each
<Action>
is structured with the following properties:name
: A unique identifier for the action. Example:'fetchPokemonMoves'
.description
: Explains what the action does. This helps developers understand its purpose.schema
: Specifies the input structure for the action, defined using azod
schema. Here, the input is a Pokémon's name (pokemonName
), and the schema ensures it's a string.examples
: Provides sample inputs for testing or guiding the agent's behavior. Example:{ pokemonName: 'pikachu' }
.
-
handler
: The Action's Core Logic Thehandler
function is where the actual functionality of the action is implemented:- Input Processing: The
e.data.message.args
extracts the input (pokemonName
) from the user's request. - Calling Helper Functions: Helper functions like
fetchPokemonMovesNames
orfetchPokemonAbilities
are invoked to fetch data from the PokéAPI. - Building the Response: The results are formatted into a string (e.g., a monologue) using
dedent
for cleaner output. - Responding to the User: The agent sends a response via
e.data.agent.monologue
. - Marking Action Completion: The
await e.commit()
call signals that the action is complete.
- Input Processing: The
The fetchPokemonMoves
Action
Learn about the basics of Actions here.
Let's break apart the fetchPokemonMoves
Action. This action retrieves a Pokémon's move names:
- Schema Validation: Ensures
pokemonName
is a valid string. - Fetch Logic: The
fetchPokemonMovesNames
helper gets the moves from the API. - User Feedback: The response lists the moves and delivers them back to the user.
You can define multiple <Action>
components, each tailored to a specific purpose. For example:
fetchPokemonAbilities
: Fetches abilities usingfetchPokemonAbilities
.fetchPokemonMoves
: Fetches moves usingfetchPokemonMovesNames
.
Finally, we call <PokeDexAssistant />
in our Agent's main code:
You can see the complete code for this component on GitHub here.
Step 4: Test out your Pokédex-like Agent!
You can run usdk chat
to test it out. Learn more
You can ask it questions like:
What are Charizard's top abilities?
Share its response in our Discord community; we'd love to know what it responds to you.
Further Challenges
- "Who's that Pokémon?" - Give the Agent an Image Perception, and create an Action so it can guess a Pokémon based on the image and provide its details