How to Use Agents in Flows#
Usually, flows serve as pipelines to ensure the robustness of agentic workloads. Employing an agent for a specific task is desirable because of its ability to invoke tools when necessary and autonomously select parameters for certain actions.
WayFlow enables the use of agents within flows, combining the predictability of flows with the adaptability of agents. This guide demonstrates how to utilize the AgentExecutionStep to embed an agent within a flow to execute a specific task.
WayFlow supports several LLM API providers. Select an LLM from 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",
)
Basic implementation#
Assuming you want to write an article. Writing an article typically involves the following steps:
Find the topic for the article.
Write the article. This stage typically includes looking for sources on the web, drafting the entire text, reviewing, checking grammar, sources, proofreading.
Submit the article by sending it via email to the editor.
Steps 1 and 3 are straightforward and can be managed using standard procedures.
However, Step 2 involves complex tasks beyond a simple LLM generation, such as web browsing and content review.
To address this, you can use AgentExecutionStep
that allows an agent to flexibly utilize tools for web browsing and article review.
Assuming you already have the following tools to browse the web and to proofread the text:
import httpx
from wayflowcore.tools.toolhelpers import DescriptionMode, tool
@tool(description_mode=DescriptionMode.ONLY_DOCSTRING)
def get_wikipedia_page_content(topic: str) -> str:
"""Looks for information and sources on internet about a given topic."""
url = "https://en.wikipedia.org/w/api.php"
response = httpx.get(
url, params={"action": "query", "format": "json", "list": "search", "srsearch": topic}
)
# extract page id
data = response.json()
search_results = data["query"]["search"]
if not search_results:
return "No results found."
page_id = search_results[0]["pageid"]
response = httpx.get(
url,
params={
"action": "query",
"format": "json",
"prop": "extracts",
"explaintext": True,
"pageids": page_id,
},
)
# extract page content
page_data = response.json()
return str(page_data["query"]["pages"][str(page_id)]["extract"])
@tool(description_mode=DescriptionMode.ONLY_DOCSTRING)
def proofread(text: str) -> str:
"""Checks and correct grammar mistakes"""
return text
Continue creating the agent, specifying the agent’s expected output using the outputs
argument:
from wayflowcore.agent import Agent, CallerInputMode
from wayflowcore.property import StringProperty
output = StringProperty(
name="article",
description="article to submit to the editor. Needs to be cited with sources and proofread",
default_value="",
)
writing_agent = Agent(
llm=llm,
tools=[get_wikipedia_page_content, proofread],
custom_instruction="""Your task is to write an article about the subject given by the user. You need to:
1. find some information about the topic with sources.
2. write an article
3. proofread the article
4. repeat steps 1-2-3 until the article looks good
The article needs to be around 100 words, always need cite sources and should be written in a professional tone.""",
output_descriptors=[output],
)
The agent should operate within a flow without user interaction.
For that, set the caller_input_mode
mode to CallerInputMode.NEVER
.
from wayflowcore.steps.agentexecutionstep import AgentExecutionStep
agent_step = AgentExecutionStep(
name="agent_step",
agent=writing_agent,
caller_input_mode=CallerInputMode.NEVER,
output_descriptors=[output],
)
Now finalize the entire flow:
from wayflowcore.controlconnection import ControlFlowEdge
from wayflowcore.dataconnection import DataFlowEdge
from wayflowcore.flow import Flow
from wayflowcore.steps import InputMessageStep, OutputMessageStep
email_template = """Dear ...,
Here is the article I told you about:
{{article}}
Best
"""
user_step = InputMessageStep(name="user_step", message_template="")
send_email_step = OutputMessageStep(name="send_email_step", message_template=email_template)
flow = Flow(
begin_step=user_step,
control_flow_edges=[
ControlFlowEdge(source_step=user_step, destination_step=agent_step),
ControlFlowEdge(source_step=agent_step, destination_step=send_email_step),
ControlFlowEdge(source_step=send_email_step, destination_step=None),
],
data_flow_edges=[DataFlowEdge(agent_step, "article", send_email_step, "article")],
)
After completing the previous configurations, execute the flow.
conversation = flow.start_conversation()
conversation.execute()
conversation.append_user_message("Oracle DB")
conversation.execute()
print(conversation.get_last_message())
As expected, the final execution message should be the email to be sent to the editor.
Agent Spec Exporting/Loading#
You can export the assistant configuration to its Agent Spec configuration using the AgentSpecExporter
.
from wayflowcore.agentspec import AgentSpecExporter
serialized_flow = AgentSpecExporter().to_json(flow)
Here is what the Agent Spec representation will look like ↓
Click here to see the assistant configuration.
{
"component_type": "Flow",
"id": "a5a83bff-aef6-408c-a29f-5d927b6bd68a",
"name": "flow_433ed84e__auto",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
},
{
"description": "article to submit to the editor. Needs to be cited with sources and proofread",
"type": "string",
"title": "article",
"default": ""
},
{
"description": "the input value provided by the user",
"type": "string",
"title": "user_provided_input"
}
],
"start_node": {
"$component_ref": "420fc58e-e8fd-4785-8cce-f9958894a8f7"
},
"nodes": [
{
"$component_ref": "1a698e2a-f6f5-4102-af16-806073d94b9f"
},
{
"$component_ref": "abcf3e84-eae4-4ee4-a373-7e8fcfc1db10"
},
{
"$component_ref": "a2fc6b81-1b9c-4429-9875-7bcecbecccf3"
},
{
"$component_ref": "420fc58e-e8fd-4785-8cce-f9958894a8f7"
},
{
"$component_ref": "93bc5db7-7868-423f-ad3b-23bc366a8b08"
}
],
"control_flow_connections": [
{
"component_type": "ControlFlowEdge",
"id": "f8e4bb84-6ed1-4a58-9acc-7a6598cb65fc",
"name": "user_step_to_agent_step_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "1a698e2a-f6f5-4102-af16-806073d94b9f"
},
"from_branch": null,
"to_node": {
"$component_ref": "abcf3e84-eae4-4ee4-a373-7e8fcfc1db10"
}
},
{
"component_type": "ControlFlowEdge",
"id": "9c9007e4-9003-4ba2-83ac-7089164f4438",
"name": "agent_step_to_send_email_step_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "abcf3e84-eae4-4ee4-a373-7e8fcfc1db10"
},
"from_branch": null,
"to_node": {
"$component_ref": "a2fc6b81-1b9c-4429-9875-7bcecbecccf3"
}
},
{
"component_type": "ControlFlowEdge",
"id": "c275c4c2-d585-4547-9db2-0430197574c1",
"name": "__StartStep___to_user_step_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "420fc58e-e8fd-4785-8cce-f9958894a8f7"
},
"from_branch": null,
"to_node": {
"$component_ref": "1a698e2a-f6f5-4102-af16-806073d94b9f"
}
},
{
"component_type": "ControlFlowEdge",
"id": "d90237ea-5e67-4465-8a51-6b67d55991c1",
"name": "send_email_step_to_None End node_control_flow_edge",
"description": null,
"metadata": {},
"from_node": {
"$component_ref": "a2fc6b81-1b9c-4429-9875-7bcecbecccf3"
},
"from_branch": null,
"to_node": {
"$component_ref": "93bc5db7-7868-423f-ad3b-23bc366a8b08"
}
}
],
"data_flow_connections": [
{
"component_type": "DataFlowEdge",
"id": "23300e2a-8af3-4bd0-9bf2-430dede761c5",
"name": "agent_step_article_to_send_email_step_article_data_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"source_node": {
"$component_ref": "abcf3e84-eae4-4ee4-a373-7e8fcfc1db10"
},
"source_output": "article",
"destination_node": {
"$component_ref": "a2fc6b81-1b9c-4429-9875-7bcecbecccf3"
},
"destination_input": "article"
},
{
"component_type": "DataFlowEdge",
"id": "dad51224-512d-4241-b908-37ee82a2d09e",
"name": "send_email_step_output_message_to_None End node_output_message_data_flow_edge",
"description": null,
"metadata": {},
"source_node": {
"$component_ref": "a2fc6b81-1b9c-4429-9875-7bcecbecccf3"
},
"source_output": "output_message",
"destination_node": {
"$component_ref": "93bc5db7-7868-423f-ad3b-23bc366a8b08"
},
"destination_input": "output_message"
},
{
"component_type": "DataFlowEdge",
"id": "67931f4d-0ac4-4f26-aeba-9575f5086830",
"name": "agent_step_article_to_None End node_article_data_flow_edge",
"description": null,
"metadata": {},
"source_node": {
"$component_ref": "abcf3e84-eae4-4ee4-a373-7e8fcfc1db10"
},
"source_output": "article",
"destination_node": {
"$component_ref": "93bc5db7-7868-423f-ad3b-23bc366a8b08"
},
"destination_input": "article"
},
{
"component_type": "DataFlowEdge",
"id": "a1d61214-c6fc-400c-bb2d-1d9fdc996050",
"name": "user_step_user_provided_input_to_None End node_user_provided_input_data_flow_edge",
"description": null,
"metadata": {},
"source_node": {
"$component_ref": "1a698e2a-f6f5-4102-af16-806073d94b9f"
},
"source_output": "user_provided_input",
"destination_node": {
"$component_ref": "93bc5db7-7868-423f-ad3b-23bc366a8b08"
},
"destination_input": "user_provided_input"
}
],
"$referenced_components": {
"a2fc6b81-1b9c-4429-9875-7bcecbecccf3": {
"component_type": "PluginOutputMessageNode",
"id": "a2fc6b81-1b9c-4429-9875-7bcecbecccf3",
"name": "send_email_step",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"description": "\"article\" input variable for the template",
"type": "string",
"title": "article"
}
],
"outputs": [
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
}
],
"branches": [
"next"
],
"expose_message_as_output": true,
"message": "Dear ...,\n\nHere is the article I told you about:\n{{article}}\n\nBest\n",
"input_mapping": {},
"output_mapping": {},
"message_type": "AGENT",
"rephrase": false,
"llm_config": null,
"component_plugin_name": "NodesPlugin",
"component_plugin_version": "25.4.0.dev0"
},
"abcf3e84-eae4-4ee4-a373-7e8fcfc1db10": {
"component_type": "AgentNode",
"id": "abcf3e84-eae4-4ee4-a373-7e8fcfc1db10",
"name": "agent_step",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [
{
"description": "article to submit to the editor. Needs to be cited with sources and proofread",
"type": "string",
"title": "article",
"default": ""
}
],
"branches": [
"next"
],
"agent": {
"component_type": "Agent",
"id": "0bcd0ffc-7781-402c-860c-6768dbb2fd91",
"name": "agent_5324c936__auto",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [
{
"description": "article to submit to the editor. Needs to be cited with sources and proofread",
"type": "string",
"title": "article",
"default": ""
}
],
"llm_config": {
"component_type": "VllmConfig",
"id": "f33a26ae-6149-4c59-9e78-2891dffb40bb",
"name": "LLAMA_MODEL_ID",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"default_generation_parameters": null,
"url": "LLAMA_API_URL",
"model_id": "LLAMA_MODEL_ID"
},
"system_prompt": "Your task is to write an article about the subject given by the user. You need to:\n1. find some information about the topic with sources.\n2. write an article\n3. proofread the article\n4. repeat steps 1-2-3 until the article looks good\n\nThe article needs to be around 100 words, always need cite sources and should be written in a professional tone.",
"tools": [
{
"component_type": "ServerTool",
"id": "c7971c42-a911-43db-a05c-ce897f135bb8",
"name": "get_wikipedia_page_content",
"description": "Looks for information and sources on internet about a given topic.",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"type": "string",
"title": "topic"
}
],
"outputs": [
{
"type": "string",
"title": "tool_output"
}
]
},
{
"component_type": "ServerTool",
"id": "0680a945-80c9-4ce7-81b7-fadeabbd5314",
"name": "proofread",
"description": "Checks and correct grammar mistakes",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"type": "string",
"title": "text"
}
],
"outputs": [
{
"type": "string",
"title": "tool_output"
}
]
}
]
}
},
"93bc5db7-7868-423f-ad3b-23bc366a8b08": {
"component_type": "EndNode",
"id": "93bc5db7-7868-423f-ad3b-23bc366a8b08",
"name": "None End node",
"description": "End node representing all transitions to None in the WayFlow flow",
"metadata": {},
"inputs": [
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
},
{
"description": "article to submit to the editor. Needs to be cited with sources and proofread",
"type": "string",
"title": "article",
"default": ""
},
{
"description": "the input value provided by the user",
"type": "string",
"title": "user_provided_input"
}
],
"outputs": [
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
},
{
"description": "article to submit to the editor. Needs to be cited with sources and proofread",
"type": "string",
"title": "article",
"default": ""
},
{
"description": "the input value provided by the user",
"type": "string",
"title": "user_provided_input"
}
],
"branches": [],
"branch_name": "next"
},
"1a698e2a-f6f5-4102-af16-806073d94b9f": {
"component_type": "PluginInputMessageNode",
"id": "1a698e2a-f6f5-4102-af16-806073d94b9f",
"name": "user_step",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [
{
"description": "the input value provided by the user",
"type": "string",
"title": "user_provided_input"
}
],
"branches": [
"next"
],
"input_mapping": {},
"output_mapping": {},
"message_template": "",
"rephrase": false,
"llm_config": null,
"component_plugin_name": "NodesPlugin",
"component_plugin_version": "25.4.0.dev0"
},
"420fc58e-e8fd-4785-8cce-f9958894a8f7": {
"component_type": "StartNode",
"id": "420fc58e-e8fd-4785-8cce-f9958894a8f7",
"name": "__StartStep__",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [],
"branches": [
"next"
]
}
},
"agentspec_version": "25.4.1"
}
component_type: Flow
id: a5a83bff-aef6-408c-a29f-5d927b6bd68a
name: flow_433ed84e__auto
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs:
- description: the message added to the messages list
type: string
title: output_message
- description: article to submit to the editor. Needs to be cited with sources and
proofread
type: string
title: article
default: ''
- description: the input value provided by the user
type: string
title: user_provided_input
start_node:
$component_ref: 420fc58e-e8fd-4785-8cce-f9958894a8f7
nodes:
- $component_ref: 1a698e2a-f6f5-4102-af16-806073d94b9f
- $component_ref: abcf3e84-eae4-4ee4-a373-7e8fcfc1db10
- $component_ref: a2fc6b81-1b9c-4429-9875-7bcecbecccf3
- $component_ref: 420fc58e-e8fd-4785-8cce-f9958894a8f7
- $component_ref: 93bc5db7-7868-423f-ad3b-23bc366a8b08
control_flow_connections:
- component_type: ControlFlowEdge
id: f8e4bb84-6ed1-4a58-9acc-7a6598cb65fc
name: user_step_to_agent_step_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: 1a698e2a-f6f5-4102-af16-806073d94b9f
from_branch: null
to_node:
$component_ref: abcf3e84-eae4-4ee4-a373-7e8fcfc1db10
- component_type: ControlFlowEdge
id: 9c9007e4-9003-4ba2-83ac-7089164f4438
name: agent_step_to_send_email_step_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: abcf3e84-eae4-4ee4-a373-7e8fcfc1db10
from_branch: null
to_node:
$component_ref: a2fc6b81-1b9c-4429-9875-7bcecbecccf3
- component_type: ControlFlowEdge
id: c275c4c2-d585-4547-9db2-0430197574c1
name: __StartStep___to_user_step_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: 420fc58e-e8fd-4785-8cce-f9958894a8f7
from_branch: null
to_node:
$component_ref: 1a698e2a-f6f5-4102-af16-806073d94b9f
- component_type: ControlFlowEdge
id: d90237ea-5e67-4465-8a51-6b67d55991c1
name: send_email_step_to_None End node_control_flow_edge
description: null
metadata: {}
from_node:
$component_ref: a2fc6b81-1b9c-4429-9875-7bcecbecccf3
from_branch: null
to_node:
$component_ref: 93bc5db7-7868-423f-ad3b-23bc366a8b08
data_flow_connections:
- component_type: DataFlowEdge
id: 23300e2a-8af3-4bd0-9bf2-430dede761c5
name: agent_step_article_to_send_email_step_article_data_flow_edge
description: null
metadata:
__metadata_info__: {}
source_node:
$component_ref: abcf3e84-eae4-4ee4-a373-7e8fcfc1db10
source_output: article
destination_node:
$component_ref: a2fc6b81-1b9c-4429-9875-7bcecbecccf3
destination_input: article
- component_type: DataFlowEdge
id: dad51224-512d-4241-b908-37ee82a2d09e
name: send_email_step_output_message_to_None End node_output_message_data_flow_edge
description: null
metadata: {}
source_node:
$component_ref: a2fc6b81-1b9c-4429-9875-7bcecbecccf3
source_output: output_message
destination_node:
$component_ref: 93bc5db7-7868-423f-ad3b-23bc366a8b08
destination_input: output_message
- component_type: DataFlowEdge
id: 67931f4d-0ac4-4f26-aeba-9575f5086830
name: agent_step_article_to_None End node_article_data_flow_edge
description: null
metadata: {}
source_node:
$component_ref: abcf3e84-eae4-4ee4-a373-7e8fcfc1db10
source_output: article
destination_node:
$component_ref: 93bc5db7-7868-423f-ad3b-23bc366a8b08
destination_input: article
- component_type: DataFlowEdge
id: a1d61214-c6fc-400c-bb2d-1d9fdc996050
name: user_step_user_provided_input_to_None End node_user_provided_input_data_flow_edge
description: null
metadata: {}
source_node:
$component_ref: 1a698e2a-f6f5-4102-af16-806073d94b9f
source_output: user_provided_input
destination_node:
$component_ref: 93bc5db7-7868-423f-ad3b-23bc366a8b08
destination_input: user_provided_input
$referenced_components:
a2fc6b81-1b9c-4429-9875-7bcecbecccf3:
component_type: PluginOutputMessageNode
id: a2fc6b81-1b9c-4429-9875-7bcecbecccf3
name: send_email_step
description: ''
metadata:
__metadata_info__: {}
inputs:
- description: '"article" input variable for the template'
type: string
title: article
outputs:
- description: the message added to the messages list
type: string
title: output_message
branches:
- next
expose_message_as_output: True
message: 'Dear ...,
Here is the article I told you about:
{{article}}
Best
'
input_mapping: {}
output_mapping: {}
message_type: AGENT
rephrase: false
llm_config: null
component_plugin_name: NodesPlugin
component_plugin_version: 25.4.0.dev0
abcf3e84-eae4-4ee4-a373-7e8fcfc1db10:
component_type: AgentNode
id: abcf3e84-eae4-4ee4-a373-7e8fcfc1db10
name: agent_step
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs:
- description: article to submit to the editor. Needs to be cited with sources
and proofread
type: string
title: article
default: ''
branches:
- next
agent:
component_type: Agent
id: 0bcd0ffc-7781-402c-860c-6768dbb2fd91
name: agent_5324c936__auto
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs:
- description: article to submit to the editor. Needs to be cited with sources
and proofread
type: string
title: article
default: ''
llm_config:
component_type: VllmConfig
id: f33a26ae-6149-4c59-9e78-2891dffb40bb
name: LLAMA_MODEL_ID
description: null
metadata:
__metadata_info__: {}
default_generation_parameters: null
url: LLAMA_API_URL
model_id: LLAMA_MODEL_ID
system_prompt: 'Your task is to write an article about the subject given by
the user. You need to:
1. find some information about the topic with sources.
2. write an article
3. proofread the article
4. repeat steps 1-2-3 until the article looks good
The article needs to be around 100 words, always need cite sources and should
be written in a professional tone.'
tools:
- component_type: ServerTool
id: c7971c42-a911-43db-a05c-ce897f135bb8
name: get_wikipedia_page_content
description: Looks for information and sources on internet about a given topic.
metadata:
__metadata_info__: {}
inputs:
- type: string
title: topic
outputs:
- type: string
title: tool_output
- component_type: ServerTool
id: 0680a945-80c9-4ce7-81b7-fadeabbd5314
name: proofread
description: Checks and correct grammar mistakes
metadata:
__metadata_info__: {}
inputs:
- type: string
title: text
outputs:
- type: string
title: tool_output
93bc5db7-7868-423f-ad3b-23bc366a8b08:
component_type: EndNode
id: 93bc5db7-7868-423f-ad3b-23bc366a8b08
name: None End node
description: End node representing all transitions to None in the WayFlow flow
metadata: {}
inputs:
- description: the message added to the messages list
type: string
title: output_message
- description: article to submit to the editor. Needs to be cited with sources
and proofread
type: string
title: article
default: ''
- description: the input value provided by the user
type: string
title: user_provided_input
outputs:
- description: the message added to the messages list
type: string
title: output_message
- description: article to submit to the editor. Needs to be cited with sources
and proofread
type: string
title: article
default: ''
- description: the input value provided by the user
type: string
title: user_provided_input
branches: []
branch_name: next
1a698e2a-f6f5-4102-af16-806073d94b9f:
component_type: PluginInputMessageNode
id: 1a698e2a-f6f5-4102-af16-806073d94b9f
name: user_step
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs:
- description: the input value provided by the user
type: string
title: user_provided_input
branches:
- next
input_mapping: {}
output_mapping: {}
message_template: ''
rephrase: false
llm_config: null
component_plugin_name: NodesPlugin
component_plugin_version: 25.4.0.dev0
420fc58e-e8fd-4785-8cce-f9958894a8f7:
component_type: StartNode
id: 420fc58e-e8fd-4785-8cce-f9958894a8f7
name: __StartStep__
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs: []
branches:
- next
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 = {
"get_wikipedia_page_content": get_wikipedia_page_content,
"proofread": proofread,
}
flow = AgentSpecLoader(tool_registry=tool_registry).load_json(serialized_flow)
Note
This guide uses the following extension/plugin Agent Spec components:
PluginInputMessageNode
PluginOutputMessageNode
See the list of available Agent Spec extension/plugin components in the API Reference
Next steps#
Having learned how to use Agents inside Flows, you may now proceed to:
How to Create Conditional Transitions in Flows to branch out depending on the agent’s response.
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# WayFlow Code Example - How to Use Agents in Flows
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 howto_agents_in_flows.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# %%[markdown]
31## Define the llm
32
33# %%
34from wayflowcore.models import VllmModel
35
36llm = VllmModel(
37 model_id="LLAMA_MODEL_ID",
38 host_port="LLAMA_API_URL",
39)
40
41# %%[markdown]
42## Define the tools
43
44# %%
45import httpx
46from wayflowcore.tools.toolhelpers import DescriptionMode, tool
47
48@tool(description_mode=DescriptionMode.ONLY_DOCSTRING)
49def get_wikipedia_page_content(topic: str) -> str:
50 """Looks for information and sources on internet about a given topic."""
51 url = "https://en.wikipedia.org/w/api.php"
52
53 response = httpx.get(
54 url, params={"action": "query", "format": "json", "list": "search", "srsearch": topic}
55 )
56 # extract page id
57 data = response.json()
58 search_results = data["query"]["search"]
59 if not search_results:
60 return "No results found."
61
62 page_id = search_results[0]["pageid"]
63
64 response = httpx.get(
65 url,
66 params={
67 "action": "query",
68 "format": "json",
69 "prop": "extracts",
70 "explaintext": True,
71 "pageids": page_id,
72 },
73 )
74
75 # extract page content
76 page_data = response.json()
77 return str(page_data["query"]["pages"][str(page_id)]["extract"])
78
79
80@tool(description_mode=DescriptionMode.ONLY_DOCSTRING)
81def proofread(text: str) -> str:
82 """Checks and correct grammar mistakes"""
83 return text
84
85# %%[markdown]
86## Define the agent
87
88# %%
89from wayflowcore.agent import Agent, CallerInputMode
90from wayflowcore.property import StringProperty
91
92output = StringProperty(
93 name="article",
94 description="article to submit to the editor. Needs to be cited with sources and proofread",
95 default_value="",
96)
97
98writing_agent = Agent(
99 llm=llm,
100 tools=[get_wikipedia_page_content, proofread],
101 custom_instruction="""Your task is to write an article about the subject given by the user. You need to:
1021. find some information about the topic with sources.
1032. write an article
1043. proofread the article
1054. repeat steps 1-2-3 until the article looks good
106
107The article needs to be around 100 words, always need cite sources and should be written in a professional tone.""",
108 output_descriptors=[output],
109)
110
111# %%[markdown]
112## Define the agent step
113
114# %%
115from wayflowcore.steps.agentexecutionstep import AgentExecutionStep
116
117agent_step = AgentExecutionStep(
118 name="agent_step",
119 agent=writing_agent,
120 caller_input_mode=CallerInputMode.NEVER,
121 output_descriptors=[output],
122)
123
124# %%[markdown]
125## Define the Flow
126
127# %%
128from wayflowcore.controlconnection import ControlFlowEdge
129from wayflowcore.dataconnection import DataFlowEdge
130from wayflowcore.flow import Flow
131from wayflowcore.steps import InputMessageStep, OutputMessageStep
132
133email_template = """Dear ...,
134
135Here is the article I told you about:
136{{article}}
137
138Best
139"""
140
141user_step = InputMessageStep(name="user_step", message_template="")
142send_email_step = OutputMessageStep(name="send_email_step", message_template=email_template)
143
144flow = Flow(
145 begin_step=user_step,
146 control_flow_edges=[
147 ControlFlowEdge(source_step=user_step, destination_step=agent_step),
148 ControlFlowEdge(source_step=agent_step, destination_step=send_email_step),
149 ControlFlowEdge(source_step=send_email_step, destination_step=None),
150 ],
151 data_flow_edges=[DataFlowEdge(agent_step, "article", send_email_step, "article")],
152)
153
154# %%[markdown]
155## Execute the flow
156
157# %%
158conversation = flow.start_conversation()
159conversation.execute()
160
161conversation.append_user_message("Oracle DB")
162conversation.execute()
163
164print(conversation.get_last_message())
165
166# %%[markdown]
167## Export config to Agent Spec
168
169# %%
170from wayflowcore.agentspec import AgentSpecExporter
171
172serialized_flow = AgentSpecExporter().to_json(flow)
173
174# %%[markdown]
175## Load Agent Spec config
176
177# %%
178from wayflowcore.agentspec import AgentSpecLoader
179
180tool_registry = {
181 "get_wikipedia_page_content": get_wikipedia_page_content,
182 "proofread": proofread,
183}
184
185flow = AgentSpecLoader(tool_registry=tool_registry).load_json(serialized_flow)