如何定义目标函数以进行评估
运行评估主要有三个部分:
本指南将向您介绍如何根据您正在评估的应用程序部分来定义目标函数。 有关如何创建数据集,请参见此处;有关如何定义评估器,请参见此处;有关运行评估的端到端示例,请参见此处。
目标函数签名
为了在代码中评估一个应用程序,我们需要一种运行该应用程序的方法。当使用 evaluate()(Python/TypeScript)时,我们将通过传入一个目标函数参数来实现这一点。该目标函数接收数据集示例(Example)的输入,并以字典形式返回应用程序的输出。在该函数内部,我们可以按需调用我们的应用程序;同时,我们也可以按需格式化输出结果。关键在于:我们所定义的任何评估器函数都必须能够处理目标函数所返回的输出格式。
from langsmith import Client
# 'inputs' will come from your dataset.
def dummy_target(inputs: dict) -> dict:
return {"foo": 1, "bar": "two"}
# 'inputs' will come from your dataset.
# 'outputs' will come from your target function.
def evaluator_one(inputs: dict, outputs: dict) -> bool:
return outputs["foo"] == 2
def evaluator_two(inputs: dict, outputs: dict) -> bool:
return len(outputs["bar"]) < 3
client = Client()
results = client.evaluate(
dummy_target, # <-- target function
data="your-dataset-name",
evaluators=[evaluator_one, evaluator_two],
...
)
evaluate() 将自动追踪您的目标函数。
这意味着,如果您在目标函数内运行任何可追踪的代码,这些代码也将作为目标追踪的子运行被追踪。
示例:单次大语言模型调用
当我们迭代优化提示词或比较不同模型时,对单次大语言模型调用进行评估会很有帮助:
- Python
- TypeScript
- Python(LangChain)
- TypeScript(LangChain)
设置环境变量 OPENAI_API_KEY 并安装依赖项 pip install -U openai langsmith。
from langsmith import wrappers
from openai import OpenAI
# Optionally wrap the OpenAI client to automatically
# trace all model calls.
oai_client = wrappers.wrap_openai(OpenAI())
def target(inputs: dict) -> dict:
# This assumes your dataset has inputs with a 'messages' key.
# You can update to match your dataset schema.
messages = inputs["messages"]
response = oai_client.chat.completions.create(
messages=messages,
model="gpt-4o-mini",
)
return {"answer": response.choices[0].message.content}
设置环境变量 OPENAI_API_KEY,并安装 openai 和 langsmith。
import OpenAI from 'openai';
import { wrapOpenAI } from "langsmith/wrappers";
const client = wrapOpenAI(new OpenAI());
// This is the function you will evaluate.
const target = async(inputs) => {
// This assumes your dataset has inputs with a `messages` key
const messages = inputs.messages;
const response = await client.chat.completions.create({
messages: messages,
model: 'gpt-4o-mini',
});
return { answer: response.choices[0].message.content };
}
设置环境变量 OPENAI_API_KEY 并安装依赖项 pip install -U langchain[openai]。
from langchain.chat_models import init_chat_model
llm = init_chat_model("openai:gpt-4o-mini")
def target(inputs: dict) -> dict:
# This assumes your dataset has inputs with a `messages` key
messages = inputs["messages"]
response = llm.invoke(messages)
return {"answer": response.content}
设置环境变量 OPENAI_API_KEY 并安装 @langchain/openai。
import { ChatOpenAI } from '@langchain/openai';
// This is the function you will evaluate.
const target = async(inputs) => {
// This assumes your dataset has inputs with a `messages` key
const messages = inputs.messages;
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
const response = await model.invoke(messages);
return {"answer": response.content};
}
示例:非大语言模型组件
有时,您可能希望评估应用程序中不涉及大语言模型(LLM)的某个步骤。这包括但不限于:
- RAG 应用中的检索步骤
- 工具执行
在本示例中,我们展示了如何测试一个简单的计算器工具。在实际应用中,评估对于具有更复杂、且难以通过单元测试验证行为的组件(例如检索器或在线研究工具)尤为有用。
- Python
- TypeScript
from langsmith import traceable
# Optionally decorate with '@traceable' to trace all invocations of this function.
@traceable
def calculator_tool(operation: str, number1: float, number2: float) -> str:
if operation == "add":
return str(number1 + number2)
elif operation == "subtract":
return str(number1 - number2)
elif operation == "multiply":
return str(number1 * number2)
elif operation == "divide":
return str(number1 / number2)
else:
raise ValueError(f"Unrecognized operation: {operation}.")
# This is the function you will evaluate.
def target(inputs: dict) -> dict:
# This assumes your dataset has inputs with `operation`, `num1`, and `num2` keys.
operation = inputs["operation"]
number1 = inputs["num1"]
number2 = inputs["num2"]
result = calculator_tool(operation, number1, number2)
return {"result": result}
import { traceable } from "langsmith/traceable";
// Optionally wrap in 'traceable' to trace all invocations of this function.
const calculatorTool = traceable(async ({ operation, number1, number2 }) => {
// Functions must return strings
if (operation === "add") {
return (number1 + number2).toString();
} else if (operation === "subtract") {
return (number1 - number2).toString();
} else if (operation === "multiply") {
return (number1 * number2).toString();
} else if (operation === "divide") {
return (number1 / number2).toString();
} else {
throw new Error("Invalid operation.");
}
});
// This is the function you will evaluate.
const target = async (inputs) => {
// This assumes your dataset has inputs with `operation`, `num1`, and `num2` keys
const result = await calculatorTool.invoke({
operation: inputs.operation,
number1: inputs.num1,
number2: inputs.num2,
});
return { result };
}
示例:应用程序或智能体
评估您的智能体应用的完整输出,能够捕捉多个组件之间的交互,从而更真实地反映端到端性能。端到端评估还可能发现集成问题和错误处理问题,而这些问题在单独测试函数或单次大语言模型(LLM)调用时容易被忽略。
- Python
- TypeScript
from my_agent import agent
# This is the function you will evaluate.
def target(inputs: dict) -> dict:
# This assumes your dataset has inputs with a `messages` key
messages = inputs["messages"]
# Replace `invoke` with whatever you use to call your agent
response = agent.invoke({"messages": messages})
# This assumes your agent output is in the right format
return response
import { agent } from 'my_agent';
// This is the function you will evaluate.
const target = async(inputs) => {
// This assumes your dataset has inputs with a `messages` key
const messages = inputs.messages;
// Replace `invoke` with whatever you use to call your agent
const response = await agent.invoke({ messages });
// This assumes your agent output is in the right format
return response;
}
如果你有一个 LangGraph/LangChain 智能体,它能够接收数据集所定义的输入,并返回评估器所需使用的输出格式,那么你可以直接将该对象作为 target 参数传入:
from my_agent import agent
from langsmith import Client
client = Client()
client.evaluate(agent, ...)