- 可观测性
- AI 评测
- LLMOps
- AI 应用
- 人工智能
【免费下载链接】phoenix
AI Observability & Evaluation
导读
本文基于 Phoenix 仓库中的 langchain-quickstart 示例,完整讲解一个基于 LangChain TypeScript 的旅行规划 Agent 从环境搭建、Tracing 接入到 LLM 评估(Eval)的全流程实战。你将学会:用@arizeai/phoenix-otel注册 Phoenix 并自动插桩 LangChain,构建带 Tavily 搜索工具的多工具 Agent,再通过phoenix-client拉取 Span、用phoenix-evals内置正确性评估器与自定义评估模板打分并回写注解,最终在 Phoenix UI 中观察完整调用链与评估结果。
前置条件
示例运行需要满足以下环境要求(见 README.md):
- Node.js 18+,以及可用的包管理器(示例使用 npm / npx)。
- Phoenix 服务:本地运行
pip install arize-phoenix && phoenix serve,或使用 Phoenix Cloud 实例。 - OpenAI API Key(
OPENAI_API_KEY):供 Agent 的 LLM 使用,模型为openai:gpt-3.5-turbo。 - Tavily API Key(
TAVILY_API_KEY):供三个工具调用搜索 API。 - Fireworks API Key(
FIREWORKS_API_KEY):仅运行自定义评估脚本时需要。
一、快速启动六步走(SETUP.md 核心流程)
SETUP.md 给出六步启动流程,下面逐步骤展开并补充源码细节。
步骤 1:进入示例目录
cd js/examples/apps/langchain-quickstart步骤 2:安装依赖
npm install根据 package.json,安装的依赖包括(版本以当前仓库 lockfile 为准):
| 依赖 | 作用 |
|---|---|
langchain | LangChain 主体与 Agent 抽象(createAgent) |
@langchain/core | 回调管理器与工具基类(StructuredTool、CallbackManager) |
zod | 工具入参的 Schema 校验 |
@arizeai/phoenix-otel | Phoenix Tracing 注册与导出 |
@arizeai/openinference-instrumentation-langchain | LangChain 自动插桩 |
@arizeai/phoenix-client | 拉取 Span、回写 Span 注解 |
@arizeai/phoenix-evals | 内置/自定义评估器 |
@ai-sdk/openai | OpenAI 兼容模型封装(Agent 与评估共用) |
dotenv | 加载.env环境变量 |
tsx | 直接运行 TypeScript 的开发工具 |
其中@arizeai/phoenix-client与@arizeai/phoenix-evals在仓库内以workspace:*形式引用(monorepo 工作区),源码位于 js/packages/phoenix-client 与 js/packages/phoenix-evals。
步骤 3:配置环境变量
从.env.example复制生成.env,至少配置以下变量:
# Agent 必需 OPENAI_API_KEY=your-key-here TAVILY_API_KEY=your-tavily-key-here # Phoenix(默认值如下)。Trace 导出到 PHOENIX_COLLECTOR_ENDPOINT; # 评估脚本通过 PHOENIX_ENDPOINT 调用 Phoenix API。 PHOENIX_COLLECTOR_ENDPOINT=http://localhost:6006 PHOENIX_ENDPOINT=http://localhost:6006 PHOENIX_PROJECT_NAME=langchain-travel-agent运行npm run custom_evals还需额外配置:
FIREWORKS_API_KEY=your-fireworks-key-here环境变量在 src/index.ts 中用于注册 Phoenix(projectName缺省时回退到langchain-travel-agent);src/tools.ts 中TAVILY_API_KEY缺失会直接抛出错误提示。
步骤 4:启动 Phoenix(本地运行场景)
在另一个终端中:
pip install arize-phoenix phoenix serve启动后 Phoenix UI 默认监听http://localhost:6006。若此前安装过旧版 Phoenix,运行pip install -U arize-phoenix升级后再启动,以避免评估注解 API(span annotations)缺失导致的 404(详见 README 的 Troubleshooting 一节)。
步骤 5:运行应用
npm start该命令实际执行npx tsx src/index.ts(见 package.json)。预期输出包括:
- 三条旅行规划查询(爱尔兰 5 天、日本 7 天、葡萄牙 3 天),每条包含目的地、时长与兴趣点;
- Agent 依次调用三个工具
essential_info、budget_basics、local_flavor后给出的回答; - 在
http://localhost:6006的 Phoenix UI 中可看到完整 Trace。
步骤 6:(可选)运行评估
Agent 运行并产生 Trace 后:
# 内置正确性评估(OpenAI) npm run pre_built_evals # 自定义正确性评估(旅行评估模板,Fireworks) npm run custom_evals二、理解示例的代码结构与数据流
SETUP.md 给出了文件结构,整理如下:
langchain-quickstart/ ├── src/ │ ├── index.ts # Phoenix 注册 + LangChain 旅行 Agent │ ├── tools.ts # essential_info / budget_basics / local_flavor(Tavily) │ ├── pre_built_evals.ts # 内置正确性评估 → Phoenix 注解 │ ├── custom_evals.ts # 自定义正确性评估(旅行模板,Fireworks) │ └── instrumentation.ts # 可选独立 Phoenix 配置(index.ts 未使用) ├── package.json # 脚本:start / pre_built_evals / custom_evals ├── .env.example # OPENAI、TAVILY、PHOENIX、FIREWORKS 示例 ├── README.md # 完整文档 └── SETUP.md # 本文所依据的快速启动文档注意:index.ts在文件顶部自行完成 Phoenix 注册与 LangChain 插桩,并未 importinstrumentation.ts;后者是留给希望以独立模块方式管理追踪初始化的读者的参考实现。
数据流总览
index.ts启动时注册 Phoenix 并对 LangChain 做自动插桩;- 三条旅行查询依次调用
createAgent生成的 Agent,Agent 按系统提示词强制依次调用三个工具; - 每个工具的
_call内部调用 Tavily 搜索 API 取回实时资料; - Agent 调用过程以 OpenInference 语义约定导出为 Trace 到 Phoenix;
- 评估脚本通过
getSpans拉取LangGraph父 Span,交给 LLM 评估器打分,再通过logSpanAnnotations回写注解。
三、源码解析:Tracing 接入与 Agent 构建(index.ts)
src/index.ts 是主入口,核心代码分三段。
1. Phoenix 注册与 LangChain 自动插桩
import { LangChainInstrumentation } from "@arizeai/openinference-instrumentation-langchain"; import { register } from "@arizeai/phoenix-otel"; import * as CallbackManagerModule from "@langchain/core/callbacks/manager"; import "dotenv/config"; const provider = register({ projectName: process.env.PHOENIX_PROJECT_NAME ?? "langchain-travel-agent", }); const lcInstrumentation = new LangChainInstrumentation(); lcInstrumentation.manuallyInstrument(CallbackManagerModule);关键点:
register({ projectName })来自@arizeai/phoenix-otel,负责 OpenTelemetry 初始化与 OTLP 导出,Trace 默认导出到PHOENIX_COLLECTOR_ENDPOINT;LangChainInstrumentation.manuallyInstrument(CallbackManagerModule)手动对 LangChain 回调管理器插桩,这样createAgent产生的中枢(agent)调用与工具调用都会被记录为 Span。
若希望将追踪初始化独立成模块,可参考 src/instrumentation.ts:它在任何其他 import 之前设置OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=25000防止 Span 属性值被截断,并可传batch: false让 Span 即时投递(开发期调试更直观)。
2. Agent 构建与系统提示词
const agent = createAgent({ model: "openai:gpt-3.5-turbo", systemPrompt: `You are a travel planner. You must produce a trip plan that includes exactly three sections, each backed by a tool call. RULES: 1. You MUST call all three tools for every trip plan: essential_info, budget_basics, and local_flavor... 2. Use only information returned by the tools. Do not invent facts, prices, or recommendations. 3. Structure your reply strictly as: (a) Essentials ... (b) Budget ... (c) Local flavor ... 4. Keep the total response under 800 words...`, tools: travelTools, });系统提示词通过四条硬规则约束 Agent 行为,这与后面评估模板的评分标准一一对应:必须三次工具调用、只依据工具返回、回答分三段、总字数小于 800。这种「提示词约束 + 评估模板度量」的组合是 Eval-Driven Development 的典型做法。
3. 三条旅行查询与强制 Flush
const queries = [ { destination: "Ireland", duration: "5 days", interests: "food, culture" }, { destination: "Japan", duration: "7 days", interests: "temples, cuisine" }, { destination: "Portugal", duration: "3 days", interests: "beaches, wine" }, ]; // ...for 循环内 agent.invoke({ messages: [{ role: "user", content: query }] }) await provider.forceFlush();provider.forceFlush()在程序退出前强制将缓冲区中的 Span 导出,避免快速退出的脚本丢失 Trace。入口在启动时还会校验OPENAI_API_KEY与TAVILY_API_KEY,缺失即打印错误并process.exit(1)。
四、源码解析:三个 Tavily 工具与 Zod Schema(tools.ts)
src/tools.ts 基于@langchain/core/tools的StructuredTool定义了三个工具,每个工具都有 name、description 与 zod schema,供 LLM 进行结构化工具调用。
共享的搜索封装
async function searchApi(query: string): Promise<string | null> { const tavilyKey = process.env.TAVILY_API_KEY; if (!tavilyKey) { throw new Error("TAVILY_API_KEY environment variable is not set..."); } const response = await fetch("https://api.tavily.com/search", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ api_key: tavilyKey, query, max_results: 3, search_depth: "basic", include_answer: true, }), }); // ...将 answer 与各条结果 content 合并,截断到 400 字符后返回 }同时提供了一个compact()函数,将搜索结果压缩为单行并限制长度(默认 200 字符),保证 Span 属性与工具输出可控。
三个工具的参数 Schema
const destinationSchema = z.string().min(1, "Destination is required").max(100); const durationSchema = z.string().regex(/^\d+\s*days?$/i, "Duration must be like '3 days' or '7 days'"); const interestsSchema = z.string().min(1, "Interests are required").max(200);essential_info:入参仅destination,查询旅行 essentials + weather + best time + attractions + etiquette;budget_basics:入参destination+duration,查询budget + average daily costs + duration;local_flavor:入参destination+interests,查询authentic local experiences + interests。
每个工具的 description 都明确写出「Required」及使用边界(例如 essential_info 明确"Do not use for budget or local experiences"),帮助 LLM 在规划中正确分派工具。工具实现中还内置了搜索无结果时的兜底文案,避免返回空字符串破坏 Agent 流程。
五、源码解析:内置正确性评估(pre_built_evals.ts)
src/pre_built_evals.ts 演示「拉取 Span → 内置评估器打分 → 回写注解」的闭环。
1. 构造内置评估器
const base_model = openai("gpt-4o-mini"); const evaluator = createCorrectnessEvaluator({ model: base_model });createCorrectnessEvaluator来自@arizeai/phoenix-evals,实现位于 js/packages/phoenix-evals/src/llm/createCorrectnessEvaluator.ts。文件内还预留了切换自定义端点 LLM 的注释块(Fireworks 的qwen3-235b-a22b-instruct-2507),取消注释并同时修改createCorrectnessEvaluator中的模型即可替换评估模型。
2. 拉取 Agent Span
const { spans } = await getSpans({ project: { projectName }, limit: 500 }); // 筛选 name === "LangGraph" 的父 Span,提取 input.value / output.value 与 span_idgetSpans来自@arizeai/phoenix-client/spans,实现在 js/packages/phoenix-client/src/spans/getSpans.ts。脚本只挑选名为LangGraph的 Agent 中枢 Span(getInputOutput依次读取input.value/input与output.value/output属性),确保评估对象是整个 Agent 的完整回答而非单次工具调用。
3. 评估并回写注解
const spanAnnotations = await Promise.all( parentSpans.map(async ({ spanId, input, output }) => { const r = await evaluator.evaluate({ input, output }); return { spanId, name: "correctness", label: r.label, score: r.score, explanation: r.explanation, annotatorKind: "LLM", metadata: { evaluator: "correctness", input, output } }; }) ); await logSpanAnnotations({ spanAnnotations, sync: true });logSpanAnnotations同样来自@arizeai/phoenix-client/spans,实现在 js/packages/phoenix-client/src/spans/logSpanAnnotations.ts。sync: true表示同步等待写入完成。评估结果以correctness为名、annotatorKind: "LLM"附着在 LangGraph Span 上,打开 Phoenix UI 即可在对应 Trace 上看到该注解及 label/score/explanation。
六、源码解析:自定义评估模板(custom_evals.ts)
src/custom_evals.ts 展示如何针对业务定制评估标准,评估结果命名为custom_correctness。
1. 自定义评估模板
const correctnessTemplate = ` You are an expert evaluator judging whether a travel planner agent's response is correct. ... CORRECT - The response: - Accurately addresses the user's destination, duration, and stated interests - Includes essential travel info (e.g., weather, best time to visit, key attractions, etiquette) - Includes a budget or cost breakdown appropriate to the destination and trip duration - Includes local experiences, cultural highlights, or authentic recommendations matching the user's interests - Is factually accurate, logically consistent, and helpful for planning the trip - Uses precise, travel-appropriate terminology INCORRECT - The response contains any of: - Factual errors about the destination, costs, or local info - Missing essential info / Missing or irrelevant budget information / Missing or generic local experiences - Wrong destination, duration, or interests addressed - Contradictions, misleading statements, or unhelpful/off-topic content [BEGIN DATA] [User Input]: {{input}} [Travel Plan]: {{output}} [END DATA] ...`;模板使用{{input}}、{{output}}占位符注入待评估内容,评估标准与 index.ts 的系统提示词严格对应(essential info / budget / local flavor 三段齐全 + 事实准确),保证「先约束、后度量」的闭环。
2. 分类评估器构造
const evaluator = createClassificationEvaluator({ model: base_model, promptTemplate: correctnessTemplate, choices: { correct: 1, incorrect: 0 }, name: EVAL_NAME, // "custom_correctness" });createClassificationEvaluator实现在 js/packages/phoenix-evals/src/llm/createClassificationEvaluator.ts。choices定义二分类标签及对应分数(correct=1, incorrect=0),name作为评估器名称,随后回写的注解名即为custom_correctness。
3. 与内置评估流程的差异
- 数据拉取与过滤逻辑与 pre_built_evals 相同(同取
LangGraph父 Span、limit: 500); - 评估结果通过
evaluator.evaluate({ input, output })拿到{ label, score, explanation }; - 回写的注解
name为custom_correctness,metadata记录evaluator: "custom_correctness"。
通过对比两个脚本可以直观理解:内置评估器开箱即用,自定义评估器则允许完全掌控模板、标签与分数语义。
七、在 Phoenix 中查看什么
应用运行后打开http://localhost:6006,在项目langchain-travel-agent下可以看到:
- Trace:每次 Agent 调用生成一条 Trace,包含
LangGraph(agent)Span 与三条工具调用 Span(essential_info、budget_basics、local_flavor),并展示 Token 用量、延迟、提示词与响应内容; - 注解:运行评估脚本后,
LangGraphSpan 上会出现correctness或custom_correctness注解,附带 label、score 与 LLM 的 explanation,可直接在 Trace 详情中核对每条旅行计划的评分理由。
注意PHOENIX_PROJECT_NAME需与你在 UI 中打开的项目名一致(默认langchain-travel-agent),否则看不到 Trace。
八、常见问题排查
结合 README.md 的 Troubleshooting 部分:
| 现象 | 排查与修复 |
|---|---|
OPENAI_API_KEY/TAVILY_API_KEY未设置报错 | 在.env中配置,或export OPENAI_API_KEY=...后运行 |
| Phoenix 中看不到 Trace | 确认phoenix serve在运行、PHOENIX_COLLECTOR_ENDPOINT可访问(默认http://localhost:6006)、PHOENIX_PROJECT_NAME与 UI 中打开的项目一致 |
| TypeScript / 模块报错 | 重新npm install,使用 Node.js 18+,确认"type": "module"与 import 路径匹配 |
评估脚本报404 Not Found(注解写入失败) | 服务端缺少 span annotations API,执行pip install -U arize-phoenix && phoenix serve升级重启;或在仓库根目录运行uv run phoenix serve。评估本身仍会运行并打印结果,仅注解回写失败 |
custom_evals报需要PHOENIX_ENDPOINT | 在.env中设置PHOENIX_ENDPOINT=http://localhost:6006,并确保FIREWORKS_API_KEY已配置 |
九、下一步扩展方向
SETUP.md 末尾给出的扩展建议,结合源码可落地的方向有:
- 更换查询数据:修改 src/index.ts 中
queries数组的目的地、时长与兴趣点; - 增删工具:在 src/tools.ts 中按
StructuredTool模式新增工具,并加入travelTools数组;注意同步调整系统提示词与评估模板; - 调整系统提示词:修改
createAgent的systemPrompt,例如放宽「必须调用三个工具」的约束或改变回答格式; - 定制评估模板:在 src/custom_evals.ts 中修改
correctnessTemplate,例如增加「预算是否合理」「推荐是否可落地」等业务维度; - 更换评估模型:参考
pre_built_evals.ts中注释掉的 Fireworks 配置块,将评估器模型切换为自定义端点模型。
这套「Agent 提示词约束 + Phoenix Tracing 观测 + LLM 评估回写」的闭环,可以直接迁移到你的 LangChain TypeScript 生产项目中:把register与LangChainInstrumentation的初始化提取到应用入口,把评估脚本接入 CI 或定时任务,即可持续度量 Agent 输出质量。
- 可观测性
- AI 评测
- LLMOps
- AI 应用
- 人工智能
【免费下载链接】phoenix
AI Observability & Evaluation
相关推荐
Opik TypeScript SDK 实战指南:LLM 应用追踪、评估与集成
Opik TypeScript SDK 实战指南:LLM 应用追踪、评估与集成 Opik TypeScript SDK(npm 包名 opik )是 Opik
人工智能LLMOps模型评测可观测性AI AgentAI 应用后端前端Phoenix Harbor 插件实战指南:将 Harbor Agent 评估沉淀为版本化数据集、实验与 ATIF 追踪
Phoenix Harbor 插件实战指南:将 Harbor Agent 评估沉淀为版本化数据集、实验与 ATIF 追踪 Harbor 负责在沙箱环境中运行 A
可观测性AI 评测LLMOpsAI 应用人工智能impeccable 设计评审(critique)实战指南:双 Agent 隔离评估、Nielsen 启发式评分与快照追踪
impeccable 设计评审(critique)实战指南:双 Agent 隔离评估、Nielsen 启发式评分与快照追踪 impeccable 是面向 AI
AI 技能前端CLIdsh-plugin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考