ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

OpenSmith:本地化LLM应用调试与追踪框架实战指南

OpenSmith:本地化LLM应用调试与追踪框架实战指南 当你正在调试一个复杂的 LLM 应用比如一个包含多步检索、多个模型调用和条件判断的 RAG 流水线时最头疼的是什么是某个环节突然返回了空结果却不知道是检索器的问题还是模型的问题是流水线执行缓慢但无法定位瓶颈到底在哪一步还是线上出了问题却因为没有详细的执行记录而难以复现和排查如果你遇到过上述问题那么今天介绍的这个开源工具——OpenSmith很可能就是你一直在寻找的解决方案。它不是一个新的大模型而是一个轻量级的本地调试与追踪框架。其核心价值在于让你能够像调试普通代码一样去可视化地追踪和剖析整个 LLM 流水线的内部执行过程并且所有数据都保存在本地无需依赖任何云服务。很多开发者习惯用print大法来调试但在复杂的 Agent 或 Pipeline 中这远远不够。OpenSmith 提出的“Trace”概念正是为了解决这一痛点。它能够自动记录下流水线中每个组件的输入、输出、耗时、token 消耗以及内部状态变化并将这些信息结构化的存入本地 SQLite 数据库。你可以通过其内置的 Web 界面清晰地回顾整个调用链精准定位问题。本文将带你从零开始全面上手 OpenSmith。你将不仅了解其核心概念更能通过一个完整的 RAG 流水线示例学会如何集成、运行和利用 Trace 功能进行深度调试。我们还将探讨其最佳实践和常见陷阱帮助你在实际项目中有效提升 LLM 应用的开发效率和可靠性。1. OpenSmith 解决的核心问题LLM 应用的可观测性困境在深入技术细节之前我们有必要先厘清 OpenSmith 究竟瞄准了哪个“靶心”。随着 LLM 应用从简单的单次对话发展为包含复杂逻辑的流水线Pipeline或智能体Agent其“黑盒”特性带来的调试难度呈指数级增长。传统调试方式的局限性打印日志Print Debugging在关键节点插入print语句。对于简单流程尚可但当流水线步骤增多、逻辑变复杂时日志会变得杂乱无章难以理清调用关系和上下文。远程云服务Cloud-based Tracing某些商业平台提供追踪功能但通常意味着你的敏感提示词和模型输出需要上传到第三方服务器存在数据安全和隐私风险。同时网络延迟和依赖也影响了调试的实时性。OpenSmith 的破局点本地化优先Local-First所有追踪数据Trace都存储在本地 SQLite 数据库中彻底杜绝了数据泄露的风险尤其适合处理企业内部或敏感数据。结构化追踪Structured Tracing它不是简单的日志记录而是将一次 LLM 流水线的执行分解为具有层级关系的“跨度Spans”。例如一个 RAG 查询可能包含“检索”、“重排”、“生成”等多个跨度每个跨度又有其子操作。这种结构让你能清晰地看到整个执行的“树状图”。深度集成与可视化它提供装饰器或上下文管理器等简单方式让开发者能以最小侵入性将现有代码转换为可追踪的流水线。并通过一个本地 Web UI 直观地展示追踪结果包括耗时、Token 使用、输入输出等关键信息。简单来说OpenSmith 为 LLM 应用开发赋予了强大的“可观测性”Observability能力。它让你能回答以下关键问题我的流水线为什么这么慢瓶颈在哪一步这次查询失败的原因是什么是检索没找到相关文档还是模型理解有误每次调用实际消耗了多少 Token成本如何如何复现和调试生产环境中出现的问题2. 核心概念解析Trace, Pipeline, Span 与 SQLite要熟练使用 OpenSmith需要理解以下几个核心概念Trace追踪这是最高层级的概念代表一次完整的 LLM 应用执行过程。例如用户提出一个问题到系统返回最终答案这整个生命周期就是一个 Trace。每个 Trace 都有一个唯一的 ID并包含全局元数据如开始时间、总耗时、状态成功/失败等。Pipeline流水线与 Span跨度一个 Trace 由多个 Span 组成。Span 代表一个逻辑操作单元比如调用一次 LLM、执行一次向量检索、或者运行一段条件判断代码。Span 之间可以存在嵌套关系形成父子层级。例如一个 “RAG Pipeline” 的 Span 可能包含 “Retriever”、“Reranker”、“LLM Generator” 三个子 Span。每个 Span 会记录其名称、输入参数、输出结果、开始和结束时间、耗时、以及可能发生的错误。SQLite 本地存储OpenSmith 使用轻量级数据库 SQLite 作为默认的存储后端。所有 Trace 和 Span 数据都以结构化的方式保存在本地的一个.db文件中。这样做的好处是零配置、无需启动额外的数据库服务非常轻便。同时你可以使用任何 SQLite 客户端如 DB Browser for SQLite直接查询和分析数据。与类似概念如 LangSmith的对比LangSmithLangChain 官方提供的商业化追踪平台功能强大但它是云服务需要付费且数据存储在云端。OpenSmith定位是开源、本地化的替代方案。它更注重隐私、可控性和轻量级部署虽然在功能集成度上可能不及成熟的商业产品但对于许多希望掌握完整数据主权的中小项目或个人开发者来说是极具吸引力的选择。为了更直观地理解这些概念的关系可以参考下面的流程对比图想象一个流程图左侧是“无 Trace 的流水线”只是一系列顺序执行的黑盒模块右侧是“有 Trace 的流水线”每个模块的执行详情都被记录并关联起来3. 环境准备与安装OpenSmith 是一个 Python 库因此安装过程非常简单。建议使用 Python 3.8 或更高版本。步骤 1创建并激活虚拟环境强烈推荐为了避免与系统或其他项目的 Python 包发生冲突最好在虚拟环境中操作。# 使用 conda conda create -n opensmith-demo python3.10 conda activate opensmith-demo # 或使用 venv python -m venv opensmith-demo source opensmith-demo/bin/activate # Linux/macOS # opensmith-demo\Scripts\activate # Windows步骤 2安装 OpenSmith目前OpenSmith 应该可以通过 pip 从 PyPI 安装。pip install opensmith步骤 3验证安装启动 Python 解释器尝试导入库如果没有报错则说明安装成功。python -c import opensmith; print(OpenSmith 安装成功)4. 快速开始创建你的第一个可追踪流水线让我们通过一个最简单的例子感受一下 OpenSmith 的基本用法。这个例子模拟一个极简的 LLM 调用流程。项目结构my_opensmith_demo/ ├── app.py └── requirements.txt代码实现 (app.py)# app.py import time from opensmith import trace, span # 使用 trace 装饰器来标记一个完整的追踪流程 trace(nameMy First Pipeline) def my_simple_pipeline(question: str) - str: 一个简单的模拟流水线包含两个步骤。 # 步骤1模拟一个预处理步骤 with span(namepreprocess, typetool) as preprocess_span: time.sleep(0.1) # 模拟处理耗时 processed_question question.upper() # 模拟预处理比如转为大写 # 记录步骤的输入输出可选但推荐 preprocess_span.record_input(question, question) preprocess_span.record_output(processed_question, processed_question) # 步骤2模拟调用 LLM with span(namemock_llm_call, typellm) as llm_span: time.sleep(0.5) # 模拟 LLM 生成耗时 # 模拟 LLM 的简单响应 answer fI received your question: {processed_question}. This is a mock response. # 记录 LLM 调用的关键信息 llm_span.record_input(prompt, processed_question) llm_span.record_output(completion, answer) # 还可以记录模拟的 token 使用量 llm_span.record_metrics(prompt_tokenslen(processed_question), completion_tokenslen(answer)) return answer if __name__ __main__: # 执行流水线 result my_simple_pipeline(What is the weather today?) print(Pipeline Result:, result) print(Trace 数据已保存至本地 SQLite 数据库。)运行代码python app.py运行后你会在控制台看到输出同时 OpenSmith 会自动在当前目录下创建或连接一个 SQLite 数据库文件通常是traces.db并将本次执行的 Trace 数据存入其中。5. 查看追踪结果使用 Web UI 和 SQLite 客户端数据存好了如何查看OpenSmith 提供了两种主要方式。方式一使用内置 Web UI推荐OpenSmith 通常附带一个轻量的 Web 服务器用于可视化展示追踪数据。启动 Web UI 的命令可能类似于请以官方文档为准opensmith ui # 或 python -m opensmith.ui启动后在浏览器中访问http://localhost:8080具体端口请查看命令行输出你就能看到一个界面列表中显示了你刚刚运行的My First PipelineTrace。点击进入可以清晰地看到整个流水线的树状结构每个 Span 的耗时、输入输出都一目了然。方式二直接查询 SQLite 数据库如果你喜欢直接操作数据库可以使用 SQLite 客户端工具。安装 DB Browser for SQLite (SQLiteStudio 亦可)这是一个图形化工具方便查看。打开生成的traces.db文件。你可以执行 SQL 查询来查看数据例如-- 查看所有的 Trace SELECT * FROM traces; -- 查看某个 Trace 下的所有 Span SELECT * FROM spans WHERE trace_id 你的Trace-ID;这种方式更灵活适合进行自定义的数据分析。6. 实战构建一个可追踪的 RAG 流水线现在我们来看一个更贴近现实的例子构建一个包含检索器Retriever和生成器Generator的 RAG 流水线并使用 OpenSmith 进行追踪。为了简化我们使用 ChromaDB 作为向量数据库Sentence Transformers 作为嵌入模型并调用 OpenAI API或其兼容开源模型作为 LLM。安装额外依赖pip install chromadb sentence-transformers openai完整代码示例 (rag_pipeline.py)# rag_pipeline.py import os from opensmith import trace, span from chromadb import Client, Settings from chromadb.config import Settings as ChromaSettings from sentence_transformers import SentenceTransformer import openai # 初始化组件 # 1. 嵌入模型 embedder SentenceTransformer(all-MiniLM-L6-v2) # 2. 向量数据库客户端 chroma_client Client(Settings(persist_directory./chroma_db, is_persistentTrue)) collection chroma_client.get_or_create_collection(demo_docs) # 3. 初始化 OpenAI 客户端 (请设置你的 API KEY) openai.api_key os.getenv(OPENAI_API_KEY) # 如果没有 OpenAI API Key可以注释掉相关代码用模拟响应代替 # 首先向向量数据库添加一些示例文档假设只做一次 sample_docs [ OpenSmith is a tool for tracing LLM pipelines locally., Python is a popular programming language for AI., RAG stands for Retrieval-Augmented Generation. ] sample_embeddings embedder.encode(sample_docs).tolist() collection.add( embeddingssample_embeddings, documentssample_docs, ids[fdoc_{i} for i in range(len(sample_docs))] ) trace(nameRAG Pipeline Demo) def rag_pipeline(user_query: str) - str: 一个简单的 RAG 流水线 context_docs [] llm_response # Span 1: 检索相关文档 with span(namedocument_retrieval, typeretriever) as retrieval_span: query_embedding embedder.encode([user_query]).tolist() results collection.query(query_embeddingsquery_embedding, n_results2) context_docs results[documents][0] if results[documents] else [No relevant document found.] retrieval_span.record_input(query, user_query) retrieval_span.record_output(retrieved_documents, context_docs) retrieval_span.record_metrics(retrieved_countlen(context_docs)) # Span 2: 构建提示词 with span(nameprompt_construction, typetool) as prompt_span: context_str \n.join([f- {doc} for doc in context_docs]) prompt fBased on the following context, please answer the users question. If the context doesnt contain the answer, say you dont know. Context: {context_str} User Question: {user_query} Answer: prompt_span.record_output(constructed_prompt, prompt) # Span 3: 调用 LLM 生成答案 with span(namellm_generation, typellm) as generation_span: try: # 使用真实的 OpenAI API response openai.ChatCompletion.create( modelgpt-3.5-turbo, messages[{role: user, content: prompt}], temperature0.7 ) llm_response response.choices[0].message.content usage response.usage generation_span.record_metrics( prompt_tokensusage.prompt_tokens, completion_tokensusage.completion_tokens, total_tokensusage.total_tokens ) except Exception as e: # 如果无法调用 API使用模拟响应 llm_response f[Mock] This is a simulated response based on your query: {user_query} and context: {context_docs} generation_span.record_metrics(prompt_tokens100, completion_tokens50, total_tokens150) generation_span.record_status(ERROR, descriptionfOpenAI API call failed: {str(e)}) finally: generation_span.record_input(prompt, prompt) generation_span.record_output(completion, llm_response) return llm_response if __name__ __main__: question What is OpenSmith? answer rag_pipeline(question) print(Question:, question) print(Answer:, answer)运行与观察运行脚本python rag_pipeline.py。启动 OpenSmith Web UIopensmith ui。在 UI 中你应该能看到一个名为 RAG Pipeline Demo 的 Trace。点开后可以清晰地看到document_retrieval,prompt_construction,llm_generation三个 Span 的层级关系、耗时以及详细的输入输出。如果检索到的文档不相关或者 LLM 调用出错你都能快速定位问题根源。7. 常见问题与排查指南在实际使用中你可能会遇到以下问题问题现象可能原因排查方式解决方案运行代码后在 Web UI 中看不到任何 Trace。1. Web UI 连接的数据库路径与代码生成的不一致。2. Trace 数据未成功提交提交时机问题。1. 检查代码运行目录下是否有traces.db文件。2. 检查 Web UI 启动时是否指定了正确的--db-path参数。3. 在代码中确保trace装饰的函数正常执行完毕。1. 确保 Web UI 和代码在同一个工作目录运行或使用绝对路径指定数据库文件。2. 在代码末尾添加time.sleep(2)确保数据写入完成。报错ModuleNotFoundError: No module named opensmithOpenSmith 库没有正确安装。检查虚拟环境是否已激活并使用 pip listgrep opensmith 确认。Span 中记录的信息不完整或为空。record_input/record_output方法调用有误或传入的数据类型不被支持。检查传入record_input/output的参数是否为基本类型str, int, dict, list。复杂对象需要先序列化。只记录关键、可序列化的信息。对于复杂对象可以记录其摘要或关键字段。追踪数据导致性能显著下降。1. 记录过于频繁或数据量过大。2. 同步写入数据库阻塞主线程。1. 检查是否在每个细粒度操作都创建了 Span。2. 查看数据库文件大小。1. 只在关键步骤创建 Span。2. 关注 OpenSmith 是否支持异步或批量写入模式如果可用。8. 最佳实践与工程建议为了让 OpenSmith 在项目中发挥最大价值请遵循以下建议有选择地追踪不是所有函数都需要包装成 Span。重点关注那些包含 LLM 调用、外部 API 请求、复杂计算或容易出错的核心组件。赋予有意义的名称为 Trace 和 Span 起一个清晰、具有业务含义的名字如customer_support_agent而非pipeline_1这将极大提升后期排查效率。记录有价值的元数据除了输入输出还应记录版本号、模型名称、参数如 temperature、错误信息等便于对比不同配置下的表现。注意数据安全虽然数据在本地但 Trace 可能包含敏感信息。在生产环境中要考虑对数据库文件进行加密或设置访问权限。对于团队协作可以建立 Trace 数据的归档和清理机制。与现有日志系统集成OpenSmith 的 Trace 不应取代传统的应用日志如 INFO, ERROR 级别日志。它们应互为补充Trace 关注宏观流程日志关注微观细节。用于性能分析利用 Trace 中的耗时信息定期分析流水线的性能瓶颈并针对性优化例如优化检索策略、缓存模型结果等。9. 总结OpenSmith 的出现标志着 LLM 应用开发工具链正在向“成熟软件工程”迈进。它提供的本地化、结构化的追踪能力解决了 LLM 流水线调试难、观测难的核心痛点。通过本文的讲解和实战希望你已经掌握了为什么需要理解了 LLM 应用可观测性的重要性。核心是什么掌握了 Trace, Span, Pipeline 等核心概念。如何上手学会了安装、基础用法和 Web UI 查看。如何实战完成了对一个 RAG 流水线的集成与追踪。如何避坑了解了常见问题及其解决方法。下一步你可以尝试将 OpenSmith 集成到你自己的 LLM 项目中无论是基于 LangChain、LlamaIndex 还是自建的流水线。从最简单的流程开始逐步增加追踪点你会发现调试和优化 LLM 应用从此变得有据可依。
返回列表