cost

package
v0.5.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package cost 提供 Hexagon AI Agent 框架的成本控制

CostController 用于控制 Agent 的资源消耗,包括: - Token 使用限制 - API 调用频率限制 - 成本预算控制

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidControllerConfig = errors.New("invalid cost controller config")

ErrInvalidControllerConfig 表示成本控制器配置无效。

Functions

func CheckAndRecord

func CheckAndRecord(ctx context.Context, model string, usage TokenUsage) error

CheckAndRecord 检查并记录(便捷函数)

func ContextWithController

func ContextWithController(ctx context.Context, c *Controller) context.Context

ContextWithController 将控制器添加到 context

func DefaultPricing

func DefaultPricing() map[string]ModelPricing

DefaultPricing 返回默认定价表的独立快照。

Types

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

Controller 成本控制器

func ControllerFromContext

func ControllerFromContext(ctx context.Context) *Controller

ControllerFromContext 从 context 获取控制器

func NewController

func NewController(opts ...ControllerOption) (*Controller, error)

NewController 创建成本控制器,并在返回前集中校验最终配置。

func (*Controller) BudgetCostFunc

func (c *Controller) BudgetCostFunc() func(*hruntime.State) float64

BudgetCostFunc 返回以 runtime.State 为输入的累计成本估算函数,首选作为 runtime/middleware.NewBudgetControl 配置的 Cost 依赖注入;直接构造 Budget 时 也可作为其 Cost。

这是"meter→cost→budget 单向数据流"的规范桥接(路线图 §12 risk7 收尾): State.Usage(计量数据)→ 本控制器 EstimateCost(成本估算所有权在此,不在别处重复) → Budget(唯一 fail-closed 强制点)。返回裸 func 签名(而非具名 CostFunc 类型), 使 runtime/middleware 无需反向依赖 security/cost——依赖方向保持单向(cost→runtime)。

首选用法(同一 Controller 还应在每次 LLM 外呼前执行 CheckRequest):

budget := middleware.NewBudgetControl(middleware.BudgetControlConfig{
    Limits: ...,
    Cost:   costController.BudgetCostFunc(),
    Record: costController.RecordUsageFunc(),
})

func (*Controller) CanAfford

func (c *Controller) CanAfford(estimatedCost float64) bool

CanAfford 检查是否能负担指定成本

func (*Controller) CheckRequest

func (c *Controller) CheckRequest(ctx context.Context, estimatedTokens int64) error

CheckRequest 在真正发起一次 LLM 请求前检查上下文、单次/累计 Token 上限与请求频率。检查通过会消耗一次频率配额,但不预留 Token、不写入 实际用量;响应返回后应由 RecordUsageFunc 记录实际用量。

Agent 场景的首选组合是:在 provider/调用方的每次外呼前对共享 Controller 调用 CheckRequest,并将 BudgetCostFunc 与 RecordUsageFunc 注入 middleware.NewBudgetControl。NewBudgetControl 底层的 Budget 提供单 run 上限, CostControl 负责响应后的跨 run 累计记账与封顶。

func (*Controller) EstimateCost

func (c *Controller) EstimateCost(model string, promptTokens, completionTokens int) float64

EstimateCost 估算成本。输入无效或成本不可表示时返回正无穷,供无 error 签名的调用方安全拒绝。

func (*Controller) RecordUsage

func (c *Controller) RecordUsage(model string, usage TokenUsage) error

RecordUsage 记录使用量

注意:此方法采用"先检查后扣费"的原子操作模式,确保不会超额消费。 如果预算不足,会返回错误且不会记录使用量。

func (*Controller) RecordUsageFunc

func (c *Controller) RecordUsageFunc() func(model string, usage llm.Usage) error

RecordUsageFunc 返回把单次 LLM 调用用量记入本控制器**累计账**(used/usedTokens/remaining) 的桥接函数,首选作为 runtime/middleware.NewBudgetControl 配置的 Record 注入;直接构造 CostControl 时也可作为其 Record。

