Graphiti 与 OpenTelemetry 分布式追踪:为 AI Agent 知识图谱接入可观测性
Graphiti 与 OpenTelemetry 分布式追踪为 AI Agent 知识图谱接入可观测性【免费下载链接】graphitiBuild Real-Time Knowledge Graphs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/grap/graphiti导读Graphiti 是一个面向 AI Agent 的实时知识图谱构建框架而 OpenTelemetry 是业界标准的可观测性规范。本文基于仓库中的 OTEL_TRACING.md 文档系统讲解如何为 Graphiti 接入 OpenTelemetry 分布式追踪包括依赖安装、TracerProvider 与 ConsoleSpanExporter 的配置、将 tracer 传入Graphiti构造器、以及 Kuzu 内存数据库下的使用方式。读完本文你将掌握 Graphiti 追踪的开关逻辑、span 命名规范、底层实现原理与可复现的完整示例并了解如何把追踪数据进一步导出到 Jaeger 等后端以支撑生产级可观测性建设。一、为什么要给 Graphiti 接入分布式追踪Graphiti 的核心价值在于把非结构化文本、JSON 等异构数据持续转化为知识图谱每次add_episode都会触发实体/关系抽取、节点解析、去重、边构建、属性提取等多个耗时阶段每次search则要完成查询向量嵌入、多作用域执行、边/节点/社区多路召回与重排。这些阶段横跨 LLM 调用、Embedding 服务与图数据库操作链路长、外部依赖多没有追踪手段几乎无法定位性能瓶颈。Graphiti 在 graphiti_core/tracer.py 中定义了一套薄薄的追踪抽象层并通过 graphiti_core/graphiti.py 在Graphiti初始化时将其注入到 LLM 客户端、搜索模块等内部组件中。追踪是完全可选的能力不传 tracer 时内部会退化为NoOpTracer/NoOpSpan所有 span 操作均为空实现零开销不影响正常功能。二、安装依赖Graphiti 的追踪基于 OpenTelemetry 官方 SDK 实现需要额外安装两个包uv add opentelemetry-sdkopentelemetry-api提供trace、Tracer、Span、StatusCode等核心 APIopentelemetry-sdk提供TracerProvider、SimpleSpanProcessor、ConsoleSpanExporter等 SDK 实现供运行时真正产生和导出 span。Graphiti 源码对缺失依赖做了防御性处理graphiti_core/tracer.py 中通过try: from opentelemetry.trace import ... except ImportError探测OTEL_AVAILABLE标志若未安装 OpenTelemetry即使显式传入 tracerOpenTelemetryTracer的构造也会抛出ImportError并提示安装命令。在 examples/opentelemetry/pyproject.toml 中官方示例项目声明的最低版本为opentelemetry-api1.20.0与opentelemetry-sdk1.20.0可作为版本参考。三、基础用法三行配置开启追踪接入流程分为三步创建TracerProvider并挂载导出器 → 注册为全局 tracer provider → 把 tracer 传给Graphiti构造器。from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor from graphiti_core import Graphiti # 1. 设置 OpenTelemetryProvider SpanProcessor Exporter provider TracerProvider() provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter())) trace.set_tracer_provider(provider) # 2. 获取 tracer 并传给 Graphiti tracer trace.get_tracer(__name__) graphiti Graphiti( uribolt://localhost:7687, # 默认使用 Neo4jURI 为 bolt 协议 userneo4j, passwordpassword, tracertracer, trace_span_prefixmyapp.graphiti, # 可选默认 graphiti )参数说明参数类型默认值作用traceropentelemetry.trace.TracerNone追踪关闭OpenTelemetry tracer 实例开启追踪的入口trace_span_prefixstrgraphiti所有 span 名的前缀便于按应用/模块区分追踪数据Graphiti.__init__中tracer与trace_span_prefix的完整签名和语义见 graphiti_core/graphiti.py。关于 span 前缀底层实现有一个细节值得注意graphiti_core/tracer.py 中OpenTelemetryTracer会执行self._span_prefix span_prefix.rstrip(.)自动去除前缀末尾多余的.实际生成的 span 全名为f{self._span_prefix}.{name}见 graphiti_core/tracer.py。因此即使传入myapp.graphiti.这类带尾点字符串最终 span 名也不会出现.llm.generate之类的双点噪音。四、与 Kuzu内存图数据库配合使用Graphiti 的图驱动层是可插拔的除了默认的 Neo4j还支持 FalkorDB、Amazon Neptune 与 Kuzu。其中 Kuzu 是嵌入式内存图数据库适合本地开发、CI 与快速原型无需启动外部服务。from graphiti_core.driver.kuzu_driver import KuzuDriver kuzu_driver KuzuDriver() graphiti Graphiti(graph_driverkuzu_driver, tracertracer)传入graph_driver后Graphiti构造器将直接采用该驱动而跳过 Neo4j 连接见 graphiti_core/graphiti.py。此时无需再传uri/user/passwordtrace_span_prefix同样适用例如可设为graphiti.example以区分示例应用与库内部调用。五、完整可运行示例stdout 追踪仓库在 examples/opentelemetry/ 目录下提供了完整可运行的示例源码见 otel_stdout_example.py它把追踪数据输出到标准输出适合零成本体验。其依赖声明在 examples/opentelemetry/pyproject.tomlgraphiti-coreeditable 本地路径引用、kuzu0.11.2与 OpenTelemetry 两件套。5.1 运行方式uv sync export OPENAI_API_KEYyour_api_key_here uv run otel_stdout_example.py运行前提需要可用的 OpenAI API Key示例默认走 OpenAI 的 LLM、Embedding 与 Reranker 客户端并联网调用。示例中 Graphiti 使用KuzuDriver因此无需额外启动图数据库。5.2 追踪配置代码from opentelemetry import trace from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor # 设置 OpenTelemetry为服务命名并输出到 stdout resource Resource(attributes{service.name: graphiti-example}) provider TracerProvider(resourceresource) provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter())) trace.set_tracer_provider(provider) tracer trace.get_tracer(__name__) graphiti Graphiti( graph_driverkuzu_driver, tracertracer, trace_span_prefixgraphiti.example, )相比基础版示例额外引入了Resource为所有 span 附加service.namegraphiti-example资源属性——在导出到 Jaeger 等后端时这是服务维度聚合与过滤的关键字段。5.3 示例的执行流程main()依次完成以下动作每一步都会在控制台打印人类可读日志同时以 span 形式输出结构化追踪信息构建图索引与约束await graphiti.build_indices_and_constraints()依次写入三段 episode——两段文本EpisodeType.textKamala Harris 的履历、任期与一段结构化 JSONEpisodeType.jsonGavin Newsom 的职务信息均通过graphiti.add_episode(...)提交见 otel_stdout_example.py执行两次语义搜索Who was the California Attorney General?与What positions has Gavin Newsom held?并打印前 3 条结果的fact与valid_at时间有效性字段体现 Graphiti 的时序知识图谱特性最后在finally中调用await graphiti.close()释放资源。5.4 你能在 stdout 上看到什么启用后add_episode的内部流程会被包裹在一个graphiti.example.add_episodespan 中见 graphiti_core/graphiti.py其中包含实体抽取、节点解析、边构建等子阶段每次 LLM 调用则产生graphiti.example.llm.generatespan如 graphiti_core/llm_client/openai_base_client.py。每次search会产生一个层级化的 span 树输出形式大致为graphiti.example.search.execute_scopes graphiti.example.search.embed_query_vector graphiti.example.search.edge_search graphiti.example.search.edge_search.execute_methods graphiti.example.search.edge_search.rerank ...六、底层原理追踪抽象层与零开销设计Graphiti 的追踪能力建立在 graphiti_core/tracer.py 中的两层抽象之上Tracer/TracerSpan抽象基类定义start_span(name)与add_attributes/set_status/record_exception接口NoOpTracer/NoOpSpan所有方法空实现start_span通过contextmanager直接 yield 一个空 span——这是“零开销”的来源OpenTelemetryTracer/OpenTelemetrySpan把 OpenTelemetry 的Span/StatusCode包装进上述接口create_tracer(otel_tracer, span_prefix)工厂函数otel_tracer is None或 OpenTelemetry 未安装时返回NoOpTracer否则返回OpenTelemetryTracer见 graphiti_core/tracer.py。几个值得注意的实现细节防御性包装OpenTelemetrySpan的add_attributes会自动过滤None值、把非原始类型如列表、对象转换为字符串避免因属性类型非法而抛错graphiti_core/tracer.pyOpenTelemetryTracer.start_span在内部出错时也会退化为NoOpSpan确保追踪故障绝不拖垮业务graphiti_core/tracer.py。状态与异常set_status(error/ok)映射到 OpenTelemetry 的StatusCode.ERROR/OKgraphiti_core/tracer.py异常通过record_exception记录。统一注入Graphiti初始化时调用create_tracer并把结果通过self.llm_client.set_tracer(self.tracer)注入 LLM 客户端graphiti_core/graphiti.py搜索模块则从clients.tracer读取缺失时回退到NoOpTracer见 graphiti_core/search/search.py 与_resolve_tracer。搜索链路中的 span 命名搜索是追踪信息最丰富的场景。Graphiti 在 graphiti_core/search/search.py 中用_trace_phase(search_tracer, name, attributes)工具函数包裹每个阶段search.py该函数还会在阶段成功时set_status(ok)、失败时记录异常并set_status(error)。已观测到的核心 span 名包括Span 名对应阶段search.embed_query_vector查询向量嵌入search.execute_scopes按作用域边/节点/社区/剧集分派检索search.edge_search边检索主流程search.edge_search.execute_methods边多方法召回如 cosine_similarity 等search.edge_search.expand_bfsBFS 邻居扩展search.edge_search.rerank重排cross-encoder / MMR 等search.edge_search.load_embeddings加载边嵌入search.edge_search.compute_mmr计算最大边际相关度search.edge_search.cross_encoder_rankcross-encoder 打分search.edge_search.seed_rrf倒数排名融合RRF播种span 上还附带了可观测属性例如search.embed_query_vector会记录query.length与query_vector.dimensionsearch.execute_scopes会记录scope.edges、result.edges等见 tests/utils/search/test_search_tracing.py。这些属性组合前缀后即为真实输出的完整 span 名如myapp.graphiti.search.edge_search.rerank。七、追踪行为测试可观测性如何被验证仓库中的 tests/utils/search/test_search_tracing.py 专门验证了追踪行为可作为理解行为的“活文档”test_search_emits_trace_spans_for_edge_similarity用一个自定义RecordingTracer捕获所有 span断言一次 cosine similarity 边检索会产生search.embed_query_vector、search.execute_scopes、search.edge_search、search.edge_search.execute_methods、search.edge_search.rerank等 span并校验 span 属性如query.length、query_vector.dimension、scope.edges是否正确写入test_search_tracing.pytest_search_uses_noop_tracer_when_client_has_no_tracer与test_edge_search_uses_noop_tracer_when_none_is_passed验证未提供 tracer 时搜索流程回退到NoOpTracer功能不受影响test_search_tracing.py。这两类测试分别覆盖了“开启追踪时的 span 正确性”与“关闭追踪时的零开销降级”两条关键路径。八、进阶导出到 Jaeger 等后端ConsoleSpanExporter只适合本地调试生产环境通常需要把 span 发送到集中式追踪后端。OpenTelemetry 生态提供了多种导出器最常用的是OTLPSpanExporter配合 Jaeger、Tempo、Zipkin 等支持 OTLP 的后端。替换方式只需把ConsoleSpanExporter换成 OTLP 导出器并选用BatchSpanProcessor以批量异步发送、降低对业务请求的阻塞from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.trace.export import BatchSpanProcessor provider TracerProvider() provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpointhttp://jaeger:4317))) trace.set_tracer_provider(provider)注意以上 OTLP 示例代码需要在项目中额外添加opentelemetry-exporter-otlp-proto-grpc等依赖且当前仓库示例未内置该代码请结合自身部署环境Jaeger 的 OTLP 端口、网络可达性调整 endpoint 地址。后续流程与基础用法完全一致——tracer trace.get_tracer(__name__)再传入Graphiti(...)即可。九、总结与最佳实践Graphiti 的 OpenTelemetry 集成可以总结为四句话可选项零成本不传tracer即使用NoOpTracer功能与性能完全不受影响生产环境可按需灰度开启三行接入TracerProvider→add_span_processor→trace.set_tracer_provider再把tracer与trace_span_prefix传给Graphiti前缀隔离借助trace_span_prefix为不同服务/环境如myapp.graphiti、graphiti.example隔离 span 命名空间配合service.name资源属性在后端按服务聚合先 stdout 后后端开发阶段用ConsoleSpanExporter快速验证生产环境切换BatchSpanProcessor OTLP 导出器实现全链路可观测。对 AI Agent 知识图谱这类“LLM 调用 向量检索 图遍历”多重外部依赖叠加的复杂系统而言分布式追踪是定位延迟、诊断失败、理解端到端行为最直接的手段。从 OTEL_TRACING.md 出发配合 examples/opentelemetry/otel_stdout_example.py 运行一遍再对照 graphiti_core/tracer.py 与 tests/utils/search/test_search_tracing.py 阅读源码你就能完整掌握 Graphiti 可观测性的接入与原理。【免费下载链接】graphitiBuild Real-Time Knowledge Graphs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/grap/graphiti创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →