| Metadata | Value |
|---|---|
| Status | Active |
| Version | 1.1.0 |
| Last Updated | 2026-09-10 |
| Author | Sangeetha Grantha Team |
| Document Type | Design reference |
[!NOTE] Design/reference material: this page may include proposals or earlier implementation assumptions. Use current ingestion guide for implemented behavior and current operating steps.
This document consolidates Koog evaluation from multiple sources:
koog-evaluation-for-import-pipeline-goose.md (Import pipeline specific evaluation)koog-integration-analysis.md (General integration options)koog-technical-integration-proposal.md (Technical integration details)Key insights from all sources have been integrated into this consolidated evaluation.
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.
The import pipeline consists of 10 stages:
imported_krithisKoog 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:
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:
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:
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:
| 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) |
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:
Complex, Multi-Stage Workflows:
Long-Running Workflows:
LLM-Heavy Workflows:
Observability Requirements:
Simple, Linear Workflows:
Performance-Critical Paths:
Rapid Iteration:
Existing Infrastructure:
Build custom coroutine-based pipeline:
WebScrapingServiceEntityResolutionServiceImportPipelineService with coroutinesRationale:
Build Koog POC for one stage:
POC Criteria:
If Koog Adds Value:
If Custom Sufficient:
┌─────────────────────────────────────────┐
│ Import API Endpoints │
└──────────────────┬──────────────────────┘
│
┌──────────────────▼──────────────────────┐
│ ImportPipelineService │
│ (Orchestrates Koog agents) │
└──────┬──────────┬──────────┬───────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Extraction│ │ Entity │ │Validation│
│ Agent │ │Resolution│ │ Agent │
│ (Koog) │ │ Agent │ │ (Koog) │
│ │ │ (Koog) │ │ │
└──────────┘ └──────────┴──────────┘
│
┌───────────▼───────────┐
│ Custom Services │
│ (Scraping, Staging) │
└──────────────────────┘
Extraction Agent:
extract_krithi_metadataEntity Resolution Agent:
resolve_composer, resolve_raga, resolve_deity, resolve_templeValidation Agent:
validate_krithi_dataWith Existing Services:
WebScrapingService: Called before Koog agentsTransliterationService: Called as tool or after extractionDevelopment:
Operational:
Dependencies:
Short-Term:
Long-Term:
Quantifiable:
Development:
Operational:
Dependencies:
Short-Term:
Long-Term:
Quantifiable:
| 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 |
| 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 |
Start with Custom Workflow:
Rationale:
Build Koog POC (After Custom):
Evaluation Criteria:
Adopt Koog If:
Stick with Custom If:
Koog offers compelling features for complex import workflows, but may not be necessary initially. The recommended approach:
Key Insight: Don’t optimize prematurely. Build what works, then evaluate if Koog adds value for specific pain points.
Success Factors: