Arize Phoenix

Arize Phoenix

Arize Phoenix는 Arize AI의 오픈소스 LLM 추적(tracing) 및 평가 프로젝트예요. 로컬 개발, 실험, 셀프 호스팅 워크플로에 사용해요.

출처: 문서

본문

Arize Phoenix는 Arize AI의 오픈소스 LLM 추적 및 평가 프로젝트예요. 로컬 개발, 실험, 셀프 호스팅 워크플로에 사용해요.

Phoenix는 프로덕션 팀, AI 네이티브 기업, 엔터프라이즈를 위한 완전한 기능의 플랫폼인 Arize AX와 별개예요. AX는 관리형 클라우드 또는 엔터프라이즈 셀프 호스팅 배포로 제공돼요. LiteLLM은 두 백엔드를 모두 지원하지만, 각각 다른 콜백, 자격 증명, 엔드포인트를 사용해요. Phoenix에는 arize_phoenix, AX에는 arize를 사용하고, 동일한 트레이스를 양쪽에 모두 보내야 할 때는 둘 다 활성화하면 돼요.

LiteLLM 트레이스를 중심으로 평가 루프를 구축하는 팀을 위해, Arize의 에이전트 평가 가이드LLM 평가 가이드는 트레이싱 실패, 모델 동작 평가, 에이전트 신뢰성 개선을 위한 프로덕션 워크플로를 다뤄요.

사전 준비 (Pre-Requisites)

uv add litellm

빠른 시작 (Quick Start)

SDK

import litellm
import os
os.environ["LITELLM_OTEL_V2"] = "true"
os.environ["PHOENIX_API_KEY"] = ""
os.environ["PHOENIX_COLLECTOR_ENDPOINT"] = "https://app.phoenix.arize.com/v1/traces"
os.environ["PHOENIX_PROJECT_NAME"] = ""   # optional, defaults to "default"

# LLM API Keys
os.environ["OPENAI_API_KEY"] = ""

# set arize_phoenix as a callback, litellm will send the data to phoenix
litellm.callbacks = ["arize_phoenix"]

# openai call
response = litellm.completion(
  model="gpt-5.6-terra",
  messages=[
    {"role": "user", "content": "Hi 👋 - i'm openai"}
  ]
)

LiteLLM Proxy

config.yaml 설정:

model_list:
  - model_name: gpt-5.6-terra
    litellm_params:
      model: openai/gpt-5.6-terra
      api_key: os.environ/OPENAI_API_KEY

litellm_settings:
  callbacks: ["arize_phoenix"]

자격 증명 설정:

LITELLM_OTEL_V2=true
PHOENIX_API_KEY="your-api-key"
PHOENIX_COLLECTOR_ENDPOINT="https://app.phoenix.arize.com/v1/traces"
PHOENIX_PROJECT_NAME="my-project"   # optional

프록시 시작:

litellm --config /path/to/config.yaml

테스트:

curl -L -X POST 'http://0.0.0.0:4000/v1/chat/completions' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer ***" \
  -d '{
  "model": "gpt-5.6-terra",
  "messages": [
    {
      "role": "user",
      "content": "Hey, how are you?"
    }
  ]
}'

Phoenix가 렌더링하는 것 (What Phoenix renders)

Phoenix를 열면 프로젝트가 PHOENIX_PROJECT_NAME(기본값 default)에서 오고, openinference.project.name 리소스 속성으로 스탬프가 찍혀요. 각 요청은 요청 루트 아래에 chat <model> 스팬으로 표시돼요. 프록시에서 팀이나 키의 LLM 스팬을 다른 Phoenix 프로젝트로 보낼 수 있어요. 팀 또는 키별 Phoenix 프로젝트로 트레이스 라우팅 참조.

Phoenix는 Arize AX와 동일한 OpenInference 어휘를 사용하므로, LLM 호출 스팬은 llm.model_name, llm.provider, llm.token_count.* 사용량 분할, llm.invocation_parameters, 콘텐츠 캡처가 켜져 있을 때 메시지 배열, llm.tools.*를 표준 gen_ai.* 키와 함께 전달해요. 전체 속성 표 참조.

