Sangeetha-Grantha

Metadata Value
Status Active
Version 1.1.0
Last Updated 2026-09-10
Author Sangeetha Grantha Team
Document Type Design reference

Koog Framework Evaluation for Import Pipeline


[!NOTE] Design/reference material: this page may include proposals or earlier implementation assumptions. Use current ingestion guide for implemented behavior and current operating steps.


Document Consolidation Note

This document consolidates Koog evaluation from multiple sources:

Key insights from all sources have been integrated into this consolidated evaluation.


1. Executive Summary

This document provides a detailed evaluation of Koog specifically for the Krithi import pipeline use case. It builds on existing Koog analysis documents and provides import-pipeline-specific recommendations.

Key Finding: Koog offers significant value for complex, multi-stage import workflows, but may be over-engineered for initial phases. A phased evaluation approach is recommended: start with custom workflow, then evaluate Koog for specific pain points.


2. Import Pipeline Requirements Recap

2.1 Pipeline Stages

The import pipeline consists of 10 stages:

  1. Discovery - URL collection
  2. Scraping - HTML fetching
  3. Extraction - AI-powered content extraction
  4. Entity Resolution - Map to canonical entities
  5. Data Cleansing - Normalization
  6. De-duplication - Duplicate detection
  7. Validation - Quality checks
  8. Staging - Store in imported_krithis
  9. Human Moderation - Review workflow
  10. Canonicalization - Create Krithi entities

2.2 Key Requirements


3. Koog Capabilities for Import Pipeline

3.1 Graph Workflows

Koog Strength: Define complex workflows as graphs

Import Pipeline as Koog Graph:

val importWorkflow = agent {
    graph {
        val discovery = node("discover") { discoverUrls(source) }
        val scraping = node("scrape") { scrapeUrl(url) }
        val extraction = node("extract") { extractMetadata(html) }
        val entityResolution = node("resolve") { resolveEntities(metadata) }
        val cleansing = node("cleanse") { cleanseData(mapped) }
        val deduplication = node("dedupe") { findDuplicates(cleaned) }
        val validation = node("validate") { validateData(processed) }
        val staging = node("stage") { stageForReview(validated) }
        
        discovery -> scraping -> extraction -> entityResolution -> 
        cleansing -> deduplication -> validation -> staging
    }
}

Benefits:

Considerations:


3.2 Tool Calling

Koog Strength: Integrate external systems as tools

Import Pipeline Tools:

val scrapingTool = tool("scrape_url") {
    description = "Scrape HTML content from URL"
    parameter<String>("url")
    execute { url ->
        webScrapingService.scrape(url)
    }
}

val entityResolutionTool = tool("resolve_composer") {
    description = "Resolve composer name to canonical entity"
    parameter<String>("name")
    execute { name ->
        entityResolutionService.resolveComposer(name)
    }
}
val validationTool = tool("validate_krithi") {
    description = "Validate extracted Krithi data"
    parameter<ExtractedMetadata>("metadata")
    execute { metadata ->
        validationService.validate(metadata)
    }
}

Benefits:

Considerations:


3.3 Retry & Fault Tolerance

Koog Strength: Built-in retry and persistence

Retry Configuration:

agent {
    retryPolicy {
        maxRetries = 3
        backoffStrategy = ExponentialBackoff(
            initialDelay = 1.seconds,
            maxDelay = 30.seconds
        )
    }
    
    persistence {
        // Save workflow state for recovery
        storage = DatabasePersistence(db)
    }
}

Benefits:

Considerations:


3.4 Observability

Koog Strength: OpenTelemetry integration

**Tracing:**

agent { tracing { exporter = OpenTelemetryExporter() level = TraceLevel.DETAILED } }


**Benefits:**
- ✅ Comprehensive tracing
- ✅ Integration with monitoring tools
- ✅ Performance insights
- ✅ Debug workflow execution

**Considerations:**
- Setup overhead
- May be overkill initially
- Can add later if needed

---

### 3.5 Provider Flexibility

**Koog Strength**: Switch LLM providers easily

Multi-Provider Support:

agent {
    llm = when (stage) {
        "extraction" -> GeminiProvider(model = "gemini-2.0-flash-exp")
        "validation" -> GeminiProvider(model = "gemini-1.5-pro")
        else -> GeminiProvider(model = "gemini-2.0-flash-exp")
    }
}

Benefits:

Considerations:


4. Koog vs. Custom Workflow Comparison

4.1 Feature Comparison Matrix

Feature Koog Custom (Coroutines) Winner
Workflow Definition Graph DSL Function composition Koog (more expressive)
Error Handling Built-in retry Manual implementation Koog (less code)
Observability OpenTelemetry Manual logging Koog (better)
State Persistence Built-in Manual (DB) Koog (easier)
Learning Curve Medium-High Low Custom (team knows it)
Performance Some overhead Direct execution Custom (faster)
Flexibility Framework constraints Full control Custom (more flexible)
Maintenance Framework updates Own code Custom (more control)
Provider Switching Easy Manual Koog (if needed)
Tool Calling Built-in Manual Koog (if using LLM tools)

