Home > EulerAgent > Tutorials > Basic > 06. Dynamic Workflows — Automatic Task Decomposition and ...

06. Dynamic Workflows — Automatic Task Decomposition and Phase Execution


Learning Objectives

After completing this tutorial, you will be able to:


Prerequisites

euleragent new marketing-expert --template marketing-expert
cat .euleragent/config/workspace.yaml
llm_profiles:
  local:
    provider: ollama
    base_url: http://localhost:11434
    model: qwen3:32b        # tool calling 지원 모델 필요
    timeout_seconds: 120
    keep_alive: 5m
    is_external: false
  openai:
    provider: openai
    api_key: ''
    model: gpt-4o-mini
    base_url: https://api.openai.com/v1
    is_external: true
default_llm_profile: local  # --dynamic은 실제 LLM 필수 (fake 불가)

rag:
  web_search:
    provider: fake          # 테스트용 (실제: tavily | brave)
    require_approval: true

Important: --dynamic requires the LLM to call the system.plan_workflow tool to decompose tasks. This feature does not work with default_llm_profile: fake. A real LLM such as Ollama or OpenAI is required.


What is --dynamic?

A regular euleragent run processes a task in a single agentic loop. When you add --dynamic, the LLM first automatically decomposes the task into multiple phases, then executes each phase sequentially.

Two-Stage Protocol

Stage 1 — Planning: Only the system.plan_workflow tool is provided to the LLM. The LLM decomposes the task into a list of phases.

{
  "workflow_title": "마케팅 전략 분석",
  "phases": [
    {"title": "리서치", "task": "경쟁사 정보 수집", "mode": "plan"},
    {"title": "분석", "task": "데이터 종합 분석", "mode": "plan"},
    {"title": "보고서 작성", "task": "최종 리포트 생성", "mode": "execute"}
  ]
}

Stage 2 — Phase-by-Phase Execution: - plan phases: Only web.search is provided to the LLM, which proposes search queries. These go to the approval queue, and the workflow pauses. - execute phases: Collected results are injected into the context, and the final output is generated.

Phase Classification Rules

Mode Keyword Classification
execute, synthesis, write, report, draft, create, generate, produce, compile execute phase
research, gather, collect, search, analyze plan phase
If the last phase has none of these keywords Automatically promoted to execute

MCP search sources and workflow phases: In environments with MCP search providers configured, each workflow phase can use different search sources. For example, you can specify --source-set to use academic sources (academic) during the research phase and news sources (news) during the analysis phase. The SearchRouter automatically routes to the appropriate MCP source based on each phase's query characteristics.


Step-by-Step Walkthrough

Step 1: Start a Workflow with --dynamic

euleragent run marketing-expert \
  --task "LangChain, CrewAI, AutoGen 3개 AI 에이전트 프레임워크를 분석하고 EulerAI의 경쟁 전략 마케팅 보고서를 작성해줘. 웹 검색 결과 기반으로 작성해야 해." \
  --dynamic

Internal behavior: 1. The LLM calls system.plan_workflow to decompose the task into phases 2. The runner classifies each phase (plan/execute) 3. WorkflowRunner executes the first phase 4. When web.search is proposed, the workflow automatically pauses

Expected output:

Workflow 'AI Framework Competitive Analysis' created (3 phases, run_id=a1b2c3d4e5f6)
  Phase 0: [plan] 리서치 단계 — LangChain, CrewAI, AutoGen 정보 수집
  Phase 1: [plan] 분석 단계 — 프레임워크 비교 및 EulerAI 포지셔닝
  Phase 2: [execute] 보고서 작성 — 경쟁 마케팅 전략 보고서 생성

Workflow paused at phase 0 (2 approval(s) pending).
  Use: euleragent approve accept-all --run-id a1b2c3d4e5f6 --actor "user:you" --execute
  Then: euleragent workflow resume a1b2c3d4e5f6 --execute

Step 2: Check Workflow Status

euleragent workflow show a1b2c3d4e5f6

Expected output:

Workflow: AI Framework Competitive Analysis
  Run ID:  a1b2c3d4e5f6
  Status:  paused
  Phases:  3 total, current=0

  → [0] 리서치 단계 (plan) — paused
        Approvals pending: apv_001, apv_002
    [1] 분석 단계 (plan) — pending
    [2] 보고서 작성 (execute) — pending

View in JSON format:

euleragent workflow show a1b2c3d4e5f6 --format json
{
  "workflow_id": "wf_x1y2z3",
  "run_id": "a1b2c3d4e5f6",
  "title": "AI Framework Competitive Analysis",
  "status": "paused",
  "current_phase": 0,
  "phases": [
    {
      "index": 0,
      "title": "리서치 단계",
      "mode": "plan",
      "status": "paused",
      "pending_approvals": ["apv_001", "apv_002"]
    },
    {
      "index": 1,
      "title": "분석 단계",
      "mode": "plan",
      "status": "pending"
    },
    {
      "index": 2,
      "title": "보고서 작성",
      "mode": "execute",
      "status": "pending"
    }
  ]
}

Inspect the workflow JSON file directly:

cat .euleragent/runs/a1b2c3d4e5f6/workflow.json

Step 3: Approve and Execute the First Phase

# 승인 목록 확인
euleragent approve list --run-id a1b2c3d4e5f6

Expected output:

Pending approvals (2):

  ID        TOOL        RISK    STATUS
  apv_001   web.search  medium  pending
  apv_002   web.search  medium  pending

Accept all approvals for the first phase and execute:

euleragent approve accept-all --run-id a1b2c3d4e5f6 --actor "user:you" --execute

Expected output:

Accepted and executed 2 approval(s).
  [OK] web.search (apv_001) — "LangChain features 2025" → 5 results
  [OK] web.search (apv_002) — "CrewAI AutoGen comparison" → 4 results
Executed 2/2 successfully.

Step 4: Resume the Workflow

Add the --execute flag to automatically handle approvals for all subsequent phases:

euleragent workflow resume a1b2c3d4e5f6 --execute

Expected output:

Resuming workflow 'AI Framework Competitive Analysis' from phase 0...

Phase 0 (리서치 단계) — approvals resolved → marked finished.

Starting phase 1 (분석 단계, plan)...
Phase 1 paused (1 new approval(s)) — auto-executing with --execute...
  [OK] web.search (apv_003) — "EulerAI positioning AI agent market" → 3 results
Executed 1/1 — continuing...

Starting phase 2 (보고서 작성, execute)...
Phase 2 paused (1 new approval(s)) — auto-executing with --execute...
  [OK] web.search (apv_004) — "EulerAI competitive advantages" → 4 results

Phase 2 re-running with search results injected (web.search excluded)...
  LLM generating final report...

Workflow 'AI Framework Competitive Analysis' finished (run_id=a1b2c3d4e5f6).

Artifacts:
  .euleragent/runs/a1b2c3d4e5f6/artifacts/phase_0/plan.md
  .euleragent/runs/a1b2c3d4e5f6/artifacts/phase_1/plan.md
  .euleragent/runs/a1b2c3d4e5f6/artifacts/phase_2/result.md

What --execute does: It automatically accepts and executes new approvals that arise in subsequent phases. Without --execute, running workflow resume requires manual handling each time a new approval is generated.


Step 5: Review Artifacts

Each phase's output is stored in a separate subdirectory:

ls .euleragent/runs/a1b2c3d4e5f6/artifacts/
phase_0/    phase_1/    phase_2/
# 리서치 단계 결과 (plan.md: 검색 제안 및 요약)
cat .euleragent/runs/a1b2c3d4e5f6/artifacts/phase_0/plan.md

# 분석 단계 결과 (plan.md: 비교 분석)
cat .euleragent/runs/a1b2c3d4e5f6/artifacts/phase_1/plan.md