설정 (Configuration)

변수 필수 설명
PHOENIX_API_KEY Phoenix Cloud만 엔드포인트가 app.phoenix.arize.com에 있을 때 필수. LiteLLM은 없으면 오류를 발생시켜요. 셀프 호스팅 Phoenix는 불필요
PHOENIX_COLLECTOR_HTTP_ENDPOINT 아니요 컬렉터 엔드포인트. 둘 다 설정되면 PHOENIX_COLLECTOR_ENDPOINT보다 우선
PHOENIX_COLLECTOR_ENDPOINT 아니요 컬렉터 엔드포인트. HTTP 변수가 설정되지 않았을 때 사용
PHOENIX_PROJECT_NAME 아니요 기본값 default. PHOENIX_COLLECTOR_PROJECT_NAME으로도 읽을 수 있음. 키나 팀이 phoenix_project_name을 설정하지 않았을 때의 폴백 프로젝트

어느 엔드포인트 변수도 설정하지 않으면 LiteLLM은 http://localhost:6006/v1/traces로 폴백해요.

프로토콜은 변수 이름이 아니라 엔드포인트에서 추론됨

어느 변수도 프로토콜에 묶여 있지 않아요. LiteLLM은 주어진 값에서 프로토콜을 선택해요. grpc://로 시작하거나 /v1/traces 경로 없이 :4317을 포함하는 엔드포인트는 gRPC로 내보내고, 그 외에는 HTTP로 내보내요. 따라서 Phoenix Cloud URL은 어느 변수에나 넣을 수 있고, PHOENIX_COLLECTOR_ENDPOINThttps://app.phoenix.arize.com/v1/traces로 지정하면 의도대로 HTTP로 전송돼요.

올바른 컬렉터 엔드포인트 선택

Phoenix에는 여러 컬렉터 엔드포인트 형태가 있고, 잘못된 것을 고르는 것이 가장 흔한 Phoenix 설정 실수예요. 배포 형태에 맞는 엔드포인트를 지정하세요:

배포 엔드포인트
Phoenix Cloud (Spaces) https://app.phoenix.arize.com/s//v1/traces
Phoenix Cloud (legacy) https://app.phoenix.arize.com/legacy/v1/traces
Phoenix Cloud (old) https://app.phoenix.arize.com/v1/traces
셀프 호스팅 http://localhost:6006/v1/traces

팀 또는 키별 Phoenix 프로젝트로 트레이스 라우팅 (Route traces to a Phoenix project per team or key)

한 Phoenix 컬렉터는 여러 프로젝트를 보유할 수 있어요. LiteLLM 프록시에서 팀이나 가상 키에 phoenix_project_name을 설정하면 그 팀(또는 키)의 LLM 스팬이 자체 Phoenix 프로젝트에 들어가요. 프로젝트 이름이 없는 키는 계속 PHOENIX_PROJECT_NAME을 사용해요.

이렇게 하면 테넌트별로 Phoenix 인스턴스를 띄우지 않고도 팀별로 트레이스를 분리할 수 있어요. 프로젝트는 프록시가 인증 시 해석한 팀 또는 키에서만 온다는 점에 유의하세요. 요청 본문에 phoenix_project_name을 넣는 호출자는 무시되며, 호출은 계속 200을 반환하고 공격자가 선택한 프로젝트는 생성되지 않아요.

OTel v2(LITELLM_OTEL_V2=true)와 callbacks: ["arize_phoenix"]가 필요해요. Phoenix 15.5.0+는 이 기능이 사용하는 x-project-name 헤더를 존중하며, 더 오래된 컬렉터는 이를 무시하고 env 프로젝트에 머물러요.

팀별 (Per team)

curl -X POST 'http://localhost:4000/team/new' \
  -H "Authorization: Bearer ***" \
  -H 'Content-Type: application/json' \
  -d '{"team_alias": "payments", "metadata": {"phoenix_project_name": "payments-prod"}}'

기존 팀도 같은 방식으로 업데이트해요:

curl -X POST 'http://localhost:4000/team/update' \
  -H "Authorization: Bearer ***" \
  -H 'Content-Type: application/json' \
  -d '{"team_id": "<team-id>", "metadata": {"phoenix_project_name": "payments-prod"}}'

