LangSmith Polly:实现LLM应用本地化可观测性的关键技术解析
1. 从LangSmith的“私有化”到Polly的“无处不在”一次关键的技术范式转移如果你在过去一年里深度参与过LLM应用开发那么LangSmith这个名字对你来说一定不陌生。它几乎是LangChain生态中事实上的“黄金标准”调试与监控平台。然而一个长期困扰着许多团队尤其是那些对数据主权、网络延迟和合规性有严格要求的团队的核心痛点就是LangSmith的部署模式。简单来说LangSmith的“大脑”——其核心的追踪、评估和监控服务——主要运行在LangChain的云端。这意味着你的每一次LLM调用、每一次工具执行、每一次链式推理的详细数据都需要跨越公网发送到远端的服务器。对于内部工具、处理敏感数据的应用或者身处严格监管行业的团队而言这种架构本身就是一道难以逾越的鸿沟。所以当看到“Polly is generally available everywhere you work in LangSmith”这个标题时我的第一反应是LangChain终于把那个最核心、最关键的“大脑”组件彻底本地化了。Polly不是一个独立的新产品而是LangSmith能力的一次“细胞级”拆分与重构。它不是一个替代品而是一个赋能器。它的核心价值在于将LangSmith引以为傲的可观测性Observability能力从单一的云端SaaS服务转变为一种可以嵌入到你工作环境任何角落的基础设施。无论你是在本地笔记本上做原型验证在CI/CD流水线中做自动化测试还是在生产环境的Kubernetes集群里运行服务Polly都能以SDK或轻量级服务的形式无缝地为你提供与LangSmith云端体验一致的追踪、日志和监控能力。这不仅仅是多了一个部署选项那么简单。它标志着LLM应用开发运维LLMOps工具链正在从“中心化监控”向“分布式可观测性”演进。以前你需要把数据“送出去”才能获得洞察现在洞察能力可以“长在”你的应用内部。这对于开发流程、安全合规和成本控制都将产生深远的影响。接下来我们就深入拆解Polly到底是什么它如何工作以及它如何真正改变你在各个工作环节中构建和运维LLM应用的方式。2. 拆解Polly它不是什么它究竟是什么在深入技术细节之前我们先划清几个关键认知边界这能帮助我们更准确地理解Polly的定位。Polly不是另一个LangSmith。这是最常见的误解。LangSmith是一个功能完整的平台它包含项目管理、团队协作、数据集管理、测试与评估、监控告警等一系列上层应用功能。你可以把它想象成一个功能丰富的“控制中心”或“仪表盘”。而Polly则是这个控制中心背后负责收集、处理和传输数据的那套“传感网络”与“数据管道”。Polly让这些数据管道变得可移植、可嵌入。Polly不是一个需要独立运维的复杂后端服务。虽然它提供了服务模式polly serve但其设计哲学是“轻量级”和“即插即用”。它的核心是一个Python SDK (langsmithSDK的一部分) 和一个可选的、单二进制文件的服务端。你不需要为了使用Polly而维护一个庞大的数据库集群或消息队列。在大多数场景下它开箱即用。那么Polly究竟是什么从技术架构上看Polly是LangSmith的客户端SDK与服务端组件的本地化实现。它主要由两部分构成Polly SDK (Client-side): 这已经集成在标准的langsmithPython包中。当你配置LANGSMITH_ENDPOINT指向本地服务或者使用特定的API密钥时你的LangChain应用发出的追踪Trace数据就不再流向api.smith.langchain.com而是流向你指定的本地Polly服务端点或者直接被SDK以特定方式缓存、处理。Polly Server (Optional): 一个用Rust编写的高性能、轻量级HTTP服务。你可以通过pip install polly然后运行polly serve来启动它。这个服务会接收来自SDK的追踪数据并将其持久化到本地文件系统默认或你配置的其他存储后端如SQLite、PostgreSQL。同时它还可能提供一个本地的UI界面或API用于实时查看这些追踪数据。核心工作流程的对比传统LangSmith云端模式你的应用 (LangChain) - 公网 - LangSmith Cloud API - LangSmith Cloud 数据库/处理集群 - LangSmith Cloud UIPolly本地/嵌入模式你的应用 (LangChain) - 本地网络/进程内 - Polly Server (本地) - 本地文件/SQLite/Postgres - (可选)本地UI 或 转发至云端LangSmith关键的区别在于数据流的第一个跃点。Polly将数据的“第一落点”从不可控的云端转移到了你完全掌控的环境内部。这带来了几个立竿见影的好处数据主权与隐私敏感数据无需离开你的网络边界。这对于医疗、金融、法律等行业的应用至关重要。低延迟与高可靠性网络调用从跨国/跨地区公网调用变为本地内网甚至进程内通信延迟极低且不受外网波动影响。调试和开发的体验更加流畅。离线工作能力你可以在完全没有互联网连接的环境如某些研发内网、保密实验室中开发和调试LLM应用依然能获得完整的调用链追踪。成本控制与可预测性避免了因大量调试追踪数据产生的云端API调用费用所有资源消耗都在本地成本透明且可控。理解了Polly的“身份”我们再来看看它如何具体嵌入到你工作的每一个环节。3. “Everywhere you work” 实战Polly在四大核心场景的落地“Everywhere you work” 这个口号非常精准。Polly的价值正是在不同的工作阶段和环境中被放大。我们分场景来看。3.1 场景一本地开发与原型设计——告别“盲人摸象”在本地使用Jupyter Notebook或Python脚本快速迭代Prompt、测试不同LLM模型或链式逻辑时传统的做法是大量使用print语句或者依赖LLM提供商平台如OpenAI Playground有限的日志。这就像“盲人摸象”你只能看到片段的输入输出对中间过程、工具调用、token消耗、耗时分布一无所知。Polly的集成方式极简配置在你的.env文件或脚本开头设置环境变量。# .env 文件示例 LANGSMITH_TRACING_V2true LANGSMITH_ENDPOINThttp://localhost:1984 # 指向本地运行的Polly服务 LANGSMITH_API_KEYls_xx # 可以是任意值如果仅本地使用或用于关联云项目的真实key启动本地Polly服务打开一个终端运行polly serve。默认会在http://localhost:1984启动服务并提供一个简单的UI。像往常一样运行你的LangChain代码。所有的LLMChain、Agent、Tool调用都会被自动捕获。实战体验与价值实时可视化打开http://localhost:1984你能立即看到一个类似LangSmith UI的界面里面是你刚刚运行的追踪记录。点击任何一条都能看到完整的树状调用链主链Chain - 子链Subchain - LLM调用 - 工具执行。每一步的输入、输出、耗时、token数、成本如果配置了模型价格一目了然。Prompt工程效率倍增调整一个Prompt后重新运行新旧两次的追踪记录并排显示。你可以直接对比两者的中间步骤和最终输出精准定位Prompt修改带来的影响是让结果变好了还是意外引入了新的问题。调试复杂Agent当Agent调用多个工具、陷入循环或返回意外结果时本地Polly的追踪是唯一的“真相来源”。你可以清晰地看到Agent的思考过程ReAct模式下的thought/action/observation精确找到是哪个工具调用失败了或者是哪一步的LLM推理出现了偏差。注意在纯本地开发且不需要将数据同步到云端LangSmith项目时LANGSMITH_API_KEY可以设置为一个虚拟值。但如果你希望本地追踪的数据能最终汇总到云端的某个LangSmith项目进行统一管理或团队共享则需要配置真实的API Key并在Polly服务配置中启用向云端的转发功能。3.2 场景二自动化测试与CI/CD流水线——让测试结果可观测、可追溯在CI/CD流水线中运行LLM应用的自动化测试例如用pytest测试一组不同的用户输入是否产生符合预期的输出是一个巨大挑战。测试失败时你通常只得到一个“断言错误”但完全不知道LLM到底输出了什么中间过程如何。排查问题需要手动重现效率极低。Polly的集成方式在测试套件中初始化Polly你可以在conftest.py或测试设置中以编程方式配置LangSmith指向一个为测试专门启动的Polly服务实例或者使用一个轻量级的“录制”模式。使用traceable装饰器或上下文管理器对于关键的测试函数或LLM调用点显式地启用追踪。from langsmith import traceable traceable(run_typetest) # 标记这是一个测试运行 def test_customer_service_chain(): chain create_customer_service_chain() result chain.invoke({query: 我的订单还没发货}) assert 物流 in result or 发货 in result # 测试无论通过与否完整的chain执行追踪已被Polly记录持久化测试追踪配置Polly服务将测试产生的追踪数据保存到CI工作空间的一个特定目录如./test-traces/或一个临时的SQLite数据库中。实战体验与价值测试失败根因分析当测试在CI中失败时除了日志CI产物中会包含这次失败运行的完整追踪文件。开发者无需拉取代码本地重现直接下载这个追踪文件导入本地的Polly UI或LangSmith就能像调试本地运行一样一步步复盘测试用例的完整执行过程精准定位是Prompt问题、工具异常还是模型响应不稳定。非确定性输出的测试LLM输出具有非确定性。通过Polly追踪你可以看到每次测试运行时模型的实际输出、使用的温度temperature等参数。这有助于区分是“正常的随机性波动”还是“真正的逻辑错误”。性能回归测试Polly记录的耗时和Token消耗数据可以集成到你的测试指标中。你可以设置断言如“单次调用平均耗时不得超过2秒”“每次对话Token消耗增长不得超过10%”从而在代码变更时自动捕捉性能回退。3.3 场景三预生产与沙盒环境——安全地模拟真实流量在将LLM应用部署到生产环境之前通常会在一个高度仿真生产环境的沙盒Staging中进行最终验证。这个环境可能连接着真实的数据库、外部API但使用测试密钥。你需要观察应用在接近真实负载下的行为但又不能将可能包含敏感信息的调试数据发送到外部云端。Polly的集成方式部署独立的Polly服务实例在沙盒环境的Kubernetes集群或虚拟机中将Polly Server作为一个独立的服务部署例如使用Docker镜像langchain/polly。应用配置指向内部Polly沙盒环境中的所有LLM应用实例其LANGSMITH_ENDPOINT都指向内部部署的Polly服务地址如http://polly-service.internal.svc.cluster.local:1984。配置存储与保留策略为Polly服务配置一个持久化存储卷如PVC并设置合理的日志滚动策略避免磁盘被撑满。可以考虑将数据存储到共享的PostgreSQL数据库中方便聚合查询。实战体验与价值集成测试与压测观测在进行端到端集成测试或压力测试时运维和开发团队可以通过访问内网的Polly UI实时观察所有用户会话的追踪。他们可以看到在并发请求下LLM调用是否出现排队、超时工具服务是否成为瓶颈。验证数据流与合规性确保在沙盒环境中所有包含用户模拟数据PII的追踪信息都严格停留在内网满足合规审计要求。同时可以检查追踪数据中是否意外包含了本应被脱敏的真实生产密钥或连接信息。调试复杂依赖问题沙盒环境可能涉及多个微服务。当LLM应用调用某个内部工具服务失败时通过Polly的追踪可以立刻看到失败的工具调用及其错误响应快速区分是LLM应用逻辑错误、工具服务故障还是网络策略问题。3.4 场景四生产环境——可控的、轻量级的深度监控直接将全量的、细粒度的LangSmith追踪数据从生产环境发送到云端会产生高昂的成本和带宽消耗也可能引发数据合规风险。但完全关闭追踪又会让线上问题排查变得异常困难。Polly在此场景下的角色是“智能采样与缓存层”或“边缘计算节点”。集成模式A采样与本地缓存在生产环境每个应用Pod中配置一个极低采样率的LangSmith SDK例如1%的请求被追踪但LANGSMITH_ENDPOINT指向一个本地Sidecar容器运行的Polly服务。Polly服务将采样的高价值追踪例如出错的请求、耗时超长的请求先缓存到本地。通过一个异步任务将缓存的这些关键追踪批量、加密后发送到云端的LangSmith进行长期存储和团队协作分析。大部分低价值或无异常的追踪数据则在本地定期清理。集成模式B关键链路追踪不为所有请求开启追踪而是在代码中针对特定的、重要的用户旅程如“支付流程中的客服对话”通过traceable装饰器显式开启追踪并标记为高优先级。这些关键链路的追踪数据直接发送到生产环境内网部署的Polly集群供运维团队实时监控核心业务流的健康度。实战体验与价值成本效益最大化只为真正需要深度分析的请求支付云端存储和处理的成本。99%的常规请求数据在本地处理并丢弃。快速故障诊断当用户报告某个对话出现奇怪回答时运维人员可以根据会话ID或时间戳直接从本地Polly存储中查询该次请求的完整追踪在几分钟内定位问题是出在Prompt、模型还是某个依赖的API而无需等待云端数据同步也无需在全量日志中大海捞针。安全合规所有原始数据在出生产环境前都经过一层本地Polly的过滤和缓存你可以在此层实施额外的数据脱敏、加密或审计逻辑确保符合数据治理政策。4. 部署与配置Polly从快速启动到生产就绪了解了场景我们来具体看看如何让Polly跑起来。它的部署梯度非常清晰从几分钟的快速体验到满足生产要求的稳健部署。4.1 快速开始单机开发模式这是最简单的模式适合个人开发者。# 1. 安装Polly服务 pip install polly # 2. 启动Polly服务默认使用本地文件存储在 ~/.polly 目录下 polly serve # 服务启动在 http://localhost:1984 一个简单的UI通常可在同地址访问 # 3. 在你的Python脚本或Notebook中配置环境变量 import os os.environ[LANGSMITH_TRACING_V2] true os.environ[LANGSMITH_ENDPOINT] http://localhost:1984 os.environ[LANGSMITH_API_KEY] ls_dummy_key # 本地使用可随意 # 4. 运行你的LangChain代码追踪数据将出现在Polly UI中4.2 进阶配置使用持久化数据库本地文件存储不适合多实例或需要查询的场景。Polly支持SQLite和PostgreSQL。# 使用SQLite (单文件简单轻量) polly serve --database sqlite:///./langsmith_traces.db # 使用PostgreSQL (适合团队共享或更高负载) polly serve --database postgresql://user:passwordlocalhost:5432/polly_db配置项详解--host/--port: 绑定地址和端口。--database: 数据库连接字符串。使用PostgreSQL时建议预先创建好数据库。--ui/--no-ui: 是否启用内置的Web UI。在生产环境或为了安全可以关闭UI仅使用API。--help: 查看所有选项。4.3 生产部署方案Docker与Kubernetes对于团队和生产环境容器化部署是标准做法。Docker部署# 使用官方镜像 docker run -p 1984:1984 \ -e DATABASE_URLpostgresql://user:passhost:5432/db \ -v ./polly_data:/data \ langchain/polly:latestKubernetes部署 (Deployment示例):apiVersion: apps/v1 kind: Deployment metadata: name: polly-server spec: replicas: 2 # 根据负载调整Polly本身是无状态的可以水平扩展 selector: matchLabels: app: polly template: metadata: labels: app: polly spec: containers: - name: polly image: langchain/polly:latest ports: - containerPort: 1984 env: - name: DATABASE_URL valueFrom: secretKeyRef: name: polly-secrets key: database-url - name: LANGSMITH_API_KEY # 如果需要转发到云端在此配置真实Key valueFrom: secretKeyRef: name: polly-secrets key: langsmith-api-key volumeMounts: - mountPath: /data name: polly-cache volumes: - name: polly-cache emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: polly-service spec: selector: app: polly ports: - port: 1984 targetPort: 1984生产环境关键考量高可用与扩展Polly服务本身无状态可以通过Deployment多副本和Service实现负载均衡与高可用。数据库PostgreSQL需要单独考虑高可用方案。资源限制为Polly容器设置合理的CPU和内存限制。其资源消耗主要与接收追踪数据的吞吐量和持久化操作有关。网络策略确保你的LLM应用Pod能够通过网络策略访问polly-service。同时严格限制Polly Service的UI/API端口对外部互联网的暴露通常只允许内网访问。数据生命周期管理生产环境追踪数据增长很快。需要规划存储策略使用高性能的云盘或SSD存储卷。清理策略Polly可能尚未内置自动清理你需要通过数据库的定时任务CronJob来定期删除过旧的追踪数据或者只保留最近N天的数据。归档策略对于需要长期审计的数据可以配置Polly将数据异步归档到对象存储如S3或数据湖中。4.4 与云端LangSmith的协同混合架构在很多企业场景下理想的架构是“混合模式”日常开发、测试和预生产使用本地Polly追求低延迟和隐私同时将重要的、脱敏后的追踪数据如测试集评估结果、生产环境错误样本有选择地同步到云端LangSmith利用其强大的协作、分析和长期趋势查看功能。实现混合架构的关键配置在Polly Server配置中启用转发这通常需要在启动Polly时设置合法的LANGSMITH_API_KEY和LANGSMITH_ENDPOINT指向云端并可能有一个开关或过滤器来决定哪些追踪需要转发。在SDK端使用标签Tags或元数据Metadata进行过滤在你的应用代码中可以为不同的运行添加标签例如envproduction、typeerror、sampledtrue。Polly服务可以配置为只转发带有特定标签如forward_to_cloudtrue的追踪。使用LangSmith的Projects进行逻辑隔离即使数据都进入云端你也可以通过不同的API Key或Project名称将来自不同环境开发、测试、生产的数据归类到不同的LangSmith项目中保持清晰。这种混合模式既保障了核心数据在敏感环节的私密性又保留了利用云端平台进行团队协作和深度分析的便利性是目前最平衡和实用的方案。5. 深入原理Polly如何实现“无缝嵌入”Polly能做到如此轻量级和无缝集成背后依赖的是LangSmith SDK和平台事先定义好的一套清晰的关注点分离架构。我们可以从协议、存储和扩展性三个层面来理解。5.1 基于开放协议的客户端-服务器模型LangSmith的追踪系统本质上是一个基于HTTP的客户端-服务器模型。langsmithSDK 是客户端它负责在代码执行时自动收集调用链信息通过装饰器、上下文管理器集成到LangChain的各个组件中。将收集到的数据序列化为预定义的格式可以近似理解为一种OpenTelemetry的变体或专用格式。通过HTTP POST请求将序列化后的数据发送到配置的LANGSMITH_ENDPOINT。Polly Server 就是这样一个兼容此协议的服务器实现。它提供一个与官方LangSmith Cloud API兼容的HTTP端点例如/traces。接收来自SDK的数据。进行验证、解析然后将其持久化到配置的后端存储中。正因为SDK只依赖一个简单的HTTP接口所以替换这个接口的后端服务从云端换成本地Polly对应用代码来说是零侵入的只需改变环境变量即可。这是“无缝嵌入”的基石。5.2 可插拔的存储后端Polly的轻量性很大程度上得益于其存储后端的可插拔设计。默认的文件系统后端非常适合快速启动和开发。而SQLite和PostgreSQL后端则为更严肃的使用场景提供了支持。文件系统将每次追踪保存为独立的JSON文件。优点是零配置无需外部依赖缺点是不利于查询和聚合性能随文件数增长下降。SQLite一个轻量级的单文件数据库。它提供了基本的SQL查询能力使得在本地UI中进行简单的过滤和搜索成为可能。它是个人项目或小团队从文件系统升级的平滑选择。PostgreSQL功能完整的关系型数据库。支持复杂的查询、连接和聚合操作。当你的团队需要基于追踪数据进行自定义分析、生成报表或者需要高并发写入时PostgreSQL是必选项。Polly的数据模型表结构很可能是公开或可推导的这为自定义BI分析打开了大门。这种设计意味着你可以根据团队规模和需求增长逐步升级存储方案而无需改变使用Polly的基本方式。5.3 扩展性与自定义处理Polly作为一个本地服务为你提供了在数据链路中进行自定义处理的钩子。这是云端SaaS服务难以做到的。例如数据脱敏PII Scrubbing在数据被存储到本地数据库或转发到云端之前你可以编写一个中间件插件对追踪数据中的特定字段如邮箱、电话、身份证号进行自动脱敏或替换。自定义过滤与采样你可以修改Polly的源码或通过配置实现更复杂的采样逻辑。例如“对包含‘错误’响应的追踪进行100%记录对成功响应的追踪仅记录1%”。与其他监控系统集成你可以从Polly的存储中读取数据将其转化为指标Metrics推送至Prometheus或生成结构化日志发送到ELK或Datadog。这样就将LLM的可观测性融入了企业现有的统一监控大盘中。这种“可扩展性”是Polly作为本地部署解决方案带来的最大红利之一它让LLM的可观测性工具真正成为了你基础设施中可定制、可集成的一环。6. 决策指南何时选择Polly何时直接使用LangSmith CloudPolly并非在所有场景下都是最优解。为了帮你做出选择我梳理了一个决策矩阵考量维度推荐LangSmith Cloud (SaaS)推荐Polly (本地/自托管)数据敏感性数据可公开或已脱敏无合规限制。处理敏感数据PII、商业机密需满足GDPR、HIPAA等合规要求数据不能出境。网络环境开发环境有稳定、快速的国际互联网连接。开发或生产环境处于隔离内网、离线环境或网络延迟高、不稳定。团队与协作小型团队或初创公司希望零运维、快速开始并需要强大的团队协作功能共享项目、评论、协作评估。中大型企业有专门的运维团队协作主要通过内部工具如Git、内部Wiki进行或需要将数据集成到内部平台。成本模型能够接受按量付费API调用、存储且用量在可控范围内。希望拥有完全可控的、固定的基础设施成本服务器、数据库避免因调试产生不可预测的云服务费用。自定义与集成需求满足于LangSmith平台提供的标准功能无需深度定制。需要深度定制数据流程如自定义脱敏、与内部监控系统集成、特定的存储策略。开发阶段早期原型探索、个人项目、公开项目。快速验证想法无需关心部署。企业级开发、预生产环境测试、生产环境深度监控。需要与现有研发流程和基础设施紧密结合。混合模式是最佳实践对于大多数严肃的企业项目我推荐采用混合模式。在开发、测试和预生产环境中使用Polly享受低延迟、高隐私和零成本的优势同时配置Polly将有价值的、脱敏后的数据如基准测试结果、错误案例转发到云端LangSmith。这样团队依然可以利用LangSmith Cloud强大的UI、评估框架和协作功能进行深入分析和知识沉淀同时确保了核心开发流程中的数据安全与效率。7. 踩坑实录与进阶技巧在实际集成和使用Polly的过程中我也遇到了一些预料之外的问题总结出以下几点经验希望能帮你绕过这些坑。7.1 性能开销与采样策略问题在本地开发时对每一个LLM调用都开启全量追踪有时会明显感觉到程序变慢尤其是在运行批量测试时。根因分析追踪本身是有开销的。SDK需要收集上下文、序列化数据、发起网络请求即使是localhost。对于非常细粒度的操作如循环中调用大量简单工具这种开销会被放大。解决方案环境变量开关在代码中通过环境变量动态控制是否开启追踪。例如只在需要调试时设置LANGSMITH_TRACING_V2true。import os if os.getenv(ENABLE_TRACING, false).lower() true: os.environ[LANGSMITH_TRACING_V2] true os.environ[LANGSMITH_ENDPOINT] http://localhost:1984使用SDK的采样配置langsmithSDK支持采样率配置。你可以在初始化时设置只追踪一定比例的请求。from langsmith import Client client Client( api_keydummy, api_urlhttp://localhost:1984, sampling_rate0.1 # 只记录10%的请求 ) # 注意需要确保你的LangChain回调配置使用了这个client实例选择性追踪不要全局开启。使用traceable装饰器只对你关心的核心函数或链进行追踪。7.2 存储空间爆炸与数据清理问题在长期运行的测试环境中Polly的本地文件或数据库体积增长极快几天就可能占用几十GB空间。根因分析每次LLM调用、工具调用都会产生一条记录。复杂的Agent对话一次可能产生数十条追踪项。如果没有清理机制数据会无限堆积。解决方案为Polly配置存储卷并设置大小限制在Docker或K8s部署时使用固定大小的Volume。实现自定义清理脚本由于Polly可能还未提供成熟的TTL生存时间自动清理功能你需要自己写一个定时任务CronJob。对于文件存储写一个脚本定期删除~/.polly或指定目录下超过N天的.json文件。对于数据库存储写一个SQL脚本定期执行DELETE FROM runs WHERE created_at NOW() - INTERVAL 7 days;以PostgreSQL为例。然后通过K8s CronJob或系统的crontab定时执行。调整追踪粒度考虑是否真的需要记录每一次LLM调用。也许只记录Chain级别的输入输出就足够了。可以通过自定义回调函数来控制记录的详细程度。7.3 与异步框架FastAPI Django的集成冲突问题在FastAPI或Django等异步Web框架中集成LangSmith追踪时可能会遇到上下文Context丢失的问题导致不同用户请求的追踪数据混在一起或者追踪链断裂。根因分析LangSmith SDK为了关联同一个请求下的所有调用依赖于上下文变量ContextVar。在异步编程中如果上下文管理不当当一个异步任务被挂起另一个任务被调度时可能会“污染”或“丢失”原来的上下文。解决方案确保在每个异步请求开始时初始化新的追踪上下文。在FastAPI中可以使用中间件Middleware来实现。from contextvars import copy_context from langsmith.run_helpers import get_current_run_tree app.middleware(http) async def langsmith_tracing_middleware(request: Request, call_next): # 为每个请求创建一个干净的上下文 ctx copy_context() # 在这里可以初始化或设置一些请求级别的追踪元数据 # 例如将请求ID设置为追踪的标签 request_id request.headers.get(X-Request-ID, str(uuid.uuid4())) def _run_in_context(): # 在这个上下文中执行请求处理 # 设置上下文变量例如当前追踪树 # 注意这里需要根据LangSmith SDK的具体API调整 # 可能类似于 tracing.set_trace_context(...) pass ctx.run(_run_in_context) response await call_next(request) return response查阅官方文档LangSmith团队对于在异步环境中使用有专门的指南。关注langsmith.run_tree或langsmith.context相关的API它们是为处理这类问题而设计的。核心是使用run_tree作为上下文管理器来包裹你的核心逻辑。from langsmith.run_tree import RunTree async def handle_request(query: str): with RunTree(namemy_web_endpoint, inputs{query: query}) as run_tree: # 在这个with块内所有的LangChain调用都会被关联到这个run_tree下 result await my_chain.ainvoke({query: query}) run_tree.end(outputsresult) return result7.4 自定义追踪字段与业务元数据问题默认的追踪信息虽然详细但缺少业务上下文。例如你无法一眼看出某条追踪对应的是哪个用户、哪个订单或哪个功能模块。解决方案充分利用tags和metadata参数。Tags标签用于分类和过滤的字符串数组。例如你可以添加[env:production, user_tier:premium, feature:checkout]。Metadata元数据用于存储任意键值对的字典。例如你可以放入{user_id: 12345, order_id: ORD-67890, session_id: sess_abc}。你可以在创建Chain时设置也可以在运行时动态添加。from langchain_core.runnables import RunnableLambda chain ( RunnableLambda(lambda x: x) .with_config({tags: [my_service], metadata: {version: 1.0}}) ) # 或者在调用时传入 result chain.invoke( {input: hello}, config{tags: [test_run], metadata: {test_case_id: 5}} )在Polly UI或LangSmith Cloud中你可以通过这些标签和元数据来快速过滤和搜索相关的追踪将LLM的可观测性与你的业务监控体系打通。Polly的正式可用标志着LLM应用开发工具链正朝着更成熟、更灵活的企业级方向迈进。它解耦了能力与交付模式把选择权交还给了开发者。无论你是一个在咖啡店里用笔记本编码的独立开发者还是一个在跨国企业复杂基础设施中运维AI应用的技术专家Polly都提供了一种方式让LangSmith级别的可观测性变得触手可及且完全适应你的工作流。