Doramagic 项目包 · 项目说明书
weave 项目
生成时间:2026-05-16 23:32:03 UTC
项目介绍
Weave 是一个用于追踪和监控 AI 应用程序的库,由 W&B(Weights & Biases)开发维护。它提供了一套完整的工具集,帮助开发者追踪 AI 模型的调用、执行过程,并支持对 AI 应用进行评估和可视化。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Weave 是一个用于追踪和监控 AI 应用程序的库,由 W&B(Weights & Biases)开发维护。它提供了一套完整的工具集,帮助开发者追踪 AI 模型的调用、执行过程,并支持对 AI 应用进行评估和可视化。
资料来源:README.md:1
核心架构
整体架构
Weave 项目主要由以下几个核心部分组成:
graph TD
A[用户代码] --> B[Weave SDK]
B --> C[Op 追踪层]
C --> D[Trace Server]
D --> E[W&B UI]
F[Python SDK] --> B
G[Node.js SDK] --> B
H[集成支持] --> B
H --> I[OpenAI]
H --> J[Anthropic]
H --> K[Mistral]主要组件
| 组件 | 位置 | 功能描述 |
|---|---|---|
| trace | weave/trace/ | Python 追踪核心实现 |
| trace_server | weave/trace_server/ | 追踪服务器接口 |
| integrations | weave/integrations/ | 第三方库集成支持 |
| flow | weave/flow/ | 评估工作流 |
| Node SDK | sdks/node/ | JavaScript/TypeScript SDK |
资料来源:README.md:20-25
核心概念
Op(操作)
Op 是 Weave 的核心抽象概念,用于包装和追踪函数调用。它支持:
- 异步函数追踪:自动处理 async/await 模式
- 流式响应处理:支持流式输出的追踪和聚合
- 调用元数据记录:记录调用参数、返回值、执行时间等信息
graph LR
A[原始函数] -->|createOpWrapper| B[Op 包装器]
B --> C{调用执行}
C -->|追踪| D[Call 对象]
C -->|返回| E[原始返回值]
D --> F[Trace Server]资料来源:sdks/node/src/opType.ts:1-30
Op 类型定义
export type Op<T extends (...args: any[]) => any> = {
__isOp: true;
__wrappedFunction: T;
__boundThis?: WeaveObject;
__name: string;
__savedRef?: OpRef | Promise<OpRef>;
__parameterNames?: ParameterNamesOption;
invoke: CallMethod<T>;
} & T;
资料来源:sdks/node/src/opType.ts:3-18
调用方法(CallMethod)
CallMethod 接口定义了 Op 的调用行为,返回一个 Promise,包含原始返回值和 Call 对象:
export interface CallMethod<F extends (...args: any[]) => any> {
(
this: any,
...params: Parameters<F>
): Promise<[Awaited<ReturnType<F>>, Call]>;
}
资料来源:sdks/node/src/opType.ts:62-68
调用对象(Call)
Call 对象用于存储追踪信息,包括:
| 字段 | 类型 | 说明 |
|---|---|---|
| callId | string | 唯一调用标识符 |
| opName | string | 操作名称 |
| inputs | object | 输入参数 |
| outputs | object | 输出结果 |
| summary | object | 调用摘要 |
| error | Error | 错误信息(如有) |
Op 装饰器
Weave 支持两种装饰器模式:现代 Stage 3 装饰器和传统装饰器语法。
现代装饰器语法(Stage 3)
class TestClass {
@weave.op
async logImage(image: WeaveImage) {
// 方法实现
}
}
传统装饰器语法
class TestClass {
@weave.op({ name: 'customName' })
async logImage(image: WeaveImage) {
// 方法实现
}
}
装饰器选项
| 选项 | 类型 | 说明 |
|---|---|---|
| name | string | 自定义操作名称 |
| streamReducer | StreamReducer | 流式响应聚合器 |
| callDisplayName | function | 动态显示名称生成 |
| summarize | function | 结果摘要生成函数 |
| bindThis | WeaveObject | 绑定 this 上下文 |
| parameterNames | string[] | 参数名称配置 |
| opKind | string | 操作类型分类 |
| opColor | string | UI 显示颜色 |
资料来源:sdks/node/src/opType.ts:71-87
集成系统
隐式集成
当隐式集成启用(默认)时,Weave 会自动检测并追踪支持的第三方库。用户只需初始化 Weave 项目:
import weave
weave.init("my-project")
import openai # 自动被追踪!
显式集成
通过设置 implicitly_patch_integrations=False 禁用隐式集成,然后手动调用 patch 函数:
import weave
weave.init("my-project", settings={'implicitly_patch_integrations': False})
weave.integrations.patch_openai()
weave.integrations.patch_anthropic()
资料来源:weave/integrations/README.md:1-50
可用集成
| 集成 | Patch 函数 | 说明 |
|---|---|---|
| OpenAI | patch_openai() | OpenAI API 调用追踪 |
| Anthropic | patch_anthropic() | Anthropic Claude API 追踪 |
| Mistral | patch_mistral() | Mistral API 追踪 |
开发新集成
开发新的供应商集成需要创建以下文件结构:
weave/integrations/<vendor>/
├── __init__.py
├── <vendor>_sdk.py
└── <vendor>_test.py
集成开发流程:
- 创建供应商文件夹
- 实现
get_<vendor>_patcher()函数 - 返回
MultiPatcher或NoOpPatcher对象 - 在
AutopatchSettings中注册设置
from weave.integrations.patcher import SymbolPatcher, MultiPatcher, NoOpPatcher
from weave.trace.autopatch import IntegrationSettings
def get_<vendor>_patcher(
settings: IntegrationSettings | None = None,
) -> MultiPatcher | NoOpPatcher:
if settings is None:
settings = IntegrationSettings()
if not settings.enabled:
return NoOpPatcher()
global _<vendor>_patcher
if _<vendor>_patcher is None:
# 实现符号替换逻辑
_<vendor>_patcher = MultiPatcher([...])
return _<vendor>_patcher
资料来源:weave/integrations/README.md:100-140
序列化系统
序列化机制
Weave 提供两种序列化方式:
| 方式 | 适用场景 | 说明 |
|---|---|---|
| 文件序列化 | 大型值(图片等) | 通过 MemTraceFilesArtifact 存储 |
| 内联序列化 | 小型值(datetime 等) | 直接嵌入序列化信息 |
资料来源:weave/trace/serialization/README.md:1-30
自定义类型支持
用户可以注册自定义的 save 和 load 方法:
from weave import register_serializer
@register_serializer(MyCustomClass)
class MyCustomSerializer:
def save(self, obj):
# 自定义序列化逻辑
return {...}
def load(self, data):
# 自定义反序列化逻辑
return MyCustomClass(...)
内置类型
Weave 内置以下类型的序列化支持:
| 类型 | 模块 | 说明 |
|---|---|---|
| 图像 | PIL.Image.Image | 图片序列化 |
| 音频 | wave.Wave_read | 音频序列化 |
| Op | weave.Op | 操作序列化 |
| 日期时间 | datetime.datetime | 时间戳序列化 |
| Markdown | rich.markdown.Markdown | Markdown 内容序列化 |
评估工作流
评估系统架构
graph TD
A[评估数据集] --> B[评估运行器]
B --> C[并行执行]
C --> D[结果聚合]
D --> E[评分计算]
E --> F[结果展示]
G[预测函数] --> B
G --> H[Op 追踪]
H --> I[Trace Server]
I --> ECallable 接口
评估系统基于 Callable 接口设计:
export interface Callable<I, O> {
run: (input: I) => Promise<O>;
}
资料来源:sdks/node/src/fn.ts:10-13
SDK 使用
Python SDK
#### 初始化项目
import weave
weave.init("my-project")
#### 追踪函数
import weave
@weave.op()
def extract_fruit(sentence):
# 函数实现
return fruit
Node.js SDK
#### 安装
npm install weave
#### 初始化和追踪
import {init, op, wrapOpenAI} from 'weave';
import {OpenAI} from 'openai';
const openai = wrapOpenAI(new OpenAI());
async function extractDinos(input) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{role: 'user', content: input}],
});
return response.choices[0].message.content;
}
const extractDinosOp = op(extractDinos);
async function main() {
await init('weave-quickstart');
const result = await extractDinosOp('输入文本');
console.log(result);
}
配置选项
Weave 初始化配置
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| project_name | string | 必填 | 项目名称 |
| settings | dict | None | 配置字典 |
| entity | string | None | 团队/用户名称 |
| host | string | api.wandb.ai | API 主机地址 |
集成设置
| 设置 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| implicitly_patch_integrations | bool | True | 是否启用隐式集成 |
| enabled | bool | True | 是否启用特定集成 |
项目结构
weave/
├── __init__.py # 主入口
├── trace/ # 追踪核心
│ ├── autopatch.py # 自动集成
│ ├── ops.py # Op 定义
│ └── serialization/ # 序列化系统
├── trace_server/ # 服务端接口
├── integrations/ # 第三方集成
│ ├── openai/ # OpenAI 集成
│ ├── anthropic/ # Anthropic 集成
│ └── mistral/ # Mistral 集成
└── flow/ # 评估工作流
sdks/
└── node/ # JavaScript SDK
├── src/
│ ├── op.ts # Op 实现
│ ├── opType.ts # 类型定义
│ └── evaluation.ts # 评估功能
└── README.md # Node SDK 文档
资料来源:README.md:15-30
快速开始
Python 快速开始
- 安装 Weave:
pip install weave - 初始化项目并追踪函数
- 查看追踪结果在 W&B 仪表板
Node.js 快速开始
- 安装:
npm install weave - 配置
~/.netrc中的 W&B API 密钥 - 使用
op()包装函数 - 运行并查看结果
贡献指南
项目当前处于代码整理阶段。核心代码位置:
- 追踪代码:
weave/trace和weave/trace_server - 评估代码:
weave/flow
资料来源:README.md:27-30
资料来源:[README.md:1]()
安装与快速开始
Weave 是一个用于 AI 应用追踪(Tracing)和监控的库,由 W&B(Weights & Biases)提供。该库支持 Python 和 Node.js 两个主要 SDK,能够自动捕获和记录 AI 应用的执行过程,帮助开发者追踪函数调用、分析性能、调试问题。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Weave 是一个用于 AI 应用追踪(Tracing)和监控的库,由 W&B(Weights & Biases)提供。该库支持 Python 和 Node.js 两个主要 SDK,能够自动捕获和记录 AI 应用的执行过程,帮助开发者追踪函数调用、分析性能、调试问题。
安装与快速开始模块是用户接触 Weave 的第一步,涵盖了环境准备、SDK 安装、项目初始化、基础追踪操作等核心流程。资料来源:README.md:1-5
环境要求
Python SDK 系统要求
| 要求类型 | 最低版本 | 说明 |
|---|---|---|
| Python | 3.8+ | 支持 Python 3.8 及以上版本 |
| pip | 最新版本 | 推荐使用最新版本的 pip 进行安装 |
Node.js SDK 系统要求
| 要求类型 | 最低版本 | 说明 |
|---|---|---|
| Node.js | 18+ | 支持 Node.js 18 及以上版本 |
| npm | 最新版本 | 用于安装 weave 包 |
网络要求
- 需要访问 W&B API 服务(api.wandb.ai)
- 部分功能需要有效的 W&B API Key
- 测试环境支持本地 Trace Server(localhost)
Python SDK 安装
使用 pip 安装
pip install weave
验证安装
安装完成后,可通过以下命令验证:
import weave
print(weave.__version__)
资料来源:pyproject.toml
Node.js SDK 安装
使用 npm 安装
npm install weave
配置认证
在 ~/.netrc 文件中添加 W&B API Key:
machine api.wandb.ai
login user
password <wandb-api-key>
API Key 可从 W&B 授权页面 获取。
项目初始化
Python 初始化流程
使用 weave.init() 函数初始化项目:
import weave
# 初始化项目
weave.init("my-project")
Node.js 初始化流程
import {init} from 'weave';
// 初始化项目
await init('my-awesome-ai-project');
初始化参数说明
| 参数名 | 类型 | 必需 | 默认值 | 说明 |
|---|---|---|---|---|
| project | string | 是 | - | 项目名称 |
| entity | string | 否 | 当前用户 | W&B 实体/团队名称 |
| settings | dict/Settings | 否 | None | 高级配置选项 |
配置选项(Settings)
初始化时可通过 settings 参数进行高级配置:
import weave
weave.init("my-project", settings={
'implicitly_patch_integrations': True, # 自动注入集成
'print_call_link': True, # 打印调用链接
})
资料来源:weave/trace/weave_init.py
追踪操作入门
使用 op 装饰器追踪函数
#### Python 示例
import weave
@weave.op()
def extract_fruit(sentence: str) -> str:
"""提取句子中的水果名称"""
return "apple"
# 调用追踪函数
result = extract_fruit("I love apples and oranges")
#### Node.js 示例
import {op} from 'weave';
const extractDinosOp = op(async function extractDinos(input) {
// 你的逻辑
return result;
});
资料来源:sdks/node/README.md:30-55
类方法追踪
#### Python 类方法
import weave
class MyAgent:
@weave.op()
async def analyze(self, text: str) -> dict:
return {"sentiment": "positive", "text": text}
agent = MyAgent()
result = await agent.analyze("This is great!")
#### Node.js 类装饰器
import * as weave from "weave";
class TestClass {
@weave.op
async logImage(image) {
// 方法逻辑
}
}
资料来源:sdks/node/README.md:55-70
自动集成与注入
隐式注入(默认启用)
当隐式注入启用时,Weave 会在支持的库被导入时自动应用追踪补丁:
import weave
weave.init("my-project")
import openai # 自动追踪已启用!
显式控制
如需显式控制,可禁用隐式注入:
import weave
weave.init("my-project", settings={'implicitly_patch_integrations': False})
# 显式启用特定集成
weave.integrations.patch_openai()
weave.integrations.patch_anthropic()
weave.integrations.patch_mistral()
支持的集成列表
| 集成名称 | 库名称 | patch 函数 |
|---|---|---|
| OpenAI | openai | weave.integrations.patch_openai() |
| Anthropic | anthropic | weave.integrations.patch_anthropic() |
| Mistral | mistral | weave.integrations.patch_mistral() |
| LlamaIndex | llama_index | weave.integrations.patch_llama_index() |
| Langchain | langchain | weave.integrations.patch_langchain() |
资料来源:weave/integrations/README.md:1-50
快速开始示例
Python 完整示例
import weave
# 1. 初始化项目
weave.init("quickstart-demo")
# 2. 定义追踪函数
@weave.op()
def extract_fruit(sentence: str) -> str:
"""从句子中提取水果名称"""
fruits = ["apple", "banana", "cherry", "date"]
for fruit in fruits:
if fruit in sentence.lower():
return fruit
return "未找到水果"
# 3. 调用函数
result = extract_fruit("I love eating apples")
print(f"结果: {result}")
# 4. 获取追踪结果
calls = list(weave_client.get_calls())
print(f"追踪到的调用数: {len(calls)}")
Node.js 完整示例
创建 predict.mjs 文件:
import {OpenAI} from 'openai';
import {init, op, wrapOpenAI} from 'weave';
const openai = wrapOpenAI(new OpenAI());
async function extractDinos(input) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{role: 'user', content: `提取恐龙信息: ${input}`}],
});
return response.choices[0].message.content;
}
const extractDinosOp = op(extractDinos);
async function main() {
await init('weave-quickstart');
const result = await extractDinosOp('T. rex 追逐三角龙');
console.log(result);
}
main();
运行:
node predict.mjs
资料来源:sdks/node/README.md:30-65
工作流程图
graph TD
A[安装 Weave SDK] --> B{选择运行环境}
B -->|Python| C[使用 pip 安装]
B -->|Node.js| D[使用 npm 安装]
C --> E[配置 W&B API Key]
D --> E
E --> F[初始化项目 weave.init]
F --> G{定义追踪操作}
G -->|函数| H[使用 @weave.op 装饰器]
G -->|类方法| I[使用 @weave.op 装饰方法]
H --> J[调用追踪函数]
I --> J
J --> K[查看追踪结果]
K --> L{启用集成追踪?}
L -->|是| M[隐式/显式注入集成]
L -->|否| K常见问题与解决方案
1. 追踪未生效
问题:调用函数后没有追踪记录。
解决方案:
- 确保在调用函数前已调用
weave.init() - 检查是否禁用了隐式注入
- 确认使用了正确的装饰器语法
2. API Key 配置错误
问题:无法连接到 W&B 服务。
解决方案:
- 验证
~/.netrc文件中的 API Key 格式正确 - 确认 API Key 具有有效权限
- 检查网络连接和代理设置
3. 集成库未被追踪
问题:使用第三方库(如 OpenAI)时未记录调用。
解决方案:
- 确认集成库已安装:
pip install openai - 显式调用 patch 函数:
weave.integrations.patch_openai() - 或确保隐式注入已启用
下一步
完成安装和快速开始后,你可以:
| 进阶主题 | 说明 |
|---|---|
| 高级追踪配置 | 自定义追踪行为、属性和显示方式 |
| 评估与测试 | 使用 Weave 构建 AI 评估流程 |
| 自定义序列化 | 添加自定义类型的序列化支持 |
| 集成开发 | 为新的供应商库开发集成支持 |
资料来源:weave/trace/serialization/README.md:1-30
相关文档链接
资料来源:[sdks/node/README.md:1-20]()
系统架构
Weave 是一个用于追踪和监控 AI 应用程序的库,支持 Python 和 Node.js 双端 SDK。其核心设计围绕追踪(Tracing)和评估(Evaluations)两大功能模块展开,旨在为 AI 应用提供可观测性和性能分析能力。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Weave 是一个用于追踪和监控 AI 应用程序的库,支持 Python 和 Node.js 双端 SDK。其核心设计围绕追踪(Tracing)和评估(Evaluations)两大功能模块展开,旨在为 AI 应用提供可观测性和性能分析能力。
系统架构采用分层设计,包含以下核心层次:
A[用户代码] --> B[Weave SDK 层]
B --> C[追踪客户端层]
C --> D[Trace Server 接口层]
D --> E[Trace Server 实现层]
E --> F[(ClickHouse 数据库)]
G[集成模块] --> B
H[自动补丁模块] --> G
资料来源:weave/trace/weave_client.py
核心组件
SDK 层架构
Weave SDK 提供 Python 和 Node.js 两种实现,共同遵循相同的架构理念:
| SDK 类型 | 主要语言 | 核心文件 | 功能定位 |
|---|---|---|---|
| Python SDK | Python | weave/trace/weave_client.py | 服务端追踪数据处理 |
| Node.js SDK | TypeScript | sdks/node/src/op.ts | 客户端函数包装与追踪 |
Python SDK 侧重于服务端 trace 数据的接收、存储和查询,而 Node.js SDK 则专注于客户端操作的包装和追踪。
追踪客户端层
WeaveClient 是 Python SDK 的核心类,负责管理追踪会话和调用记录:
classDiagram
class WeaveClient {
+project_id: str
+settings: WeaveStorageSettings
+pushNewCall() CallContext
+finishCall() None
+finishCallWithException() None
+waitForBatchProcessing() None
}
class CallContext {
+currentCall: Call
+parentCall: Call | None
+newStack: list
}客户端通过 pushNewCall() 创建新的调用上下文,跟踪操作的执行状态和层级关系。
资料来源:weave/trace/weave_client.py
Op 包装机制
Op(操作)是 Weave 追踪的基本单元,通过 op() 函数包装用户函数:
A[用户定义函数 fn] --> B[op(fn) 包装]
B --> C[创建 Op 对象]
C --> D[注入追踪逻辑]
D --> E[返回包装后的函数]
E --> F[同步函数处理]
E --> G[异步函数处理]
E --> H[流式响应处理]
F --> I[直接返回结果]
G --> J[Promise 包装]
H --> K[AsyncIterator 代理]
Op 对象保留原函数的所有特性,同时添加追踪能力:
export type Op<T extends (...args: any[]) => any> = {
__isOp: true;
__wrappedFunction: T;
__boundThis?: WeaveObject;
__name: string;
__savedRef?: OpRef | Promise<OpRef>;
__parameterNames?: ParameterNamesOption;
invoke: CallMethod<T>;
} & T;
资料来源:sdks/node/src/opType.ts:1-30
Trace Server 接口层
trace_server_bindings 定义了 Weave 与后端服务之间的接口契约:
| 接口方法 | 功能描述 | 数据格式 |
|---|---|---|
calls/stream_query | 流式查询调用记录 | NDJSON |
call/upsert_batch | 批量创建/更新调用 | JSON |
obj/* | 对象管理 | JSON |
table/* | 表格数据管理 | JSON |
file/* | 文件存储管理 | 二进制 |
接口层采用 RESTful 设计,兼容生产环境和测试环境。
资料来源:weave/trace_server_bindings
Trace Server 实现层
clickhouse_trace_server_batched.py 实现了基于 ClickHouse 的 trace 服务器:
graph LR
A[批量请求接收] --> B[请求队列管理]
B --> C[批处理优化]
C --> D[ClickHouse 写入]
D --> E[查询接口]
E --> F[NDJSON 流式响应]批量处理机制显著提高了数据写入效率,降低了数据库连接开销。
资料来源:weave/trace_server/clickhouse_trace_server_batched.py
集成模块架构
自动补丁系统
Weave 的自动补丁系统通过 sys.meta_path 拦截导入,自动应用追踪补丁:
A[import vendor_lib] --> B[Meta Path 钩子]
B --> C{patch_<vendor> 可用?}
C -->|是| D[调用 patch_<vendor>]
C -->|否| E[跳过补丁]
D --> F[修改 vendor_lib 函数]
F --> G[注入追踪调用]
用户可通过配置控制隐式补丁行为:
# 启用隐式补丁(默认)
weave.init('my-project')
# 禁用隐式补丁
weave.init('my-project', settings={'implicitly_patch_integrations': False})
# 或通过环境变量
# export WEAVE_IMPLICITLY_PATCH_INTEGRATIONS=false
支持的集成
自动补丁系统支持主流 AI 服务商的 SDK:
| 集成名称 | 补丁函数 | 追踪范围 |
|---|---|---|
| OpenAI | patch_openai() | Chat completions, Embeddings |
| Anthropic | patch_anthropic() | Messages, Completions |
| Mistral | patch_mistral() | Chat endpoints |
每个集成都有对应的 get_<vendor>_patcher() 函数用于获取补丁器实例。
资料来源:weave/integrations/patch.py
数据流架构
调用追踪数据流
sequenceDiagram
participant User as 用户代码
participant SDK as Weave SDK
participant Client as WeaveClient
participant Server as Trace Server
participant DB as ClickHouse
User->>SDK: 调用 op 包装函数
SDK->>Client: pushNewCall()
Client->>Client: 创建 CallContext
User->>SDK: 执行业务逻辑
SDK->>Client: finishCall(result)
Client->>Server: upsert_batch(calls)
Server->>DB: 批量写入
DB-->>Server: 确认写入
Server-->>Client: 响应流式响应处理
对于支持流式输出的 AI API,Weave 通过代理模式拦截 AsyncIterator:
const proxy = new Proxy(result, {
get: (target, prop) => {
if (prop === Symbol.asyncIterator) {
return WeaveIterator;
}
return Reflect.get(target, prop);
},
});
流式处理结合 StreamReducer 实现状态聚合和最终结果记录:
export interface StreamReducer<T, R> {
initialStateFn: () => R;
reduceFn: (state: R, chunk: T) => R;
finalizeFn: (state: R) => void;
}
资料来源:sdks/node/src/op.ts:150-200
配置系统
初始化配置
Weave 通过 init() 函数初始化追踪环境:
weave.init(
project_id: str, # 项目标识符
settings: dict | None = None # 配置字典
)
自动补丁配置
AutopatchSettings 类定义了各集成的独立配置:
class AutopatchSettings(BaseModel):
openai: IntegrationSettings = Field(default_factory=IntegrationSettings)
anthropic: IntegrationSettings = Field(default_factory=IntegrationSettings)
mistral: IntegrationSettings = Field(default_factory=IntegrationSettings)
# ... 其他集成
客户端设置
WeaveStorageSettings 控制客户端行为:
| 设置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
implicitly_patch_integrations | bool | True | 是否启用隐式集成补丁 |
should_print_call_link | bool | True | 是否打印调用链接 |
测试架构
Mock Trace Server
trace_server_mock 提供轻量级的内存 trace 服务器用于测试:
A[测试用例] --> B[启动 Mock Server]
B --> C[设置环境变量]
C --> D[执行测试逻辑]
D --> E[查询 /test/getCalls]
E --> F[断言验证]
F --> G[清理 Mock Server]
Mock 服务器支持以下测试专用端点:
| 端点 | 方法 | 用途 |
|---|---|---|
/test/health | GET | 健康检查 |
/test/getCalls | GET | 查询已记录的调用 |
/test/reset | POST | 重置测试数据 |
资料来源:trace_server_mock/README.md
VCR 录制机制
集成测试使用 pytest-recording 和 vcrpy 录制网络请求:
@pytest.mark.vcr(
filter_headers=["authorization"],
allowed_hosts=["api.wandb.ai", "localhost"],
)
def test_<vendor>_quickstart(
client: weave.weave_client.WeaveClient,
patch_<vendor>: None,
) -> None:
# 测试逻辑
录制模式支持 --record-mode=rewrite 重新生成录制文件。
序列化和反序列化
序列化架构
Weave 支持自定义类型的序列化和反序列化:
graph LR
A[Python 对象] -->|save| B[MemTraceFilesArtifact]
B --> C[序列化数据]
C --> D[HTTP 上传]
D --> E[Trace Server]
E --> F[ClickHouse 存储]
F --> G[加载请求]
G --> H[反序列化函数]
H --> I[load_my_type]
I --> J[Python 对象]自定义类型需通过 serializer.register_serializer() 注册保存和加载函数。
资料来源:weave/trace/serialization/README.md
关键设计模式
1. 代理模式
Op 包装使用 JavaScript Proxy 拦截 AsyncIterator 访问,实现流式响应的透明追踪。
2. 工厂模式
各集成通过 get_<vendor>_patcher() 工厂函数获取统一的 Patcher 实例。
3. 装饰器模式
Node.js SDK 支持 @weave.op 装饰器用于类方法的追踪包装:
class TestClass {
@weave.op
async logImage(image: WeaveImage) {
// 方法实现
}
}
4. 批量处理模式
Trace Server 采用批量写入优化,减少数据库 I/O 开销。
总结
Weave 系统架构围绕追踪核心,采用分层和模块化设计:
- SDK 层:提供 Python/Node.js 双端 API
- 客户端层:管理调用上下文和追踪状态
- 接口层:定义统一的 trace 数据交换协议
- 服务端层:实现高效的数据存储和查询
- 集成层:支持主流 AI 服务的自动追踪
架构设计强调透明性(无需修改业务代码)和可扩展性(支持自定义集成和类型),为 AI 应用提供无缝的可观测性能力。
资料来源:[weave/trace/weave_client.py](https://github.com/wandb/weave/blob/main/weave/trace/weave_client.py)
追踪数据流
追踪数据流(Trace Data Flow)是 Weave 框架中负责捕获、记录和传递 AI 应用执行信息的核心机制。它通过在函数调用前后插入钩子(Hook),将每次操作的输入、输出、执行时间和上下文信息收集起来,形成完整的调用链路追踪。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
追踪数据流(Trace Data Flow)是 Weave 框架中负责捕获、记录和传递 AI 应用执行信息的核心机制。它通过在函数调用前后插入钩子(Hook),将每次操作的输入、输出、执行时间和上下文信息收集起来,形成完整的调用链路追踪。
Weave 的追踪系统主要分为两个层面:
- Python SDK 层:基于
weave/trace目录下的核心组件,负责 Python 环境和第三方库的集成追踪 - Node SDK 层:基于
sdks/node/src/目录下的 TypeScript 实现,为 JavaScript/TypeScript 环境提供追踪能力
资料来源:README.md:1-20
核心数据类型
Op 类型定义
Op(Operation)是 Weave 追踪的基本单位,表示一个被追踪的函数或方法。其核心类型定义如下:
export type Op<T extends (...args: any[]) => any> = {
__isOp: true; // 类型标记
__wrappedFunction: T; // 原始函数引用
__boundThis?: WeaveObject; // 绑定的 this 对象
__name: string; // 操作名称
__savedRef?: OpRef | Promise<OpRef>; // Op 的持久化引用
__parameterNames?: ParameterNamesOption;// 参数名称配置
invoke: CallMethod<T>; // 调用方法
} & T;
资料来源:sdks/node/src/opType.ts:3-17
Call 类型
Call 表示一次函数调用的完整记录,包含调用 ID、时间戳、输入输出等信息:
export interface Call {
id: string;
traceId?: string;
parentId?: string;
startedAt: Date;
endedAt?: Date;
inputs?: Record<string, any>;
outputs?: Record<string, any>;
summary?: CallSummary;
attributes?: Record<string, any>;
opName?: string;
opRef?: OpRef;
}
OpRef 类型
OpRef 是操作的持久化引用,用于在 UI 中定位和分享特定的操作版本:
export class OpRef {
constructor(
public projectId: string,
public objectId: string,
public digest: string
) {}
public uri() {
return `weave:///${this.projectId}/op/${this.objectId}:${this.digest}`;
}
public ui_url() {
const domain = getGlobalDomain();
return `https://${domain}/${this.projectId}/weave/ops/${this.objectId}/versions/${this.digest}`;
}
}
资料来源:sdks/node/src/opType.ts:65-85
追踪流程架构
整体数据流图
graph TD
A[用户调用被追踪函数] --> B[Op Wrapper 拦截调用]
B --> C[创建 InternalCall 对象]
C --> D[推入新调用栈]
D --> E[记录开始时间戳]
E --> F[执行原始函数]
F --> G[收集返回值]
G --> H[记录结束时间戳]
H --> I[构建 Call 对象]
I --> J[发送到 Trace Server]
J --> K[返回结果给调用方]
L[异步迭代器场景] --> M[StreamReducer 处理]
M --> N[增量收集流式输出]
N --> O[组装完整输出]
O --> H调用上下文管理
Weave 使用全局客户端和上下文栈来管理调用层级关系:
interface CallContext {
currentCall: Call;
parentCall: Call | null;
newStack: boolean;
}
class WeaveClient {
// 推送新调用并获取上下文
pushNewCall(): CallContext {
// 创建新的 Call 对象
// 建立父子调用关系
// 返回上下文信息
}
}
资料来源:sdks/node/src/op.ts:30-80
Op 创建与包装
创建流程
当用户使用 @weave.op 装饰器或 op() 函数包装函数时,Weave 执行以下步骤:
sequenceDiagram
participant U as 用户代码
participant O as op() 函数
participant CP as createOpWrapper
participant IC as InternalCall
participant C as WeaveClient
U->>O: op(myFunction, options?)
O->>CP: createOpWrapper(myFunction, options)
CP->>IC: new InternalCall()
IC->>C: pushNewCall()
C-->>IC: 返回 CallContext
IC-->>CP: wrapped function
CP-->>O: Op<T> 对象
O-->>U: 可追踪的函数Op Wrapper 实现
核心的函数包装逻辑位于 createOpWrapper 函数中:
const opWrapper = async function (
this: any,
...params: Parameters<T>
): Promise<Awaited<ReturnType<T>>> {
const client = getGlobalClient();
// 检查客户端是否初始化
if (!client) {
warnOnce('weave-not-initialized', 'WARNING: Weave is not initialized...');
return await fn.apply(thisArg, params);
}
// 创建调用上下文
const {currentCall, parentCall, newStack} = client.pushNewCall();
const startTime = new Date();
// 打印调用链接(可选)
if (client.settings.shouldPrintCallLink && parentCall == null) {
console.log(`${TRACE_CALL_EMOJI} https://${domain}/${client.projectId}/r/call/${currentCall.callId}`);
}
// 执行原始函数
const result = await fn.apply(thisArg, params);
// 记录完成信息并发送
// ...
return result;
};
资料来源:sdks/node/src/op.ts:50-100
装饰器支持
Weave 支持两种装饰器模式:
| 装饰器类型 | 使用方式 | 代码示例 |
|---|---|---|
| Stage 3 装饰器 | @weave.op | @weave.op async method() |
| Legacy 装饰器 | @weave.op() | @weave.op() async method() |
| 装饰器工厂 | @weave.op(options) | @weave.op({name: 'custom'}) async method() |
// Stage 3 装饰器处理
function handleModernDecorator<T extends (...args: any[]) => any>(
originalMethod: T,
context: ClassMethodDecoratorContext,
factoryOptions?: Partial<OpOptions<T>>
): T {
const derivedName = `${String(context.name)}`;
const options = {
...factoryOptions,
isDecorator: true,
originalFunction: originalMethod,
context: context,
};
return createOpWrapper<T>(originalMethod, options);
}
资料来源:sdks/node/src/op.ts:150-200
异步迭代器支持
StreamReducer 接口
对于返回异步迭代器的函数(如流式 LLM 输出),Weave 使用 StreamReducer 接口进行处理:
export interface StreamReducer<T, R> {
initialStateFn: () => R; // 初始状态工厂
reduceFn: (state: R, chunk: T) => R; // 归约函数
finalizeFn: (state: R) => void; // 最终化函数
}
资料来源:sdks/node/src/opType.ts:18-24
并行流式处理
对于评估场景中的并行流式处理,Weave 提供了以下机制:
async function* asyncParallelMap<T, U>(
asyncIterator: AsyncIterable<T>,
fn: (item: T, ...args: any[]) => Promise<U>,
fnParams: (item: T) => any[],
maxConcurrency: number
) {
const itemPromiseMap: Map<T, Promise<{item: T; result: Awaited<U>}>> = new Map();
for await (const item of asyncIterator) {
// 控制并发数量
if (itemPromiseMap.size >= maxConcurrency) {
const done = await Promise.race(itemPromiseMap.values());
itemPromiseMap.delete(done.item);
yield { ...done, nRunning: itemPromiseMap.size, nDone: ++nDone };
}
const prom = runOne(item);
itemPromiseMap.set(item, prom);
}
// 处理剩余项目...
}
资料来源:sdks/node/src/evaluation.ts:40-70
集成追踪机制
隐式补丁模式
Weave 通过 sys.meta_path 拦截机制实现隐式补丁:
graph LR
A[import vendor_lib] --> B[meta_path 拦截]
B --> C[调用 patch_<vendor>()]
C --> D[SymbolPatcher 替换符号]
D --> E[vendor_lib 函数被追踪]显式补丁模式
当隐式补丁被禁用时,用户需要显式调用补丁函数:
import weave
# 初始化,禁用隐式补丁
weave.init("my-project", settings={'implicitly_patch_integrations': False})
# 显式启用追踪
weave.integrations.patch_openai()
weave.integrations.patch_anthropic()
weave.integrations.patch_mistral()
资料来源:weave/integrations/README.md:30-60
Patch 函数结构
每个集成需要实现 get_<vendor>_patcher 函数:
def get_<vendor>_patcher(
settings: IntegrationSettings | None = None,
) -> MultiPatcher | NoOpPatcher:
if settings is None:
settings = IntegrationSettings()
if not settings.enabled:
return NoOpPatcher()
global _<vendor>_patcher
if _<vendor>_patcher is None:
_<vendor>_patcher = MultiPatcher([
# 添加具体的补丁对象...
])
return _<vendor>_patcher
追踪服务端交互
批量上传接口
追踪数据通过 HTTP API 批量上传到 Trace Server:
sequenceDiagram
participant SDK as Weave SDK
participant TS as Trace Server
participant DB as In-Memory Store
SDK->>TS: POST /call/upsert_batch
TS->>DB: 存储调用记录
DB-->>TS: 确认存储
TS-->>SDK: 200 OK
Note over SDK,TS: 支持生产环境 API 格式模拟服务器
测试环境使用轻量级模拟 Trace Server:
READY=http://127.0.0.1:NNNN
主要端点:
| 端点 | 方法 | 用途 |
|---|---|---|
/call/upsert_batch | POST | 批量上传调用记录 |
/calls/stream_query | POST | 流式查询调用 |
/test/health | GET | 健康检查 |
/test/getCalls | GET | 获取调用列表(测试专用) |
/test/reset | POST | 重置存储(测试专用) |
资料来源:trace_server_mock/README.md:15-30
Callable 抽象
CallableObject 基类
Weave 提供了 CallableObject 抽象类,用于构建可追踪的自定义类型:
export interface Callable<I, O> {
run: (input: I) => Promise<O>;
}
export abstract class CallableObject<I, O>
extends WeaveObject
implements Callable<I, O>
{
abstract run(input: I): Promise<O>;
}
参数映射
提供了 mapArgs 工具函数用于参数重映射:
export function mapArgs<
T extends Record<string, any>,
M extends Record<string, keyof T>,
>(input: T, mapping: M): {[K in keyof M]: T[M[K]]} {
const result: Partial<{[K in keyof M]: T[M[K]]}> = {};
for (const [newKey, oldKey] of Object.entries(mapping)) {
if (oldKey in input) {
result[newKey as keyof M] = input[oldKey];
}
}
return result as {[K in keyof M]: T[M[K]]};
}
初始化与配置
项目初始化
使用 init 函数初始化追踪项目:
import {init} from 'weave';
await init('my-awesome-ai-project');
追踪选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
shouldPrintCallLink | boolean | - | 是否打印调用链接到控制台 |
implicitly_patch_integrations | boolean | true | 是否启用隐式集成补丁 |
callDisplayName | function | undefined | 自定义调用名称生成器 |
opKind | string | undefined | 操作类型标识 |
opColor | string | undefined | UI 显示颜色 |
操作装饰器选项
interface OpOptions<F extends (...args: any[]) => any> {
name?: string;
callDisplayName?: (args: Parameters<F>) => string;
bindThis?: any;
isDecorator?: boolean;
shouldAdoptThis?: boolean;
originalFunction?: F;
context?: ClassMethodDecoratorContext;
opKind?: string;
opColor?: string;
}
数据序列化
序列化策略
追踪数据支持多种序列化策略:
| 策略 | 适用场景 | 说明 |
|---|---|---|
| 文件序列化 | 大型对象(如图片) | 通过 MemTraceFilesArtifact 存储 |
| 内联序列化 | 小型对象(如 datetime) | 直接存储在 Call 对象中 |
内置序列化类型
Weave 内置以下第一类序列化器:
- 图片:
PIL.Image.Image - 音频:
wave.Wave_read - 操作:
weave.Op - 日期时间:
datetime.datetime - Markdown:
rich.markdown.Markdown
资料来源:weave/trace/serialization/README.md:20-35
调用链路追踪
父子调用关系
每次函数调用都会建立父子调用关系:
graph TD
A[根调用: extract_dinos] --> B[子调用: openai.chat.completions.create]
B --> C[子调用: model.invoke]
A --> D[子调用: post_process]
C --> D调用链接打印
当 shouldPrintCallLink 启用且为根调用时,系统会打印追踪链接:
const TRACE_CALL_EMOJI = '🔍';
console.log(
`${TRACE_CALL_EMOJI} https://${domain}/${client.projectId}/r/call/${currentCall.callId}`
);
错误处理
未初始化警告
当 Weave 未初始化时,追踪调用会被静默跳过:
if (!client) {
warnOnce(
'weave-not-initialized',
'WARNING: Weave is not initialized, so calls wont be tracked. Call `weave.init` to initialize before calling ops.'
);
return await fn.apply(thisArg, params);
}
补丁失败处理
对于未成功加载的集成,返回 NoOpPatcher:
if not settings.enabled:
return NoOpPatcher()
总结
Weave 的追踪数据流通过以下关键组件实现:
- Op 抽象层:提供统一的函数包装和追踪接口
- Call 上下文管理:维护调用栈和父子关系
- 集成补丁系统:支持第三方库的自动和手动追踪
- 异步迭代器处理:支持流式输出的增量追踪
- 序列化层:处理复杂数据类型的持久化
整个系统在 Python SDK 和 Node SDK 之间保持了架构一致性,同时针对各语言特性进行了优化适配。
资料来源:[README.md:1-20]()
函数追踪机制
函数追踪机制(Function Tracing Mechanism)是 Weave 框架的核心能力之一,用于自动捕获、记录和监控 AI 应用程序中函数的执行情况。该机制通过将普通函数包装为可追踪的 Op(操作)对象,实现对函数调用链路、输入输出、执行时间等关键信息的完整记录。
继续阅读本节完整说明和来源证据。
概述
函数追踪机制(Function Tracing Mechanism)是 Weave 框架的核心能力之一,用于自动捕获、记录和监控 AI 应用程序中函数的执行情况。该机制通过将普通函数包装为可追踪的 Op(操作)对象,实现对函数调用链路、输入输出、执行时间等关键信息的完整记录。
Weave 的函数追踪机制主要包含以下特性:
- 透明包装:通过装饰器或显式包装,将现有函数转换为可追踪的 Op
- 调用链路:自动维护父子调用关系,构建完整的调用树
- 属性标注:支持为操作添加分类标签(如
llm、agent、tool)和自定义颜色 - 流式支持:兼容异步生成器,可追踪流式输出的中间结果
- 集成支持:通过自动补丁机制,无缝集成第三方 SDK(如 OpenAI、Anthropic)
来源:https://github.com/wandb/weave / 项目说明书
评估系统
评估系统(Evaluation System)是 Weave 项目中用于评测 AI 模型和应用性能的核心模块。根据项目文档,评估相关代码主要位于 weave/flow 目录下,包括评分器(Scorer)、评估运行器(Evaluator)和排行榜(Leaderboard)三个主要组件。
继续阅读本节完整说明和来源证据。
概述
评估系统(Evaluation System)是 Weave 项目中用于评测 AI 模型和应用性能的核心模块。根据项目文档,评估相关代码主要位于 weave/flow 目录下,包括评分器(Scorer)、评估运行器(Evaluator)和排行榜(Leaderboard)三个主要组件。
评估系统的主要功能包括:
- 对模型输出进行自动化评分
- 支持自定义评分逻辑
- 运行批量评估任务
- 追踪和比较不同模型版本的表现
- 提供排行榜功能用于结果展示
资料来源:README.md
资料来源:[README.md](https://github.com/wandb/weave/blob/main/README.md)
评分器模块
根据对 Weave 仓库的分析,评分器模块(Scorers Module)是 Weave 评估系统的核心组件之一,负责对 AI 应用的输出结果进行量化评估。该模块位于 weave/scorers 目录下,为开发者提供了标准化的评估接口和多种开箱即用的评分器实现。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
根据对 Weave 仓库的分析,评分器模块(Scorers Module)是 Weave 评估系统的核心组件之一,负责对 AI 应用的输出结果进行量化评估。该模块位于 weave/scorers 目录下,为开发者提供了标准化的评估接口和多种开箱即用的评分器实现。
根据仓库结构,Weave 的评估代码主要集中在 weave/flow 目录中。资料来源:README.md:54
评分器模块的主要职责包括:
- 结果评分:对 LLM、Agent、Tool 等操作的输出进行标准化评分
- 多维度评估:支持单一指标和多维度综合评估
- 自定义扩展:允许开发者创建自定义评分器以满足特定业务需求
- 评估流程集成:与 Weave 的追踪系统无缝集成,支持端到端的可观测性
核心架构
模块目录结构
weave/scorers/
├── __init__.py
├── scorer_types.py # 评分器类型定义
├── llm_as_a_judge_scorer.py # LLM 评判评分器
├── classification_scorer.py # 分类评分器
└── [其他评分器实现]
设计模式
评分器模块采用面向对象的设计模式,定义了一套标准的评分器接口。所有评分器均继承自基类 Scorer,实现统一的评估方法。这种设计模式确保了评分器之间的可互换性和可扩展性。
内置评分器
LLM 即评判评分器 (LLM As A Judge Scorer)
LLMAsAJudgeScorer 是 Weave 提供的一种高级评分器,利用大型语言模型作为评判者来评估其他 LLM 输出的质量。这种方法被称为"LLM 评判"或"AI 评估",是 AI 系统评估领域的重要技术。
资料来源:weave/scorers/llm_as_a_judge_scorer.py
核心特性:
| 特性 | 说明 |
|---|---|
| 灵活 prompt 模板 | 支持自定义评估 prompt |
| 多维度评分 | 可同时评估多个维度 |
| 可解释性 | 提供评分理由 |
| 批量评估 | 支持批量处理多个样本 |
分类评分器 (Classification Scorer)
ClassificationScorer 专门用于评估分类任务的准确性。它通过比较模型预测结果与真实标签来计算各种分类指标。
资料来源:weave/scorers/classification_scorer.py
支持的评估指标:
| 指标名称 | 说明 |
|---|---|
| Accuracy | 分类准确率 |
| Precision | 精确率 |
| Recall | 召回率 |
| F1-Score | F1 分数 |
| Confusion Matrix | 混淆矩阵 |
评分器类型系统
评分器模块定义了一套完整的类型系统,用于规范化评分器的输入输出。
资料来源:weave/scorers/scorer_types.py
核心类型定义
# 评分结果类型
class ScoreResult:
name: str # 评分器名称
value: float # 评分值
reason: str # 评分理由
metadata: dict # 附加元数据
# 评分器基类
class Scorer(ABC):
@abstractmethod
async def score(self, input_data, output_data) -> ScoreResult:
pass
类型层级关系
graph TD
A[Scorer 基类] --> B[LLMAsAJudgeScorer]
A --> C[ClassificationScorer]
A --> D[CustomScorer]
B --> E[单一维度评判]
B --> F[多维度评判]
C --> G[二分类]
C --> H[多分类]评分器工作流程
评估流程图
graph TD
A[输入数据] --> B[选择评分器]
B --> C[LLM 评判]
B --> D[分类评估]
B --> E[自定义评估]
C --> F[生成评估 Prompt]
D --> G[计算分类指标]
E --> H[执行业务逻辑]
F --> I[调用 LLM API]
G --> J[输出评分结果]
H --> J
I --> J
J --> K[返回 ScoreResult]异步评分流程
评分器采用异步设计,支持高并发评估场景:
sequenceDiagram
participant Client as 客户端
participant Scorer as 评分器
participant LLM as LLM API
participant Weave as Weave 追踪
Client->>Scorer: 提交评分请求
Scorer->>Scorer: 验证输入
Scorer->>LLM: 发送评估请求
LLM-->>Scorer: 返回评估结果
Scorer->>Weave: 记录评估过程
Scorer-->>Client: 返回 ScoreResult与追踪系统集成
评分器模块与 Weave 的追踪系统深度集成,提供了完整的可观测性支持。
集成方式
- 自动追踪:评分器的执行过程自动记录到 Weave 追踪服务器
- 上下文传递:评分器可以访问被评分操作的完整上下文信息
- 结果关联:评分结果与原始调用自动关联
# 评分器使用示例
import weave
@weave.op()
async def my_evaluation(input_data):
# 使用评分器评估
scorer = LLMAsAJudgeScorer(prompt_template=my_template)
result = await scorer.score(input_data, model_output)
return result
资料来源:sdks/node/src/opType.ts:1-30
扩展评分器
创建自定义评分器
开发者可以通过继承 Scorer 基类来创建自定义评分器:
from weave.scorers import Scorer, ScoreResult
class MyCustomScorer(Scorer):
def __init__(self, config):
self.config = config
async def score(self, input_data, output_data) -> ScoreResult:
# 自定义评分逻辑
score_value = self.calculate_score(output_data)
return ScoreResult(
name="my_custom_scorer",
value=score_value,
reason="Custom evaluation reason",
metadata={"config": self.config}
)
评分器配置选项
| 配置项 | 类型 | 说明 | 默认值 |
|---|---|---|---|
name | str | 评分器名称 | 类名 |
description | str | 评分器描述 | 空字符串 |
threshold | float | 通过阈值 | 0.0 |
aggregation | str | 聚合方式 | "mean" |
最佳实践
1. 选择合适的评分器
| 场景 | 推荐评分器 |
|---|---|
| LLM 输出质量评估 | LLMAsAJudgeScorer |
| 分类模型评估 | ClassificationScorer |
| 自定义业务逻辑 | CustomScorer |
2. 性能优化建议
- 批量评分:使用批量接口减少 API 调用开销
- 异步执行:充分利用异步能力提高吞吐量
- 缓存结果:对于相同输入,可考虑缓存评分结果
3. 评估结果分析
评分结果应包含:
- 原始分数值
- 详细的评分理由
- 相关的元数据
- 与其他评估维度的关联信息
总结
评分器模块是 Weave 评估系统的基础组件,提供了标准化、可扩展的评估能力。通过内置的 LLM 评判评分器和分类评分器,开发者可以快速构建 AI 应用的评估流程。同时,该模块支持深度定制,满足各种复杂的业务评估需求。
与 Weave 的追踪系统集成后,评分器不仅能够提供量化评估结果,还能记录完整的评估上下文,为 AI 应用的持续优化提供了数据基础。
资料来源:[weave/scorers/llm_as_a_judge_scorer.py]()
模型供应商集成
模型供应商集成(Model Vendor Integration)是 Weave 框架中用于自动追踪和监控第三方 AI 模型供应商 SDK 调用的一种机制。通过隐式补丁(Implicit Patching)和显式补丁(Explicit Patching)两种模式,开发者可以在几乎不修改业务代码的情况下,将 OpenAI、Anthropic、Google GenAI、Mist...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
模型供应商集成(Model Vendor Integration)是 Weave 框架中用于自动追踪和监控第三方 AI 模型供应商 SDK 调用的一种机制。通过隐式补丁(Implicit Patching)和显式补丁(Explicit Patching)两种模式,开发者可以在几乎不修改业务代码的情况下,将 OpenAI、Anthropic、Google GenAI、Mistral 等主流 AI 服务商的 API 调用自动记录到 Weave 追踪系统中。
集成架构的核心设计理念是:零侵入式追踪。Weave 通过 Python 的 sys.meta_path 导入钩子机制,在支持的供应商库被导入时自动应用补丁,使追踪功能对业务代码完全透明。
资料来源:weave/integrations/README.md:1-30
架构设计
整体架构图
graph TD
A[用户代码] -->|import weave| B[Weave 初始化]
B --> C{隐式补丁启用?}
C -->|是| D[sys.meta_path 导入钩子]
C -->|否| E[手动调用 patch_xxx]
D --> F[供应商库导入]
F --> G[自动调用 patch_xxx]
G --> H[Monkey Patch 注入]
H --> I[API 调用拦截]
I --> J[Weave Client]
J --> K[Trace Server]
E --> L[手动 patch 函数]
L --> H核心组件
| 组件 | 文件路径 | 职责 |
|---|---|---|
| Patcher 基类 | weave/integrations/patcher.py | 定义统一补丁接口 |
| Patch 注册器 | weave/integrations/patch.py | 统一暴露各供应商 patch 函数 |
| Autopatch 机制 | weave/trace/autopatch.py | 管理隐式补丁配置 |
| 供应商 SDK 包装器 | weave/integrations/<vendor>/<vendor>_sdk.py | 具体供应商的追踪实现 |
资料来源:weave/integrations/patch.py:1-50
集成注册机制
供应商集成结构
每个供应商集成都遵循统一的项目结构:
weave/integrations/
├── __init__.py
├── openai/
│ ├── __init__.py
│ ├── openai_sdk.py
│ └── openai_test.py
├── anthropic/
│ ├── __init__.py
│ ├── anthropic_sdk.py
│ └── anthropic_test.py
├── google_genai/
│ ├── __init__.py
│ ├── google_genai_sdk.py
│ └── google_genai_test.py
└── mistral/
├── __init__.py
├── mistral_sdk.py
└── mistral_test.py
资料来源:weave/integrations/README.md:45-60
注册新供应商集成
开发新的供应商集成需要完成以下步骤:
- 在
weave/integrations/下创建供应商文件夹 - 实现
<vendor>_sdk.py核心补丁逻辑 - 在
patch.py中注册 patch 函数 - 在
AutopatchSettings中添加配置字段
#### Step 1: 创建 patch 函数
在 weave/integrations/patch.py 中添加:
def patch_<vendor>(settings: IntegrationSettings | None = None) -> None:
"""Enable Weave tracing for <Vendor>."""
from weave.integrations.<vendor>.<vendor>_sdk import get_<vendor>_patcher
if settings is None:
settings = IntegrationSettings()
get_<vendor>_patcher(settings).attempt_patch()
资料来源:weave/integrations/README.md:60-85
#### Step 2: 添加配置支持
在 weave/trace/autopatch.py 的 AutopatchSettings 类中添加:
class AutopatchSettings(BaseModel):
# ... existing fields ...
<vendor>: IntegrationSettings = Field(default_factory=IntegrationSettings)
资料来源:weave/integrations/README.md:100-110
补丁机制详解
隐式补丁(Implicit Patching)
隐式补丁通过 Python 的 sys.meta_path 导入钩子实现。当 weave.init() 被调用时,Weave 注册一个自定义的导入finder,该 finder 会拦截对支持供应商库的导入请求。
# 启用隐式补丁(默认行为)
weave.init("my-project")
import openai # 自动被追踪!
# 禁用隐式补丁
weave.init("my-project", settings={'implicitly_patch_integrations': False})
资料来源:weave/integrations/README.md:25-40
显式补丁(Explicit Patching)
显式补丁允许开发者手动控制何时启用追踪:
import weave
# 初始化时禁用隐式补丁
weave.init("my-project", settings={'implicitly_patch_integrations': False})
# 显式启用特定集成
weave.integrations.patch_openai()
weave.integrations.patch_anthropic()
weave.integrations.patch_mistral()
# 使用供应商 SDK
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(...) # 会被追踪
资料来源:weave/integrations/README.md:40-55
补丁执行流程
sequenceDiagram
participant U as 用户代码
participant P as Patcher
participant V as 供应商 SDK
participant W as Weave Client
U->>P: attempt_patch()
P->>V: 获取目标方法
P->>P: 保存原始方法引用
P->>V: 注入包装方法
U->>V: 调用 API
V->>W: 记录调用信息
W->>U: 返回结果
Note over P: undo_patch() 可恢复原始行为供应商 SDK 包装模式
OpenAI 包装
OpenAI 集成通过 Monkey Patch 方式包装 openai.OpenAI 客户端的关键方法:
chat.completions.create→ 包装为 Op- 流式响应通过
streamReducer处理
def wrapOpenAI(openai: OpenAI): T {
// 包装 chat.completions.create
return wrappedClient
}
Google GenAI 包装
Google GenAI 集成使用 Proxy 模式包装 models 对象:
const wrappedModels = new Proxy(models, {
get(target, prop, receiver) {
if (prop === 'generateContent') {
return wrappedGenerateContent;
}
if (prop === 'generateContentStream') {
return wrappedGenerateContentStream;
}
return Reflect.get(target, prop, receiver);
},
});
资料来源:sdks/node/src/integrations/googleGenAI.ts:80-95
Op 包装器设计
Weave 的核心追踪单元是 Op(操作)。Op 包装器接口定义如下:
export interface OpWrapper<F extends (...args: any[]) => any> {
(this: any, ...params: Parameters<F>): AsyncResult<F>;
}
export interface CallMethod<F extends (...args: any[]) => any> {
(
this: any,
...params: Parameters<F>
): Promise<[Awaited<ReturnType<F>>, Call]>;
}
Op 包装器支持多种使用模式:
| 模式 | 签名 | 用途 |
|---|---|---|
| 函数包装 | op(fn) | 装饰器风格 |
| 选项包装 | op(fn, options) | 自定义配置 |
| 装饰器工厂 | @op(options) | Stage 3 装饰器 |
| 传统装饰器 | @op | 兼容旧语法 |
资料来源:sdks/node/src/opType.ts:40-75
配置管理
IntegrationSettings
每个供应商集成都有独立的配置对象:
class IntegrationSettings(BaseModel):
enabled: bool = True
# 供应商特定配置选项
AutopatchSettings
class AutopatchSettings(BaseModel):
openai: IntegrationSettings = Field(default_factory=IntegrationSettings)
anthropic: IntegrationSettings = Field(default_factory=IntegrationSettings)
mistral: IntegrationSettings = Field(default_factory=IntegrationSettings)
# 新供应商...
环境变量配置
| 变量名 | 值 | 作用 |
|---|---|---|
WEAVE_IMPLICITLY_PATCH_INTEGRATIONS | true/false | 全局控制隐式补丁 |
资料来源:weave/integrations/README.md:28-35
测试框架
VCR 测试模式
Weave 使用 pytest-recording(基于 vcrpy)进行集成测试:
@pytest.mark.vcr(
filter_headers=["authorization"],
allowed_hosts=["api.wandb.ai", "localhost"],
)
def test_<vendor>_quickstart(
client: weave.weave_client.WeaveClient,
patch_<vendor>: None,
) -> None:
# 测试代码
calls = list(client.get_calls())
assert len(calls) == 1
测试夹具
@pytest.fixture()
def patch_<vendor>() -> Generator[None, None, None]:
from weave.integrations.<vendor>.<vendor>_sdk import get_<vendor>_patcher
patcher = get_<vendor>_patcher()
patcher.attempt_patch()
yield
patcher.undo_patch()
资料来源:weave/integrations/README.md:120-140
运行测试
# 录制模式
MISTRAL_API_KEY=... pytest --record-mode=rewrite weave/integrations/mistral/mistral_test.py
# 重放模式
pytest weave/integrations/mistral/mistral_test.py
# 生产环境测试
MISTRAL_API_KEY=... pytest --trace-server=prod weave/integrations/mistral/mistral_test.py
资料来源:weave/integrations/README.md:145-155
Trace Server 接口
核心端点
| 端点 | 方法 | 用途 |
|---|---|---|
/call/upsert_batch | POST | 批量记录调用 |
/calls/stream_query | POST | 查询调用历史 |
/test/health | GET | 健康检查 |
Mock Server
测试使用内存中的 mock server,支持:
- 项目隔离(通过
project_id) - 调用记录查询
- 状态重置
资料来源:trace_server_mock/README.md:1-40
Op 选项配置
可用选项
export interface OpOptions<T extends (...args: any[]) => any> {
name?: string; // 自定义操作名称
streamReducer?: StreamReducer; // 流式响应处理
originalFunction?: T; // 原始函数引用
callDisplayName?: Function; // 动态显示名称
summarize?: Function; // 结果摘要生成
bindThis?: WeaveObject; // this 绑定
parameterNames?: ParameterNamesOption; // 参数命名
opKind?: string; // 操作类型(llm/agent/tool/search)
opColor?: string; // UI 颜色
}
资料来源:sdks/node/src/opType.ts:80-105
流式响应处理
export interface StreamReducer<T, R> {
initialStateFn: () => R;
reduceFn: (state: R, chunk: T) => R;
finalizeFn: (state: R) => void;
}
开发指南
添加新供应商的检查清单
- ✅ 创建
weave/integrations/<vendor>/目录 - ✅ 实现
<vendor>_sdk.py(继承 Patcher 基类) - ✅ 在
patch.py中添加patch_<vendor>()函数 - ✅ 在
AutopatchSettings中注册配置 - ✅ 创建
<vendor>_test.py测试文件 - ✅ 运行测试并录制 VCR cassettes
- ✅ 验证追踪数据正确性
常见问题排查
| 问题 | 解决方案 |
|---|---|
| 补丁未生效 | 检查 implicitly_patch_integrations 设置 |
| API Key 错误 | 使用环境变量或设置 dummy key |
| 测试失败 | 确认 VCR cassettes 录制完整 |
| 重复追踪 | 避免多次调用 attempt_patch() |
资料来源:weave/integrations/README.md:140-160
相关资源
资料来源:[weave/integrations/README.md:1-30]()
框架集成
框架集成(Framework Integration)是 Weave 为第三方 AI 框架和 SDK 提供的自动追踪支持机制。通过在 weave/integrations/ 目录下实现的集成模块,Weave 能够自动拦截和记录用户使用 LangChain、DSPy、LlamaIndex、CrewAI、AutoGen 等主流 AI 框架时的 API 调用,将这些调用以结构化的...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
框架集成(Framework Integration)是 Weave 为第三方 AI 框架和 SDK 提供的自动追踪支持机制。通过在 weave/integrations/ 目录下实现的集成模块,Weave 能够自动拦截和记录用户使用 LangChain、DSPy、LlamaIndex、CrewAI、AutoGen 等主流 AI 框架时的 API 调用,将这些调用以结构化的方式记录到 Weave Trace Server 中。
集成的核心价值在于零侵入性——用户无需修改原有代码,通过隐式补丁(Implicit Patching)或显式调用补丁函数,即可启用追踪功能。这种设计使得追踪能力的添加变得透明且可配置。
目录结构
每个框架集成都遵循统一的目录结构规范:
weave/integrations/
├── __init__.py
├── patch.py # 所有补丁函数的统一入口
├── langchain/
│ ├── __init__.py
│ ├── langchain.py # LangChain 集成核心实现
│ └── langchain_test.py # 集成测试
├── dspy/
│ ├── __init__.py
│ ├── dspy_callback.py # DSPy 回调实现
│ └── dspy_test.py
├── llamaindex/
│ ├── __init__.py
│ ├── llamaindex.py # LlamaIndex 集成核心
│ └── llamaindex_test.py
├── crewai/
│ ├── __init__.py
│ ├── crewai_sdk.py # CrewAI SDK 集成
│ └── crewai_test.py
└── autogen/
├── __init__.py
├── autogen_sdk.py # AutoGen 集成
└── autogen_test.py
核心架构
集成架构图
graph TD
A[用户代码] --> B[Weave 初始化]
B --> C{隐式补丁启用?}
C -->|是| D[修改 sys.meta_path]
C -->|否| E[手动调用 patch_* 函数]
D --> F[import hook 拦截]
F --> G[Vendor SDK 导入]
G --> H[自动调用对应 patcher]
E --> I[调用 patch_<vendor>]
I --> J[attempt_patch 执行]
H --> J
J --> K[Monkey Patch SDK]
K --> L[API 调用拦截]
L --> M[Call 记录创建]
M --> N[Trace Server 上报]
O[patch_<vendor> 函数] --> P[get_<vendor>_patcher]
P --> Q[Patcher 实例]
Q --> R[attempt_patch]
Q --> S[undo_patch]组件职责
| 组件 | 职责 | 典型实现位置 |
|---|---|---|
patch.py | 统一导出所有补丁函数 | weave/integrations/patch.py |
<vendor>_sdk.py | 核心补丁逻辑实现 | 各框架目录下 |
IntegrationSettings | 集成配置数据模型 | weave/integrations/ |
AutopatchSettings | 全局自动补丁配置 | weave/trace/autopatch.py |
WeaveCallback | 框架特定的回调处理器 | 各框架目录 |
补丁机制
隐式补丁流程
当用户初始化 Weave 并设置 implicitly_patch_integrations=True(默认值)时,Weave 会修改 Python 的 sys.meta_path 导入钩子链:
sequenceDiagram
participant User as 用户代码
participant Hook as MetaPath Finder
participant Patch as patch_<vendor>
participant SDK as Vendor SDK
participant Weave as Weave Tracing
User->>Weave: weave.init("project")
Weave->>Hook: 注册 Import Hook
User->>SDK: import openai
Hook->>Patch: 拦截导入
Patch->>Patch: attempt_patch()
Patch->>SDK: Monkey Patch
SDK-->>User: 返回 patched 模块
User->>SDK: client.chat.completions.create()
SDK->>Weave: 触发 WeaveCallback
Weave->>Weave: 记录 Call显式补丁接口
用户也可以禁用隐式补丁,手动选择要追踪的框架:
import weave
# 禁用隐式补丁
weave.init("my-project", settings={'implicitly_patch_integrations': False})
# 显式启用特定框架追踪
weave.integrations.patch_openai()
weave.integrations.patch_anthropic()
weave.integrations.patch_langchain()
weave.integrations.patch_llamaindex()
weave.integrations.patch_dspy()
weave.integrations.patch_crewai()
weave.integrations.patch_autogen()
每个补丁函数的签名遵循统一规范:
def patch_<vendor>(settings: IntegrationSettings | None = None) -> None:
"""启用 <Vendor> 的 Weave 追踪。"""
from weave.integrations.<vendor>.<vendor>_sdk import get_<vendor>_patcher
if settings is None:
settings = IntegrationSettings()
get_<vendor>_patcher(settings).attempt_patch()
配置系统
集成配置类
每个框架都有对应的配置类,用于控制追踪行为:
class IntegrationSettings(BaseModel):
"""集成配置基类。"""
enabled: bool = True
capture_input: bool = True
capture_output: bool = True
tags: list[str] = []
全局自动补丁配置
AutopatchSettings 类管理所有集成的全局配置:
class AutopatchSettings(BaseModel):
enabled: bool = True
openai: IntegrationSettings = Field(default_factory=IntegrationSettings)
anthropic: IntegrationSettings = Field(default_factory=IntegrationSettings)
langchain: IntegrationSettings = Field(default_factory=IntegrationSettings)
llamaindex: IntegrationSettings = Field(default_factory=IntegrationSettings)
dspy: IntegrationSettings = Field(default_factory=IntegrationSettings)
crewai: IntegrationSettings = Field(default_factory=IntegrationSettings)
autogen: IntegrationSettings = Field(default_factory=IntegrationSettings)
配置方式
| 方式 | 代码示例 | 优先级 |
|---|---|---|
| 初始化参数 | weave.init(project, settings={...}) | 高 |
| 环境变量 | WEAVE_IMPLICITLY_PATCH_INTEGRATIONS=false | 中 |
| 默认值 | IntegrationSettings() 构造 | 低 |
框架特定集成
LangChain 集成
LangChain 集成通过实现自定义 Callback Handler 来拦截 LLM 调用:
# weave/integrations/langchain/langchain.py
class WeaveCallbackHandler(BaseCallbackHandler):
"""LangChain 的 Weave 回调处理器。"""
def __init__(self, settings: IntegrationSettings | None = None):
self.settings = settings or IntegrationSettings()
# 初始化追踪上下文...
def on_llm_start(self, serialized, prompts, **kwargs):
"""LLM 调用开始时记录。"""
# 创建 Call 记录...
def on_llm_end(self, response, **kwargs):
"""LLM 调用完成时记录结果。"""
# 结束 Call 记录...
DSPy 集成
DSPy 集成使用回调机制捕获模块执行:
# weave/integrations/dspy/dspy_callback.py
class WeaveCallback:
"""DSPy 的 Weave 回调实现。"""
def __init__(self):
self._calls = []
def before_forward(self, program, inputs):
"""模块前向传播前记录。"""
pass
def after_forward(self, program, outputs):
"""模块前向传播后记录。"""
pass
LlamaIndex 集成
# weave/integrations/llamaindex/llamaindex.py
class WeaveCallbackHandler(BaseCallbackHandler):
"""LlamaIndex 的 Weave 回调处理器。"""
def on_event_start(self, event_type, payload, **kwargs):
"""事件开始时记录。"""
pass
def on_event_end(self, event_type, payload, **kwargs):
"""事件结束时记录。"""
pass
CrewAI 集成
# weave/integrations/crewai/crewai_sdk.py
def get_crewai_patcher(settings: IntegrationSettings | None = None) -> Patcher:
"""获取 CrewAI 的补丁实例。"""
return CrewAIHandler(settings)
AutoGen 集成
# weave/integrations/autogen/autogen_sdk.py
class WeaveAutoGenCallback:
"""AutoGen 的 Weave 回调实现。"""
def __init__(self, settings: IntegrationSettings | None = None):
self.settings = settings or IntegrationSettings()
补丁器模式
每个框架的集成都遵循统一的 Patcher 模式:
classDiagram
class Patcher {
+settings: IntegrationSettings
+attempt_patch(): None
+undo_patch(): None
#_do_patch(): None
#_do_unpatch(): None
}
class LangChainPatcher {
+attempt_patch(): None
+undo_patch(): None
}
class DSPyPatcher {
+attempt_patch(): None
+undo_patch(): None
}
class LlamaIndexPatcher {
+attempt_patch(): None
+undo_patch(): None
}
Patcher <|-- LangChainPatcher
Patcher <|-- DSPyPatcher
Patcher <|-- LlamaIndexPatcherPatcher 接口规范
| 方法 | 参数 | 返回 | 说明 |
|---|---|---|---|
get_<vendor>_patcher | settings: IntegrationSettings | Patcher | 工厂函数,返回补丁器实例 |
attempt_patch | 无 | None | 执行补丁,拦截 SDK 调用 |
undo_patch | 无 | None | 撤销补丁,恢复原始实现 |
测试框架
测试工具链
集成测试使用 pytest-recording 和 vcrpy 来录制和回放网络请求:
@pytest.mark.vcr(
filter_headers=["authorization"],
allowed_hosts=["api.wandb.ai", "localhost"],
)
def test_<vendor>_quickstart(
client: weave.weave_client.WeaveClient,
patch_<vendor>: None,
) -> None:
"""框架快速开始测试。"""
# 执行框架操作...
calls = list(client.get_calls())
assert len(calls) == 1
测试 Fixtures
@pytest.fixture()
def patch_<vendor>() -> Generator[None, None, None]:
"""自动应用和清理补丁。"""
from weave.integrations.<vendor>.<vendor>_sdk import get_<vendor>_patcher
patcher = get_<vendor>_patcher()
patcher.attempt_patch()
yield
patcher.undo_patch()
运行测试
# 录制模式
pytest --record-mode=rewrite weave/integrations/<vendor>/<vendor>_test.py
# 回放模式(默认)
pytest weave/integrations/<vendor>/<vendor>_test.py
# 使用生产 Trace Server
pytest --trace-server=prod weave/integrations/<vendor>/<vendor>_test.py
数据流
Call 记录流程
graph LR
A[Framework API Call] --> B[WeaveCallback]
B --> C[创建 Call.start]
C --> D[执行原始调用]
D --> E[获取响应]
E --> F[创建 Call.end]
F --> G[序列化为 JSON]
G --> H[上传到 Trace Server]
H --> I[存储到数据库]序列化的数据类型
| 类型 | 存储方式 | 说明 |
|---|---|---|
| 小型对象 | Inline | 直接存储在 Call 记录中 |
| 大型对象 | 文件 | 存储为 MemTraceFilesArtifact |
| 图像 | 文件 | 使用 PIL 序列化 |
| 音频 | 文件 | 使用 wave 模块序列化 |
| Op | 内联 | 存储为 Op 类型引用 |
开发新集成
开发步骤
- 创建目录结构:在
weave/integrations/下创建新框架的目录 - 实现
<vendor>_sdk.py:包含get_<vendor>_patcher工厂函数 - 注册补丁函数:在
weave/integrations/patch.py中添加导出 - 添加配置支持:在
AutopatchSettings中添加新字段 - 编写测试:使用 pytest-recording 录制网络请求
- 运行测试:验证集成正确工作
最小集成模板
# weave/integrations/<vendor>/<vendor>_sdk.py
from weave.integrations import IntegrationSettings, Patcher
class <Vendor>Patcher(Patcher):
def __init__(self, settings: IntegrationSettings | None = None):
self.settings = settings or IntegrationSettings()
self._original = None
def attempt_patch(self) -> None:
"""应用补丁。"""
# 1. 保存原始实现
# 2. Monkey Patch 新实现
pass
def undo_patch(self) -> None:
"""撤销补丁。"""
# 恢复原始实现
pass
def get_<vendor>_patcher(
settings: IntegrationSettings | None = None
) -> <Vendor>Patcher:
return <Vendor>Patcher(settings)
环境变量
| 变量名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
WEAVE_IMPLICITLY_PATCH_INTEGRATIONS | bool | true | 是否启用隐式补丁 |
WEAVE_DISPLAY_VIEWER | string | auto | 显示查看器配置 |
<VENDOR>_API_KEY | string | - | 各框架的 API 密钥 |
限制与注意事项
- 线程安全:部分集成可能存在线程安全问题,高并发场景下需谨慎使用
- 版本兼容:框架更新可能导致集成失效,需保持版本同步
- 性能开销:自动追踪会带来一定的性能开销,生产环境可选择性禁用
- 数据脱敏:敏感信息(如 API Key)需通过
filter_headers配置进行过滤
来源:https://github.com/wandb/weave / 项目说明书
数据序列化
数据序列化(Serialization)是 Weave 追踪系统中的核心基础设施,负责将 Python 对象转换为 JSON 可序列化的格式,以便在客户端与服务器之间传输,并在需要时将数据还原为原始 Python 对象。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
数据序列化(Serialization)是 Weave 追踪系统中的核心基础设施,负责将 Python 对象转换为 JSON 可序列化的格式,以便在客户端与服务器之间传输,并在需要时将数据还原为原始 Python 对象。
Weave 的序列化系统支持多种数据类型,包括 Python 原生类型(int、float、str、bool、None)、集合类型(list、tuple、dict)、自定义对象以及"可字典化"(dictifiable)的对象。资料来源:weave/trace/serialization/README.md
核心组件
序列化入口点
序列化系统的主要入口点是 weave/trace/serialization/serialize.py,该文件包含两个核心函数:
| 函数 | 功能 | 可逆性 |
|---|---|---|
to_json() | 将 Python 对象转换为 JSON 可序列化格式 | 是 |
from_json() | 将 JSON 数据还原为 Python 对象 | 是 |
资料来源:weave/trace/serialization/README.md
自定义对象序列化模块
weave/trace/serialization/custom_objs.py 是处理自定义对象序列化的主要模块,包含以下关键函数:
| 函数 | 功能 |
|---|---|
encode_custom_obj() | 使用注册的序列化器编码自定义对象(支持内联和文件两种方式) |
decode_custom_inline_obj() | 解码内联自定义对象 |
decode_custom_obj() | 解码基于文件的自定义对象 |
资料来源:weave/trace/serialization/README.md
内存追踪文件工件
MemTraceFilesArtifact 类负责文件-based 序列化的读写操作。当保存自定义对象时,数据被写入工件文件;当需要还原对象时,数据从工件文件中读取。
def _my_type(artifact: MemTraceFilesArtifact, name: str) -> MyCustomType:
# Load the object's data from the file in the artifact
with artifact.open(f"{name}.txt") as f:
value = f.read()
return MyCustomType(value)
资料来源:weave/trace/serialization/README.md
序列化类型支持
Python 原生类型
| 类型 | 可逆性 | 说明 |
|---|---|---|
| int | ✓ | 整数 |
| float | ✓ | 浮点数 |
| str | ✓ | 字符串 |
| bool | ✓ | 布尔值 |
| None | ✓ | 空值 |
集合类型
| 类型 | 可逆性 | 说明 |
|---|---|---|
| list | ✓ | 列表 |
| tuple | ✓ | 元组 |
| dict | ✓ | 字典 |
注册的自定义对象
通过 custom_objs 模块注册的自定义对象具有可逆性,前提是序列化器已正确注册。
任意 Python 对象
任意 Python 对象(未注册序列化器)无法被序列化还原。
可字典化对象
"Dictifiable"对象只能部分还原,最终还原为字典而非原始类型。
资料来源:weave/trace/serialization/README.md
序列化流程
整体序列化流程
Weave 的序列化采用客户端-服务端架构,数据在用户代码与服务器存储之间流转:
flowchart LR
UserCode1["用户代码"] -->|"Python 对象"| WeaveClient
subgraph WeaveClient["Weave 客户端"]
ClientSave["client.save()"] --> ToJson["to_json()"]
ToJson -->|"JSON 数据"| ServerStorage["服务器存储"]
ServerStorage -->|"JSON 数据"| FromJson["from_json()"]
FromJson --> ClientGet["client.get()"]
end
WeaveClient -->|"Python 对象"| UserCode2["用户代码"]自定义对象序列化流程
对于基于文件的自定义对象,序列化过程涉及注册序列化器、写入工件文件、解码还原等步骤:
flowchart TD
CustomObj["自定义对象<br/>(PIL.Image.Image, wave.Wave_read 等)"] --> ToJson["to_json()"]
ToJson --> EncodeCustomObj["encode_custom_obj()"]
subgraph CustomSerialization["自定义对象序列化过程"]
EncodeCustomObj --> Serializer["已注册的序列化器<br/>(save 方法)"]
Serializer -->|"写入文件"| MemArtifact["MemTraceFilesArtifact"]
MemArtifact -->|"读取文件"| Deserializer["已注册的序列化器<br/>(load 方法)"]
Deserializer --> DecodeCustomObj["decode_custom_obj()"]
end
DecodeCustomObj --> FromJson["from_json()"]
FromJson --> ReconstructedObj["还原的自定义对象"]
RegisterSerializer["register_serializer()"] -.->|"注册"| Serializer
RegisterSerializer -.->|"注册"| Deserializer资料来源:weave/trace/serialization/README.md
自定义类型注册机制
注册序列化器
Weave 允许用户为自定义类型指定 save 和 load 方法,实现与追踪系统的集成:
from weave.trace.serialization import serializer
# 为自定义类型注册序列化器
serializer.register_serializer(MyCustomType, save_my_type, load_my_type)
序列化器定义
自定义序列化器需要实现两个核心函数:
保存函数(save_my_type):
def save_my_type(obj: MyCustomType, artifact: MemTraceFilesArtifact) -> None:
# 将对象写入工件文件
with artifact.open("my_type.txt", "w") as f:
f.write(obj.value)
加载函数(load_my_type):
def load_my_type(artifact: MemTraceFilesArtifact) -> MyCustomType:
# 从工件文件读取数据并还原对象
with artifact.open("my_type.txt") as f:
value = f.read()
return MyCustomType(value)
资料来源:weave/trace/serialization/README.md
序列化模式
内联序列化
对于序列化表示较小的对象(如 Python datetime 对象),序列化系统会将值直接"内联"存储,与其他序列化信息(如类名、反序列化 Op)一起存储。这种方式避免了额外的 API 请求来检索值。
基于文件的序列化
较大的值(如图片)通常使用基于文件的序列化方式。技术层面支持每个工件包含多个文件,但目前实践中每个工件只使用一个文件(obj.py)。
资料来源:weave/trace/serialization/README.md
第一类序列化类型
Weave 内置了对以下常见类型的序列化支持,这些类型定义在 weave/type_handlers/ 目录中:
| 类型 | 处理类 | 用途 |
|---|---|---|
| PIL.Image.Image | 图像处理器 | 图片数据序列化 |
| wave.Wave_read | 音频处理器 | 音频数据序列化 |
| weave.Op | Op 处理器 | 操作对象序列化 |
| datetime.datetime | 日期时间处理器 | 日期时间对象序列化 |
| rich.markdown.Markdown | Markdown 处理器 | Markdown 内容序列化 |
这些 KNOWN_TYPES 使用 register_serializer 实现。与其他类型不同的是,这些类型始终使用 SDK 当前的 load 函数进行加载,而非使用对象包中的加载函数。
资料来源:weave/trace/serialization/README.md
跨运行时兼容性
当保存自定义对象时,Weave 还会将 load 函数作为 Op 保存到对象中。这使得对象可以在未注册序列化器的 Python 运行时中进行反序列化,只要必要的依赖可用。这是以"最大努力"方式实现的,如果任何依赖不可用,对象将无法加载。
目前 Weave 不保存依赖的锁定文件,但未来可能考虑添加此功能以提供更好的可移植性。
资料来源:weave/trace/serialization/README.md
Op 类型定义
在 TypeScript SDK 中,Op 类型定义如下:
export type Op<T extends (...args: any[]) => any> = {
__isOp: true;
__wrappedFunction: T;
__boundThis?: WeaveObject;
__name: string;
__savedRef?: OpRef | Promise<OpRef>;
__parameterNames?: ParameterNamesOption;
invoke: CallMethod<T>;
} & T &
((
...args: Parameters<T>
) => ReturnType<T> extends AsyncIterable<infer U>
? AsyncIterable<Awaited<U>>
: Promise<Awaited<ReturnType<T>>>);
Op 核心属性
| 属性 | 类型 | 说明 | |
|---|---|---|---|
__isOp | boolean | 标识符,用于 isOp() 函数判断 | |
__wrappedFunction | T | 被包装的原始函数 | |
__name | string | 操作名称 | |
__savedRef | OpRef \ | Promise\<OpRef\> | 保存的引用 |
__parameterNames | ParameterNamesOption | 参数名称配置 |
Op 工具函数
export function isOp(value: any): value is Op<any> {
return value && value.__isOp === true;
}
export function getOpName(opValue: Op<any>): string {
return opValue.__name;
}
export function getOpWrappedFunction<T extends (...args: any[]) => any>(
opValue: Op<T>
): T {
return opValue.__wrappedFunction;
}
OpOptions 配置选项
OpOptions 接口定义了可用于配置 op 包装器的选项:
export interface OpOptions<T extends (...args: any[]) => any> {
name?: string;
streamReducer?: StreamReducer<any, any>;
originalFunction?: T;
callDisplayName?: (...args: Parameters<T>) => string;
summarize?: (result: Awaited<ReturnType<T>>) => Record<string, any>;
bindThis?: WeaveObject;
isDecorator?: boolean;
shouldAdoptThis?: boolean;
parameterNames?: ParameterNamesOption;
/** 操作类型 (如 'llm', 'agent', 'tool', 'search'),用于 UI 分类 */
opKind?: string;
/** 操作在 UI 中的自定义颜色 */
opColor?: string;
}
OpOptions 参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
name | string | 操作的显示名称 |
streamReducer | StreamReducer | 流式结果 reducer 配置 |
originalFunction | T | 原始函数引用 |
callDisplayName | function | 自定义调用显示名称 |
summarize | function | 结果摘要生成函数 |
bindThis | WeaveObject | 绑定的 this 对象 |
isDecorator | boolean | 是否为装饰器模式 |
shouldAdoptThis | boolean | 是否采用原始函数的 this 值 |
parameterNames | ParameterNamesOption | 参数名称配置 |
opKind | string | 操作类型分类 |
opColor | string | UI 显示颜色 |
Callable 抽象接口
Fn 模块定义了 Callable 接口用于抽象可调用对象:
export interface Callable<I, O> {
run: (input: I) => Promise<O>;
}
export abstract class CallableObject<I, O>
extends WeaveObject
implements Callable<I, O>
{
abstract run(input: I): Promise<O>;
}
类型别名
export type FnInputs<T extends Callable<any, any>> =
T extends Callable<infer I, any> ? I : never;
export type FnOutput<T extends Callable<any, any>> =
T extends Callable<any, infer O> ? O : never;
参数映射工具函数
export function mapArgs<
T extends Record<string, any>,
M extends Record<string, keyof T>,
>(input: T, mapping: M): {[K in keyof M]: T[M[K]]} {
const result: Partial<{[K in keyof M]: T[M[K]]}> = {};
for (const [newKey, oldKey] of Object.entries(mapping)) {
if (oldKey in input) {
result[newKey as keyof M] = input[oldKey];
}
}
return result as {[K in keyof M]: T[M[K]]};
}
资料来源:sdks/node/src/fn.ts
当前限制与未来改进
已知的限制
- 文件 I/O 可能阻塞主线程:对于特别大的文件,文件 I/O 操作可能阻塞主线程。
- 序列化器信息不透明:目前没有简单的方法了解已注册的类型及其相对顺序。
- 序列化和反序列化逻辑分散:inline 和 file-backed 自定义对象的信息分散在
serializer.py和custom_objs.py中,增加了复杂性。
建议的改进方向
- 将文件创建逻辑从
serializer.py移至custom_objs.py。
- 暴露单一的
decode_custom_obj方法,与单一的encode方法对应。
- 添加依赖锁定文件以提高跨运行时兼容性。
资料来源:weave/trace/serialization/README.md
使用示例
基本序列化操作
import weave
# 初始化客户端
client = weave.init()
# 创建自定义对象
my_obj = MyCustomType("Hello, Weave!")
# 保存对象到 Weave
ref = client.save(my_obj, "my-custom-object")
# 从 Weave 检索对象
retrieved_obj = client.get(ref)
TypeScript 中定义 Op
import * as weave from "weave";
class TestClass {
@weave.op
async logImage(image: WeaveImage) {
// 处理图片
}
}
资料来源:weave/trace/serialization/README.md 资料来源:sdks/node/README.md
总结
Weave 的数据序列化系统提供了灵活而强大的对象序列化能力,支持原类型、自定义对象以及各种复杂数据结构。通过注册自定义序列化器,开发者可以轻松扩展系统以支持任意类型。系统采用内联和文件两种序列化模式,根据对象大小和复杂性自动选择最优方案。同时,通过将反序列化逻辑作为 Op 保存,确保了跨运行时环境的兼容性。
资料来源:[weave/trace/serialization/README.md]()
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能影响升级、迁移或版本选择。
可能增加新用户试用和生产接入成本。
可能增加新用户试用和生产接入成本。
可能阻塞安装或首次运行。
Pitfall Log / 踩坑日志
项目:wandb/weave
摘要:发现 15 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:安装坑 - 来源证据:v0.52.31。
1. 安装坑 · 来源证据:v0.52.31
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:v0.52.31
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_5abf422dae9b416fa8f2c65c21c2a4cd | https://github.com/wandb/weave/releases/tag/v0.52.31 | 来源讨论提到 windows 相关条件,需在安装/试用前复核。
2. 安装坑 · 来源证据:v0.52.40
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:v0.52.40
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_ac47498581a248b0b6be5e90b060b5ec | https://github.com/wandb/weave/releases/tag/v0.52.40 | 来源讨论提到 npm 相关条件,需在安装/试用前复核。
3. 配置坑 · 来源证据:v0.52.30
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:v0.52.30
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_8279f2b8caaa46f893597430a4238d93 | https://github.com/wandb/weave/releases/tag/v0.52.30 | 来源类型 github_release 暴露的待验证使用条件。
4. 配置坑 · 来源证据:v0.52.35
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:v0.52.35
- 对用户的影响:可能阻塞安装或首次运行。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_82d6e8a0c7804ed9875e5d4df6cfbf3f | https://github.com/wandb/weave/releases/tag/v0.52.35 | 来源类型 github_release 暴露的待验证使用条件。
5. 配置坑 · 来源证据:v0.52.36
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:v0.52.36
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_0347e61db43c4471a16dabca6f9d4b7f | https://github.com/wandb/weave/releases/tag/v0.52.36 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
6. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:650377372 | https://github.com/wandb/weave | README/documentation is current enough for a first validation pass.
7. 维护坑 · 来源证据:v0.52.38
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:v0.52.38
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_e6ca52f3493342d3b958dd3159f4f8fe | https://github.com/wandb/weave/releases/tag/v0.52.38 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
8. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:650377372 | https://github.com/wandb/weave | last_activity_observed missing
9. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:650377372 | https://github.com/wandb/weave | no_demo; severity=medium
10. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:650377372 | https://github.com/wandb/weave | no_demo; severity=medium
11. 安全/权限坑 · 来源证据:v0.52.33
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:v0.52.33
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_c4f93114a48d4bee972dce582d09d376 | https://github.com/wandb/weave/releases/tag/v0.52.33 | 来源类型 github_release 暴露的待验证使用条件。
12. 安全/权限坑 · 来源证据:v0.52.37
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:v0.52.37
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_c68137d6b888458d83ba2b477f463aaa | https://github.com/wandb/weave/releases/tag/v0.52.37 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
13. 安全/权限坑 · 来源证据:v0.52.39
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:v0.52.39
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_de6a7e38f1644ad9ae7b67c43f2baad3 | https://github.com/wandb/weave/releases/tag/v0.52.39 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
14. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:650377372 | https://github.com/wandb/weave | issue_or_pr_quality=unknown
15. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:650377372 | https://github.com/wandb/weave | release_recency=unknown
来源:Doramagic 发现、验证与编译记录