SDK로 평가자 관리하기
SDK로 평가자 관리하기
SDK로 LangSmith 평가자를 프로그래매틱하게 생성, 조회, 업데이트, 나열, 삭제하는 방법을 알려드릴게요.
LangSmith SDK를 사용해 평가자를 프로그래매틱하게 만들고 관리합니다. SDK를 통해 만든 평가자는 LangSmith UI의 Evaluators 테이블에 UI에서 만든 평가자와 동일하게 나타나는 워크스페이스 수준 리소스입니다. 데이터셋에 연결해 오프라인 평가를 실행하고, 트레이싱 프로젝트에 연결해 온라인 평가를 실행할 수 있습니다. SDK를 사용해 평가자 관리를 자동화하고 기존 워크플로에 평가를 통합하세요.
출처: 문서
본문
사전 요구사항
SDK를 통한 평가자 관리에는 다음이 필요합니다:
- Python:
langsmith>=0.9.8(PyPI) - TypeScript:
langsmith>=0.7.16(npm)
참고: 설치와 설정은 Python SDK 문서와 TypeScript SDK 문서를 참고하세요.
이 페이지의 예제는 클라이언트를 인자 없이 초기화하므로 LANGSMITH_API_KEY와 LANGSMITH_ENDPOINT 환경 변수를 읽습니다. API 키를 하드코딩하지 말고 환경 변수로 구성하세요.
다음 예제에서 <evaluator-uuid> 같은 플레이스홀더를 LangSmith의 해당 정보로 바꾸세요. 이 페이지의 모든 Python async 예제는 코드 평가자 생성 예제처럼 async def main(): ... asyncio.run(main()) 안에서 실행된다고 가정합니다.
평가자 생성
코드 평가자
코드 평가자는 정의한 함수로 각 실행 또는 예제를 채점합니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
created = await client.evaluators.create(
name="Correctness evaluator",
type="code",
code_evaluator={
"code": "def perform_eval(run, example):\n return {'score': 1}",
"language": "python",
},
)
evaluator_id = created.evaluator.id
print("Created evaluator:", evaluator_id)
asyncio.run(main())
import { Client } from "langsmith";
const client = new Client();
const created = await client.evaluators.create({
name: "Correctness evaluator",
type: "code",
code_evaluator: {
code: "def perform_eval(run, example):\n return {'score': 1}",
language: "python",
},
});
const evaluatorId = created.evaluator?.id;
console.log("Created evaluator:", evaluatorId);
LLM-as-a-judge 평가자
LLM-as-a-judge 평가자는 프롬프트 허브의 프롬프트를 참조하고 실행 또는 예제 필드를 프롬프트 변수에 매핑합니다.
참고: 프롬프트는 구조화된 프롬프트(유형
StructuredPrompt)여야 합니다.StructuredPrompt는 프롬프트 템플릿과 출력 스키마를 결합해 모델이 정의된 구조로 데이터를 반환하게 합니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
created = await client.evaluators.create(
name="LLM judge",
type="llm",
llm_evaluator={
"prompt_repo_handle": "<prompt-repo-handle>",
"commit_hash_or_tag": "<commit-hash-or-tag>",
"variable_mapping": {
"input": "inputs.question",
"output": "outputs.answer",
"reference": "reference.answer",
},
},
)
evaluator_id = created.evaluator.id
asyncio.run(main())
const created = await client.evaluators.create({
name: "LLM judge",
type: "llm",
llm_evaluator: {
prompt_repo_handle: "<prompt-repo-handle>",
commit_hash_or_tag: "<commit-hash-or-tag>",
variable_mapping: {
input: "inputs.question",
output: "outputs.answer",
reference: "reference.answer",
},
},
});
const evaluatorId = created.evaluator?.id;
prompt_repo_handle는 프롬프트의 표시 제목이나 URL이 아닌 내부 저장소 이름입니다. 찾으려면 워크스페이스 프롬프트를 나열하고 repo_handle 필드를 읽거나, LangSmith에서 식별자로 특정 프롬프트를 조회하세요. 프롬프트의 식별자는 다음과 같은 형식일 수 있습니다:
promptName(비공개 프롬프트용), 예:my-prompt.owner/promptName(공개 프롬프트용), 예:langchain-ai/correctness.
# List workspace prompts and read each repo handle
for prompt in client.list_prompts(limit=10).repos:
print("prompt-repo-handle:", prompt.repo_handle) # value to use for prompt_repo_handle
print("prompt-full-name:", prompt.full_name) # display name
print("description:", prompt.description)
# Or retrieve a specific prompt by identifier
prompt = client.get_prompt("<prompt-identifier>")
print("prompt-repo-handle:", prompt.repo_handle)
// List workspace prompts and read each repo handle.
// listPrompts() has no `limit` option in this SDK version — it's an async
// generator over all prompts, so cap the count client-side and break.
const prompts = client.listPrompts();
let count = 0;
for await (const prompt of prompts) {
console.log("prompt-repo-handle:", prompt.repo_handle);
console.log("prompt-full-name:", prompt.full_name);
console.log("description:", prompt.description);
console.log("---");
if (++count >= 10) break; // first 10 only; stops further pagination
}
// Or retrieve a specific prompt by identifier
const prompt = await client.getPrompt("<prompt-identifier>");
console.log("prompt-repo-handle:", prompt.repo_handle);
평가자 조회
ID로 단일 평가자를 가져와 이름, 유형, 피드백 키, 실행 규칙을 포함한 구성을 읽습니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
evaluator_id = "<evaluator-uuid>"
evaluator = await client.evaluators.retrieve(evaluator_id)
print(evaluator.name)
print(evaluator.type)
print(evaluator.feedback_keys)
print(evaluator.run_rules)
asyncio.run(main())
const evaluator = await client.evaluators.retrieve(evaluatorId);
console.log(evaluator.name);
console.log(evaluator.type);
console.log(evaluator.feedback_keys);
console.log(evaluator.run_rules);
평가자 업데이트
평가자 유형과 일치하는 필드를 전달합니다: 코드 평가자는 code_evaluator, LLM-as-a-judge 평가자는 llm_evaluator. update는 전달한 필드만 변경합니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
# Update a code evaluator
code_evaluator_id = "<code-evaluator-uuid>"
updated = await client.evaluators.update(
code_evaluator_id,
name="Updated correctness evaluator",
code_evaluator={
"code": "def perform_eval(run, example):\n return {'score': 0.8}",
"language": "python",
},
)
print(updated.evaluator.name if updated.evaluator else None)
# Update the name and prompt of an LLM-as-a-judge evaluator
llm_evaluator_id = "<llm-evaluator-uuid>"
await client.evaluators.update(
llm_evaluator_id,
name="Updated LLM judge",
llm_evaluator={
"prompt_repo_handle": "<prompt-repo-handle>",
"commit_hash_or_tag": "<commit-hash-or-tag>",
},
)
asyncio.run(main())
// Update a code evaluator
const codeEvaluatorId = "<code-evaluator-uuid>";
const updated = await client.evaluators.update(codeEvaluatorId, {
name: "Updated correctness evaluator",
code_evaluator: {
code: "def perform_eval(run, example):\n return {'score': 0.8}",
language: "python",
},
});
console.log(updated.evaluator?.name);
// Update the name and prompt of an LLM-as-a-judge evaluator
const llmEvaluatorId = "<llm-evaluator-uuid>";
await client.evaluators.update(llmEvaluatorId, {
name: "Updated LLM judge",
llm_evaluator: {
prompt_repo_handle: "<prompt-repo-handle>",
commit_hash_or_tag: "<commit-hash-or-tag>",
},
});
런타임 설정 구성
LLM-as-a-judge 평가자는 트레이스를 채점하는 방법을 제어하는 추가 설정을 수락합니다:
variable_mapping: 실행 또는 예제 필드를 판사 프롬프트 변수에 매핑합니다. 평가자가 실행될 때 적용됩니다.use_corrections_dataset및num_few_shot_examples: 인간 점수 수정에서 few-shot 학습을 활성화합니다. 평가자가 프로젝트나 데이터셋에 연결되고 수정이 제출되었을 때만 적용됩니다.
참고: 이 설정들은
update를 호출할 때가 아니라 다음 평가 실행에서 적용됩니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
llm_evaluator_id = "<llm-evaluator-uuid>"
await client.evaluators.update(
llm_evaluator_id,
llm_evaluator={
"prompt_repo_handle": "<prompt-repo-handle>",
"commit_hash_or_tag": "<commit-hash-or-tag>",
"variable_mapping": {
"input": "inputs.question",
"output": "outputs.answer",
},
"use_corrections_dataset": True,
"num_few_shot_examples": 3,
},
)
asyncio.run(main())
const llmEvaluatorId = "<llm-evaluator-uuid>";
await client.evaluators.update(llmEvaluatorId, {
llm_evaluator: {
prompt_repo_handle: "<prompt-repo-handle>",
commit_hash_or_tag: "<commit-hash-or-tag>",
variable_mapping: {
input: "inputs.question",
output: "outputs.answer",
},
use_corrections_dataset: true,
num_few_shot_examples: 3,
},
});
평가자 나열
이름, 유형, 피드백 키, 연결된 리소스, 태그 값으로 필터링하고 결과를 정렬·페이지네이션합니다. list()는 반환된 객체를 직접 반복할 때 모든 일치 항목을 자동 페이지네이션합니다. limit는 요청별 페이지 크기(1~100)를 설정하며, 총 결과 수가 아닙니다. sort_by는 선택 사항이며 created_at 또는 updated_at을 수락하고 기본값은 created_at입니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
# Read a single page of results
page = await client.evaluators.list(
name_contains="correctness",
type="code",
limit=10,
)
for evaluator in page.evaluators:
print(evaluator.id, evaluator.name, evaluator.type)
# Collect every match into a list
evaluators = [
evaluator
async for evaluator in client.evaluators.list(feedback_key="correctness", limit=20)
]
# Filter, sort, and paginate
page = await client.evaluators.list(
feedback_key="correctness",
name_contains="judge",
resource_id=["<project-or-dataset-uuid>"],
tag_value_id=["<tag-value-uuid>"],
type="llm",
sort_by="updated_at", # "created_at" (default) or "updated_at"
sort_by_desc=False,
limit=20,
offset=0,
)
asyncio.run(main())
// Read a single page of results
const page = await client.evaluators.list({
name_contains: "correctness",
type: "code",
limit: 10,
});
for (const evaluator of page.evaluators) {
console.log(evaluator.id, evaluator.name, evaluator.type);
}
// Collect every match into an array
const evaluators = [];
for await (const evaluator of client.evaluators.list({
feedback_key: "correctness",
limit: 20,
})) {
evaluators.push(evaluator);
}
// Filter, sort, and paginate
await client.evaluators.list({
feedback_key: "correctness",
name_contains: "judge",
resource_id: ["<project-or-dataset-uuid>"],
tag_value_id: ["<tag-value-uuid>"],
type: "llm",
sort_by: "updated_at", // "created_at" (default) or "updated_at"
sort_by_desc: false,
limit: 20,
offset: 0,
});
평가자 지출 추적
평가자에 대한 추정 USD 지출과 트레이스 수를 조회합니다:
period_start:2026-06-29같은 날짜 전용 ISO 문자열. datetime을 전달하면 400 오류가 반환됩니다.- 시간 창:
period_start는period_start와 그 후 6일을 포함하는 고정 7일 창을 시작합니다. 창은 반개방형,[period_start, period_start + 7 days)이므로period_end(period_start + 7일)는 제외됩니다. 예를 들어period_start가2026-06-29이면2026-06-29부터2026-07-05까지를 포함하고,2026-07-06은 제외됩니다.
- 시간 창:
type: 결과를 단일 평가자 유형(llm또는code)으로 범위 지정. 생략하면 모든 유형을 포함합니다.- 빈 결과: 창에 지출이 기록되지 않으면 반환된
groups목록은 비어 있습니다.
참고:
group_by,evaluator_id,session_id(LangSmith 트레이싱 프로젝트 UUID),dataset_id중 정확히 하나를 전달하세요.
import asyncio
from langsmith import Client
async def main():
client = Client()
evaluator_uuid = "<evaluator-uuid>"
start_date = "<period-start-date>" # for example, "2026-06-29"
# Spend for a single evaluator
spend = await client.evaluators.spend(
period_start=start_date,
evaluator_id=evaluator_uuid,
)
for group in spend.groups or []:
print(group.evaluator_name, group.total_spend_usd, group.total_trace_count)
# Group spend by evaluator
spend_by_evaluator = await client.evaluators.spend(
period_start=start_date,
group_by="evaluator",
type="llm",
)
print("Group by evaluator")
for group in spend_by_evaluator.groups or []:
print(group.evaluator_name, group.total_spend_usd, group.total_trace_count)
# Group spend by resource
spend_by_resource = await client.evaluators.spend(
period_start=start_date,
group_by="resource",
type="llm",
)
print("Group by resource")
for group in spend_by_resource.groups or []:
print(group.session_name, group.dataset_name, group.total_spend_usd, group.total_trace_count)
# Group spend by run_rule
spend_by_run_rule = await client.evaluators.spend(
period_start=start_date,
group_by="run_rule",
type="llm",
)
print("Group by run_rule")
for group in spend_by_run_rule.groups or []:
print(group.run_rule_name, group.total_spend_usd, group.total_trace_count)
asyncio.run(main())
const evaluatorUUID = "<evaluator-uuid>";
const startDate = "<period-start-date>"; // for example, "2026-06-29"
// Spend for a single evaluator
const spend = await client.evaluators.spend({
period_start: startDate,
evaluator_id: evaluatorUUID,
});
for (const group of spend.groups ?? []) {
console.log(group.evaluator_name, group.total_spend_usd, group.total_trace_count);
}
// Group spend by evaluator
const spendByEvaluator = await client.evaluators.spend({
period_start: startDate,
group_by: "evaluator",
type: "llm",
});
console.log("Group by evaluator");
for (const group of spendByEvaluator.groups ?? []) {
console.log(group.evaluator_name, group.total_spend_usd, group.total_trace_count);
}
// Group spend by resource
const spendByResource = await client.evaluators.spend({
period_start: startDate,
group_by: "resource",
type: "llm",
});
console.log("Group by resource");
for (const group of spendByResource.groups ?? []) {
console.log(group.session_name, group.dataset_name, group.total_spend_usd, group.total_trace_count);
}
// Group spend by run_rule
const spendByRunRule = await client.evaluators.spend({
period_start: startDate,
group_by: "run_rule",
type: "llm",
});
console.log("Group by run_rule");
for (const group of spendByRunRule.groups ?? []) {
console.log(group.run_rule_name, group.total_spend_usd, group.total_trace_count);
}
평가자 삭제
평가자가 트레이싱 프로젝트나 데이터셋에 연결되어 있는 동안에는 삭제할 수 없습니다. 평가자를 삭제하기 전에 평가자를 참조하는 실행 규칙을 삭제하려면 delete_run_rules를 true로 설정합니다.
import asyncio
from langsmith import Client
async def main():
client = Client()
evaluator_id = "<evaluator-uuid>"
await client.evaluators.delete(
evaluator_id,
delete_run_rules=True, # run rules referencing the evaluator are deleted first
)
asyncio.run(main())
const evaluatorId = "<evaluator-uuid>";
await client.evaluators.delete(evaluatorId, {
delete_run_rules: true, // run rules referencing the evaluator are deleted first
});
관련 자료
- 평가자 관리: LangSmith UI에서 평가자 보기·관리.
- LLM-as-a-judge 온라인 평가자 설정: LangSmith UI에서 LLM-as-a-judge 온라인 평가자 구성.
- 온라인 코드 평가자 설정: LangSmith UI에서 온라인 코드 평가자 구성.