PageSourceSearch

https://midscenejs.com/static/js/async/route-c77303f08dfc.0c760595ee.js

js midscenejs.com collected 2026-09-25 20:12:58 UTC 31,220 bytes, 1 lines download raw bytes

1"use strict";(self.rspackChunkdoc=self.rspackChunkdoc||[]).push([[3648],{9980(e,s,n){n.r(s);var r=n(5723),i=n(1470),l=n(6155);function c(e){let s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",span:"span",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.h1,{id:"模型调试与可观测性",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#模型调试与可观测性",children:"#"}),"模型调试与可观测性"]}),"\n",(0,r.jsx)(s.p,{children:"本文介绍如何排查模型连接和兼容性问题、观察延迟和 Token 使用量、采集 Trace,以及记录模型调用。"}),"\n",(0,r.jsxs)(s.h2,{id:"验证模型连接",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#验证模型连接",children:"#"}),"验证模型连接"]}),"\n",(0,r.jsx)(s.p,{children:"本节提供两种验证方法。先直接请求模型服务,确认模型 API 可以连接。再运行 Midscene 验证命令,检查模型兼容性。"}),"\n",(0,r.jsxs)(s.h3,{id:"直接请求模型服务",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#直接请求模型服务",children:"#"}),"直接请求模型服务"]}),"\n",(0,r.jsxs)(s.p,{children:["以下 ",(0,r.jsx)(s.code,{children:"curl"})," 请求用于检查 Base URL、API Key 和模型名称是否可用。该请求只验证模型 API 的基础连接。它不会检查模型是否满足 Midscene 的兼容性要求。"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"bash",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"MIDSCENE_MODEL_BASE_URL"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'替换为你的 baseUrl'"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"MIDSCENE_MODEL_API_KEY"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'替换为你的 API Key'"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"MIDSCENE_MODEL_NAME"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'替换为你的 model name'"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"curl"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" -X"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" POST"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "${MIDSCENE_MODEL_BASE_URL'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"%/"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'}/chat/completions"'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" \\"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"  -H"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "Authorization: Bearer ${MIDSCENE_MODEL_API_KEY}"'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" \\"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"  -H"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "Content-Type: application/json"'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" \\"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:"  -d"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:" '{"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'  "model": "\'"${MIDSCENE_MODEL_NAME}"\'",'})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'  "messages": ['})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"    {"})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'      "role": "user",'})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'      "content": "What is 1+1?"'})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"    }"})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"  ]"})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:"}'"})})]})})}),"\n",(0,r.jsxs)(s.h3,{id:"使用-midscene-验证命令",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#使用-midscene-验证命令",children:"#"}),"使用 Midscene 验证命令"]}),"\n",(0,r.jsx)(s.p,{children:"该命令同时检查模型连接和 Midscene 兼容性。"}),"\n",(0,r.jsxs)(s.p,{children:["将模型配置放入 ",(0,r.jsx)(s.code,{children:".env"})," 文件,然后运行:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"bash",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# 如果当前项目已安装 @midscene/cli,可以使用本地的 midscene 命令"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"npx"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" midscene"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" model"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" verify"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# 如果当前项目未安装 @midscene/cli,或需要使用最新版本"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"npx"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" @midscene/cli@latest"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" model"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" verify"})]})]})})}),"\n",(0,r.jsxs)(s.p,{children:["该命令会读取当前工作目录下的 ",(0,r.jsx)(s.code,{children:".env"})," 文件。Dotenv 的 Debug 日志默认开启。",(0,r.jsx)(s.code,{children:".env"})," 中的变量会覆盖已有的 Shell 环境变量。"]}),"\n",(0,r.jsxs)(s.p,{children:["如果 ",(0,r.jsx)(s.code,{children:"curl"})," 请求成功,但 Midscene 验证命令失败,说明模型 API 可以连接。请继续检查模型能力和 Midscene 配置。"]}),"\n",(0,r.jsxs)(s.h2,{id:"常见配置错误",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#常见配置错误",children:"#"}),"常见配置错误"]}),"\n",(0,r.jsxs)(s.h3,{id:"midscene_model_family-未设置为多模态模型",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#midscene_model_family-未设置为多模态模型",children:"#"}),(0,r.jsx)(s.code,{children:"MIDSCENE_MODEL_FAMILY"})," 未设置为多模态模型"]}),"\n",(0,r.jsxs)(s.p,{children:["如果收到 ",(0,r.jsx)(s.code,{children:"MIDSCENE_MODEL_FAMILY is not set to a multimodal model with UI localization"}
1)," 错误,请确认已正确配置多模态模型的 ",(0,r.jsx)(s.code,{children:"MIDSCENE_MODEL_FAMILY"})," 环境变量。"]}),"\n",(0,r.jsxs)(s.p,{children:["从 1.0 版本开始,Midscene 推荐使用 ",(0,r.jsx)(s.code,{children:"MIDSCENE_MODEL_FAMILY"})," 指定多模态模型类型。旧的 ",(0,r.jsx)(s.code,{children:"MIDSCENE_USE_..."})," 配置仍然兼容,但已经废弃。"]}),"\n",(0,r.jsxs)(s.p,{children:["正确的模型 family 和完整配置示例请参考",(0,r.jsx)(s.a,{href:"/zh/model-common-config.html",children:"支持的模型与配置"}),"。"]}),"\n",(0,r.jsxs)(s.h3,{id:"base-url-或模型名称不正确",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#base-url-或模型名称不正确",children:"#"}),"Base URL 或模型名称不正确"]}),"\n",(0,r.jsxs)(s.p,{children:["确认 ",(0,r.jsx)(s.code,{children:"MIDSCENE_MODEL_BASE_URL"})," 指向服务商的 API 接入地址。该地址通常以 ",(0,r.jsx)(s.code,{children:"/v1"})," 等版本号结尾。请勿添加 ",(0,r.jsx)(s.code,{children:"/chat/completion"}),",底层 SDK 会自动添加请求路径。"]}),"\n",(0,r.jsxs)(s.p,{children:["同时确认 ",(0,r.jsx)(s.code,{children:"MIDSCENE_MODEL_NAME"})," 与该接入地址提供的模型一致。"]}),"\n",(0,r.jsxs)(s.h2,{id:"模型效果不理想",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#模型效果不理想",children:"#"}),"模型效果不理想"]}),"\n",(0,r.jsx)(s.p,{children:"如果模型可以正常连接,但定位、规划或页面理解不稳定,可以尝试以下方法:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["查看",(0,r.jsx)(s.a,{href:"/zh/consume-report-file.html",children:"回放报告"}),",确认任务执行顺序正确,并且没有进入错误页面或逻辑分支。"]}),"\n",(0,r.jsx)(s.li,{children:"优先使用同一系列中较新的正式支持版本。"}),"\n",(0,r.jsx)(s.li,{children:"使用代表性任务对比不同服务商的模型,关注成功率、延迟和成本。"}),"\n",(0,r.jsxs)(s.li,{children:["复杂任务可以单独配置 Planning 模型或 Insight 模型。具体分工请参考",(0,r.jsx)(s.a,{href:"/zh/model-strategy.html",children:"模型策略"}),"。"]}),"\n"]}),"\n",(0,r.jsxs)(s.h2,{id:"调试能力",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#调试能力",children:"#"}),"调试能力"]}),"\n",(0,r.jsxs)(s.h3,{id:"debug-日志",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#debug-日志",children:"#"}),"Debug 日志"]}),"\n",(0,r.jsxs)(s.p,{children:["需要额外的诊断信息时,可以设置 ",(0,r.jsx)(s.code,{children:"DEBUG"}),"。常用选择器包括:"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"DEBUG=midscene:ai:profile:stats"}),":打印模型延迟和 Token 使用量。"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"DEBUG=midscene:ai:call"}),":打印 AI 响应详情。"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"DEBUG=midscene:*"}),":打印全部 Midscene Debug 日志。"]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["完整的选择器列表、日志目录和使用注意事项,请参考",(0,r.jsx)(s.a,{href:"/zh/reference.html#debug-logs",children:"运行时配置:Debug 日志"}),"。"]}),"\n",(0,r.jsxs)(s.p,{children:["生成的",(0,r.jsx)(s.a,{href:"/zh/consume-report-file.html",children:"报告文件"}),"中也包含模型使用量统计。"]}),"\n",(0,r.jsxs)(s.h3,{id:"记录模型调用",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#记录模型调用",children:"#"}),"记录模型调用"]}),"\n",(0,r.jsxs)(s.p,{children:["设置 ",(0,r.jsx)(s.code,{children:"MIDSCENE_RECORD_MODEL_CALL=true"}),",可以将模型请求、响应和流式 Chunk 写入 JSONL 文件:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"text",children:(0,r.jsx)(s.code,{children:(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{children:"midscene_run/model-requests/<启动时间>-<pid>.jsonl"})})})})}),"\n",(0,r.jsx)(s.p,{children:"每个进程生成一个文件,每行对应一个 JSON 事件。只有 Node.js 和 Electron 支持写入本地文件。浏览器和 Worker 不会写入本地文件。使用 Codex App Server 时,记录还会包含可获取的协议元数据。"}),"\n",(0,r.jsxs)(s.p,{children:["每个事件的 ",(0,r.jsx)(s.code,{children:"type"})," 为 ",(0,r.jsx)(s.code,{children:"request"}),"、",(0,r.jsx)(s.code,{children:"chunk"}),"、",(0,r.jsx)(s.code,{children:"response"})," 或 ",(0,r.jsx)(s.code,{children:"error"}),"。事件还包含 ",(0,r.jsx)(s.code,{children:"executionId"}),",用于关联同一个 execution ID 下的调用及其重试。对于 HTTP 模型请求,这个值也会通过 ",(0,r.jsx)(s.code,{children:"x-midscene-execution-id"})," Header 发送。不属于报告 execution 的调用(例如连接检查)会使用带 ",(0,r.jsx)(s.code,{children:"unscoped-"})," 前缀的生成 ID。"]}),"\n",(0,r.jsxs)(l.Pq,{type:"warning",title:"注意事项",children:[(0,r.jsxs)(s.p,{children:["文件包含请求 Body(包括自定义 ",(0,r.jsx)(s.code,{children:"extraBody"}),")、响应 Header 和 Body、流式响应,以及可能采用 Base64 编码的截
1图。请求 Header 不会被记录。"]}),(0,r.jsx)(s.p,{children:"这些文件可能包含敏感信息,且体积较大。请仅在排查问题时启用记录,并在使用后妥善保管或删除文件。记录格式不保证跨版本兼容。"})]}),"\n",(0,r.jsxs)(s.h3,{id:"请求追踪-header",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#请求追踪-header",children:"#"}),"请求追踪 Header"]}),"\n",(0,r.jsx)(s.p,{children:"Midscene 会自动为 OpenAI-compatible HTTP 模型请求添加以下 Header:"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Header"}),(0,r.jsx)(s.th,{children:"值"}),(0,r.jsx)(s.th,{children:"用途"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"x-midscene-version"})}),(0,r.jsxs)(s.td,{children:["当前 ",(0,r.jsx)(s.code,{children:"@midscene/core"})," 版本"]}),(0,r.jsx)(s.td,{children:"标识发起请求的 Midscene 版本"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"x-midscene-execution-id"})}),(0,r.jsx)(s.td,{children:"当前 execution ID"}),(0,r.jsxs)(s.td,{children:["关联同一个 execution ID 下的全部模型请求及其重试,例如一次 ",(0,r.jsx)(s.code,{children:"aiAct"})," 调用"]})]})]})]}),"\n",(0,r.jsxs)(s.p,{children:["不属于报告 execution 的调用(例如连接检查)会使用带 ",(0,r.jsx)(s.code,{children:"unscoped-"})," 前缀的生成 execution ID。这两个 Header 会被默认发送,如果 ",(0,r.jsx)(s.code,{children:"MIDSCENE_*_INIT_CONFIG_JSON"})," 中自定义了同名 Header,则会被 Midscene 覆盖。"]}),"\n",(0,r.jsxs)(s.h2,{id:"可观测性平台",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#可观测性平台",children:"#"}),"可观测性平台"]}),"\n",(0,r.jsxs)(s.h3,{id:"langsmith",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#langsmith",children:"#"}),"LangSmith"]}),"\n",(0,r.jsx)(s.p,{children:"LangSmith 是用于调试大语言模型的平台。安装依赖并设置环境变量后,Midscene 可以自动接入 LangSmith。"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"安装依赖"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"bash",children:(0,r.jsx)(s.code,{children:(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"npm"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" install"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" langsmith"})]})})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"设置环境变量"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"bash",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# 启用 Midscene 的 LangSmith 自动集成"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" MIDSCENE_LANGSMITH_DEBUG"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"1"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# LangSmith 配置"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" LANGCHAIN_API_KEY"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"your-langchain-api-key-here"'})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" LANGCHAIN_TRACING"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"true"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" LANGCHAIN_ENDPOINT"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"https://api.smith.langchain.com"'})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:'# export LANGCHAIN_ENDPOINT="https://eu.api.smith.langchain.com" # 如果在欧洲区域注册'})})]})})}),"\n",(0,r.jsx)(s.p,{children:"启动 Midscene 后,应该会看到类似以下内容的日志:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"log",children:(0,r.jsx)(s.code,{children:(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"DEBUGGING MODE: langsmith wrapper enabled"})})})})}),"\n",(0,r.jsx)(s.p,{children:"注意事项:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"LangSmith 和 Langfuse 可以同时启用。"}),"\n",(0,r.jsx)(s.li,{children:"该集成仅支持 Node.js。浏览器环境会抛出错误。"}),"\n",(0,r.jsxs)(s.li,{children:["如果使用 ",(0,r.jsx)(s.a,{href:"/zh/reference.html#%E8%87%AA%E5%AE%9A%E4%B9%89-openai-%E5%AE%A2%E6%88%B7%E7%AB%AF",children:(0,r.jsx)(s.code,{children:"createOpenAIClient"})}),",它会覆盖通过环境变量启用的自动集成。"]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["如需进行更细粒度的控制,例如只对特定任务启用 LangSmith,请使用 ",(0,r.jsx)(s.a,{href:"/zh/reference.html#%E8%87%AA%E5%AE%9A%E4%B9%89-openai-%E5%AE%A2%E6%88%B7%E7%AB%AF",children:(0,r.jsx)(s.code,{children:"createOpenAIClient"})})," 手动包装客户端。"]}),"\n",(0,r.jsxs)(s.h3,{id:"langfuse",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#langfuse",children:"#"}),"Langfuse"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://langfuse.com",rel:"noopener noreferrer",target:"_blank",children:"Langfuse"})," 是一个 LLM 可观测性平台。Midscene 集成了 Langfuse 的 ",(0,r.jsx)(s.code,{children:"observeOpenAI"})," wrapper,可以自动追踪 OpenAI API 调用。"]}),"\n",(0,r.jsx)(s.p,{children:"Langfuse 的追踪基于 OpenTelemetry,因此需要在应用启动时初始化 OpenTelemetry SDK。"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"安装依赖"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"bash",children:(0,r.jsx)(s.code,{children:(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"npm"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" install"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" @langfuse/openai"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" @langfuse/otel"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string)"},children:" @opentelemetry/sdk-node"})]})})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"初始化 OpenTelemetry"})}),"\n",(0,r.jsx)(s.p,{children:"在应用入口文件的最顶部添加以下代码:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"typescript",children:(0,r.jsxs)(s.code,{children:[(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { NodeSDK } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "@opentelemetry/sdk-node"'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" { LangfuseSpanProcessor } "}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "@langfuse/otel"'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:" sdk"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:" new"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" NodeSDK"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"({"})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"  spanProcessors"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" ["}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"new"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:" LangfuseSpanProcessor"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"}
1,children:"()]"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"});"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"sdk"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:".start"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]})]})})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"设置环境变量"})}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"bash",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# 启用 Midscene 的 Langfuse 自动集成"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" MIDSCENE_LANGFUSE_DEBUG"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"1"})]}),"\n",(0,r.jsx)(s.span,{className:"line"}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# Langfuse 配置"})}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" LANGFUSE_PUBLIC_KEY"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"your-langfuse-public-key-here"'})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" LANGFUSE_SECRET_KEY"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"your-langfuse-secret-key-here"'})]}),"\n",(0,r.jsxs)(s.span,{className:"line",children:[(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:" LANGFUSE_BASE_URL"}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"https://cloud.langfuse.com"'}),(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:" # 🇪🇺 欧洲区域"})]}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:'# export LANGFUSE_BASE_URL="https://us.cloud.langfuse.com" # 🇺🇸 美国区域'})})]})})}),"\n",(0,r.jsx)(s.p,{children:"启动 Midscene 后,应该会看到类似以下内容的日志:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(s.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"log",children:(0,r.jsxs)(s.code,{children:[(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"OpenTelemetry SDK initialized for Langfuse tracing"})}),"\n",(0,r.jsx)(s.span,{className:"line",children:(0,r.jsx)(s.span,{style:{color:"var(--shiki-foreground)"},children:"DEBUGGING MODE: langfuse wrapper enabled"})})]})})}),"\n",(0,r.jsxs)(s.p,{children:["更多配置和最佳实践请参考 ",(0,r.jsx)(s.a,{href:"https://langfuse.com/integrations/model-providers/openai-js",rel:"noopener noreferrer",target:"_blank",children:"Langfuse OpenAI 集成文档"}),"。"]}),"\n",(0,r.jsx)(s.p,{children:"注意事项:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"LangSmith 和 Langfuse 可以同时启用。"}),"\n",(0,r.jsx)(s.li,{children:"该集成仅支持 Node.js。浏览器环境会抛出错误。"}),"\n",(0,r.jsxs)(s.li,{children:["如果使用 ",(0,r.jsx)(s.a,{href:"/zh/reference.html#%E8%87%AA%E5%AE%9A%E4%B9%89-openai-%E5%AE%A2%E6%88%B7%E7%AB%AF",children:(0,r.jsx)(s.code,{children:"createOpenAIClient"})}),",它会覆盖通过环境变量启用的自动集成。"]}),"\n"]}),"\n",(0,r.jsxs)(s.h2,{id:"安全注意事项",children:[(0,r.jsx)(s.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#安全注意事项",children:"#"}),"安全注意事项"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["不要将 ",(0,r.jsx)(s.code,{children:".env"})," 文件、Trace、Debug 日志或模型调用记录提交到源码仓库。"]}),"\n",(0,r.jsx)(s.li,{children:"日志和 Trace 可能包含模型输入、输出或截图,分享前请先检查内容。"}),"\n"]})]})}function a(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}a.__RSPRESS_PAGE_META={},a.__RSPRESS_PAGE_META["zh%2Fmodel-debugging-observability.mdx"]={toc:[{id:"验证模型连接",text:"验证模型连接",depth:2},{id:"直接请求模型服务",text:"直接请求模型服务",depth:3},{id:"使用-midscene-验证命令",text:"使用 Midscene 验证命令",depth:3},{id:"常见配置错误",text:"常见配置错误",depth:2},{id:"midscene_model_family-未设置为多模态模型",text:"`MIDSCENE_MODEL_FAMILY` 未设置为多模态模型",depth:3},{id:"base-url-或模型名称不正确",text:"Base URL 或模型名称不正确",depth:3},{id:"模型效果不理想",text:"模型效果不理想",depth:2},{id:"调试能力",text:"调试能力",depth:2},{id:"debug-日志",text:"Debug 日志",depth:3},{id:"记录模型调用",text:"记录模型调用",depth:3},{id:"请求追踪-header",text:"请求追踪 Header",depth:3},{id:"可观测性平台",text:"可观测性平台",depth:2},{id:"langsmith",text:"LangSmith",depth:3},{id:"langfuse",text:"Langfuse",depth:3},{id:"安全注意事项",text:"安全注意事项",depth:2}],title:"模型调试与可观测性",headingTitle:"模型调试与可观测性",frontmatter:{}},n.d(s,{default:()=>a})}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.