Build a Simple Conversational Assistant with Agents#

python-icon Download Python Script

Python script/notebook for this tutorial.

Agent tutorial script

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:

  1. Get a feel for how WayFlow works by creating a simple conversational assistant.

  2. 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:

  1. Set up the coding environment by importing the necessary modules and configuring the LLMs.

  2. Specify the Agents’ instructions.

  3. 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",
    )

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:

  1. A persona description defining the role of the agent.

  2. A short description of the task to be solved.

  3. A detailed description of the task. More precise descriptions lead to more consistent results.

  4. 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.

  1. What is the salary for John Smith?

  2. Does John Smith earn more that Mary Jones?

  3. 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:

  1. How much does Jones Jones earn?

  2. 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"
}

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)