与 BudgetCostFunc 的区别决定了二者的语义分工:

  • BudgetCostFunc 只**读** State.Usage(单 run)供底层 middleware.Budget 的 per-run 检查;
  • 本函数**写**控制器的跨 run 累计账,且复用 RecordUsage 的"先检查后扣费"原子语义—— 累计成本突破预算时返回错误且不记账。因控制器在 agent 的多次 run 间共享,故经 NewBudgetControl 底层的 middleware.CostControl 即可对多 run agent (PlanExecute/Reflection)实现"全程累计预算"。

CheckRequest 是外呼前的 Token/频率预检,不会写实际用量;它与本函数各司其职, 应在同一个跨 run 共享 Controller 上配合使用。

返回裸 func 签名(而非具名类型),使 runtime/middleware 无需反向依赖 security/cost, 依赖方向保持单向(cost→runtime)。

func (*Controller) RemainingBudget

func (c *Controller) RemainingBudget() float64

RemainingBudget 返回剩余预算

func (*Controller) RemainingTokens

func (c *Controller) RemainingTokens() int64

RemainingTokens 返回剩余 Token 如果未设置总 Token 限制(maxTokensTotal=0),返回 math.MaxInt64 表示无限制。 结果不会为负数。

func (*Controller) Reset

func (c *Controller) Reset()

Reset 重置统计

func (*Controller) Stats

func (c *Controller) Stats() ControllerStats

Stats 返回统计信息

type ControllerOption

type ControllerOption func(*controllerConfig)

ControllerOption 控制器选项

func OnBudgetExceeded

func OnBudgetExceeded(fn func(used, budget float64)) ControllerOption

OnBudgetExceeded 设置预算超限回调

func OnRateExceeded

func OnRateExceeded(fn func(requests, limit int)) ControllerOption

OnRateExceeded 设置速率超限回调

func OnTokensExceeded

func OnTokensExceeded(fn func(used, limit int64)) ControllerOption

OnTokensExceeded 设置 Token 超限回调

func WithBudget

func WithBudget(budget float64) ControllerOption

WithBudget 设置预算

func WithMaxTokensPerRequest

func WithMaxTokensPerRequest(tokens int64) ControllerOption

WithMaxTokensPerRequest 设置单次请求最大 Token,0 表示不限制。

func WithMaxTokensTotal

func WithMaxTokensTotal(tokens int64) ControllerOption

WithMaxTokensTotal 设置总 Token 限制,0 表示不限制。

func WithPricing

func WithPricing(pricing map[string]ModelPricing) ControllerOption

WithPricing 设置自定义定价表

func WithRequestsPerMinute

func WithRequestsPerMinute(rpm int) ControllerOption

WithRequestsPerMinute 设置每分钟请求数

type ControllerStats

type ControllerStats struct {
	Budget          float64 `json:"budget"`
	Used            float64 `json:"used"`
	Remaining       float64 `json:"remaining"`
	UsedTokens      int64   `json:"used_tokens"`
	MaxTokensTotal  int64   `json:"max_tokens_total"`
	RequestsLastMin int     `json:"requests_last_min"`
	RequestsPerMin  int     `json:"requests_per_min"`
}

ControllerStats 控制器统计

type ModelPricing

type ModelPricing struct {
	PromptPrice     float64 // 输入 Token 价格(每 1000 Token)
	CompletionPrice float64 // 输出 Token 价格(每 1000 Token)
}

ModelPricing 模型定价

type TokenUsage

type TokenUsage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	// TotalTokens 在存在拆分维度时可为零(自动采用拆分之和)或等于拆分之和;
	// 拆分维度均为零时可单独承载 aggregate-only 配额计数。
	TotalTokens int `json:"total_tokens"`
}

TokenUsage Token 使用量

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL