Agent Orchestration Examples
This chapter presents practical examples of orchestrating agent nodes combined with other RuleGo nodes. These examples are applicable to scenarios that require linking LLM output with business logic.
Tip: In most scenarios, simply configuring an
ai/agentnode + tools/skills is sufficient. The following examples are advanced use cases for specific scenarios such as small model intent orchestration and multi-step processing pipelines.
# Example 1: IoT Command Routing
# Scenario Description
Use a small model (such as qwen3.5-2b) to convert user natural language into IoT device commands, without calling tools, outputting structured JSON, followed by routing nodes to dispatch to the device control platform. Suitable for smart home, industrial equipment control, and similar scenarios.
# Execution Flow
User input
|
[ai/agent] Small model command parsing (maxStep=1, no tools)
| Outputs JSON: {"action": "turnOn", "device": "light"}
[jsTransform] Clean output (extract JSON)
|
[jsFilter] Route decision (has action field?)
|-- True -> [restApiCall] Send to device control platform
+-- False -> End directly
|
End
2
3
4
5
6
7
8
9
10
11
# Complete Configuration
{
"ruleChain": {
"id": "iot-command-router",
"name": "IoT Command Router",
"additionalInfo": {
"description": "Natural language to device commands + route to control platform"
}
},
"metadata": {
"firstNodeIndex": 0,
"nodes": [
{
"id": "node_agent",
"type": "ai/agent",
"name": "Command Parsing",
"configuration": {
"url": "${global.models.providers.default.base_url}",
"key": "${global.models.providers.default.api_key}",
"model": "${global.models.providers.default.model}",
"maxStep": 1,
"systemPrompt": "${include(global.root_dir+'/workspace/AGENTS.md')}",
"tools": [],
"params": {
"temperature": 0.3
}
}
},
{
"id": "node_clean",
"type": "jsTransform",
"name": "Clean Output",
"configuration": {
"jsScript": "// Extract JSON, remove markdown code block markers\nif(typeof msg==='string'){\n msg=msg.replace(/^```[a-z]*\\s*/i,'').replace(/\\s*```$/,'');\n var i=msg.indexOf('{');\n if(i>0) msg=msg.substring(i);\n msg=msg.trim();\n}\nreturn {msg:msg, metadata:metadata, msgType:msgType, dataType:'JSON'};"
}
},
{
"id": "node_route",
"type": "jsFilter",
"name": "Route Decision",
"configuration": {
"jsScript": "// Check if action field exists\nif(typeof msg==='string'){\n try{ var o=JSON.parse(msg); return !!o.action; }\n catch(e){ return false; }\n}\nreturn typeof msg==='object' && !!msg.action;"
}
},
{
"id": "node_execute",
"type": "restApiCall",
"name": "Send Command",
"configuration": {
"requestMethod": "POST",
"restEndpointUrlPattern": "${global.iot_platform_url}/api/v1/device/command",
"headers": { "Content-Type": "application/json" },
"readTimeoutMs": 5000
}
},
{
"id": "node_end",
"type": "end",
"name": "End"
}
],
"connections": [
{ "fromId": "node_agent", "toId": "node_clean", "type": "Success" },
{ "fromId": "node_agent", "toId": "node_end", "type": "Stream" },
{ "fromId": "node_agent", "toId": "node_end", "type": "Failure" },
{ "fromId": "node_clean", "toId": "node_route", "type": "Success" },
{ "fromId": "node_route", "toId": "node_execute", "type": "True" },
{ "fromId": "node_route", "toId": "node_end", "type": "False" },
{ "fromId": "node_execute", "toId": "node_end", "type": "Success" },
{ "fromId": "node_execute", "toId": "node_end", "type": "Failure" }
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Key Configuration Notes
| Configuration | Description |
|---|---|
systemPrompt | Loads prompt from external file via ${include()}, takes effect without restart after file modification |
maxStep: 1 | Only one inference pass, no tool call loop |
tools: [] | Empty array, no tools used |
temperature: 0.3 | Low temperature for more stable output |
node_clean | Cleans LLM output markdown markers, extracts pure JSON |
node_route | Decides whether to send command based on presence of action field |
Tip:
systemPromptsupports loading prompt content from external files via${include('file_path')}, which is easier to maintain and iterate than inline JSON. After modifying the file, the agent's next execution will pick up the changes without restarting the service or updating the rule chain configuration.
The corresponding workspace/AGENTS.md file content:
# Task
You are an IoT command parser. Convert user natural language into device control JSON.
## Supported Devices
light, fan, ac, curtain
## Supported Actions
- turnOn
- turnOff
- setTimer
## Output Format
{"action": "action", "device": "device_name"}
Timer scenario: {"action": "setTimer", "device": "device_name", "delay": seconds}
## Examples
- "Help me turn on the light" -> {"action": "turnOn", "device": "light"}
- "Turn off the AC" -> {"action": "turnOff", "device": "ac"}
- "Turn off the fan in 5 minutes" -> {"action": "setTimer", "device": "fan", "delay": 300}
## Constraints
Output only JSON, no explanations, no markdown formatting.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Example 2: Equipment Fault Diagnosis + Work Order Generation
# Scenario Description
When equipment fails, operations staff describe the fault phenomena in natural language (which may contain vague or inaccurate information). The LLM analyzes root causes combined with equipment knowledge and provides remediation suggestions, automatically generating work orders submitted to the operations system. This scenario requires the LLM's semantic understanding and reasoning capabilities, which cannot be covered by hard-coded rule engine logic.
# Execution Flow
Operations staff fault description
|
[ai/agent] Fault diagnosis (maxStep=1, no tools)
| Outputs JSON: {"rootCause": "...", "severity": "...", "suggestion": "..."}
[jsTransform] Clean output + attach equipment information
|
[jsFilter] Severity level judgment (is severity critical?)
|-- True (urgent) -> [restApiCall] Create urgent work order
+-- False (normal) -> [restApiCall] Create normal work order
|
End
2
3
4
5
6
7
8
9
10
11
# Complete Configuration
{
"ruleChain": {
"id": "iot-fault-diagnosis",
"name": "Equipment Fault Diagnosis",
"additionalInfo": {
"description": "AI fault diagnosis + automatic work order generation by severity level"
}
},
"metadata": {
"firstNodeIndex": 0,
"nodes": [
{
"id": "node_agent",
"type": "ai/agent",
"name": "Fault Diagnosis",
"configuration": {
"url": "${global.models.providers.default.base_url}",
"key": "${global.models.providers.default.api_key}",
"model": "${global.models.providers.default.model}",
"maxStep": 1,
"systemPrompt": "${include(global.root_dir+'/workspace/AGENTS.md')}",
"tools": [],
"params": {
"temperature": 0.3
}
}
},
{
"id": "node_enrich",
"type": "jsTransform",
"name": "Construct Work Order",
"configuration": {
"jsScript": "// Clean LLM output, attach equipment info, construct work order\nvar result = msg;\nif(typeof msg==='string'){\n msg=msg.replace(/^```[a-z]*\\s*/i,'').replace(/\\s*```$/,'');\n var i=msg.indexOf('{');\n if(i>0) msg=msg.substring(i);\n result=JSON.parse(msg);\n}\nvar ticket = {\n title: result.summary,\n description: result.rootCause + '\\n\\nRemediation suggestion: ' + result.suggestion,\n severity: result.severity,\n category: result.category,\n deviceId: metadata.deviceId || '',\n reporter: metadata.reporter || '',\n createdAt: new Date().toISOString()\n};\nreturn {msg:JSON.stringify(ticket), metadata:metadata, msgType:msgType, dataType:'JSON'};"
}
},
{
"id": "node_route",
"type": "jsFilter",
"name": "Is Urgent",
"configuration": {
"jsScript": "var o=typeof msg==='string'?JSON.parse(msg):msg;\nreturn o.severity==='critical';"
}
},
{
"id": "node_urgent",
"type": "restApiCall",
"name": "Create Urgent Work Order",
"configuration": {
"requestMethod": "POST",
"restEndpointUrlPattern": "${global.iot_platform_url}/api/v1/ticket/urgent",
"headers": { "Content-Type": "application/json" },
"readTimeoutMs": 5000
}
},
{
"id": "node_normal",
"type": "restApiCall",
"name": "Create Normal Work Order",
"configuration": {
"requestMethod": "POST",
"restEndpointUrlPattern": "${global.iot_platform_url}/api/v1/ticket/normal",
"headers": { "Content-Type": "application/json" },
"readTimeoutMs": 5000
}
},
{
"id": "node_end",
"type": "end",
"name": "End"
}
],
"connections": [
{ "fromId": "node_agent", "toId": "node_enrich", "type": "Success" },
{ "fromId": "node_agent", "toId": "node_end", "type": "Failure" },
{ "fromId": "node_enrich", "toId": "node_route", "type": "Success" },
{ "fromId": "node_route", "toId": "node_urgent", "type": "True" },
{ "fromId": "node_route", "toId": "node_normal", "type": "False" },
{ "fromId": "node_urgent", "toId": "node_end", "type": "Success" },
{ "fromId": "node_urgent", "toId": "node_end", "type": "Failure" },
{ "fromId": "node_normal", "toId": "node_end", "type": "Success" },
{ "fromId": "node_normal", "toId": "node_end", "type": "Failure" }
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# Key Configuration Notes
| Configuration | Description |
|---|---|
maxStep: 1 | Single inference, no tool calls |
systemPrompt | Loads diagnostic knowledge and rules from external file via ${include()} |
node_enrich | Cleans LLM output + attaches equipment/reporter information from metadata, assembles into work order format |
node_route | Determines whether to create urgent work order based on severity field |
node_urgent | Urgent work orders go through expedited channel, triggering on-call notifications |
node_normal | Normal work orders go through standard process |
The corresponding workspace/AGENTS.md file content:
# Task
You are an equipment fault diagnosis expert. Analyze possible causes based on the fault phenomena described by operations staff and provide remediation suggestions.
## Output Format
{
"category": "fault category",
"severity": "severity level",
"summary": "one-line summary",
"rootCause": "root cause analysis",
"suggestion": "remediation suggestion"
}
## Fault Categories
- power: Power faults (outage, overload, short circuit)
- network: Communication faults (disconnection, weak signal, protocol errors)
- mechanical: Mechanical faults (abnormal vibration, jamming, wear)
- sensor: Sensor faults (abnormal data, drift, loss of contact)
- environmental: Environmental faults (temperature/humidity exceedance, water leak, smoke)
- software: Software faults (crash, configuration error, version incompatibility)
## Severity Levels
- critical: Affects production safety or causes equipment shutdown, requires immediate action
- major: Affects partial functionality, requires prompt action
- minor: Does not affect main functionality, can be planned for action
## Analysis Principles
1. Infer the most likely cause based on the description; if multiple possibilities exist, rank by probability
2. Remediation suggestions should be specific and actionable, not vague
3. If description information is insufficient, state in rootCause what needs further confirmation
## Constraints
Output only JSON, no explanations, no markdown formatting.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Diagnosis Examples
| Operations Staff Description | AI Diagnosis Result | Route |
|---|---|---|
| "Line 3 robot arm can't stop after reaching position, some overshoot, getting worse lately" | {"category": "mechanical", "severity": "major", "rootCause": "Servo drive position loop gain degradation or mechanical transmission wear", "suggestion": "First check if servo parameters have drifted, then check ballscrew and guide rail wear"} | -> Normal work order |
| "Electrical cabinet smells burnt, hear buzzing sound" | {"category": "power", "severity": "critical", "rootCause": "Suspected loose terminal causing arcing", "suggestion": "Immediately cut power, evacuate personnel, contact electrician to check wiring"} | -> Urgent work order |
| "Warehouse temperature and humidity sensor data keeps jumping around" | {"category": "sensor", "severity": "minor", "rootCause": "Sensor aging or signal cable interference", "suggestion": "Replace sensor or check shield wire grounding"} | -> Normal work order |
# Orchestration Pattern Summary
# Common Node Types
| Node Type | Purpose | Typical Scenarios |
|---|---|---|
ai/agent | AI agent, ReAct reasoning loop | Intent classification, text generation, tool calls |
ai/llm | Single LLM call, no tools | Simple text generation, classification |
jsFilter | JavaScript conditional filtering | Route decisions, data validation |
jsTransform | JavaScript data transformation | Clean output, format conversion, construct request body |
restApiCall | Call external REST API | Execute commands, data synchronization |
end | End node | Required, marks process end |
# Connection Types
| Type | Description |
|---|---|
Success | Synchronous execution success |
Stream | Streaming output (one message per chunk) |
Failure | Execution failure |
True | jsFilter condition is true |
False | jsFilter condition is false |
# Design Recommendations
- Small model + no tools: Use
maxStep=1+tools: []for intent classification scenarios to reduce cost and latency - Output cleanup: LLM output often contains markdown markers; use
jsTransformto clean before routing - Error handling: Add
Failureconnections for key nodes to ensure errors are not lost - Streaming support: Add
Streamconnections forai/agentnodes to support real-time output
# Related Documentation
- Overview — Framework positioning and core concepts
- [Agent Node](./02.Agent Node.md) — ReAct node configuration details
- [Tool System](./03.Tool System.md) — Tool types and configuration
- Agent Component — Complete configuration reference for
ai/agent - [Application Case Study](./08.Application Case Study.md) — Complete smart assistant platform case study