news 2026/10/15 15:45:31

OpenLLMetry Haystack 插桩实战:一行代码追踪 LLM 应用全链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenLLMetry Haystack 插桩实战:一行代码追踪 LLM 应用全链路
  • LLMOps
  • 可观测性

【免费下载链接】openllmetry

Open-source observability for your GenAI or LLM application, based on OpenTelemetry

项目地址:https://gitcode.com/gh_mirrors/op/openllmetry
点击查看免费下载

导读

本文讲解 openllmetry 仓库中 opentelemetry-instrumentation-haystack 包的完整用法:从安装、两行代码接入,到自动生成的 Workflow / LLM Span 结构,再到默认记录 Prompt 与 Completion 的隐私取舍与关闭方式。读完本文,你将掌握用 OpenTelemetry 语义约定追踪 Haystack 2.x Pipeline 全流程、并结合源码读懂底层埋点原理的方法。

一、这个包解决什么问题

Haystack(deepset-ai 推出的开源 LLM 框架)用Pipeline把 Prompt 构建、检索、生成等组件编排成完整的 RAG / 对话应用。要观测这类应用的运行质量,往往需要手工在管道各处插入日志或调用链代码,成本高且口径不统一。

opentelemetry-instrumentation-haystack基于 OpenTelemetry 规范,通过自动埋点把 Haystack 应用的关键节点(Pipeline 运行、OpenAI 生成器调用)转换为标准 Span,并附带 OpenLLMetry 定义的 GenAI 语义约定属性,让你无需改动业务代码即可拿到输入 Prompt、输出 Completion、模型与采样参数等可观测数据,用于调试、评估与成本分析。

二、安装

pip install opentelemetry-instrumentation-haystack

从 pyproject.toml 可以确认该包的运行前提:

  • 支持 Python>=3.10,<4;
  • 目标框架haystack-ai >= 2.0.0(即 Haystack 2.x 组件化架构);
  • 依赖opentelemetry-api>=1.38.0、opentelemetry-instrumentation>=0.59b0,以及opentelemetry-semantic-conventions-ai>=0.5.1,<0.6.0(提供 Span 属性常量);
  • 包同时注册了haystack-ai的 OpenTelemetry 插桩入口点,方便使用opentelemetry-instrument命令或 SDK 自动发现机制加载。

三、快速开始:两行代码接入

from opentelemetry.instrumentation.haystack import HaystackInstrumentor HaystackInstrumentor().instrument()

调用instrument()后,插桩会通过wrapt的wrap_function_wrapper对以下三个关键方法进行包装(见init.py 中的WRAPPED_METHODS):

包装目标追踪内容
haystack.components.generators.openai.OpenAIGenerator.run文本补全型生成调用
haystack.components.generators.chat.openai.OpenAIChatGenerator.run对话型生成调用
haystack.core.pipeline.pipeline.Pipeline.run整条 Pipeline 的运行过程

这意味着凡是经过Pipeline.run()编排、且内部使用 OpenAI 系生成组件的应用,都会自动产生完整追踪,无需在每个组件里手动打点。

HaystackInstrumentor还接受一个可选参数exception_logger:传入回调函数后,当埋点过程自身抛异常时,异常会被交给该回调处理(而不是影响业务代码),具体见 config.py 与 utils.py 中dont_throw装饰器的实现。

四、自动生成的 Span 结构:Workflow + LLM 双层模型

以官方测试用例 test_simple_pipeline.py 为例,一个由DynamicChatPromptBuilder+OpenAIChatGenerator组成的简单 Pipeline 运行后,会生成两个 Span:

assert { "haystack.openai.chat", "haystack_pipeline.workflow", } == {span.name for span in spans}

1. 管道级 Workflow Span

wrap_pipeline.py 在Pipeline.run()外层创建名为haystack_pipeline.workflow的 Span,并标记:

  • traceloop.span.kind=workflow(对应TraceloopSpanKindValues.WORKFLOW);
  • traceloop.entity.name=haystack_pipeline;
  • 若启用了内容追踪,还会写入traceloop.entity.input(请求输入)与traceloop.entity.output(管道输出)两个 JSON 序列化属性。

测试同样验证了这一点:workflow Span 上存在TRACELOOP_ENTITY_INPUT与TRACELOOP_ENTITY_OUTPUT。

2. LLM 调用级 Span