4.2 Code Complexity Comparison

suspend fun importPipeline(url: String): ImportResult {
    return try {
        val html = webScrapingService.scrape(url)
        val extracted = extractionService.extract(html)
        val resolved = entityResolutionService.resolve(extracted)
        val cleaned = cleansingService.cleanse(resolved)
        val validated = validationService.validate(cleaned)
        stagingService.stage(validated)
        ImportResult.Success
    } catch (e: Exception) {
        // Manual retry logic
        if (retryCount < 3) {
            delay(exponentialBackoff(retryCount))
            importPipeline(url)
        } else {
            ImportResult.Failure(e)
        }
    }
}

Koog Workflow:

val importAgent = agent {
    graph {
        val scrape = node("scrape") { scrapeUrl(url) }
        val extract = node("extract") { extractMetadata(html) }
        val resolve = node("resolve") { resolveEntities(metadata) }
        val cleanse = node("cleanse") { cleanseData(mapped) }
        val validate = node("validate") { validateData(cleaned) }
        val stage = node("stage") { stageForReview(validated) }
        
        scrape -> extract -> resolve -> cleanse -> validate -> stage
    }
    
    retryPolicy { maxRetries = 3 }
    tracing { level = TraceLevel.DETAILED }
}

Analysis:


5. Use Case Analysis

5.1 Where Koog Excels

Complex, Multi-Stage Workflows:

Long-Running Workflows:

LLM-Heavy Workflows:

Observability Requirements:


5.2 Where Custom Solution Excels

Simple, Linear Workflows:

Performance-Critical Paths:

Rapid Iteration:

Existing Infrastructure:


6. Hybrid Approach Recommendation

6.1 Phase 1: Custom Workflow (Weeks 1-4)

Build custom coroutine-based pipeline:

Rationale:


6.2 Phase 2: Koog POC (Weeks 5-6)

Build Koog POC for one stage:

POC Criteria:


6.3 Phase 3: Decision Point

If Koog Adds Value:

If Custom Sufficient:


7. Koog Implementation Plan (If Adopted)

7.1 Architecture

┌─────────────────────────────────────────┐
│         Import API Endpoints             │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│      ImportPipelineService              │
│  (Orchestrates Koog agents)            │
└──────┬──────────┬──────────┬───────────┘
       │          │          │
       ▼          ▼          ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Extraction│ │  Entity  │ │Validation│
│   Agent   │ │Resolution│ │  Agent   │
│  (Koog)   │ │  Agent   │ │  (Koog)  │
│           │ │  (Koog)  │ │          │
└──────────┘ └──────────┴──────────┘
                   │
       ┌───────────▼───────────┐
       │   Custom Services     │
       │  (Scraping, Staging)  │
       └──────────────────────┘

7.2 Key Components

Extraction Agent:

Entity Resolution Agent:

Validation Agent:

7.3 Integration Points

With Existing Services:


8. Cost-Benefit Analysis

8.1 Koog Adoption Costs

Development:

Operational:

Dependencies:


8.2 Koog Benefits

Short-Term:

Long-Term:

Quantifiable:


8.3 Custom Solution Costs

Development:

Operational:

Dependencies:


8.4 Custom Solution Benefits

Short-Term:

Long-Term:

Quantifiable:


9. Risk Assessment

9.1 Koog Risks

Risk Impact Probability Mitigation
Learning Curve Medium High Training, documentation, POC
Framework Changes Medium Low Version pinning, monitoring
Over-Engineering Low Medium Start with POC, evaluate value
Performance Overhead Low Medium Benchmark, optimize if needed
Team Resistance Medium Low Involve team in decision

9.2 Custom Solution Risks

Risk Impact Probability Mitigation
Missing Features Medium Medium Add as needed, consider Koog later
Error Handling Complexity Medium Medium Use proven patterns, test thoroughly
Observability Gaps Low Medium Add OpenTelemetry manually
Maintenance Burden Low Low Well-structured code, good tests

10. Recommendations

10.1 Immediate Recommendation

Start with Custom Workflow:

  1. Build coroutine-based pipeline
  2. Implement basic retry and error handling
  3. Add simple logging
  4. Get to production quickly

Rationale:


10.2 Evaluation Phase

Build Koog POC (After Custom):

  1. Choose extraction stage for POC
  2. Implement same functionality with Koog
  3. Compare side-by-side
  4. Document findings
  5. Team discussion and decision

Evaluation Criteria:


10.3 Decision Framework

Adopt Koog If:

Stick with Custom If:


11. Conclusion

Koog offers compelling features for complex import workflows, but may not be necessary initially. The recommended approach:

  1. Phase 1: Custom workflow (fast, low risk, meets needs)
  2. Phase 2: Koog POC (evaluate value, compare)
  3. Phase 3: Decision (adopt if value clear, enhance custom otherwise)

Key Insight: Don’t optimize prematurely. Build what works, then evaluate if Koog adds value for specific pain points.

Success Factors:


12. References


Documentation home · Feature status