그런 다음 해당 팀의 키를 생성하고 평소처럼 프록시를 호출해요:

curl -X POST 'http://localhost:4000/key/generate' \
  -H "Authorization: Bearer ***" \
  -H 'Content-Type: application/json' \
  -d '{"team_id": "<team-id>"}'
curl -X POST 'http://localhost:4000/v1/chat/completions' \
  -H 'Authorization: Bearer ***' \
  -H 'Content-Type: application/json' \
  -d '{"model": "gpt-5.6-terra", "messages": [{"role": "user", "content": "hello"}]}'

키별 (Per key)

단일 키는 팀에 속하지 않은 키를 포함해 자체 프로젝트 이름을 지정할 수 있어요.

curl -X POST 'http://localhost:4000/key/generate' \
  -H "Authorization: Bearer ***" \
  -H 'Content-Type: application/json' \
  -d '{"metadata": {"phoenix_project_name": "payments-canary"}}'

기존 키는 /key/update에서 같은 필드를 사용해요.

Admin UI에서 팀이나 키에 동일한 metadata.phoenix_project_name 필드를 설정할 수도 있어요.

chat(또는 /v1/messages, /v1/responses) 호출 후, Phoenix는 그 요청의 chat <model> 스팬을 포함한 payments-prod라는 프로젝트를 보여줘요. phoenix_project_name: "search-prod"인 두 번째 팀은 같은 컬렉터의 다른 프로젝트에 들어가요.

어느 프로젝트가 우선하는가 (Which project wins)

우선순위가 높은 순서:

  1. 키 또는 팀의 phoenix_project_name_override
  2. 키 또는 팀의 phoenix_project_name
  3. PHOENIX_PROJECT_NAME (또는 PHOENIX_COLLECTOR_PROJECT_NAME), 아니면 default

같은 필드가 키와 팀 양쪽에 설정되면 팀의 값이 사용돼요. phoenix_project_name_override는 키가 팀의 프로젝트를 벗어나야 할 때 사용하는 이스케이프 해치(escape hatch)예요.

라우팅되는 것과 아닌 것

LLM 호출 스팬(chat <model>)은 Phoenix가 이름이 지정된 프로젝트를 만들고 채우는 데 사용하는 스팬이에요. 요청의 HTTP 루트, 인증, 데이터베이스 스팬은 env 설정 기본 프로젝트에 머물러요.

Phoenix는 스팬 중 먼저 도착하는 것에 따라 전체 트레이스를 한 프로젝트에 할당해요. 따라서 라우팅된 LLM 스팬은 자체 트레이스를 시작하고, 요청 트레이스에 대한 링크를 다시 포함해 둘 사이를 오갈 수 있어요.

gRPC 전용 Phoenix 익스포터는 라우팅할 수 없어요. x-project-name은 OTLP/HTTP에서만 존중되며, PHOENIX_COLLECTOR_HTTP_ENDPOINT를 HTTP /v1/traces URL로 지정해야 해요. 가드레일 스팬은 프로젝트 라우팅되지 않아요.

이는 테넌트의 트레이스를 자체 백엔드 계정으로 보내는 팀별 자격 증명과는 다르다는 점에 유의하세요. 프로젝트 라우팅은 한 Phoenix 컬렉터에 머물면서 프로젝트 이름만 바꿔요.

고급 (Advanced)

Phoenix와 Arize AX에 동시에 보내기

프리셋은 합성되므로 한 프록시에서 두 백엔드를 모두 실행할 수 있어요:

litellm_settings:
  callbacks: ["arize_phoenix", "arize"]

전체 OpenTelemetry 참조

이 페이지는 Phoenix 특정 설정을 다뤄요. 스팬 속성, 프롬프트·응답 캡처, 메트릭, 분산 추적, 추적되는 라우트에 대해서는 OpenTelemetry v2 가이드를 참조하세요.

추적이 아니라 프롬프트 관리를 찾고 있다면 Arize Phoenix Prompt Management를 참조하세요.

더 알아보기 (Learn more)