How to Execute Agent Spec Across Frameworks#
This guide demonstrates how to:
Load an Agent Spec JSON representation of an agent
Run it with an agentic framework using one of the Agent Spec adapters
Build the basics of an Agent Spec adapter
This guide shows how to execute a flexible ReAct RAG agent using a tool that simulates information retrieval based on a query. The example uses a pre-built Agent Spec representation of the agent, shown below.
{
"component_type": "Agent",
"id": "7d3f3251-8d66-42d3-aff8-0e0d0d9486a8",
"name": "adaptive_expert_agent",
"description": null,
"metadata": {},
"inputs": [
{
"title": "domain_of_expertise",
"type": "string"
}
],
"outputs": [],
"llm_config": {
"component_type": "VllmConfig",
"id": "301ea6c6-17b7-46ab-967f-e354c15ba97b",
"name": "Llama 3.1 8B instruct",
"description": null,
"metadata": {},
"default_generation_parameters": {},
"url": "LLAMA_PLACEHOLDER_LINK",
"model_id": "meta-llama/Meta-Llama-3.1-8B-Instruct"
},
"system_prompt": "You are an expert in {{domain_of_expertise}}.\nPlease help the users with their requests.",
"tools": [
{
"component_type": "ServerTool",
"id": "5c38a0ba-8ac4-4712-bf26-39759fe48ccb",
"name": "rag_tool",
"description": "Tool that performs RAG",
"metadata": {},
"inputs": [
{
"title": "query",
"type": "string"
}
],
"outputs": [
{
"items": {
"type": "string"
},
"title": "results",
"type": "array"
}
]
}
],
"agentspec_version": "25.4.1"
}
component_type: Agent
id: 7d3f3251-8d66-42d3-aff8-0e0d0d9486a8
name: adaptive_expert_agent
description: null
metadata: {}
inputs:
- title: domain_of_expertise
type: string
outputs: []
llm_config:
component_type: VllmConfig
id: 301ea6c6-17b7-46ab-967f-e354c15ba97b
name: Llama 3.1 8B instruct
description: null
metadata: {}
default_generation_parameters: {}
url: LLAMA_PLACEHOLDER_LINK
model_id: meta-llama/Meta-Llama-3.1-8B-Instruct
system_prompt: 'You are an expert in {{domain_of_expertise}}.
Please help the users with their requests.'
tools:
- component_type: ServerTool
id: 5c38a0ba-8ac4-4712-bf26-39759fe48ccb
name: rag_tool
description: Tool that performs RAG
metadata: {}
inputs:
- title: query
type: string
outputs:
- items:
type: string
title: results
type: array
agentspec_version: 25.4.1
It also assumes having a common registry of tool implementations containing the tool utilized by this agent.
from typing import List
def hello_world() -> None:
"""Prints 'Hello world!'"""
print("Hello world!")
return None
def rag_tool(query: str) -> List[str]:
"""Search and return the list of results"""
return ["result 1", "result 2"]
tool_registry = {
"rag_tool": rag_tool,
"hello_world_tool": hello_world,
}
Adapters#
Using adapters is the recommended way of integrating an agentic framework runtime. Ideally, an adapter should translate programmatically the representation of the Agent Spec components into the equivalent solution, as per each framework’s definition, and return an object that developers can run.
As a reference runtime for Agent Spec, WayFlow offers an Agent Spec adapter as part of the package. Besides WayFlow, the Agent Spec team provides the implementation of adapters for two other common agentic frameworks:
Each adapter contains two main public classes, AgentSpecExporter
and AgentSpecLoader
.
The AgentSpecExporter
exposes APIs to export an object of the reference agentic framework into the equivalent
Agent Spec representation in one of the following forms: YAML, JSON, or PyAgentSpec Component object.
class AgentSpecExporter:
"""Helper class to convert agentic framework objects to Agent Spec configurations."""
def to_yaml(self, framework_component: FrameworkComponent) -> str:
"""Transform the given framework component into the respective Agent Spec YAML representation."""
def to_json(self, framework_component: FrameworkComponent) -> str:
"""Transform the given framework component into the respective Agent Spec JSON representation."""
def to_component(self, autogen_component: FrameworkComponent) -> Component:
"""Transform the given framework component into the respective PyAgentSpec Component."""
The AgentSpecLoader
exposes APIs to load an Agent Spec representation in one of the aforementioned forms, i.e.,
YAML, JSON, or PyAgentSpec Component object, into the corresponding agentic framework’s object.
The loader requires to specify the registry of tool implementations.
These tools will be mapped to the ServerTools used in the Agent Spec representation to load and transform.
class AgentSpecLoader:
"""Helper class to convert Agent Spec configurations to agentic framework objects."""
def __init__(self, tool_registry: Optional[Dict[str, Callable]] = None):
"""Ask for the tool registry containing the implementation of ServerTools"""
def load_yaml(self, serialized_assistant: str) -> FrameworkComponent:
"""Transform the given Agent Spec YAML representation into the respective framework Component"""
def load_json(self, serialized_assistant: str) -> FrameworkComponent:
"""Transform the given Agent Spec JSON representation into the respective framework Component"""
def load_component(self, agentspec_component: AgentSpecComponent) -> FrameworkComponent:
"""Transform the given PyAgentSpec Component into the respective framework Component"""
Basic implementation of an adapter#
As an example of how to build an adapter, let’s take WayFlow as agentic framework and implement the main functions needed to perform the transformation from an Agent Spec representation to a runnable WayFlow component.
1. Load an Agent Spec JSON representation of an agent#
The first step is to read the Agent Spec JSON representation of the assistant and deserialize it to obtain a PyAgentSpec Agent component. This component and its internals serve as the basis for building framework-specific implementations of the agent. We can take advantage of the PyAgentSpec deserialization functionality for that.
from pyagentspec.serialization import AgentSpecDeserializer
with open(CONFIGS_DIR / "simple_agent_with_rag_tool.json", "r") as file:
assistant_json = file.read()
deserializer = AgentSpecDeserializer()
deserialized_agentspec_agent = deserializer.from_json(assistant_json)
API Reference: AgentSpecDeserializer
The agent contains mainly three components that need to be created in WayFlow:
The vLLM used by the agent
The RAG tool that the agent could use to gather more information
The agent itself
The following sections detail how to create these components across different frameworks. The programmatic way to accomplish this is to build reusable methods that translate individual Agent Spec components, which are then combined to perform the final agent translation.
2. Defining the LLM#
WayFlow provides a specialized class for vLLMs called VllmModel
.
Use this class to define the agent’s language model.
from wayflowcore.models import VllmModel
from pyagentspec.llms import LlmConfig, VllmConfig
def convert_agentspec_llm_to_wayflow(agentspec_llm: LlmConfig):
if isinstance(agentspec_llm, VllmConfig):
return VllmModel(
model_id=agentspec_llm.model_id,
host_port=agentspec_llm.url,
)
# Here we should write the translation for
# the other types of LLM that are available in Agent Spec
3. Defining the tools#
The tool types available in WayFlow align with the ones defined in Agent Spec (Client, Server, Remote).
If the Agent Spec specifies a ServerTool
, the corresponding class in WayFlow must be used.
from wayflowcore.property import Property
from wayflowcore.tools import ServerTool as WayflowServerTool
from pyagentspec.tools import ServerTool, Tool
def convert_agentspec_tool_to_wayflow(agentspec_tool: Tool):
if isinstance(agentspec_tool, ServerTool):
return WayflowServerTool(
func=tool_registry[agentspec_tool.name],
name=agentspec_tool.name,
description=agentspec_tool.description,
input_descriptors=[
Property.from_json_schema(input_.json_schema) for input_ in agentspec_tool.inputs
],
output_descriptors=[
Property.from_json_schema(output.json_schema) for output in agentspec_tool.outputs
],
)
4. Defining the agent#
Create a ReAct-style agent in WayFlow using the Agent
class and providing the list of available tools.
from wayflowcore.agent import Agent as WayflowAgent
from pyagentspec.agent import Agent
def convert_agentspec_agent_to_wayflow(agentspec_agent: Agent):
return WayflowAgent(
llm=convert_agentspec_llm_to_wayflow(agentspec_agent.llm_config),
custom_instruction=agentspec_agent.system_prompt,
tools=[convert_agentspec_tool_to_wayflow(tool) for tool in agentspec_agent.tools],
)
5. Conversion#
Define the conversion method for the required Agent Spec components and invoke it on the agent to produce the corresponding WayFlow implementation.
from pyagentspec import Component
def convert_agentspec_to_wayflow(agentspec_component: Component):
if isinstance(agentspec_component, LlmConfig):
return convert_agentspec_llm_to_wayflow(agentspec_component)
elif isinstance(agentspec_component, Tool):
return convert_agentspec_tool_to_wayflow(agentspec_component)
elif isinstance(agentspec_component, Agent):
return convert_agentspec_agent_to_wayflow(agentspec_component)
# Here we should write the translation for
# the other components that are available in Agent Spec
agent = convert_agentspec_to_wayflow(deserialized_agentspec_agent)
6. Execution#
Finally, we can start the conversation with our new agent and execute it.
# We fill the input of the Agent when we start the conversation
conversation = agent.start_conversation(inputs={"domain_of_expertise": "computer science"})
status = conversation.execute()
Using the Agent Spec adapter from WayFlow#
The execution of this section requires to install the package wayflowcore
.
pip install "wayflowcore==25.4.1"
The transformation can be easily performed using this library by creating an AgentSpecLoader
object,
and calling the load_json
method directly on the Agent Spec JSON representation of the agent,
or the load_component
method on the PyAgentSpec component object.
from wayflowcore.agentspec import AgentSpecLoader
from wayflowcore.tools import tool
loader = AgentSpecLoader(
tool_registry={
tool_name: tool(tool_function, description_mode="only_docstring")
for tool_name, tool_function in tool_registry.items()
}
)
agent = loader.load_component(deserialized_agentspec_agent)
You can find more information about the Agent Spec adapter in the WayFlow API Reference.
Recap#
This guide covered how to:
Load an Agent Spec JSON representation of an agent
Run it with an agentic framework using WayFlow
Build the basics of an Agent Spec adapter
Below is the complete code from this guide.
from typing import List
def hello_world() -> None:
"""Prints 'Hello world!'"""
print("Hello world!")
return None
def rag_tool(query: str) -> List[str]:
"""Search and return the list of results"""
return ["result 1", "result 2"]
tool_registry = {
"rag_tool": rag_tool,
"hello_world_tool": hello_world,
}
from pyagentspec.serialization import AgentSpecDeserializer
with open(CONFIGS_DIR / "simple_agent_with_rag_tool.json", "r") as file:
assistant_json = file.read()
deserializer = AgentSpecDeserializer()
deserialized_agentspec_agent = deserializer.from_json(assistant_json)
from wayflowcore.models import VllmModel
from pyagentspec.llms import LlmConfig, VllmConfig
def convert_agentspec_llm_to_wayflow(agentspec_llm: LlmConfig):
if isinstance(agentspec_llm, VllmConfig):
return VllmModel(
model_id=agentspec_llm.model_id,
host_port=agentspec_llm.url,
)
# Here we should write the translation for
# the other types of LLM that are available in Agent Spec
from wayflowcore.property import Property
from wayflowcore.tools import ServerTool as WayflowServerTool
from pyagentspec.tools import ServerTool, Tool
def convert_agentspec_tool_to_wayflow(agentspec_tool: Tool):
if isinstance(agentspec_tool, ServerTool):
return WayflowServerTool(
func=tool_registry[agentspec_tool.name],
name=agentspec_tool.name,
description=agentspec_tool.description,
input_descriptors=[
Property.from_json_schema(input_.json_schema) for input_ in agentspec_tool.inputs
],
output_descriptors=[
Property.from_json_schema(output.json_schema) for output in agentspec_tool.outputs
],
)
from wayflowcore.agent import Agent as WayflowAgent
from pyagentspec.agent import Agent
def convert_agentspec_agent_to_wayflow(agentspec_agent: Agent):
return WayflowAgent(
llm=convert_agentspec_llm_to_wayflow(agentspec_agent.llm_config),
custom_instruction=agentspec_agent.system_prompt,
tools=[convert_agentspec_tool_to_wayflow(tool) for tool in agentspec_agent.tools],
)
from pyagentspec import Component
def convert_agentspec_to_wayflow(agentspec_component: Component):
if isinstance(agentspec_component, LlmConfig):
return convert_agentspec_llm_to_wayflow(agentspec_component)
elif isinstance(agentspec_component, Tool):
return convert_agentspec_tool_to_wayflow(agentspec_component)
elif isinstance(agentspec_component, Agent):
return convert_agentspec_agent_to_wayflow(agentspec_component)
# Here we should write the translation for
# the other components that are available in Agent Spec
agent = convert_agentspec_to_wayflow(deserialized_agentspec_agent)
conversation = agent.start_conversation(inputs={"domain_of_expertise": "computer science"})
status = conversation.execute()
from wayflowcore.agentspec import AgentSpecLoader
from wayflowcore.tools import tool
loader = AgentSpecLoader(
tool_registry={
tool_name: tool(tool_function, description_mode="only_docstring")
for tool_name, tool_function in tool_registry.items()
}
)
agent = loader.load_component(deserialized_agentspec_agent)
If you are interested in implementing an Agent Spec runtime adapter for a framework that is not currently supported, or you would like to enhance one of the existing ones, contributions are welcome! See the Contributing section for more details.
Next steps#
Having seen how to implement the same agent across three different frameworks, consider experimenting with your preferred one using your own Agent Spec configuration.