# 최종 보고서 (result.md: 마케팅 전략 리포트)
cat .euleragent/runs/a1b2c3d4e5f6/artifacts/phase_2/result.md

Full run directory structure:

.euleragent/runs/a1b2c3d4e5f6/
├── input.json              # 실행 입력 (플래닝 메타데이터)
├── messages.jsonl          # 모든 단계의 LLM 대화 기록 (누적)
├── tool_calls.jsonl        # 모든 단계의 도구 호출 기록 (누적)
├── approvals.jsonl         # 모든 승인 기록 (누적)
├── workflow.json           # 최종 워크플로우 상태
├── workflow_events.jsonl   # 이벤트 로그 (created/started/paused/resumed/finished)
├── search_routing.jsonl    # 검색 라우팅 결정 기록 (MCP 사용 시)
└── artifacts/
    ├── phase_0/
    │   └── plan.md
    ├── phase_1/
    │   └── plan.md
    └── phase_2/
        └── result.md

If you are using MCP search providers, each phase's search routing decisions are recorded in search_routing.jsonl:

cat .euleragent/runs/a1b2c3d4e5f6/search_routing.jsonl
{"phase": 0, "query": "LangChain features 2025", "routed_to": "tavily", "source_set": "default", "timestamp": 1740268215.0}
{"phase": 0, "query": "CrewAI AutoGen comparison", "routed_to": "brave", "source_set": "default", "timestamp": 1740268216.0}
{"phase": 1, "query": "EulerAI positioning AI agent market", "routed_to": "tavily", "source_set": "default", "timestamp": 1740268240.0}

Check the workflow event history:

cat .euleragent/runs/a1b2c3d4e5f6/workflow_events.jsonl
{"type": "workflow.created", "run_id": "a1b2c3d4e5f6", "phases": 3, "timestamp": 1740268200.0}
{"type": "workflow.phase.started", "phase_id": "phase_0", "mode": "plan", "timestamp": 1740268210.0}
{"type": "workflow.paused", "phase_id": "phase_0", "approval_ids": ["apv_001", "apv_002"], "timestamp": 1740268215.0}
{"type": "workflow.resumed", "phase_id": "phase_0", "timestamp": 1740268230.0}
{"type": "workflow.phase.finished", "phase_id": "phase_0", "timestamp": 1740268231.0}
{"type": "workflow.phase.started", "phase_id": "phase_1", "mode": "plan", "timestamp": 1740268232.0}
{"type": "workflow.phase.finished", "phase_id": "phase_1", "timestamp": 1740268250.0}
{"type": "workflow.phase.started", "phase_id": "phase_2", "mode": "execute", "timestamp": 1740268251.0}
{"type": "workflow.finished", "run_id": "a1b2c3d4e5f6", "timestamp": 1740268310.0}

Step 6: REST API — euleragent serve

Use the REST API when integrating with CI/CD pipelines or dashboards:

# 터미널 1: 서버 시작
euleragent serve

Expected output:

euleragent API server running at http://localhost:8844
  WebSocket: ws://localhost:8844/ws/events
  Press Ctrl+C to stop.

API calls from terminal 2:

# 런 상태 확인
curl http://localhost:8844/runs/a1b2c3d4e5f6/status
{"run_id": "a1b2c3d4e5f6", "state": "paused", "agent": "marketing-expert"}
# 워크플로우 상태 확인
curl http://localhost:8844/runs/a1b2c3d4e5f6/workflow
{
  "status": "paused",
  "current_phase": 0,
  "phases": [{"index": 0, "status": "paused"}, ...]
}
# 승인 목록 조회
curl "http://localhost:8844/approvals?run_id=a1b2c3d4e5f6"
[
  {"id": "apv_001", "tool_name": "web.search", "status": "pending"},
  {"id": "apv_002", "tool_name": "web.search", "status": "pending"}
]
# CI/CD: 모든 승인 일괄 수락 + 실행
curl -X POST \
  "http://localhost:8844/approvals/accept-all?run_id=a1b2c3d4e5f6&execute=true"
{"accepted": 2, "executed": 2, "failed": 0}

