人工智能 + 链上 应用设计与智能合约辅助开发:上线后怎样观察真实使用情况

把大模型决策代理接到 Web3 链上智能合约之后,很多团队都会遭遇一个尴尬的死角:智能合约在以太坊或者 Solana 上抛出了事件,后端 LLM 代理依据这些事件做二次推理并触发新的链上交易,但整个异步链路一旦卡顿或产生非预期状态,现场排查极其艰难。链上交易有 Hash,但大模型内部 Prompt 拼接、上下文检索、以及 RPC 节点的 HTTP 延时,在传统的日志系统里往往处于断连状态。

在链下 Agent 与链上 Smart Contract 交互的混合架构中,持续观察线上效果不能只看 RPC 节点的 HTTP 200 响应率。你需要建立一套覆盖“链上事件捕获 -> LLM 上下文检索 -> 代理决策导出 -> 签名交易广播”的全链路 Trace 与指标观测体系。


链路切片与可观测数据建模

当 AI 代理根据 DeFi 资金池的质押率变动自动调整对冲策略时,一个完整的业务闭环包含链上、链下及大模型推理三部分。要做到全链路可追踪,关键是将以太坊的 txHashlogIndex 与 OpenTelemetry 的 traceparent Header 深度绑定。

链上事件是异步触发源。我们不能依赖传统的 HTTP Header 传递链路上下文,应当在监听服务捕获到 Log 的第一时间,将链上元数据映射为 Trace Span 的 Attributes。

在此模型中,每一笔被触发的推理任务都应当承载链上数据的上下文根。如果智能合约抛出日志时包含 txHash = 0x8f2a...,该 Hash 即被直接作为根 Span 的 Tag 写入。后续 LLM 向量数据库检索(RAG)、API 调用以及发起对冲交易的签名过程,全部作为子 Span 挂载。


面向生产环境的事件监听与 Trace 贯通实现

下面是一个采用 TypeScript 与 Ethers.js v6,结合 OpenTelemetry SDK 实现的离线事件监听与 AI 决策链追踪代码。代码中直接注入了 Span 上下文,确保每一笔大模型调用的 Token 消耗和时延都归因到具体的链上交易。

import { ethers } from "ethers";
import { trace, context, SpanStatusCode, MetricAttributes } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
import { OpenAI } from "openai";

const tracer = trace.getTracer("web3-ai-agent-tracer", "1.2.0");
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

// 结构化日志输出
function logStructured(level: string, message: string, meta: Record<string, any>) {
  console.log(JSON.stringify({
    timestamp: new Date().toISOString(),
    level,
    message,
    ...meta
  }));
}

interface ContractEventPayload {
  poolAddress: string;
  sender: string;
  amount0In: bigint;
  amount1Out: bigint;
  rawEvent: ethers.Log;
}

export class ChainAgentObserver {
  private provider: ethers.JsonRpcProvider;
  private poolContract: ethers.Contract;

  constructor(rpcUrl: string, poolAddress: string, abi: any) {
    this.provider = new ethers.JsonRpcProvider(rpcUrl);
    this.poolContract = new ethers.Contract(poolAddress, abi, this.provider);
  }

  public async startListening() {
    logStructured("INFO", "Starting blockchain event watcher...", { address: this.poolContract.target });

    this.poolContract.on("Swap", async (sender, amount0In, amount1In, amount0Out, amount1Out, to, event) => {
      const log = event.log;
      // 提取链上唯一凭证创建根 Span
      const traceName = `Event:Swap:${log.transactionHash.slice(0, 10)}`;
      
      await tracer.startActiveSpan(traceName, {
        attributes: {
          "blockchain.tx_hash": log.transactionHash,
          "blockchain.block_number": log.blockNumber,
          "blockchain.log_index": log.index,
          "blockchain.contract_address": log.address,
        }
      }, async (span) => {
        try {
          const payload: ContractEventPayload = {
            poolAddress: log.address,
            sender,
            amount0In,
            amount1Out,
            rawEvent: log
          };

          logStructured("INFO", "Chain event captured, triggering AI inference", {
            txHash: log.transactionHash,
            blockNumber: log.blockNumber
          });

          // 执行 AI 代理决策
          const decision = await this.processAIDecision(payload);
          
          span.setAttribute("agent.decision_action", decision.action);
          span.setAttribute("agent.confidence_score", decision.confidence);
          span.setStatus({ code: SpanStatusCode.OK });
        } catch (err: any) {
          span.recordException(err);
          span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
          logStructured("ERROR", "Execution pipeline failed", { error: err.message, txHash: log.transactionHash });
        } finally {
          span.end();
        }
      });
    });
  }

