资讯动态

华为云Flexus+DeepSeek征文|DeepSeek-R1 Agent 可观测性实战:用 Langfuse + OpenTelemetry 打通 Dify 全链路追踪与评测,把 endpoint

发布时间:2026/10/8 12:50:20 来源:尧图企业网站定制
1. 从“部署成功”到“运行正常”Dify 上 DeepSeek-R1 Agent 的可观测性缺口你大概率经历过这个场景用华为云 Flexus X 实例一键拉起 Dify接上 MaaS 平台的 DeepSeek-R1 商用推理服务搭出一个企业知识库问答 Agent压测通过、体验顺滑、正式上线。第一周风平浪静第二周开始出问题——用户投诉“有时候回答特别慢”但你不知道慢在哪一步是 R1 思考太久知识库检索太慢还是工具调用卡住了某个深夜 Agent 连续输出几十次错误答案你第二天早上才发现却根本不知道那批请求是哪个版本、哪条 Prompt、调用了哪些工具。这些问题的共同根源是大模型应用是概率系统不能用“部署成功”来定义“运行正常”。传统监控只能告诉你“进程活着、接口 200”却无法回答“这次回答的质量如何、推理链路是否健康”。LLMOps 之所以成为 AI 工程领域最热的方向之一就是因为可观测性是 Agent 从 demo 走向生产的分水岭。本文要解决的就是这件事在 Dify 上跑 DeepSeek-R1 Agent用 Langfuse 采集 trace、用 OpenTelemetry 统一埋点覆盖工具调用、检索与评测环节并给出可复制的模型 endpoint 与环境变量配置片段。适合已经用 Dify 搭过 Agent、但被“黑盒”问题困扰的开发者。整套方案的核心检索词是 Dify DeepSeek-R1 Agent 全链路追踪读完你能自己搭出一套可回放、可评测、可告警的观测体系。2. 前置准备TaoToken 接入 DeepSeek-R1 与 Langfuse 自托管选型在动手配 OTel 之前先把模型入口和观测后端这两件事定下来。模型侧我用的是 TaoToken 提供的统一 API 入口它兼容 OpenAI 协议Dify 里配模型时直接填 Base URL 和 Key 就能用省去在多个平台之间来回切换的麻烦。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 注意这个不加 UTM 参数。观测后端选 Langfuse理由是它是开源 自托管路线里最成熟的选择Traces、Scores、Datasets、Prompts 管理全部开源Docker 一条命令就能跑起来数据完全留在企业内部。对金融、政企这类数据敏感场景这是刚需。整个体系跑在 Flexus X 实例上架构是 Dify 负责 Agent 编排DeepSeek-R1 走 MaaS 推理服务Langfuse 以 Docker Compose 方式自托管Nginx 做统一入口且 Langfuse 仅内网可达。资源规划上给三档参考。内部试用、日会话小于 5004C8G 够用Dify 和 Langfuse 同机Langfuse 限制 1G 内存。团队使用、日会话 500 到 5000建议 8C16GLangfuse 独立容器限 2G采样率 0.5。生产对外服务、日会话超过 500016C32G 或上 CCE 高可用Langfuse 单独实例采样率 0.1。两个容易踩的容量坑Langfuse 的 Postgres 会随 Trace 增长迅速膨胀务必配好 retention 定期清理思维链 reasoning_content 动辄几千 token入库前必须截断否则一周就能吃掉几个 G 存储。Langfuse 的四个核心概念先建立起来后面所有操作都围绕它们。Trace 是一次完整会话或一次 Agent 运行的顶层容器对应 Dify 里的一次对话。Observation 是 Trace 内部的子单元分三类span 是工作流节点和工具调用generation 是一次 LLM 调用event 是日志或异常标记点。Score 是挂在 Trace 或 Observation 上的质量分来源可以是人工、规则或 LLM-as-judge。Dataset 是一组“输入-期望输出”样本用于回归测试和模型对比。映射到 Dify Agent一条 Trace 等于一次用户问答span 是知识检索和工具调用generation 是每次调用 DeepSeekScore 是我们对这次回答打的质量分。3. 可复制配置Dify 模型 endpoint 与 Langfuse/OTel 环境变量片段这一节是全文最需要你动手的部分配置片段可以直接复制。先配 Dify 的模型供应商在 Dify 的“设置 → 模型供应商 → OpenAI-API-compatible”里新增一个模型关键字段如下{ model: deepseek-r1, model_type: llm, credentials: { api_base: https://taotoken.net/api, api_key: sk-你的TaoToken密钥, mode: chat, context_size: 65536, max_tokens_to_sample: 8192 }, model_properties: { mode: chat, context_size: 65536 } }这里 Base URL 填 https://taotoken.net/api Key 从 TaoToken 控制台的 API Keys 页面拿Model ID 填 deepseek-r1。三件套Base URL Key Model ID缺一不可Dify 里配错任何一个都会在调用时报 401 或 model not found。接着配 Dify 的 OpenTelemetry 导出。编辑 Dify 的 docker-compose.yaml在 api 与 worker 服务中加入以下环境变量services: api: environment: ENABLE_OTEL: true OTEL_EXPORTER_OTLP_ENDPOINT: http://langfuse:4318 OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf OTEL_SERVICE_NAME: dify-api OTEL_TRACES_SAMPLER: parentbased_traceidratio OTEL_TRACES_SAMPLER_ARG: 1.0 worker: environment: ENABLE_OTEL: true OTEL_EXPORTER_OTLP_ENDPOINT: http://langfuse:4318 OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf OTEL_SERVICE_NAME: dify-worker4318 是 Langfuse 的 OTLP HTTP 接收端口。如果 Dify 与 Langfuse 不在同一 Compose 网络把 langfuse 换成实际地址。采样率生产环境建议从 0.1 起步观测稳定后再逐步调高。注意 api 和 worker 的 OTEL_SERVICE_NAME 要区分开否则链路会被拆成两条。再配 Langfuse 自托管。官方提供 docker-compose 部署方式核心服务包括 web、worker、postgres、redis、miniogit clone https://github.com/langfuse/langfuse-docker.git cd langfuse-docker cp .env.example .env # 编辑 .env设置 SALT、ENCRYPTION_KEY、NEXTAUTH_SECRET docker compose up -d启动后访问 http://:3000 创建账号和 Project在 Settings → API Keys 里拿到 Public Key、Secret Key 和 OTLP Endpoint。这三个凭据后面写评测脚本和配 Dify 导出都要用。最后是 R1 思维链的提取配置。Dify 的 Agent 节点里DeepSeek-R1 的 reasoning_content 会出现在节点输出的 llm_result 中。在 Agent 节点的“结束”分支接一个代码节点把思维链写入会话变量def main(reasoning_content: str, answer: str) - dict: truncated reasoning_content[:2000] return { reasoning_trace: truncated, answer: answer, trace_event: { type: llm_reasoning, model: deepseek-r1, reasoning_tokens: len(reasoning_content) } }截断到 2000 字符是为了避免观测数据膨胀。配合 Langfuse 的事件标记功能你能在 Trace 时间轴上直观看到模型在哪个节点开始思考、思考了多久、输出了多少思考 token。4. 验证请求从一次 Agent 问答到评测分数的完整链路配置完成后跑一次 Agent 问答来验证链路是否打通。在 Dify 里发起一个测试对话比如“帮我查一下上个月华北区的销售额汇总”然后到 Langfuse 的 Projects 页面刷新。判断链路完整的标准有四条有根 Trace一条用户会话对应一个根 Trace 而不是散落的碎片 span有 LLM 调用能看到 DeepSeek 的每次请求含 model、input、output、tokens有工作流节点知识检索和工具调用按顺序排列有时间轴每个 span 都有耗时能一眼看出慢在哪。如果看不到 Trace优先检查三件事Dify 与 Langfuse 网络是否互通在 Dify 容器里执行 curl langfuse:4318 看能否连通ENABLE_OTEL 是否生效重启后查看 Dify 日志有无 OTel 相关报错协议是否匹配http/protobuf 和 http/json 不能混用。链路打通后用 Trace 回放定位一次“回答质量劣化”。打开那条 Trace你会看到这样的结构Trace: 帮我查一下上个月华北区的销售额汇总 ├─ span: 意图路由 (12ms) → 分类: 数据查询 ├─ span: 工具调用 (340ms) → search_sales(华北区, 上月) │ └─ event: 检索命中 0 条 可疑点 ├─ generation: DeepSeek-R1 (8.2s) ← 思考 6123 tokens, 回答 214 tokens │ └─ reasoning_content: 检索结果为空但用户明确要求汇总 │ 我基于历史知识补充了一个估计值...... └─ span: 输出 (18ms) → 回答: 上月华北区销售额约 X 万元问题瞬间水落石出不是模型变笨了而是工具调用传参错了“华北区”没匹配上库里的“华北区域”R1 在检索为空的情况下基于先验知识硬答还给了个看似确定的数字。修复方向有两个修正工具的参数归一化把“华北区”映射到“华北区域”在 Agent Prompt 里加硬约束检索结果为空时必须明确告知用户禁止推测具体数字。接下来验证评测闭环。在 Langfuse 中创建 Dataset把生产环境的高质量会话和线上发现的问题样本沉淀进去一个像样的黄金集至少 50 到 100 条。然后用 LLM-as-judge 打分裁判 Prompt 示例你是一个严谨的评测员。请根据以下维度对回答打分(每项 0-10): 1. 忠实度: 回答是否完全基于给定知识, 未引入外部幻觉 2. 完整性: 是否覆盖了用户问题的所有关键方面 3. 可操作性: 是否给出了可直接执行的建议或结论 4. 安全性: 是否存在泄露、误导或不当内容 【问题】{question} 【参考知识】{context} 【待评回答】{answer} 请输出 JSON: {faithfulness: 8, completeness: 7, actionability: 9, safety: 10, reason: ...}用脚本把评分写回对应 Tracefrom langfuse import Langfuse langfuse Langfuse( public_keypk-..., secret_keysk-..., hosthttp://flexus-ip:3000 ) langfuse.score( trace_idtrace_id_xxx, namefaithfulness, value8.0, comment回答忠实于知识库, 但漏了同比数据 )实测下来我们对“运维工单助手”做了三轮迭代用 80 条黄金集评测忠实度与完整性的平均分变化如下迭代变更内容忠实度完整性结论基线R1 直答无检索校验6.87.1幻觉率偏高v2增加知识库 RAG 引用来源8.57.9忠实度 1.7v3v2 检索为空禁答硬约束9.18.2双指标达标这张表就是给产品经理、给评审看的最硬证据“R1 比 V3 强”不再是一句感觉而是一组可以持续跟踪的数字。5. 常见报错排查401、local proxy failed、reading choices、OAuth 对照配置过程中最容易撞上的几类报错这里逐一对照。401 Unauthorized。出现在 Dify 调用模型时说明 TaoToken 的 Key 配错了或者没生效。检查三件套Base URL 是不是 https://taotoken.net/api Key 有没有多余空格Model ID 是不是 deepseek-r1。如果 Key 是从控制台复制的注意别把前后引号也带进去。local proxy failed。出现在 Dify 容器内访问 Langfuse 时通常是网络不通。在 Dify 的 api 容器里执行 curl -v http://langfuse:4318 如果解析不到主机名说明两个服务不在同一 Compose 网络把 OTEL_EXPORTER_OTLP_ENDPOINT 改成 Langfuse 的实际 IP 或域名。如果连接被拒绝检查 Langfuse 的 4318 端口有没有映射出来。reading choices 相关报错。出现在解析模型响应时多半是 Dify 的模型配置里 mode 填错了。DeepSeek-R1 走 chat 模式如果填成 completion返回结构对不上就会报这个。另外 context_size 和 max_tokens_to_sample 要按模型实际能力填填太大可能被服务端拒绝。OAuth 报错。出现在 Langfuse 登录或 API 调用时通常是 NEXTAUTH_SECRET 没配或者配得太短。在 .env 里设置一个足够长的随机字符串重启 Langfuse 容器。如果是 API 调用报 OAuth检查 Public Key 和 Secret Key 有没有搞反Public Key 用于客户端上报Secret Key 用于服务端 API。Trace 只有一半。Dify 的 API 与 Worker 都导出了但 Langfuse 里只看到 API 的 span。检查两边的 OTEL_SERVICE_NAME 是否一致不一致会导致链路被拆成两条确认异步任务Agent 执行在 Worker 侧的导出配置已生效。数据量爆炸。全量采样加完整思维链入库一周就把 Postgres 撑爆。生产环境采样率先设 0.1思维链截断到 2000 字符定期归档旧 Trace。思维链字段丢失。R1 的 reasoning_content 在 Dify 某些版本不会自动进入 OTel 的 generation output。用代码节点显式提取并写入 metadata 或事件别依赖隐式传递。评测分数不稳定。LLM-as-judge 同一问题评两次分不一样。固定温度等于 0一次评测跑 3 次取中位数维度拆细不要一个笼统的质量分拆成忠实度、完整性等模型在细粒度维度上更稳定。时区与 ID 对不上。Dify 的会话 ID 与 Langfuse Trace ID 映射困难。在 Dify 的 HTTP 请求节点把会话 ID 写入 Trace 的 metadata比如 session_idLangfuse 里按 metadata 检索打通业务侧与观测侧。6. 语义一致 CTA把观测闭环接回你的 Dify 工作流整套体系跑通后你会发现可观测性带来的最大变化不是“多了一个看板”而是 Agent 的迭代方式变了。以前改 Prompt 靠感觉现在改之前先跑一遍黄金集分数下降就回滚分数上升才发布。以前用户投诉“答得慢”你只能猜现在打开 Trace 一眼看出是 R1 思考 token 失控还是工具调用卡住。如果你还没配好模型入口先去 TaoToken 控制台拿 API Key接入文档在 https://taotoken.net/doc 里面有 Dify、Cline、Claude Code 等客户端的完整配置示例。想先验证 DeepSeek-R1 的对话效果可以直接用模型对话页面试几轮确认 Base URL 和 Key 没问题再往 Dify 里配。如果你打算长期跑编码类或 Agent 类任务Coding Plan 的额度模型比按次计费更划算适合把观测体系当成日常开发流程的一部分。最后留一个实用技巧Langfuse 的 Prompts 管理支持多版本 Prompt 的 A/B 对比把评测分数和 Prompt 版本关联起来你就能回答“这次改动到底值不值”这个问题。观测的终点不是看板而是让每一次改动都有数据支撑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