CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-common

Common AI framework utilities for the Embabel Agent system including LLM configuration, output converters, prompt contributors, and embedding service abstractions.

Overview
Eval results
Files

pricing.mddocs/supporting/

Pricing

Pricing calculation system for LLM usage based on input and output tokens.

Core Interface

PricingModel

Calculate LLM usage costs from token counts.

interface PricingModel {
    fun usdPerInputToken(): Double
    fun usdPerOutputToken(): Double
    fun costOf(inputTokens: Int, outputTokens: Int): Double
    fun costOf(usage: Usage): Double

    companion object {
        @JvmStatic
        val ALL_YOU_CAN_EAT: PricingModel

        @JvmStatic
        fun usdPerToken(
            usdPerInputToken: Double,
            usdPerOutputToken: Double
        ): PricingModel

        @JvmStatic
        fun usdPer1MTokens(
            usdPer1mInputTokens: Double,
            usdPer1mOutputTokens: Double
        ): PricingModel
    }
}

Basic Usage:

// Zero-cost model (local/free)
val freePricing = PricingModel.ALL_YOU_CAN_EAT
val cost1 = freePricing.costOf(10000, 5000) // $0.00

// Per-million-token pricing (most common)
val gpt4Pricing = PricingModel.usdPer1MTokens(
    usdPer1mInputTokens = 30.0,
    usdPer1mOutputTokens = 60.0
)
val cost2 = gpt4Pricing.costOf(1000, 500) // $0.06

// Per-token pricing (rarely used)
val perTokenPricing = PricingModel.usdPerToken(
    usdPerInputToken = 0.00003,
    usdPerOutputToken = 0.00006
)

PerTokenPricingModel

Concrete pricing implementation.

const val ONE_MILLION = 1000000.0

class PerTokenPricingModel(
    val usdPer1mInputTokens: Double,
    val usdPer1mOutputTokens: Double
) : PricingModel

Usage:

val pricing = PerTokenPricingModel(
    usdPer1mInputTokens = 10.0,
    usdPer1mOutputTokens = 30.0
)

println("Input rate: $${pricing.usdPer1mInputTokens} per 1M tokens")
val cost = pricing.costOf(5000, 2000)

Common LLM Pricing

OpenAI

// GPT-4
val gpt4 = PricingModel.usdPer1MTokens(30.0, 60.0)

// GPT-4 Turbo
val gpt4Turbo = PricingModel.usdPer1MTokens(10.0, 30.0)

// GPT-3.5 Turbo
val gpt35 = PricingModel.usdPer1MTokens(0.5, 1.5)

// o1-preview
val o1 = PricingModel.usdPer1MTokens(15.0, 60.0)

Anthropic

// Claude 3 Opus
val claude3Opus = PricingModel.usdPer1MTokens(15.0, 75.0)

// Claude 3 Sonnet
val claude3Sonnet = PricingModel.usdPer1MTokens(3.0, 15.0)

// Claude 3 Haiku
val claude3Haiku = PricingModel.usdPer1MTokens(0.25, 1.25)

Local Models

val ollama = PricingModel.ALL_YOU_CAN_EAT
val localLlama = PricingModel.ALL_YOU_CAN_EAT

Cost Tracking

Session Tracker

class CostTracker(private val pricing: PricingModel) {
    private var totalInputTokens = 0
    private var totalOutputTokens = 0

    fun recordUsage(inputTokens: Int, outputTokens: Int) {
        totalInputTokens += inputTokens
        totalOutputTokens += outputTokens
    }

    fun totalCost(): Double {
        return pricing.costOf(totalInputTokens, totalOutputTokens)
    }

    fun summary(): String {
        return """
            Input tokens: $totalInputTokens
            Output tokens: $totalOutputTokens
            Total cost: ${"$%.4f".format(totalCost())}
        """.trimIndent()
    }
}

// Usage
val tracker = CostTracker(gpt4Pricing)
tracker.recordUsage(1000, 500)
println(tracker.summary())

Budget Management

class BudgetManager(
    private val pricing: PricingModel,
    private val maxBudget: Double
) {
    private val tracker = CostTracker(pricing)

    fun canAfford(inputTokens: Int, outputTokens: Int): Boolean {
        val estimatedCost = pricing.costOf(inputTokens, outputTokens)
        return tracker.totalCost() + estimatedCost <= maxBudget
    }

    fun recordUsage(inputTokens: Int, outputTokens: Int) {
        if (!canAfford(inputTokens, outputTokens)) {
            throw BudgetExceededException(
                "Request would exceed budget of $$maxBudget"
            )
        }
        tracker.recordUsage(inputTokens, outputTokens)
    }

    fun remainingBudget(): Double {
        return maxBudget - tracker.totalCost()
    }
}

Cost Comparison

fun comparePricing(
    inputTokens: Int,
    outputTokens: Int,
    models: Map<String, PricingModel>
): Map<String, Double> {
    return models.mapValues { (_, pricing) ->
        pricing.costOf(inputTokens, outputTokens)
    }.toSortedMap(compareBy { models[it]!!.costOf(inputTokens, outputTokens) })
}

// Usage
val models = mapOf(
    "GPT-4" to gpt4Pricing,
    "GPT-4 Turbo" to gpt4TurboPricing,
    "Claude 3 Opus" to claude3OpusPricing
)

val comparison = comparePricing(10000, 5000, models)
comparison.forEach { (model, cost) ->
    println("$model: ${"$%.4f".format(cost)}")
}

Cost Optimization

Model Selection by Budget

fun selectModelByBudget(
    inputTokens: Int,
    outputTokens: Int,
    maxCost: Double,
    models: Map<String, PricingModel>
): String? {
    return models
        .filter { (_, pricing) ->
            pricing.costOf(inputTokens, outputTokens) <= maxCost
        }
        .minByOrNull { (_, pricing) ->
            pricing.costOf(inputTokens, outputTokens)
        }
        ?.key
}

Token Budget Planning

fun calculateTokenBudget(
    budget: Double,
    pricing: PricingModel,
    inputOutputRatio: Double = 2.0
): Pair<Int, Int> {
    val inputRate = pricing.usdPerInputToken()
    val outputRate = pricing.usdPerOutputToken()

    val totalTokens = (budget / (inputRate + outputRate / inputOutputRatio)).toInt()
    val inputTokens = (totalTokens * inputOutputRatio / (1 + inputOutputRatio)).toInt()
    val outputTokens = totalTokens - inputTokens

    return inputTokens to outputTokens
}

Integration with LLM Metadata

val metadata = LlmMetadata(
    name = "gpt-4",
    provider = "openai",
    knowledgeCutoffDate = LocalDate.of(2023, 4, 1),
    pricingModel = PricingModel.usdPer1MTokens(30.0, 60.0)
)

metadata.pricingModel?.let { pricing ->
    val cost = pricing.costOf(1000, 500)
    println("Cost: $$cost")
} ?: println("Pricing not available")

Design Patterns

  • Strategy Pattern: Different pricing models implement the same interface
  • Factory Pattern: Companion object methods for creating pricing models
  • Value Object: PerTokenPricingModel is an immutable value object
tessl i tessl/maven-com-embabel-agent--embabel-agent-common@0.3.1

docs

index.md

quick-reference.md

README.md

tile.json