wrap_openai.py 针对两种生成器分别创建:

  • haystack.openai.chat(OpenAIChatGenerator,请求类型chat);
  • haystack.openai.completion(OpenAIGenerator,请求类型completion)。

Span 类型为SpanKind.CLIENT,并在创建时写入以下基础属性:

  • gen_ai.system=OpenAI;
  • llm.request.type=chat或completion。
输入属性

_set_input_attributes按请求类型记录:

  • 补全请求:gen_ai.prompt.0.user(即传入的prompt);
  • 对话请求:gen_ai.prompt.0.user(从messages列表中提取每个message.content)。

若generation_kwargs中存在以下参数,也会一并落盘到 Span:

参数Span 属性
modelgen_ai.request.model
temperaturegen_ai.request.temperature
top_pgen_ai.request.top_p
frequency_penaltyllm.frequency_penalty
presence_penaltyllm.presence_penalty
输出属性

_set_response_attributes遍历返回的choices,写入gen_ai.completion.<index>.content,对话模式下还会写入gen_ai.completion.<index>.role=assistant,并以StatusCode.OK标记 Span 状态。

3. 节点级 Task Span(预留能力)

仓库中还提供了 wrap_node.py,它会在单个 Pipeline 节点外层创建<node_name>.task形式、traceloop.span.kind=task的 Span,并把节点名写入上下文供子 Span 关联。从源码结构看,该包装器当前尚未登记进WRAPPED_METHODS的自动包装列表,属于为节点级细粒度追踪预留的实现。

五、完整的 RAG 应用示例

仓库的 sample-app 提供了一个开箱即用的 RAG 场景,展示了在真实业务中如何组合使用:Traceloop.init(app_name="haystack_example", disable_batch=True)初始化 SDK 后,构造InMemoryDocumentStore写入文档、SentenceTransformersDocumentEmbedder/TextEmbedder做向量化、InMemoryEmbeddingRetriever检索、PromptBuilder拼装提示词,最后经OpenAIGenerator(gpt-3.5-turbo)生成回答,所有环节都在一条Pipeline内串接:

basic_rag_pipeline = Pipeline() basic_rag_pipeline.add_component("text_embedder", text_embedder) basic_rag_pipeline.add_component("retriever", retriever) basic_rag_pipeline.add_component("prompt_builder", prompt_builder) basic_rag_pipeline.add_component("llm", generator) basic_rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding") basic_rag_pipeline.connect("retriever", "prompt_builder.documents") basic_rag_pipeline.connect("prompt_builder", "llm") response = basic_rag_pipeline.run( {"text_embedder": {"text": question}, "prompt_builder": {"question": question}} ) print(response["llm"]["replies"][0])

由于插桩包装的是Pipeline.run()与OpenAIGenerator.run(),上述管道运行时便会自动产出haystack_pipeline.workflow与haystack.openai.completion两层 Span,供你分析检索结果对生成质量的影响。

六、隐私配置:关闭 Prompt / Completion 记录

需要特别注意默认行为:默认情况下,该插桩会把 Prompt、Completion 和 Embedding 内容写入 Span 属性,以提供对应用运行的清晰可见性,便于调试与输出质量评估。但这类数据可能包含用户敏感信息,也会显著增大 trace 体积。

若需出于隐私或成本考虑关闭,只需设置环境变量:

TRACELOOP_TRACE_CONTENT=false

其判定逻辑位于 utils.py 的should_send_prompts():读取TRACELOOP_TRACE_CONTENT,未设置时默认视为true(即默认记录内容),只有显式设置为false才会停止把输入输出 JSON 写入traceloop.entity.input/output属性。同时,该函数还支持通过 OpenTelemetry Context 中的override_enable_content_tracing值在运行时按请求覆盖全局开关,实现更精细的内容追踪控制。

关闭后,Pipeline 级与 LLM 级的 Span 仍会照常生成(框架、模型名、耗时、状态等元数据不受影响),只是不再包含具体 Prompt 文本与生成内容。测试目录 tests/conftest.py 中也固定把该变量设为true以便断言输入输出属性存在,侧面印证了该开关的作用范围。

七、测试与验证:如何确认追踪生效

