Run Persistence

Run Persistence 是将 Agent Run 的执行记录(步骤、状态、token 消耗、工具调用)持久化到数据库,用于回溯、调试和成本分析。

#type / concept #status / evergreen #tech / backend #tech / architecture

[!info] related notes

Run Persistence

一句话定义

Run Persistence 是将 Agent Run 的执行记录持久化到数据库。每次 Run 的步骤、状态变化、token 消耗、工具调用详情都被记录,用于回溯调试、成本分析和质量监控。

核心原理

Run 记录结构

CREATE TABLE runs (
    id VARCHAR(36) PRIMARY KEY,
    session_id VARCHAR(36),
    status VARCHAR(20), -- pending, running, completed, failed, cancelled
    input_message TEXT,
    output_message TEXT,
    total_tokens INT,
    total_duration_ms INT,
    step_count INT,
    model VARCHAR(50),
    error TEXT,
    created_at TIMESTAMP,
    started_at TIMESTAMP,
    completed_at TIMESTAMP
);

CREATE TABLE run_steps (
    id VARCHAR(36) PRIMARY KEY,
    run_id VARCHAR(36) REFERENCES runs(id),
    step_index INT,
    type VARCHAR(20), -- llm_call, tool_execution
    input JSONB,
    output JSONB,
    tokens INT,
    duration_ms INT,
    status VARCHAR(20),
    created_at TIMESTAMP
);

Go 实现

type RunRepository struct {
    db *sql.DB
}

func (r *RunRepository) SaveRun(ctx context.Context, run *Run) error {
    return r.db.ExecContext(ctx, `
        INSERT INTO runs (id, session_id, status, input_message, total_tokens, created_at)
        VALUES (?, ?, ?, ?, ?, ?)
    `, run.ID, run.SessionID, run.Status, run.InputMessage, run.TotalTokens, run.CreatedAt)
}

func (r *RunRepository) SaveStep(ctx context.Context, step *RunStep) error {
    return r.db.ExecContext(ctx, `
        INSERT INTO run_steps (id, run_id, step_index, type, input, output, tokens, duration_ms, status)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `, step.ID, step.RunID, step.StepIndex, step.Type, step.Input, step.Output, step.Tokens, step.Duration, step.Status)
}

func (r *RunRepository) CompleteRun(ctx context.Context, runID string, summary RunSummary) error {
    return r.db.ExecContext(ctx, `
        UPDATE runs SET status = 'completed', total_tokens = ?, total_duration_ms = ?, step_count = ?, completed_at = NOW()
        WHERE id = ?
    `, summary.TotalTokens, summary.TotalDuration, summary.StepCount, runID)
}

常见坑

  1. 不记录 LLM 输入: 无法复现问题
  2. Run 和 Message 混淆: Run 是执行记录,Message 是对话内容
  3. 不做清理: Run 记录无限增长
  4. 不记录 token: 无法分析成本

参考资料

创建于 2026/6/30 更新于 2026/7/15