@amaster

Langfuse 的可观察性 深层空间( dsh)数字 :
- 一个 生成 每一次LLM呼叫(
llm/stream瀑布),外加一窝llm-request横跨带逐字记录环路请求 - 一个 工具观察 每个工具呼叫( e)
tools/pre-execute结束tools/result(中文(简体) ) - 一个 间距 百分比
hook/invoked编号 :hook/result组合,带有钩点、决定、退出代码和持续时间(下面是stder摘要)captureContent(中文(简体) ) - 一个 追踪 与观察到的活动相交的每届会议
session/event)——根被创建在第一个消息上或被观察到的操作上,保留了原来的转弯起始时间,结束于turn/end; 已完成的转折没有活动导出任何内容,而错误和取消仍然可见 - 子剂子会话嵌入到父母的树下(
session/created页眉链接 +subagent/start编号 :subagent/end(中文(简体) ) - 在生成输出、可选图像显示、继承的用户/标签和最终转弯重度方面进行结构化推理
- 每个会话提供的可选 W3C 父上下文,而不采用主机的环境 OTEL 上下文
安装
dsh plugin --profile my-agent add @amaster.ai/dsh-langfuse \
@langfuse/tracing @langfuse/otel @opentelemetry/sdk-trace-node \
@opentelemetry/api @opentelemetry/exporter-trace-otlp-http
SDK同龄人(@langfuse/tracing, (中文(简体) ), @langfuse/otel, (中文(简体) ), @opentelemetry/sdk-trace-node, (中文(简体) ), @opentelemetry/api)通过懒惰动态加载 import(),所以未使用的安装成本一无所有——但它们都必须在运行时在场(dsh plugin add 不自动安装对等树,所以出口商 @langfuse/otel 明确列出其同行.
配置
默认禁用 。 通过配置配置配置 cordis.patch.yml数字 :
- insert:
- id: langfuse
name: '@amaster.ai/dsh-langfuse'
config:
enabled: true
publicKey: pk-lf-...
secretKey: sk-lf-... # secret role
baseUrl: https://cloud.langfuse.com
traceName: dsh-turn
captureContent: true # set false to record metadata only
maxPayloadBytes: 262144 # LLM payload and tool IO cap (256 KiB)
userId: developer
tags: [coding, experiment-a]
environment: development
release: build-42
redactFields: [password, authorization]
captureMedia: false # opt in to uploading images
maxMediaBytes: 5242880 # total image bytes per display payload
mediaTimeoutMs: 5000 # attachment read deadline
明确剖面值优先于环境变量。 空证书/基准 URL 返回到 LANGFUSE_PUBLIC_KEY, (中文(简体) ), LANGFUSE_SECRET_KEY,以及 LANGFUSE_BASE_URL (当时的欧盟云URL). userId 倒计时 LANGFUSE_USER_ID。空环境/释放值使用 SDK LANGFUSE_TRACING_ENVIRONMENT 编号 : LANGFUSE_RELEASE 默认值. LANGFUSE_TRACING_ENABLED=false (或 0) 覆盖配置主控开关;仅环境密钥无法启用插件 .
缓冲期排出 session/flush(session);出口者用插件纤维关闭。 一个会场检查点等待其自身的显示预测,包括已经附在追踪上的子孙会议工作;不相关的会议不会拖延。 任何检查站都列入无会话预测。 卸载排出所有待定的预测。 SDK 出口商仍由插件共享 。 卸载还用收集的部分内容/使用关闭未完成的模型调用,并标记不完整调用 WARNING,包括从未消耗过溪流的电话;原溪流仍然可以平息而无需两次结束这些观测. 附件在背景中读取, 绝不会延迟代理商的块流或工具返回值; 超过最后期限的读取会降解为图像元数据, 即使后端忽略了取消 。 SDK的车 LANGFUSE_FLUSH_AT, (中文(简体) ), LANGFUSE_FLUSH_INTERVAL,以及 LANGFUSE_TIMEOUT 控制出口商批量和网络超时.
与 captureContent: true两者 llm-call 财务报告和审定财务报表 llm-request 输入包含 llm/stream 请求选项,但不可串行的除外 AbortSignal。新的请求字段无需插件更新即可通过。 对于有图像的请求,生成输入被更新为显示投影; llm-request 保留原附件引用。 兰福斯的同辈人 modelParameters 属性概括已知的采样字段;它不是请求输入的一部分。 这些是 dsh- side 值,而不是精确的提供者 HTTP 有效载荷:适配器可能在此接合后添加默认值,项目消息/工具,或者重命名字段. 与 captureContent: false,收集器保留块/工具调用计数和使用,而无需缓冲文本、推理、工具参数或生块;输入则保留结构计数而分开 modelParameters 属性保存安全参数元数据; 解答节录,推理,工具参数/结果,出错文本,以及从观测名称和IO中不包含介质.
maxPayloadBytes 独立绑定每个抓取的请求,原始块流,以及每个 LLM 调用组装的输出,以及每个工具输入,输出,和出错状态消息(默认为 256 KiB). Span更新和结尾也绑定了记者边界上的IO,包括普通转会根和A2A任务根;遗留的痕量IO属性得到相同的受限值. 结构过大的有效载荷成为有界限的预览;过大的溪流只保留接合块/前缀和设定 metadata.truncated。在重度和 metadata.truncated 继续提供。 这些限制仅适用于遥测副本:转发的块和原始信件/结果保持不变。 会话处理结束该会话的活性 LLM/工具观测;一个在激活前回滚的儿童 subagent/start 立即关闭,而已经启动的孩子仍然关闭在 subagent/end。 。 。 .
配置 Langfuse 证书和 pk-lf-* 编号 : sk-lf-* 数值在记者的有效载荷、姓名、状况信息和标签上进行编辑. redactFields 连续替换匹配的有效载荷字段,包括JSON编码参数,忽略大小写。 名称摘录由编辑后产生. 三角洲块也被检查为已组装的文本,因此零碎的证书不能绕过遮罩:受影响的块保留其记录计数/类型/索引,在第一个三角洲和后来的三角洲中清理出已消化的文本. 编辑只更改遥测副本;原始消息/结果和转发流保持不变。 出口商对IO和元数据使用同样的口罩作为最终保障. 用户/标签是明确的元数据,在内容捕捉功能关闭时仍保留.
理由、图像和结果
仅文本生成输出仍然是字符串 。 当出现推理或工具调用时,输出会使用Langfuse聊天格式: role: "assistant"选项 content, (中文(简体) ), thinking 块,和 tool_calls 和函数参数。 这使得在格式化的预览中思考和引用工具成为可能. 最初的推理三角洲仍留在巢穴中 llm-request 输出; 没有创建额外的生成 .
captureMedia: true 需要获取内容和可用的 ctx.attachments 服务@deepseek-ai/dsh-attachment >=0.2.0-rc.1 || >=0.2.2-rc.1). 即时,生成-输入,和工具-输出图像引用通过该服务被读取,并被转换为SDK媒体上传器的数据URI. 安装适合部署的附件捆绑; 插件不会即时切换存储后端 。 缺失/ 失效读取, 卸载图像, 不支持的 MIME 类型, 超大小的图像, 被禁用的媒体会回到 MIME/ 大小/ dimension 元数据 。 一代字节预算涵盖该请求中的所有信息. 当模型,工具,或转弯完成时,会捕捉到观测结束时间;被延迟的图像读取不会扩展业务延迟. LANGFUSE_MEDIA_UPLOAD_ENABLED=false (或 0) 超越媒体捕获. 逐字记录引用仍然是元数据;它们的字节没有上传.
根重度跟随最后转弯原因:错误是 ERROR; 取消、 屏蔽、 符号限制和中断 WARNING. 回收的中间生成/工具/ hook/ subagent 错误集 hadErrors 元数据,而最后转折成功 DEFAULT。这可以保持重试失败的可见性,而不将恢复视为失败转折。 杰出工具也接近 WARNING 在卸货时,包括没有代理/会话的电话;没有反复遥测或媒体读取的延迟结果仍然送达其最初的呼叫者.
按要求提供的元数据、标签和分布式追踪
主机可以在会话下一个跟踪开始前提供上下文 :
ctx.emit('langfuse/context', session.id, {
userId: 'user-123',
tags: ['support', 'experiment-b'],
metadata: {
projectId: 'project-a',
requestId: 'request-123',
experiment: { name: 'retrieval', variant: 2 },
labels: ['interactive'],
},
traceparent: '00-1234567890abcdef1234567890abcdef-1234567890abcdef-01',
});
被打出的事件通过此软件包的 Cordis 增强导出. 背景通过下个转折跟踪(或先创建出局跟踪)消耗一次;再次发送到另一个请求. 标签覆盖了该跟踪的配置默认值,并通过世代、工具、钩子和嵌入子剂传播。 当处理会话或插件卸下时会丢弃队列上下文 。 同时会话有独立的上下文;没有修改进程-全局请求环境.
metadata 接受带有任意字符串键和嵌入值的平面 JSON 对象:平面对象、密集数组、有限数、布尔数、无效和字符串(包括空字符串)。 事件立即验证,快照并掩盖了上下文,因此后来的呼叫者突变无法改变. 请求元数据由每个观察所携带; 插件生成的字段, 如 turn, (中文(简体) ), provider, (中文(简体) ), toolName 财务报告和审定财务报表 taskId 以这一看法为准。 现有证明面具和 redactFields ,在 captureContent: false。 。 。 .
非JSON元数据以诊断方式拒绝提交的全部上下文,而不会中断代理或保留较早的待处理上下文. 这包括非无限数字,未定义,函数,符号, BigInt, 循环引用, 抛出获取器, 类例(包括 Date, Map and Set), 稀有数组, 额外数组属性, 以及符号键或非可假设对象属性. 价值观从不默默转换或下降,自定义 toJSON 不引用函数。 仍然支持允许的可选上下文字段。 对于一项现有的A2A任务,提供新的元数据取代它为任务根请求的元数据,并随后创建了转弯和后继;已经创建的观测保留了上下文.
该插件在其OTLP有效载荷中保留了JSON类型. Langfuse 服务器 API 可能会使存储的值正常化: 例如, v3 读取了 API 解析一个顶级元数据字符串 "123" 作为数字 123。 。 。 .
只有具有非零微分/span ID的清晰的W3C版本-00父母被加入. 无效的标题记录一个前缀的诊断并启动一个独立的跟踪. 没有信头, 插件总是会启动独立的追踪 。 每个观测点都是在原生的OTEL内部产生的 ROOT_CONTEXT:排除了外号和Langfuse行李(用户/tags/metadata),同时保留了明确的父母和插件标签. 这种范围化上下文并不取代主机的全球提供者或上下文管理器. 加入外出微量时,dsh的转弯是被提供母体下的观察;SDK的自动app-root索赔被禁用,外出所有者的微量名和微量层IO保持不变.
托肯用途和费用
生成 usageDetails 有脱节 input, (中文(简体) ), cache_read_input_tokens, (中文(简体) ), cache_creation_input_tokens, (中文(简体) ), output,以及 output_reasoning_tokens 桶加起来 total。在成为自己的桶之前,从提供者输出中减去理由;缓存输入单独计算。 这些密钥与官方的Pi集成相匹配. 使用上一个定义 input_cache_read, (中文(简体) ), input_cache_creation,或 output_reasoning 名称必须更新其价格键。 这样做可避免双重计算使用量和所推断的费用。 在 Langfuse v3 上,紧凑的标志徽章可能只显示基座 input编号 :output 桶头. 打开其总输入(包括缓存)和产出(包括推理)的使用分解; total 已经包括每个桶。 不将缓存的令牌添加到 input 再次改变徽章.
Langfuse 推断美元成本 当生成模型将模型定义与该模型的价格相匹配时 精确使用密钥。在项目设置 → 模型中,为私人路线、模型别名或自定义价格配置这些桶;推理输出一般使用模型的输出率。 符号总计不能证明存在匹配的价格定义. 如果一代显示出"创造模型定义",其模型没有匹配的定义. 对于网关别名,在定义价格时使用实际的路由模型和网关的费率;插件保留所请求的模型名而不是猜测上游模型. 定义的改变仅适用于新一代。 dsh 的当前 TokenUsage 因此,插件不主张供应商开具发票的费用或维持自己的价格表.
接通电话和会话标题 llm/stream 已经接收到他们自己的一代 purpose 元数据,包括转出电话。 使用相同LLM服务的工具也在那里被观察到;从工具-结果使用中添加第二代将重复核算.
当dsh悬钩桥发出对接的会话记录时,会出现钩子跨. 已启用内容抓取, 它们显示 hook:<point>:<name>,可选输入和解析结果,以及可用边框进程输出与执行状态。 出厂商必须放出这些字段;升级此插件无法回收省略的数据. SessionStart 只有在制作人报告并且安装的运行时间承认记录时才会出现.
自定义钩子生产商
自定义桥使用相同的 hook/invoked 财务报告和审定财务报表 hook/result 会议记录。 作家和消费者接受不受限制的 dialect 源字符串 (gemini, (中文(简体) ), codex, (中文(简体) ), company-validator)等),录入会话日志仍取决于已安装的运行时间变量. 不需要方言注册或单独的出口商。 插件只注意记录,从来不执行钩子或更改其决定.
导入 appendHookEvent, (中文(简体) ), HookInvoked,以及 HookResult 从 @amaster.ai/dsh-langfuse。这个键入的写器使用真实的 session.append 发布路径而不重新声明 SessionEventMap。它的TypeScript适应允许自定义有效载荷,尽管上游可选 dsh-hook-protocol 类型增强;它不扩大该软件包的运行时间合同、跑道或桥接API。 作者验证字段、 捕获附件失败、 日志 [dsh-langfuse],并返回布尔;遥测成功绝不能控制钩子的决定.
DSH0.2.1-rc.2. 维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球在线解说-维基月球 Anders. 上游悬钩无常伴并 dsh-invariants 软件包不再是此运行时间的一部分。 自定义方言和延迟结果通过会话出版物接合被接受;插件仍然验证钩子记录并包含附件失败.
运行时兼容边界( 已验证) [email protected]) (中文(简体) ). 当它的无常伴侣被注册和启用时 dsh-invariants,它拒绝除 claude-code编号 :codex在开阔的转弯之外引用,在开阔的转弯之后,或者在开阔的转弯之后,产生结果。 类型断言不能绕过这些承诺前检查 . appendHookEvent 返回时 false (c) 未经证实或公布,没有制作Langfuse钩观测结果.
| 运行时间构成 | Claude Code/Codex在开关对口 | 自定义方言 | 引言/延迟结果 |
|---|---|---|---|
| 无活性钩子- protocol 无变量 | 支助 | 支助 | 获得支持 invocationId |
| 活性悬钩-活性无变量0.2.0-rc.2 | 支助 | 被拒绝 | 被拒绝 |
编剧从不禁用或重新配置不变量. 使用活性伴侣的应用程序在采用自定义记录或后期记录之前需要上游合同变更. 即使遥测被否决,制片人仍然拥有钩行和决定权. 以下自定义示例需要包含这些记录的运行时间构成.
import { randomUUID } from 'node:crypto';
import { appendHookEvent } from '@amaster.ai/dsh-langfuse';
// The bridge determines turn/point, executes the command, and owns its outcome.
const invocationId = randomUUID();
const identity = { turn, point: 'BeforeAgent', handlerId: 'request-validator', invocationId };
appendHookEvent(session, 'hook/invoked', {
...identity,
dialect: 'company-validator',
name: 'Validate request',
input: { request: 'example' },
});
// After execution, including exceptions, timeout or cancellation:
appendHookEvent(session, 'hook/result', {
...identity,
decision: 'pass',
outcome: 'success',
exitCode: 0,
durationMs: 37,
result: { reason: 'valid', additionalContext: 'checked', continue: true },
});
每个自定义的处决都应该有一个独特的 invocationId 并释放出结果 生产者 finally 路径。 两个记录必须共享 turn, (中文(简体) ), point, (中文(简体) ), handlerId,以及 invocationId。 。 。 . handlerId 识别配置的处理器; invocationId 确定一次处决,包括同时处决一名处理者。 可选 name 在启用内容抓取时标记观察. HookInvoked.input 携带脚本有效载荷; HookResult.result 带有已解析的输出对象,包括现有理由、额外上下文和继续/停止指令。 消费者保留这些由生产者界定的领域,而不将它们解释为决定。 未匹配/悬钩不得放出引用:这些记录代表实际执行. 可选 stdout, (中文(简体) ), stderr 遗产 stderrSummary 被蒙上面罩,然后在观察中每个字符限为4096个,其中 stdoutTruncated, (中文(简体) ), stderrTruncated 财务报告和审定财务报表 stderrSummaryTruncated 元数据。 制片人还应约束持续的流程输出,省去没有的可选字段,而不是写入 undefined 输入 JSON 会话日志.
工具钩应该包括行刑 callId 在两个记录。 插件在发端会话内匹配并转出;它从不选择最后一个活动工具. 工具观测开始于 tools/pre-execute (预设观察员) tools/result,涵盖同步/等待的"Tool"和"AfterTool"的钩子,发送前拒绝,以及最终的政策后输出. 在最后结果通知之前,桥梁必须在执行前瀑布范围内运行前Tool,在执行后范围内运行后Tool。 登记在观察员前面的桥梁在报告吊钩之前,必须先委托代表。 代理钩和遗留记录没有 callId 仍在转弯/输水器下。 未知或已经完成的呼叫返回到该父调;后引出在原转会外使用下面的离子根行为.
hook/result.outcome 独立描述进程执行 decision数字 : success 是正常的补全, failed 是执行失败, timed-out 期限终止,以及 cancelled 正在取消。 制作方将其过程语义映射到这些值上;表达政策否定的退出代码仍然能够成功执行. 可选 exitCode 财务报告和审定财务报表 signal 保存进程细节。 死刑的被执行/执行的被执行失败/被执行的被执行人收到错误的观察,被取消的被执行人收到警告,而成功执行则保留基于决定的警告。 没有明确结果的记录保留了遗留的退出码解释(0/2是非错误的). 插件记录 durationMs 永远不要从缺失的退出代码中推断出超时或取消.
对于届会所接受的记录,请使用 invocationId 保留关联 turn/end 以及随后 turn/start; 后期结果结束原钩子跨度而不附加到新转弯上. 延迟援引,包括: UserCancel,重复使用它们的发源回合的父回合,即使下一回合开始。 该插件保留了所有会议的最新128个完成的转会协会,清理了会议协会的处置问题和所有卸载协会。 报告从不重开结束的根或改变其结束时间或最终状态;每个钩子记录自己的持续时间. 当原父母不能或被驱逐时,援引会收到一个单独的根 detachedHook: true 和原始转接号码;其结果既会结束钩和倒接根. 路径都不消耗 langfuse/context 排入下个回合。 分离的生产者必须在会议结束之前完成报告。 会话处理/插件卸载关闭未完成的运行 hook result not observed;这意味着缺少遥测,而不是执行失败的证据. 没有遗产记录 invocationId 仍然靠近转弯边界.
自定义名称、 钩入、 解析结果和原始进程输出如下 captureContent; 全权证书和 redactFields 被现有记者所掩盖。 新的结果、相关ID、方言、点、期限和处理元数据仍然可用,但内容捕捉被禁用。 事件写作机不会对会话日志本身进行消毒:应用程序的制作者仍然对其坚持不懈负责. 应用程序必须明确用此标准生产者路径来取代任何私有的钩子事件,再使用相同 invocationId,并报告实际结果;安装/升级插件不会调整应用程序桥或修复历史 Trace 概览 IO(问题#59).
可观测性是无推移接合:后端错误用一个记录 [dsh-langfuse] 前缀并永不逃入代理循环.
兼容性
运行 pnpm test:sdk 使用真正的 Langfuse SDK 和现有的本地 OTLP 接收器进行无秘密检查。 它验证导出、本地工具类型、SDK标签编辑、环境袋隔离、外部痕量所有权、无代理工具卸载、真实工具运行时间和钩子过程、工具锁定的养育方式和附加时间戳、内容遮盖和自定义钩子出口。 它与被嘲弄的单元套房和网关/真-Langfuse E2E腿分开.
独立 dsh-langfuse.tool-hooks E2E腿将已打包的插件在真实的无头配置中靴出,要求模型读取一个标记文件,并通过一个E2E-只制作者执行"Tool"/"AfterTool"脚本. 它需要网关和Langfuse的证书,然后对真实的Observation API进行投票,以验证被命名的钩子,工具召唤的育儿,包含工具时间戳,脚本输入和解析的输出,认证口罩,和stdout截取. 现有 dsh-langfuse.hook leg 继续检查上游的 Codex UserPromptSubmit 桥;新的固定器验证了共享事件合同,不取代应用程序的双子桥集成.
这个 dsh-langfuse.cancel-hook E2E腿在工具边界上取消一个真正的代理,排队它的下个转弯,并在转弯开始后同步运行一个UserCancel进程. Real Langfuse API read-back 必须在已取消的转弯根和痕量ID下显示钩子,根子仍然被中止并结束于钩子自身持续时间之前. 它需要现有的网关 和Langfuse的秘密在 integration.yml。 。 。 .
追踪概览相容性
总投入/产出属于 dsh-turn 根观察. 当转弯结束时会导出根;当一个长转弯运行时,在根出现之前已经可以看到子观测. 完成后,允许同步摄入进行结算.
插件还发送已贬值 langfuse.trace.input 编号 : langfuse.trace.output 属性在独立拥有的根上用于后继 Trace 概览兼容性。 在加入外部拥有的痕迹时,它从来不写这些字段. Langfuse 推荐 根观测 IO;空的 Trace 概览字段本身并不确定缺失的观测数据.
Real Track/root API 读取后在自办的 Langfuse 上被验证 3.172.1 (中文(简体) ) 与JS SDK 5.10.1 联合国 财务报告和审定财务报表 5.1.1.1 (中文(简体) )这验证了新的合成转子,包括从根部出口的儿童,以及外部观察与跟踪结合。 它不为每个服务器版本建立相容性,也不修复历史痕迹. 问题59 含有历史SDK 5.1.1.1痕量,其根 IO 已存在,但 Trace IO 仍为空;这一差异的原因没有被新转回. 为了追踪,请选择 dsh-turn 阅读总体请求和答复.
在没有LLM的情况下验证您的部署 LANGFUSE_PUBLIC_KEY, (中文(简体) ), LANGFUSE_SECRET_KEY,以及 LANGFUSE_BASE_URL 在进程环境中,然后运行:
pnpm --filter @amaster.ai/dsh-langfuse build
node .github/scripts/integration/lib/langfuse-trace-io-check.mjs
检查在环境中创建合成跟踪 ci 在两分钟的期限内进行投票 重试瞬间网络错误 HTTP 429(荣誉) Retry-After 5xx回复。 它直接用ID来读取每个观察,在摄取时重试404;其他永久性的4xx错误立即失效. 它明确要求跟踪IOfields=core,io),而不是依赖服务器配置的默认字段. 它首先验证了车主的根和Trace IO,然后输出出外部观察,并等待它在同一跟踪中特有的IO,同时检查车主的Trace IO仍然完好无损. 全权证书和答复机构未印出。 只靠根的成功不会通过此检查 .
Dsh/cordis 版本在 根相配矩阵事件有效载荷搭载预放出 dsh API-检查 TODO(verify) 标记在 src/ 在升级 dsh 之前.
许可证
麻省理工学院
Langfuse 整合方案与环境的标签观测 ci编辑 GITHUB_SHA,以及情景的标记,运行ID,和工作流程运行尝试. 选择环境 ci 在Langfuse找到新的E2E痕迹。 Read-back对每个模型运行使用限定的时间窗口,并在摄取时直接查询已发现的踪迹.