十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hindsight 监控与可观测性实战:Prometheus 指标、Grafana 仪表盘与 OpenTelemetry 分布式追踪

Hindsight 监控与可观测性实战:Prometheus 指标、Grafana 仪表盘与 OpenTelemetry 分布式追踪 Hindsight 监控与可观测性实战Prometheus 指标、Grafana 仪表盘与 OpenTelemetry 分布式追踪【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsightHindsightAgent Memory That Learns为记忆服务的三大核心链路——retain记忆摄入、recall记忆检索、reflect代理推理——提供了完整的可观测性体系Prometheus 指标、OpenTelemetry 分布式追踪和预置 Grafana 仪表盘。本文基于官方文档 developer/monitoring 并结合 hindsight_api/metrics.py 与 hindsight_api/tracing.py 的源码实现展开读完你可以在本地一条命令拉起 Grafana LGTM 监控栈、读懂并告警 Hindsight 的全套指标、按 GenAI 语义约定解读 LLM 调用追踪并理解指标卡基数控制与跨进程追踪传播的底层机制。一、可观测性体系总览Hindsight 的可观测性由三根支柱构成Prometheus 指标API 进程在/metrics端点暴露 Prometheus 格式指标覆盖操作延迟、LLM 调用与 Token 用量、HTTP 请求、数据库连接池和进程资源OpenTelemetry 分布式追踪为记忆操作和 LLM 调用生成 Span 层级遵循 GenAI 语义约定 v1.37可导出到任意 OTLP 兼容后端预置 Grafana 仪表盘三套开箱即用的 JSON 仪表盘覆盖运维、LLM 成本与 API 服务健康。实现集中在两个模块指标采集由 metrics.py 中的MetricsCollector完成基于opentelemetry.exporter.prometheus.PrometheusMetricReader导出追踪由 tracing.py 中的TracerProvider与LLMSpanRecorder完成。二者均为条件启用指标默认开启追踪默认关闭且禁用时零开销使用NoOpMetricsCollector/NoOpTracer空实现见 metrics.py#L341-L412 与 tracing.py#L55-L94。二、本地快速启动Grafana LGTM 监控栈2.1 一条命令启动本地开发场景使用 Grafana LGTMLoki、Grafana、Tempo、Mimir一体化栈./scripts/dev/start-monitoring.sh该脚本是一个便捷包装器直接 exec 到 scripts/dev/monitoring/start.sh实际编排定义在 scripts/dev/monitoring/docker-compose.yaml。它启动单个grafana/otel-lgtm:latest容器提供Grafana UIhttp://localhost:3000容器内设置了GF_AUTH_ANONYMOUS_ENABLEDtrue与GF_AUTH_ANONYMOUS_ORG_ROLEAdmin即匿名管理员访问仅限本地开发TracesTempoOTLP 端点http://localhost:4318HTTP与http://localhost:4317gRPCMetricsPrometheus/Mimir自动抓取http://localhost:8888/metricsLogsLoki日志聚合可用预置仪表盘Hindsight Operations、Hindsight LLM Metrics、Hindsight API Service。生产部署提示本地监控栈仅用于开发。生产环境应独立部署 Grafana LGTM或使用商业平台Grafana Cloud、DataDog、New Relic 等。2.2 从源码看容器如何接入 Hindsightdocker-compose.yaml 中有两个容易被忽略的细节抓取目标走host.docker.internal。宿主机上的 Hindsight API8888 端口通过extra_hosts: host.docker.internal:host-gateway映射进容器。配套的 prometheus.yml 定义了 5 秒间隔的抓取任务且同时抓取 API 与独立 worker 两个目标scrape_configs: - job_name: hindsight-api static_configs: - targets: [host.docker.internal:8888] metrics_path: /metrics scrape_interval: 5s - job_name: hindsight-worker static_configs: - targets: [host.docker.internal:8889] metrics_path: /metrics这意味着独立 worker8889 端口的异步任务指标也纳入监控——即使宿主上没跑 worker该目标也只是无害的空抓取。仪表盘自动挂载。三套 Hindsight 仪表盘 JSON 被只读挂载进容器并通过 grafana-dashboards.yaml 的 provisioning 配置自动装载无需手动导入。2.3 在 API 侧启用追踪export HINDSIGHT_API_OTEL_TRACES_ENABLEDtrue export HINDSIGHT_API_OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4318这两个环境变量在 config.py#L681-L685 定义解析逻辑见 config.py#L4817-L4821HINDSIGHT_API_OTEL_TRACES_ENABLED接受true/1/yes未设置时默认关闭启用但缺少 endpoint 时initialize_tracing_from_config会记录警告并保持追踪关闭——追踪初始化失败永远不会阻止进程启动见 tracing.py#L212-L264。三、Grafana 预置仪表盘预置仪表盘位于monitoring/grafana/dashboards/将以下 JSON 文件导入你的 Grafana 实例即可使用上面的本地监控栈脚本时会自动 provisioning仪表盘文件说明Hindsight Operationshindsight-operations.json操作速率、延迟百分位、按 bank 的指标Hindsight LLM Metricshindsight-llm.jsonLLM 调用量、Token 用量、按 scope/provider 的延迟Hindsight API Servicehindsight-api-service.jsonHTTP 请求、错误率、DB 连接池、进程指标四、Metrics 端点与指标体系Hindsight 在/metrics暴露 Prometheus 指标curl http://localhost:8888/metrics4.1 操作指标Operation Metrics指标类型标签说明hindsight.operation.durationHistogramoperation, bank_id, source, budget, max_tokens, success操作耗时秒hindsight.operation.totalCounteroperation, bank_id, source, budget, max_tokens, success已执行操作总数标签说明operation操作类型retain、recall、reflect以及consolidation等异步 worker 任务类型bank_id记忆库标识source操作触发来源api、reflect、internal、workerbudget指定时的预算等级low、mid、highmax_tokens指定时的 Token 上限success操作是否成功true、false。source标签用于区分api客户端直接 API 调用、reflectreflect 操作期间的内部 recall 调用、internal其他内部操作、worker异步 worker 完成、即已认领任务到达终态结果时记录。对于sourceworkersuccess是一个完成吞吐量信号false表示任务在重试耗尽后抛出到 poller或发生了未预期错误在 executor 内部处理掉并正常返回的失败这里仍记为successtrue。权威的异步操作失败状态请看hindsight_async_operations{statusfailed}。源码级补充——客户端取消不计入指标record_operation上下文管理器在异常路径上会检测OperationCancelledError见 metrics.py#L620-L671。客户端断开导致的协作式取消既非成功也非失败被完全排除在hindsight.operation.total之外避免拉高失败率或成功率。4.2 Retain 指标指标类型标签说明hindsight.retain.documents.totalCounteroutcome, bank_idretain 处理的文档数按抽取结果分outcomefactsretain 后文档有记忆单元或no_facts没有bank_id记忆库标识。outcomeno_facts是关键告警信号文档已存储但没有产生任何记忆在重新处理之前对recall和reflect完全不可见——而且 retain 本身是成功的系统其他任何地方都不会报告这种文档。占比上升通常意味着 retain mission 排除了比预期更多的内容源码注释追溯到 issue #3040见 metrics.py#L482-L492。推荐查询sum(rate(hindsight_retain_documents_total{outcomeno_facts}[15m])) / sum(rate(hindsight_retain_documents_total[15m]))4.3 LLM 指标指标类型标签说明hindsight.llm.durationHistogramprovider, model, scope, successLLM API 调用耗时秒hindsight.llm.calls.totalCounterprovider, model, scope, successLLM API 调用总数hindsight.llm.tokens.inputCounterprovider, model, scope, success, token_bucketLLM 调用输入 Tokenhindsight.llm.tokens.outputCounterprovider, model, scope, success, token_bucketLLM 调用输出 Token标签说明providerLLM 提供商openai、anthropic、gemini、groq、ollama、lmstudio、bedrock、litellm等model模型名如gpt-4、claude-3-sonnetscope该 LLM 调用的用途memory、reflect、consolidation、answersuccess调用是否成功token_bucketToken 计数量桶用于卡基数控制0-100、100-500、500-1k、1k-5k、5k-10k、10k-50k、50k。token_bucket的分桶逻辑实现在 get_token_bucket()把连续的 Token 数映射为 7 个离散桶标签使得可以在不产生高基数序列的前提下分析 Token 用量模式。源码级补充——成本归因的两个额外计数器record_llm_call还接受cached_input_tokens与thoughts_tokens参数见 metrics.py#L725-L795对应两个文档未展开的计数器hindsight.llm.tokens.cached_input按缓存费率计费的输入 Token 子集如 Gemini 上下文缓存可独立跟踪 prompt-cache 命中率hindsight.llm.tokens.thoughts推理/思考 TokenGemini 2.5 系列按输出费率计费但不出现在候选输出里。源码注释明确指出只按输出量看显得很便宜的工作负载若模型在跑长推理链实际成本可能很高——这两个计数器让成本归因保持诚实。4.4 HTTP 请求指标指标类型标签说明hindsight.http.durationHistogrammethod, endpoint, status_code, status_classHTTP 请求耗时秒hindsight.http.requests.totalCountermethod, endpoint, status_code, status_classHTTP 请求总数hindsight.http.requests.in_progressUpDownCountermethod, endpoint正在处理中的请求数methodHTTP 方法GET、POST、PUT、DELETEendpoint请求路径做了归一化以降低基数——UUID 替换为{id}status_codeHTTP 状态码200、400、500等status_class状态码类别2xx、4xx、5xx。源码级补充——endpoint 归一化normalize_http_endpoint() 除替换 UUID 与纯数字 ID 为{id}外还会把/banks/任意 bank id段折叠为/banks/{bank_id}包括user-123这类非数字 bank id否则每个 bank 都会创建一条永不淘汰的 OTel 时间序列。这与token_bucket是同一设计思路先模板化高基数维度再打点。4.5 数据库连接池指标指标类型标签说明hindsight.db.pool.sizeGauge-池中当前连接数hindsight.db.pool.idleGauge-池中空闲连接数hindsight.db.pool.minGauge-池最小连接数hindsight.db.pool.maxGauge-池最大连接数4.6 进程指标指标类型标签说明hindsight.process.cpu.secondsGaugetype进程 CPU 时间秒hindsight.process.memory.bytesGaugetype进程内存用量字节hindsight.process.open_fdsGauge-打开的文件描述符数hindsight.process.threadsGauge-活跃线程数标签取值CPU 的type为user或system内存的type为rss_max最大常驻集大小。实现上是四个 observable gauge在 scrape 时回调采集见 _setup_process_metricsCPU/内存来自resource.getrusageLinux 上ru_maxrss以 KB 计源码内做 ×1024 换算open_fds直接统计/proc/self/fd条目数整个进程指标块仅在resource模块可用时注册即 Windows 上会被跳过。4.7 直方图桶边界为提升百分位精度三个时长直方图均配置了自定义桶边界定义于 metrics.py#L73-L79通过ExplicitBucketHistogramAggregationView 绑定到对应 instrument操作耗时桶秒0.1, 0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 5.0, 7.5, 10.0, 15.0, 20.0, 30.0, 60.0, 120.0LLM 耗时桶秒0.1, 0.25, 0.5, 1.0, 2.0, 3.0, 5.0, 10.0, 15.0, 30.0, 60.0, 120.0HTTP 耗时桶秒0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 30.04.8 源码中的额外指标运行时卡滞与流水线剖面除文档列出的核心指标外MetricsCollector 还暴露了一批面向故障定位的运行时指标值得在生产监控中一并接入指标说明hindsight.db.pool.acquire_waitHistogram调用方获取池化 DB 连接的等待时长——连接池耗尽信号hindsight.retain.phase.duration/hindsight.retain.phase.callsHistogram/Counterretain 各阶段耗时与轮次数。retain 横跨分块、embedding、memories store、Postgres 四个子系统慢 retain 从此可定位到具体阶段阶段在子批并发时可能重叠应与hindsight.retain.duration对比阅读hindsight.recall.phase.durationHistogramrecall 各阶段耗时。源码注释指出默认桶首桶 5 秒会让所有毫秒级阶段挤进一个桶、百分位失真因此该直方图显式配置了0.001~10.0秒的细桶diagnostic标签区分父阶段的子集与兄弟阶段防止把时间重复求和hindsight.event_loop.stalls/hindsight.event_loop.stall_durationCounter/Histogram事件循环卡滞检测配合 loop watchdog线程阻塞的运行时信号hindsight.consolidation.batch_failuresCounterconsolidation LLM 批调用失败计数按failure_classretry可自愈的传输型失败 /fail_fast响应 schema 被拒的失败区分——它是卡住的行计数之外的缺失信号异步操作/整合积压 gaugemetrics_backlog_enabled开启时队列深度类指标由后台任务每 30 秒刷新缓存保证 scrape 路径保持同步卡基数控制配置record_operation_result中bank_id标签是否附加由配置项metrics_include_bank_id控制见 metrics.py#L673-L707 与 config.py。bank 数量多的部署可以关闭它以收敛序列数所有指标都额外携带tenant标签用于多租户区分。五、Prometheus 抓取配置独立部署 Prometheus 时最小抓取配置如下scrape_configs: - job_name: hindsight static_configs: - targets: [localhost:8888]本地监控栈中的 prometheus.yml 则展示了生产化写法5 秒抓取间隔、host.docker.internal目标、以及同时覆盖 API8888与 worker8889两个 job。六、常用 PromQL 查询按类型统计操作平均延迟rate(hindsight_operation_duration_sum[5m]) / rate(hindsight_operation_duration_count[5m])每分钟 LLM 调用量按 providerrate(hindsight_llm_calls_total[1m]) * 60P95 LLM 延迟histogram_quantile(0.95, rate(hindsight_llm_duration_bucket[5m]))各模型累计消耗 Tokensum by (model) (hindsight_llm_tokens_input_total hindsight_llm_tokens_output_total)内部 vs API 的 recall 操作sum by (source) (rate(hindsight_operation_total{operationrecall}[5m]))每秒 HTTP 请求数按 endpointsum by (endpoint) (rate(hindsight_http_requests_total[1m]))HTTP 错误率5xxsum(rate(hindsight_http_requests_total{status_class5xx}[5m])) / sum(rate(hindsight_http_requests_total[5m]))P95 HTTP 延迟histogram_quantile(0.95, sum by (le) (rate(hindsight_http_duration_seconds_bucket[5m])))数据库连接池利用率 / 活跃连接数hindsight_db_pool_size / hindsight_db_pool_max hindsight_db_pool_size - hindsight_db_pool_idleCPU 使用率rate(hindsight_process_cpu_seconds{typeuser}[1m])七、分布式追踪OpenTelemetryHindsight 支持对记忆操作与 LLM 调用做 OpenTelemetry 分布式追踪遵循 GenAI 语义约定 v1.37。完整环境变量说明见 developer/configuration 的 OpenTelemetry Tracing 一节。7.1 快速开始# 启用追踪 export HINDSIGHT_API_OTEL_TRACES_ENABLEDtrue export HINDSIGHT_API_OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4318 # 用 Grafana LGTM本地开发查看 traces ./scripts/dev/start-monitoring.sh # 打开 http://localhost:3000 → Explore → Tempo支持任意 OTLP 兼容后端Grafana LGTM、Langfuse、OpenLIT、DataDog、New Relic、Honeycomb、Pydantic Logfire 等。除核心两个变量外config.py#L681-L685 还定义了HINDSIGHT_API_OTEL_EXPORTER_OTLP_HEADERSkey1value1,key2value2格式的导出请求头用于商业后端的鉴权HINDSIGHT_API_OTEL_SERVICE_NAME覆盖service.name资源属性HINDSIGHT_API_OTEL_DEPLOYMENT_ENVIRONMENTdeployment.environment.name资源属性。值得注意的实现细节见 tracing.py#L151-L209导出协议是 OTLP HTTPOTLPSpanExporter且 endpoint 若不以/v1/traces结尾会自动追加——所以本地 LGTM 填http://localhost:4318HTTP 端口即可不要填 4317那是 gRPC 端口本实现不使用API 与独立 worker 都会初始化追踪initialize_tracing_from_config同时被 FastAPI lifespan 与独立 worker 入口调用因此设置HINDSIGHT_API_OTEL_*后所有执行工作的进程都会上报 traces而不只是服务 HTTP 的进程优雅退出会强制 flushshutdown_tracing直接对 SDK provider 调shutdown()强制排空BatchSpanProcessor队列——worker 上单个 consolidation span 可能长达数分钟若进程收到 SIGTERM 时不 flush批处理队列里的一切都会丢失。7.2 Span 层级父 Span操作层hindsight.retain—— 记忆摄入hindsight.recall—— 记忆检索hindsight.recall_embedding—— 查询向量化hindsight.recall_retrieval—— 并行检索语义、BM25、图、时序hindsight.recall_fusion—— 倒数排名融合hindsight.recall_rerank—— 交叉编码器重排hindsight.reflect—— 代理式推理hindsight.reflect_tool_call—— 工具执行recall、lookup 等hindsight.consolidation—— 观察合成hindsight.mental_model_refresh—— 心智模型更新子 SpanLLM 调用层按 scope 命名如hindsight.memory、hindsight.reflect以 event 形式包含完整 prompt/completion属性遵循 GenAI 语义约定操作父 Span 由 create_operation_span() 创建统一打上hindsight.operation与hindsight.bank_id属性LLM 子 Span 由 LLMSpanRecorder 在调用完成后用显式起止时间戳创建start_time end - duration以兼容各 provider 已有的同步打点模式。源码级补充——跨进程追踪上下文传播API 入队的异步任务在 worker 进程执行worker 本身无从知道是哪个请求入队了它没有额外机制时API 的 span 与 worker 的hindsight.retainspan 会是两条互不相关的 trace。Hindsight 的解法是把 W3Ctraceparent注入任务 payload键_traceparentworker 侧再提取并续接调用方 trace见 inject_task_trace_context / extract_task_trace_context。内部定时任务或追踪关闭时入队的 payload 不携带该键提取返回 None逻辑安全降级。7.3 Span 属性操作 Spanhindsight.operation—— 操作类型hindsight.bank_id—— 记忆库 IDhindsight.query—— 查询文本截断至 100 字符hindsight.fact_types—— recall 的事实类型hindsight.thinking_budget—— 预算分配hindsight.max_tokens—— Token 上限LLM SpanGenAI 语义约定gen_ai.operation.name—— 恒为chatgen_ai.provider.name—— 提供商openai、anthropic、google等gen_ai.request.model—— 模型名gen_ai.usage.input_tokens/gen_ai.usage.output_tokens—— 输入/输出 Tokenhindsight.scope—— LLM 调用用途memory、reflect、consolidation等Eventgen_ai.client.inference.operation.details—— 完整 prompt 与 completion含输入/输出消息 JSON、系统指令、finish reasons见 tracing.py#L501-L515三个实现层面的注意点提供商名映射PROVIDER_NAME_MAPPING 将 Hindsight 内部提供商名规范化到 GenAI 约定——gemini/vertexai统一映射为google、claude-code映射为anthropic、github-copilot映射为github因此消费端按gen_ai.provider.name聚合时不会因内部别名而分裂内容截断单条内容超过 10 万字符MAX_CONTENT_LENGTH会被截断并追加[TRUNCATED: ...]标注防止 span 超出后端大小限制追踪永不拖累业务LLMSpanRecorder.record_llm_call整体包裹在 try/except 中且外层是CompositeSpanRecorder扇出结构——任一 recorder 失败只记录 debug 日志既不影响 LLM 调用本身也不影响其他 recorder。八、小结Hindsight 的可观测性设计可以归纳为三条主线指标覆盖从 HTTP 入口到 LLM 调用的全链路操作、retain 抽取结果、LLM 成本、连接池、进程资源并通过token_bucket、endpoint 模板化、metrics_include_bank_id等手段系统性控制卡基数追踪遵循 GenAI 语义约定Span 层级与记忆管道retain/recall/reflect/consolidation一一对应且通过 payload 级 traceparent 传播打通了 API 与 worker 两个进程的 trace工具链上一条./scripts/dev/start-monitoring.sh即可获得带三套预置仪表盘的本地 LGTM 全栈。把 monitoring/grafana/dashboards/ 中的仪表盘导入生产 Grafana、将hindsight.operation.total的失败率与outcomeno_facts占比纳入告警即可在记忆库规模增长时第一时间定位是 LLM 侧、数据库侧还是抽取策略侧出了问题。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表