Receive real-time events via WebSocket:

# wscat 설치: npm install -g wscat
wscat -c ws://localhost:8844/ws/events
{"type": "server.connected", "timestamp": 1740268200.0}
{"type": "workflow.phase.started", "run_id": "a1b2c3d4e5f6", "phase_id": "phase_1"}
{"type": "workflow.paused", "run_id": "a1b2c3d4e5f6", "approval_ids": ["apv_003"]}
{"type": "workflow.finished", "run_id": "a1b2c3d4e5f6"}

--dynamic vs Regular Patterns — Selection Guide

Situation Recommended Approach
Simple task with clear steps Regular euleragent run
Multiple web searches followed by report generation --dynamic
Complex task where decomposition is unclear --dynamic
Running the same pipeline repeatedly Formalize with --task-file
Complex dependencies between steps --dynamic
Quick single task Regular euleragent run --mode execute
CI/CD automation euleragent serve + REST API

Expected Output Summary

# 워크플로우 생성
Workflow 'AI Framework Competitive Analysis' created (3 phases, run_id=a1b2c3d4e5f6)
  Phase 0: [plan] 리서치 단계
  Phase 1: [plan] 분석 단계
  Phase 2: [execute] 보고서 작성
Workflow paused at phase 0 (2 approval(s) pending).

# 워크플로우 상태 확인
euleragent workflow show a1b2c3d4e5f6
  → [0] 리서치 단계 (plan) — paused
    [1] 분석 단계 (plan) — pending
    [2] 보고서 작성 (execute) — pending

# 승인 후 재개
euleragent workflow resume a1b2c3d4e5f6 --execute
  Phase 1 auto-executing...  [OK] web.search
  Phase 2 re-running with results injected...
Workflow finished.

FAQ / Common Errors

Q: I get the error "Agent did not call system.plan_workflow."

--dynamic requires a real LLM. Check that default_llm_profile in workspace.yaml is not set to fake:

default_llm_profile: local   # fake가 아닌 실제 LLM 프로필

Verify that Ollama is running and a model with tool calling support is available:

ollama list
ollama serve

Q: All phases are shown as [plan] and no result.md is generated.

When working correctly, the last phase is automatically promoted to execute. This feature may not be present in older versions. Upgrade and try again:

pip install -e . --upgrade

To verify manually:

euleragent workflow show <run-id> --format json | python3 -m json.tool
# 마지막 phase의 "mode" 확인

Q: The workflow keeps pausing at the same phase after workflow resume.

Check if there are remaining pending approvals:

euleragent approve list --run-id a1b2c3d4e5f6

If there are still pending approvals:

euleragent approve accept-all --run-id a1b2c3d4e5f6 --actor "user:you" --execute
euleragent workflow resume a1b2c3d4e5f6 --execute

Q: The workflow immediately finishes without any approval steps.

This was a bug in earlier versions. In the latest version, only web.search is provided to the LLM during plan phases, ensuring search proposals are always generated. Upgrade and try again.

Also verify that web.search is included in the agent's tools.yaml allowlist:

cat .euleragent/agents/marketing-expert/tools.yaml
# allowlist에 web.search 포함 여부 확인

Q: I want to change the default port for euleragent serve.

euleragent serve --port 9000

Then access it at http://localhost:9000.


Common Mistakes (Order Issues)

Symptom Cause Recovery
Error: No workflow found for run 'X'. Tried workflow resume on a run executed without --dynamic euleragent run <agent> --task '...' --dynamic
Error: Run 'X' not found. Incorrect run ID ls .euleragent/runs/
Pending approvals remain, cannot resume Approvals not fully processed euleragent approve accept-all --run-id <id> --execute

Next step: 07_web_rag.md — Learn how to combine web search with a local knowledge base (RAG).

← Prev Back to List Next →