  private async processAIDecision(eventData: ContractEventPayload) {
    return tracer.startActiveSpan("AI_Agent_Inference", async (span) => {
      const startTime = Date.now();
      try {
        const prompt = `Analyze liquidity swap on pool ${eventData.poolAddress}. AmountIn: ${eventData.amount0In.toString()}. Suggest rebalance action.`;
        
        span.setAttribute("llm.model", "gpt-4-turbo");
        span.setAttribute("llm.prompt_length", prompt.length);

        const response = await openai.chat.completions.create({
          model: "gpt-4-turbo",
          messages: [{ role: "system", content: "You are an automated DeFi risk agent." }, { role: "user", content: prompt }],
          temperature: 0.1,
        });

        const duration = Date.now() - startTime;
        const usage = response.usage;

        span.setAttribute("llm.completion_tokens", usage?.completion_tokens || 0);
        span.setAttribute("llm.prompt_tokens", usage?.prompt_tokens || 0);
        span.setAttribute("llm.total_tokens", usage?.total_tokens || 0);
        span.setAttribute("llm.latency_ms", duration);

        const content = response.choices[0].message.content || "{}";
        const parsed = JSON.parse(content);
        
        return {
          action: parsed.action || "HOLD",
          confidence: parsed.confidence || 0.0
        };
      } catch (error: any) {
        span.recordException(error);
        throw error;
      } finally {
        span.end();
      }
    });
  }
}

代码中关键设计在于避免将日志写入本地磁盘文本。所有结构化 JSON 日志直接打到标准输出,由 Vector 或 FluentBit 采集并提取 trace_id 自动关联。


核心观测指标(Metrics)设计与 Prometheus 聚类

光有 Trace 还不够。Trace 解决的是“某一次异常交易发生时到底卡在哪”,而系统整体健康度应当依靠 Metrics 聚合。AI + Web3 系统需要关注三组交叉指标:

1. 成本与经济效率指标

  • Token-to-Tx Cost Ratio: 平均每完成一次链上自动化调仓所消耗的大模型 API 成本与链上 Gas Fee 比例。
  • Gas Limit Drift: AI 合约生成工具自动生成的智能合约 Payload 在真实执行时,实际 Gas 消耗与预估 Gas 的偏差幅度。

2. 时延与一致性指标

  • Block-to-Inference Latency: 从区块打包确认(Included in Block)到 AI Agent 完成 Prompt 推理出结果的时延分布(P95 / P99)。
  • Reorg Invalidation Rate: 因以太坊主网或 L2 发生软分叉(Reorg)导致 AI 代理提前触发链上决策而失效的比例。

3. 决策成功率与置信度分布

  • Decision Confidence Buckets: 统计大模型输出置信度在 [0, 0.5]、[0.5, 0.8]、[0.8, 1.0] 的数量分布。当低于 0.6 的低置信决策占比突然上升,说明市场行情进入未知区间或 Prompt 注入了异常干扰。

智能合约与链下 Agent 联调排查实践

线上排查往往面临“链上状态已变,链下无法复现”的问题。智能合约被触发后,链上状态是强时序不可逆的,如果 AI 代理做出错误的清算决策,不能简单重新运行脚本。

在实际工程中,可观测系统的最高级别应用是回放与调试。当某个 txHash 对应的 Span 被标记为 Error 时,运维和研发应当能够从日志聚合系统提取该 Span 下记录的所有属性:

  1. 当时的区块高度(Block Number)与合约状态快照。
  2. 传递给 LLM 的准确 Context(包括向量检索返回的前 K 个 Chunk)。
  3. 大模型返回的原生 JSON 文本(原始输出,未经过 Sanitizer 校验前)。

借助 Foundry 的 anvil 或 Hardhat Network,在本地分叉(Fork)出发生异常那一刻的主网状态,再把日志中还原的 Prompt 重新投喂给本地 Agent 实例,才能实现 100% 精确的现场复现。


告警策略与异常止损熔断

线上监控不仅是为了看仪表盘,更重要的是自动触发熔断。在 AI + Web3 场景中,出现以下两种情况应当自动关断 Agent 的私钥签名权限:

  1. 幻觉交易频度超限: 如果 AI Agent 在连续 5 分钟内发起了超过 3 笔 Slippage(滑点)设为 0 或输出参数格式非法的交易,可观测仪表盘触发 Alertmanager,将签名服务中的 Session Key 标记失效。
  2. Gas 消耗暴涨: 大模型因为死循环或逻辑混乱,频繁发送低效无用交易,导致账户余额快速消耗。

建立覆盖日志、指标与分布式追踪的三位一体可观测系统,是现代 Web3 与 AI 深度结合从 Demo 迈向生产级基础设施的关键一步。没有这层防护网,自动化代理在去中心化网络中就如同无方向盘的赛车。

更多推荐