This post walks through building and running a real-world agentic workflow with Agentican and Quarkus.
Specifically, an agentic workflow to automate market research and information sharing:
- Identify the top vendors within a market category.
- Research the positioning and strengths of each vendor.
- Classify the findings as either standard or urgent.
- Draft a brief to share with others in the company.
Prerequisites
- Quarkus
- Java 25
- Maven (or Gradle)
- LLM provider API key
Step 1: Add the dependency
Create a Quarkus app, and add the Agentican Quarkus runtime module:
<dependency>
<groupId>ai.agentican</groupId>
<artifactId>agentican-quarkus-runtime</artifactId>
<version>0.1.0-alpha.4</version>
</dependency>
Step 2: Define agents, skills and the workflow
Create an agentican-catalog.yaml file on the classpath.
This is where you describe:
- Who does the work (agents).
- What they need to do it (skills).
- How they will do it (workflows).
agents:
- id: researcher
name: researcher
role: |
Expert at finding accurate, sourced information about
companies and markets. Quotes sources. Distinguishes
opinion from fact.
- id: writer
name: writer
role: |
Synthesizes research into structured, concise briefs.
Avoids hedging language. Cites concrete evidence.
skills:
- id: web-search
name: web-search
instructions: |
When a question requires external information, call the
search tool first. Quote sources in your answer.
Update the agentican-catalog.yaml file to define the workflow.
workflows:
- id: market-brief
name: market-brief
description: Research vendors in a market and produce a
structured brief
outputStep: deliver
params:
- name: topic
description: Market to research
required: true
- name: vendor_count
description: Number of vendors
defaultValue: "5"
steps:
- name: identify
agent: researcher
skills: [web-search]
instructions: |
Identify the top {{param.vendor_count}} vendors in
{{param.topic}}. Return a JSON array of vendor names
— names only, no commentary.
- name: deep-dive
type: loop
over: identify
steps:
- name: analyze
agent: researcher
skills: [web-search]
instructions: |
Deep-dive vendor {{item}}: positioning, key
strengths, recent news. Quote sources.
- name: classify
agent: writer
instructions: |
Read the per-vendor deep-dives below. If any vendor has
launched a competitive feature in the last 30 days,
return the single word 'urgent'. Otherwise return
'standard'.
Deep-dives: {{step.deep-dive.output}}
dependencies: [deep-dive]
- name: deliver
type: branch
from: classify
default: standard
branches:
- name: urgent
steps:
- name: urgent-brief
agent: writer
instructions: |
Synthesize a vendor brief flagged URGENT for
executive review. Lead with the recent
competitive moves.
Topic: {{param.topic}}
Deep-dives: {{step.deep-dive.output}}
- name: standard
steps:
- name: standard-brief
agent: writer
instructions: |
Synthesize a vendor brief.
Topic: {{param.topic}}
Deep-dives: {{step.deep-dive.output}}
A few things worth flagging:
-
agent: researcherreferences the agent for an agent step. -
outputStepdesignates the step whose output becomes the workflow's result. -
{{param.X}}interpolates workflow inputs into step instructions. -
{{step.X.output}}interpolates an upstream step's output. -
{{item}}is the current value inside a loop iteration. -
type: loopsteps take anoverreference (a step that produced a list). -
type: loopsteps run their nestedstepsonce per item, and in parallel. -
type: branchsteps take afromreference (step used to select branch). -
branches:mutually exclusive steps withdefaultfor unrecognized values.
The framework loads agentican-catalog.yaml from the classpath at boot, or you can define where it's loaded from:
agentican.catalog-config=/etc/agentican/agentican-catalog.yaml
Note: Agents, skills and workflows can be defined via a fluent builder API as well.
Step 3: Configure the models
Agentican loads runtime configuration from application.properties. The minimum is one LLM:
agentican.llm[0].api-key=${ANTHROPIC_API_KEY}
The provider defaults to anthropic, and the model defaults to claude-sonnet-4-5.
OpenAI
agentican.llm[0].provider=openai
agentican.llm[0].api-key=${OPENAI_API_KEY}
agentican.llm[0].model=gpt-4o-mini
Multiple, named LLMs
agentican.llm[0].name=default
agentican.llm[0].api-key=${ANTHROPIC_API_KEY}
agentican.llm[1].name=efficient
agentican.llm[1].provider=openai
agentican.llm[1].api-key=${OPENAI_API_KEY}
agentican.llm[1].model=gpt-4o-mini
Step 4: Create a typed workflow instance
Define the workflow input and output records:
public record ResearchParams(String topic, int vendorCount) {}
public record VendorBrief(String topic, List<Vendor> vendors) {
public record Vendor(String name,
String positioning,
List<String> strengths) {}
}
Then inject the typed workflow, and call it from a REST endpoint:
@Path("/market-brief")
public class VendorBriefResource {
@Inject
@AgenticanWorkflow(name = "market-brief")
Workflow<ResearchParams, VendorBrief> brief;
@POST
@Path("/{topic}")
public VendorBrief generate(@PathParam("topic") String topic) {
return brief.start(new ResearchParams(topic, 5)).await();
}
}
Now, test the endpoint:
curl -X POST http://localhost:8080/market-brief/databases
A few things worth flagging — they're what set this apart from a generic "call an LLM" library:
-
ResearchParams.vendorCountbecomes the workflow parametervendor_countviaSNAKE_CASEmapping. -
start()returns aWorkflowRun<VendorBrief>.await()parses the output step's text into aVendorBrief. -
@AgenticanWorkflow(name = "vendor-brief")resolves the registered workflow at injection time.
The WorkflowRun itself exposes future() for a CompletableFuture<R>, and there's a ReactiveWorkflow<P, R> Mutiny variant for Vert.x stacks.
Step 5: Add tools (MCP and Composio).
Agentican ships two integrations out of the box:
MCP (Model Context Protocol)
There is one config block per server. Tools are auto-discovered:
agentican.mcp[0].slug=github
agentican.mcp[0].name=GitHub
agentican.mcp[0].url=https://mcp.github.com/sse
agentican.mcp[0].headers.Authorization=Bearer ${GITHUB_TOKEN}
Composio
100+ SaaS toolkits — Slack, Notion, Linear, Salesforce, GitHub, Google Workspace:
agentican.composio.api-key=${COMPOSIO_API_KEY}
agentican.composio.user-id=user-123
Tools are reference by name within agent steps:
steps:
- name: research
agent: researcher
tools: [github_search_repositories]
instructions: "Profile open-source vendors in {{param.topic}}."
Where to go next
- Getting Started — install, configure and run workflows
- Core Concepts — architecture, terminology and data flow
- Workflows & Steps — CDI surface, beans, qualifiers, override patterns.
- Agents — defining agents, skills and roles
- Getting Started (Quarkus) — dependency setup, config, first task
- CDI Integration — injection, qualifiers, lifecycle events, bean overrides
- REST API — endpoints, SSE streaming, WebSocket, error codes
- Observability — Micrometer metrics, OTel tracing, Prometheus queries
Structured agentic workflows for the JVM.
United States
NORTH AMERICA
Related News
Amazon Employees Are 'Tokenmaxxing' Due To Pressure To Use AI Tools
20h ago
UCP Variant Data: The #1 Reason Agent Checkouts Fail
6h ago

Décryptage technique : Comment builder un téléchargeur de vidéos Reddit performant (DASH, HLS & WebAssembly)
16h ago
How Braze’s CTO is rethinking engineering for the agentic area
10h ago
Encryption Protocols for Secure AI Systems: A Practical Guide
20h ago