Build a Simple Conversational Assistant with Agents#
Prerequisites
This guide does not assume any prior knowledge about WayFlow. However, it assumes the reader has a basic knowledge of LLMs.
You will need a working installation of WayFlow - see Installation.
Learning Goals#
In this first tutorial you will develop a simple HR chatbot Assistant that uses a Tool to search an HR database to answer the employee’s HR-related question.
The HR system will be represented by a set of dummy data that we will be made available to the agent. The agent will use this dummy data to answer your questions and if it is asked a question that can not be answered from the dummy data, then it will say so.
By completing this tutorial, you will:
Get a feel for how WayFlow works by creating a simple conversational assistant.
Learn the basics of using an Agent to build an assistant.
A primer on Agents#
Assistants created using WayFlow are AI-powered assistants designed to solve tasks in a (semi-)autonomous and intelligent manner. WayFlow supports two main types of assistants:
Flows - Used for assistants that follow a predefined process to complete tasks. A Flow consists of individual steps connected to form a logical sequence of actions. Each step in a Flow serves a specific function, similar to functions in programming.
Agents - Used to create conversational agents that can autonomously plan, think, act, and execute tools in a flexible manner.
Additionally, WayFlow provides Tools, which are wrappers around external APIs. Assistants can use these tools to retrieve relevant data and information necessary for completing tasks.
Tip
When to use a Flow and when an Agent? Flows are useful to model business processes with clear requirements, as these assistants provide a high level of control over their behavior. On the other hand, Agents are not easy to control, but they can be useful in ambiguous environments that necessitate flexibility and creativity.
In this tutorial, you will use the Agent, which is a general-purpose assistant that can interact with users, leverage LLMs, and execute tools to complete tasks.
Note
To learn more about building assistants with Flows, check out Build a Simple Fixed-flow Assistant with Flows Build a Simple Fixed-Flow Assistant with Flows.
Building the Agent#
The process for building a simple Agent will be composed of the following elements:
Set up the coding environment by importing the necessary modules and configuring the LLMs.
Specify the Agents’ instructions.
Create the Agent.
Imports and LLM configuration#
First import what is needed for this tutorial:
1from wayflowcore.agent import Agent
2from wayflowcore.agentspec import AgentSpecExporter, AgentSpecLoader
3from wayflowcore.executors.executionstatus import (
4 FinishedStatus,
5 UserMessageRequestStatus,
6)
7from wayflowcore.tools import tool
WayFlow supports several LLM API providers. First choose an LLM from one of the options below:
from wayflowcore.models import OCIGenAIModel
if __name__ == "__main__":
llm = OCIGenAIModel(
model_id="provider.model-id",
service_endpoint="https://url-to-service-endpoint.com",
compartment_id="compartment-id",
auth_type="API_KEY",
)
from wayflowcore.models import VllmModel
llm = VllmModel(
model_id="model-id",
host_port="VLLM_HOST_PORT",
)
from wayflowcore.models import OllamaModel
llm = OllamaModel(
model_id="model-id",
)
Note
API keys should never be stored in code. Use environment variables and/or tools such as python-dotenv instead.
Creating a tool for the Agent#
The agent shown in this tutorial is equipped with a tool search_hr_database
, which -as the name indicates-
will enable the assistant to search a (ficticious) HR database.
1@tool(description_mode="only_docstring")
2def search_hr_database(query: str) -> str:
3 """Function that searches the HR database for employee benefits.
4
5 Parameters
6 ----------
7 query:
8 a query string
9
10 Returns
11 -------
12 a JSON response
13
14 """
15 return '{"John Smith": {"benefits": "Unlimited PTO", "salary": "$1,000"}, "Mary Jones": {"benefits": "25 days", "salary": "$10,000"}}'
16
Here, the tool returns some dummy data about two fictitious employees, John Smith and Mary Jones. The dummy data returned contains details of the salary and benefits for each of these employees. The agent will use this dummy data to answer the user’s salary queries.
Specifying the agent instructions#
Next, give the agent instructions on how to approach the task. The instructions are shown below.
1HRASSISTANT_GENERATION_INSTRUCTIONS = """
2You are a knowledgeable, factual, and helpful HR assistant that can answer simple \
3HR-related questions like salary and benefits.
4You are given a tool to look up the HR database.
5Your task:
6 - Ask the user if they need assistance
7 - Use the provided tool below to retrieve HR data
8 - Based on the data you retrieved, answer the user's question
9Important:
10 - Be helpful and concise in your messages
11 - Do not tell the user any details not mentioned in the tool response, let's be factual.
12""".strip()
The LLM is provided with these instructions to guide it in solving the task. In this context, the LLM acts as an HR assistant.
Note
For advanced LLM users, these instructions correspond to the system prompt. The underlying LLM is used as a multi-turn chat model, with these instructions serving as the initial system prompt.
Hint
How do I write good instructions? Good instructions for an LLM should include the following elements:
A persona description defining the role of the agent.
A short description of the task to be solved.
A detailed description of the task. More precise descriptions lead to more consistent results.
Instructions on how the output should be formatted.
Creating the Agent#
Now that the tool is created and the instructions are written, you can then create the Agent.
The code for the agent is shown below.
1assistant = Agent(
2 custom_instruction=HRASSISTANT_GENERATION_INSTRUCTIONS,
3 tools=[search_hr_database], # this is a decorated python function (Server tool in this example)
4 llm=llm, # the LLM object we created above
5)
The Agent interacts with the user through conversations. During each turn, it may choose to respond to the user, execute tools or flows, or consult expert agents.
This completes your first Agent!
Running the Agent#
Finally, run your agent using a simple turn-based conversation flow until the conversation concludes. You can execute the assistant by implementing a finite conversation sequence, or a conversation loop.
In the given example conversation loop, the agent’s output is displayed to you, and when additional information is needed, you will be prompted for input. The script reads your input and responds accordingly, requiring it to be run in an “interactive” manner.
1# With a linear conversation
2conversation = assistant.start_conversation()
3
4conversation.append_user_message("What are John Smith's benefits?")
5status = conversation.execute()
6if isinstance(status, UserMessageRequestStatus):
7 assistant_reply = conversation.get_last_message()
8 print(f"---\nAssistant >>> {assistant_reply.content}\n---")
9else:
10 print(f"Invalid execution status, expected UserMessageRequestStatus, received {type(status)}")
11
12# then continue the conversation
13
14# %%
15# Or with an execution loop
16def run_agent_in_command_line(assistant: Agent):
17 inputs = {}
18 conversation = assistant.start_conversation(inputs)
19
20 while True:
21 status = conversation.execute()
22 if isinstance(status, FinishedStatus):
23 break
24 assistant_reply = conversation.get_last_message()
25 if assistant_reply is not None:
26 print("\nAssistant >>>", assistant_reply.content)
27 user_input = input("\nUser >>> ")
28 conversation.append_user_message(user_input)
29
Before we run the assistant, what are some questions that you could ask it? The following questions can be answered form the dummy HR data and are a good starting point.
What is the salary for John Smith?
Does John Smith earn more that Mary Jones?
How much annual leave does John Smith get?
But, we can also ask the assistant questions that it shouldn’t be able to answer, because it hasn’t been given any data that is relevant to the question:
How much does Jones Jones earn?
What is Mary Jones favorite color?
So with some questions ready you can now run the assistant. Run the code below to run the assistant. To quit the assistant type, Done.
1# run_agent_in_command_line(assistant)
2# ^ uncomment and execute
Agent Spec Exporting/Loading#
You can export the assistant configuration to its Agent Spec configuration using the AgentSpecExporter
.
from wayflowcore.agentspec import AgentSpecExporter
serialized_assistant = AgentSpecExporter().to_json(assistant)
Here is what the Agent Spec representation will look like ↓
Click here to see the assistant configuration.
{
"component_type": "Agent",
"id": "61bd7075-4f41-4344-8e0d-1d6935975794",
"name": "agent_58415549__auto",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [],
"llm_config": {
"component_type": "VllmConfig",
"id": "7796961b-db94-4a5e-bd12-8c532989fe0f",
"name": "LLAMA_MODEL_ID",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"default_generation_parameters": null,
"url": "LLAMA_API_URL",
"model_id": "LLAMA_MODEL_ID"
},
"system_prompt": "You are a knowledgeable, factual, and helpful HR assistant that can answer simple HR-related questions like salary and benefits.\nYou are given a tool to look up the HR database.\nYour task:\n - Ask the user if they need assistance\n - Use the provided tool below to retrieve HR data\n - Based on the data you retrieved, answer the user's question\nImportant:\n - Be helpful and concise in your messages\n - Do not tell the user any details not mentioned in the tool response, let's be factual.",
"tools": [
{
"component_type": "ServerTool",
"id": "c6d943c1-20a3-4f66-b89b-8173ab854e0b",
"name": "search_hr_database",
"description": "Function that searches the HR database for employee benefits.\n\nParameters\n----------\nquery:\n a query string\n\nReturns\n-------\n a JSON response",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"type": "string",
"title": "query"
}
],
"outputs": [
{
"type": "string",
"title": "tool_output"
}
]
}
],
"agentspec_version": "25.4.1"
}
component_type: Agent
id: 61bd7075-4f41-4344-8e0d-1d6935975794
name: agent_58415549__auto
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs: []
llm_config:
component_type: VllmConfig
id: 7796961b-db94-4a5e-bd12-8c532989fe0f
name: LLAMA_MODEL_ID
description: null
metadata:
__metadata_info__: {}
default_generation_parameters: null
url: LLAMA_API_URL
model_id: LLAMA_MODEL_ID
system_prompt: "You are a knowledgeable, factual, and helpful HR assistant that can\
\ answer simple HR-related questions like salary and benefits.\nYou are given a\
\ tool to look up the HR database.\nYour task:\n - Ask the user if they need\
\ assistance\n - Use the provided tool below to retrieve HR data\n - Based\
\ on the data you retrieved, answer the user's question\nImportant:\n - Be helpful\
\ and concise in your messages\n - Do not tell the user any details not mentioned\
\ in the tool response, let's be factual."
tools:
- component_type: ServerTool
id: c6d943c1-20a3-4f66-b89b-8173ab854e0b
name: search_hr_database
description: "Function that searches the HR database for employee benefits.\n\n\
Parameters\n----------\nquery:\n a query string\n\nReturns\n-------\n a\
\ JSON response"
metadata:
__metadata_info__: {}
inputs:
- type: string
title: query
outputs:
- type: string
title: tool_output
agentspec_version: 25.4.1
You can then load the configuration back to an assistant using the AgentSpecLoader
.
from wayflowcore.agentspec import AgentSpecLoader
TOOL_REGISTRY = {"search_hr_database": search_hr_database}
assistant: Agent = AgentSpecLoader(
tool_registry=TOOL_REGISTRY
).load_json(serialized_assistant)
Next steps#
You have successfully learned how to build a conversational assistant using WayFlow Agent. With the basics covered, you can now start building more complex assistants.
To continue learning, check out:
Full code#
Click on the card at the top of this page to download the full code for this guide or copy the code below.
1# Copyright © 2025 Oracle and/or its affiliates.
2#
3# This software is under the Universal Permissive License
4# %%[markdown]
5# Tutorial - Build a Conversational Assistant with Agents
6# -------------------------------------------------------
7
8# How to use:
9# Create a new Python virtual environment and install the latest WayFlow version.
10# ```bash
11# python -m venv venv-wayflowcore
12# source venv-wayflowcore/bin/activate
13# pip install --upgrade pip
14# pip install "wayflowcore==26.1"
15# ```
16
17# You can now run the script
18# 1. As a Python file:
19# ```bash
20# python tutorial_agent.py
21# ```
22# 2. As a Notebook (in VSCode):
23# When viewing the file,
24# - press the keys Ctrl + Enter to run the selected cell
25# - or Shift + Enter to run the selected cell and move to the cell below# (UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl) or Apache License
26# 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0), at your option.
27
28
29
30
31# %%[markdown]
32## Imports for this guide
33
34# %%
35from wayflowcore.agent import Agent
36from wayflowcore.agentspec import AgentSpecExporter, AgentSpecLoader
37from wayflowcore.executors.executionstatus import (
38 FinishedStatus,
39 UserMessageRequestStatus,
40)
41from wayflowcore.tools import tool
42
43# %%[markdown]
44## Configure your LLM
45
46# %%
47from wayflowcore.models import VllmModel
48
49llm = VllmModel(
50 model_id="LLAMA70B_MODEL_ID",
51 host_port="LLAMA70B_API_URL",
52)
53
54# %%[markdown]
55## Defining a tool for the agent
56
57# %%
58@tool(description_mode="only_docstring")
59def search_hr_database(query: str) -> str:
60 """Function that searches the HR database for employee benefits.
61
62 Parameters
63 ----------
64 query:
65 a query string
66
67 Returns
68 -------
69 a JSON response
70
71 """
72 return '{"John Smith": {"benefits": "Unlimited PTO", "salary": "$1,000"}, "Mary Jones": {"benefits": "25 days", "salary": "$10,000"}}'
73
74
75# %%[markdown]
76## Specifying the agent instructions
77
78# %%
79HRASSISTANT_GENERATION_INSTRUCTIONS = """
80You are a knowledgeable, factual, and helpful HR assistant that can answer simple \
81HR-related questions like salary and benefits.
82You are given a tool to look up the HR database.
83Your task:
84 - Ask the user if they need assistance
85 - Use the provided tool below to retrieve HR data
86 - Based on the data you retrieved, answer the user's question
87Important:
88 - Be helpful and concise in your messages
89 - Do not tell the user any details not mentioned in the tool response, let's be factual.
90""".strip()
91
92# %%[markdown]
93## Creating the agent
94
95# %%
96assistant = Agent(
97 custom_instruction=HRASSISTANT_GENERATION_INSTRUCTIONS,
98 tools=[search_hr_database], # this is a decorated python function (Server tool in this example)
99 llm=llm, # the LLM object we created above
100)
101
102# %%[markdown]
103## Running the agent
104
105# %%
106# With a linear conversation
107conversation = assistant.start_conversation()
108
109conversation.append_user_message("What are John Smith's benefits?")
110status = conversation.execute()
111if isinstance(status, UserMessageRequestStatus):
112 assistant_reply = conversation.get_last_message()
113 print(f"---\nAssistant >>> {assistant_reply.content}\n---")
114else:
115 print(f"Invalid execution status, expected UserMessageRequestStatus, received {type(status)}")
116
117# then continue the conversation
118
119# %%
120# Or with an execution loop
121def run_agent_in_command_line(assistant: Agent):
122 inputs = {}
123 conversation = assistant.start_conversation(inputs)
124
125 while True:
126 status = conversation.execute()
127 if isinstance(status, FinishedStatus):
128 break
129 assistant_reply = conversation.get_last_message()
130 if assistant_reply is not None:
131 print("\nAssistant >>>", assistant_reply.content)
132 user_input = input("\nUser >>> ")
133 conversation.append_user_message(user_input)
134
135
136# %%[markdown]
137## Running with the execution loop
138
139# %%
140# run_agent_in_command_line(assistant)
141# ^ uncomment and execute
142
143# %%[markdown]
144## Export config to Agent Spec
145
146# %%
147from wayflowcore.agentspec import AgentSpecExporter
148
149serialized_assistant = AgentSpecExporter().to_json(assistant)
150
151# %%[markdown]
152## Load Agent Spec config
153
154# %%
155from wayflowcore.agentspec import AgentSpecLoader
156
157TOOL_REGISTRY = {"search_hr_database": search_hr_database}
158assistant: Agent = AgentSpecLoader(
159 tool_registry=TOOL_REGISTRY
160).load_json(serialized_assistant)