该包在 tests 下提供验证方式:conftest.py使用InMemorySpanExporter捕获 Span,并全局启用HaystackInstrumentor;test_simple_pipeline.py用 VCR 录制(过滤authorization头)的 OpenAI 响应驱动真实 Pipeline 运行,随后断言:

  1. 生成的 Span 名称集合恰好为haystack.openai.chat与haystack_pipeline.workflow;
  2. workflow Span 包含traceloop.entity.input与traceloop.entity.output属性。

你可以把同样的断言思路应用到自己的项目中——接入 exporter 后运行一次 Pipeline,即可直观核对插桩是否按预期产出 Span。

八、小结

opentelemetry-instrumentation-haystack把 Haystack 2.x 应用的可观测性收敛为“一次 install + 一次 instrument()”的标准动作:上层由haystack_pipeline.workflow描述整条管道,下层由haystack.openai.chat/completion描述具体生成调用,并统一复用 OpenLLMetry 的 GenAI 语义约定,方便与 OpenAI、Anthropic、LangChain 等其他插桩的 trace 在同一观测后端横向对比。接入后请务必结合业务场景决定TRACELOOP_TRACE_CONTENT的取值——默认记录内容虽利于调试,但对隐私敏感或 trace 体积受限的生产环境,应显式设为false。

  • LLMOps
  • 可观测性

【免费下载链接】openllmetry

Open-source observability for your GenAI or LLM application, based on OpenTelemetry

项目地址:https://gitcode.com/gh_mirrors/op/openllmetry
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 15:45:20

多选消息为什么会选错?稳定 ID、分页与提交快照

勾选了列表里的第二条消息&#xff0c;新消息插到顶部后&#xff0c;勾选却跑到了另一条消息上&#xff1b;翻到下一页再回来&#xff0c;选择又消失了。这类问题不一定来自点击事件&#xff0c;而可能来自选择状态保存了“位置”&#xff0c;没有保存“对象的身份”。 以米米…

作者头像 李华
网站建设 2026/10/15 15:45:19

群晖升级后Photos找不到了?照片没丢

群晖升级后 Photos 找不到了&#xff1f;照片没丢&#xff0c;是套件换了名字&#xff1a;三步找回入口 不少人家里的群晖 NAS 升级系统之后&#xff0c;突然发现桌面上熟悉的照片套件没了——原来叫 Photo Station&#xff0c;现在主菜单里翻遍了也找不到&#xff0c;进套件中…

作者头像 李华
网站建设 2026/10/15 15:45:01

SPSS多响应集详解:多选题定义、编码与频率交叉分析

实际分析问卷数据的时候&#xff0c;最容易被新手问倒的往往不是因子分析、回归模型这些听起来高级的东西&#xff0c;反而是“多选题怎么录、怎么定义、怎么分析”这种最基础的操作。SPSS里有个专门的功能叫“多响应集”&#xff0c;也就是我标题里说的“多选题定义”。不少人…

作者头像 李华
网站建设 2026/10/15 15:44:11

CentOS 7 部署 Django 生产环境:Python3 + uWSGI + Nginx 完整指南

第一次在一台 CentOS 7 服务器上部署 Django 项目时&#xff0c;我天真地以为流程就是把代码传上去、装个 Django、然后访问 IP 就能看到页面。后来真到了生产环境才发现&#xff0c;CentOS 7 默认自带的 Python 2.7 根本不满足 Django 新版本的要求&#xff1b;就算你费劲装了…

作者头像 李华
网站建设 2026/10/15 15:43:10

数字人小程序源码实战:从TTS到口型同步的完整链路与避坑指南

简介&#xff1a;这份123数字人小程序源码面向对数字分身、虚拟形象与口播应用感兴趣的开发者&#xff0c;尤其适合具备微信小程序基础、希望快速搭建数字人交互原型的初中级前端与AI应用学习者。资源以zip压缩包形式提供&#xff0c;共260个文件&#xff0c;整体约683KB&#…

作者头像 李华
网站建设 2026/10/15 15:42:33

自动驾驶感知与控制链路:车道线检测如何转化为转向指令

简介&#xff1a;面向C开发者和车辆控制/自动驾驶初学者&#xff0c;这份压缩包围绕道路检测与整车控制两大主题&#xff0c;提供一套完整的Visual Studio工程源码及相关学术资料。其中包含斑马线自动识别、车道偏离预警等检测方向的C实现代码&#xff0c;以及整车控制策略的参…

作者头像 李华