Skip to content

轨迹日志与执行可观测性 ​

可观测性由三层组成:线程内 ConversationContext、领域事件/实时持久化监听器、JSONL trajectory 与数据库投影。应用日志适合排障,trajectory 适合恢复和审计,SSE 适合用户实时反馈,三者不能互相替代。

1. 链路上下文 ​

ConversationContext.start 创建 ConversationTrace,绑定 traceId、sessionId、agentId、userId、流式标记、原始输入、runId 和开始时间。当前实现使用 InheritableThreadLocal,dispatcher/虚拟线程执行时必须在 worker 上重新绑定并在 finally 清理,避免线程复用造成跨 session 污染。

节点由 TrackedNodeAction/ConversationContext.startNode 包装,记录:

字段含义
nodeName、nodeType、graphName主图/子图节点身份
iterationAgentic Loop 轮次
userVisible是否对前端展示
start/end/duration节点时延
status/error成功、失败和异常
totalTokens节点下关联模型用量

2. 调用记录类型 ​

ConversationTrace 聚合不同调用:

记录关键字段典型来源
AgentExecutionCallAgent、动作、输入摘要、终态子 Agent/主 Agent
LlmExecutionCall/LlmCallprovider、model、call type、tokens、延迟、成本ChatModel/Streaming wrapper
ToolExecutionCalltoolName、executorType、params、status、durationToolCallNode/Skill/RAG
RagExecutionCallDataset、retriever、query、命中、质量Rag/Embedding listener
NodeExecution节点状态和迭代TrackedNodeAction

SmartLlmCallListener、SmartStreamingChatModelWrapper、SmartEmbeddingModelListener 和 SmartEmbeddingStoreListener 会把 LangChain4j 回调转换为统一调用记录。流式模型在成功、错误、取消三种路径都要完成一次记录,否则总 token/成本和首 token 延迟会失真。

3. 事件发布与持久化 ​

text
ConversationContext.record...
  -> EventPublisherHolder/ApplicationEventPublisher
  -> RealtimeLogPersistenceListener
  -> node_execution_log / llm_call_log / tool_call_log / rag_log

JSONL 监听器同时写 session event ledger:

  • 节点开始/完成、LLM 请求结果、工具开始/结果、RAG、Skill、Todo、重规划。
  • assistant text delta、structured block 和运行控制事件。
  • checkpoint、compaction、branch、Sandbox 生命周期和错误。

数据库表适合分页查询和运营统计;JSONL 保留顺序、sequence、payload 引用和恢复所需 cursor。事件写入失败不能吞掉 Agent 主流程,但必须触发告警并保留可诊断错误。

4. 脱敏和负载策略 ​

普通日志和数据库摘要不得写入 API key、Bearer Token、完整 system prompt、用户文件全文或外部服务密钥。SessionPersistenceProperties 对通用、LLM、工具、请求 profile 设置不同 inline 字节阈值,超过后写 blob 引用;恢复和轨迹详情再按权限读取。

建议记录:模型名、provider、输入/输出 token、耗时、状态、错误类型、参数摘要、结果长度、引用 ID。对完整 payload 使用访问控制、租户校验和保留期限。

5. 关键指标 ​

指标维度用途
首 token 延迟provider/model/Agent判断排队、建连或模型慢
总运行时延session/run/终态用户体验和超时分析
input/output/total tokensmodel/tenant/Agent成本与上下文压缩
工具成功率/超时率tool/serviceType依赖健康和重试判断
RAG 命中、质量分、空结果率Dataset/retriever检索质量
队列积压、channel waitqueue/session背压和 SSE 配置
pause/recovery blocked/cancelrun status控制链路可靠性
SSE 断开和 pending event 数session/channel前端连接问题

6. 常用排障路径 ​

text
traceId
 -> ConversationTrace 状态/总时延
 -> NodeExecution 最后节点
 -> LlmExecutionCall 或 ToolExecutionCall
 -> JSONL sequence / checkpoint
 -> SSE pending 或 response snapshot

常见判断:

  • 没有 trace:检查 dispatcher 是否在 worker 建立 ConversationContext。
  • 有 trace 无节点:检查 Agent 是否在 channel 等待或配置加载前失败。
  • 节点成功但无模型调用:可能走了直接回答、缓存工具结果或 web_search_only 路径。
  • 工具显示成功但任务失败:查看 refining 的连续失败、重规划和 loopSignal。
  • 数据库有完成状态但页面无文本:检查 SseStreamHandler flush、assistant snapshot 和 pending event。

7. 新节点/新提供器的埋点要求 ​

新节点必须使用 TrackedNodeAction 或 ConversationContext.withNode,声明正确 NodeType 和 userVisible。新模型/Embedding/Store provider 必须接入对应 listener,记录成功与失败、token/向量维度、延迟和 trace 绑定。新工具必须写 executorType、toolCallId、side-effect、输入摘要、结果长度和失败原因。