> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Evaluator SDK

> Failproof AI 세션을 동기 또는 비동기로 평가하는 서비스를 구축합니다.

평가자(evaluator)는 완료된 에이전트 세션을 받아 품질 신호를 반환합니다. 여기에는 숫자 점수, 각 점수에 대한 설명, 그리고 선택적인 요약이 포함됩니다. Failproof AI는 이 결과를 트레이스 옆에 저장하고 에이전트 및 환경 전반에 걸쳐 차트로 시각화합니다.

## 평가자 설정

<Steps>
  <Step title="평가자 SDK 설치">
    SDK와 실행에 필요한 서버를 설치합니다.

    ```bash theme={null}
    pip install failproofai-sdk uvicorn
    ```
  </Step>

  <Step title="평가 항목 정의">
    `evaluator.py`를 생성합니다. 이 예시에서는 세션에 실패한 도구 호출이 있는지 확인합니다.

    ```python theme={null}
    import os
    from failproofai.evaluator import Evaluator, EvalResponse

    app = Evaluator(token=os.environ.get("EVALUATOR_TOKEN"))

    @app.config
    def config():
        return {"inactivity_timeout_secs": 1800}

    @app.evaluator
    def evaluate(req):
        tool_errors = sum(
            1 for item in req.events
            if item.event_type == "tool_result" and item.payload.get("error")
        )
        return EvalResponse(
            scores={"tool_reliability": 1.0 if tool_errors == 0 else 0.0},
            reasoning={"tool_reliability": f"{tool_errors} tool errors"},
        )
    ```
  </Step>

  <Step title="로컬에서 실행 및 테스트">
    공유 토큰을 설정하고 평가자를 시작한 뒤, 헬스 엔드포인트가 응답하는지 확인합니다.

    ```bash theme={null}
    export EVALUATOR_TOKEN=<shared-token>
    uvicorn evaluator:app --host 0.0.0.0 --port 8080
    ```

    다른 터미널에서:

    ```bash theme={null}
    curl http://127.0.0.1:8080/health
    ```
  </Step>
</Steps>

## Failproof AI에 평가자 연결

1. Failproof AI Cloud에서 접근 가능한 HTTPS URL에 평가자를 배포합니다.
2. 해당 URL로 `EVALUATOR_ENDPOINT`를 설정하고, `EVALUATOR_TOKEN`을 평가자에서 사용하는 것과 동일한 토큰으로 설정합니다. 관리형 Cloud의 경우 [support@befailproof.ai](mailto:support@befailproof.ai)로 연락하여 연결을 설정합니다.
3. 평가를 실행하고 점수가 Failproof AI에 표시되는지 확인합니다.

<Tabs>
  <Tab title="대시보드">
    **Observe → Sessions**에서 완료된 세션을 열고, 자동으로 평가되지 않은 경우 **Run evaluation**을 선택합니다. 세션의 **Evaluation** 패널에서 상태, 점수, 추론, 요약을 확인합니다.

    **Observe → Evaluations**를 사용하여 에이전트 또는 환경 전반에 걸쳐 점수를 비교합니다. **Observe → Metrics**에서는 지연 시간, 비용, 토큰 수 및 기타 숫자 측정값을 확인할 수 있습니다.

    먼저 하나의 세션으로 시작하여 평가자가 해당 특정 실행에 대해 예상한 점수 키와 유용한 추론을 반환했는지 확인하세요.

    <img src="https://mintcdn.com/exosphere/WgPwQzedeDNwJBTy/images/dashboard/session-detail.png?fit=max&auto=format&n=WgPwQzedeDNwJBTy&q=85&s=7b5f022dd5c485565a8cd92b2e936235" alt="트레이스 옆에 평가 점수와 추론이 표시된 세션 상세 화면." width="3200" height="2000" data-path="images/dashboard/session-detail.png" />

    개별 결과가 올바르게 보이면, 평가 대시보드를 사용하여 시간 경과에 따른 점수와 에이전트 또는 환경별 점수를 비교합니다.

    <img src="https://mintcdn.com/exosphere/WgPwQzedeDNwJBTy/images/dashboard/dashboard-quality.png?fit=max&auto=format&n=WgPwQzedeDNwJBTy&q=85&s=74c925ae831046fc869a3a3d6e81fc25" alt="시간 경과에 따른 평가자 점수를 차트로 보여주는 품질 대시보드." width="2880" height="1800" data-path="images/dashboard/dashboard-quality.png" />

    정상적인 차트는 안정적인 점수 이름을 사용합니다. 키를 변경하면 별도의 계열이 생성됩니다.
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    fp evals --since 1h --score tool_reliability:0..1
    fp evals --since 24h --aggregate
    ```
  </Tab>
</Tabs>

자체 호스팅 Cloud 인스턴스의 경우, 서버 프로세스에 `EVALUATOR_ENDPOINT`가 설정되기 전까지 자동 평가가 비활성화됩니다. 평가자 환경 변수를 변경한 후에는 서버를 재시작하세요.

이 서비스는 `GET /health`, `GET /config`, `POST /evaluate`, 그리고 선택적으로 `GET /evaluate/{job_id}`를 노출합니다. 비동기 작업에는 `JobPending`을 반환하고 Failproof AI가 폴링할 수 있도록 `@app.job_lookup`을 등록하세요.

토큰이 설정된 경우, 헬스 라우트를 제외한 모든 라우트에서 Failproof AI가 `EVALUATOR_TOKEN`으로 전송하는 동일한 베어러 토큰이 필요합니다.

## SDK 타입

| 타입                | 필드                                                                                            |
| ----------------- | --------------------------------------------------------------------------------------------- |
| `AgentEvent`      | `id`, `ts`, `event_type`, `payload`                                                           |
| `EvalRequest`     | `schema_version`, `session_id`, `agent_id`, `environment`, `started_at`, `ended_at`, `events` |
| `EvalResponse`    | `scores`, `reasoning`, `summary`                                                              |
| `JobPending`      | `job_id`, `next_poll_secs`                                                                    |
| `EvaluatorConfig` | `inactivity_timeout_secs`, `default_poll_interval_secs`                                       |

## 데코레이터 및 라우트

| 데코레이터             | 라우트                      | 필수 여부             |
| ----------------- | ------------------------ | ----------------- |
| `@app.evaluator`  | `POST /evaluate`         | 예                 |
| `@app.job_lookup` | `GET /evaluate/{job_id}` | `JobPending` 반환 시 |
| `@app.config`     | `GET /config`            | 아니오               |

SDK는 평가 요청 본문을 25 MiB로 제한합니다. 알 수 없는 요청 필드는 무시되므로 이벤트 계약이 확장되더라도 서비스 호환성이 유지됩니다.

## 비동기 작업 반환

평가를 단일 요청 내에서 완료할 수 없는 경우 `JobPending`을 사용합니다. 작업 ID는 Failproof AI에 대해 불투명(opaque)하며, 결과가 수집되거나 서버 타임아웃이 만료될 때까지 서비스에서 해결 가능한 상태로 유지되어야 합니다.

```python theme={null}
from failproofai.evaluator import EvalRequest, EvalResponse, Evaluator, JobPending

app = Evaluator(token="shared-secret")

@app.evaluator
def start(req: EvalRequest) -> JobPending:
    job_id = enqueue(req)
    return JobPending(job_id=job_id, next_poll_secs=30)

@app.job_lookup
def lookup(job_id: str):
    result = get_result(job_id)
    if result is None:
        return JobPending(job_id=job_id, next_poll_secs=30)
    return EvalResponse(
        scores=result.scores,
        reasoning=result.reasoning,
        summary=result.summary,
    )
```

폴링 주기는 다음 순서로 결정됩니다: `JobPending.next_poll_secs`, `EvaluatorConfig.default_poll_interval_secs`, 그 다음 서버의 `EVALUATOR_POLLING_INTERVAL_SECS`. 값은 1초에서 1시간 사이로 제한됩니다. 서버의 기본 실제 시간(wall-clock) 폴링 상한은 1시간입니다.

## 요청 및 응답 필드

| 필드                                      | 타입                         | 비고                             |
| --------------------------------------- | -------------------------- | ------------------------------ |
| `EvalRequest.schema_version`            | `str`                      | 현재 `"1"`.                      |
| `session_id`, `agent_id`, `environment` | `str`                      | 세션 식별자 및 환경.                   |
| `started_at`                            | `datetime`                 | 첫 번째 이벤트의 타임스탬프.               |
| `ended_at`                              | `datetime \| None`         | 세션이 종료 이벤트를 방출한 경우 존재.         |
| `events`                                | `list[AgentEvent]`         | 완전한 순서가 있는 이벤트 스트림.            |
| `AgentEvent.id`                         | `int`                      | 백엔드 이벤트 행 식별자.                 |
| `AgentEvent.ts`                         | `datetime`                 | 이벤트 타임스탬프.                     |
| `AgentEvent.event_type`                 | `str`                      | `tool_use`와 같은 이벤트 계열.         |
| `AgentEvent.payload`                    | `dict[str, Any]`           | 완전한 이벤트 페이로드.                  |
| `EvalResponse.scores`                   | `dict[str, float] \| None` | 평가에서 차트로 표시되는 숫자 차원.           |
| `EvalResponse.reasoning`                | `dict[str, str] \| None`   | 점수별 설명; 키는 `scores`와 일치해야 합니다. |
| `EvalResponse.summary`                  | `str \| None`              | 전체 평가 서술.                      |

## 서버 운영자 설정

자동 평가는 배포 전체에 적용되며 `EVALUATOR_ENDPOINT`가 없으면 비활성화됩니다.

| 변수                                 | 기본값     | 용도                                   |
| ---------------------------------- | ------- | ------------------------------------ |
| `EVALUATOR_ENDPOINT`               | 미설정     | 평가자 서비스의 기본 URL.                     |
| `EVALUATOR_TOKEN`                  | 미설정     | `Evaluator(token=...)`와 공유하는 베어러 토큰. |
| `EVALUATOR_WORKERS`                | `2`     | 동시 디스패처 워커 수.                        |
| `EVALUATOR_CLAIM_BATCH`            | `4`     | 디스패처 패스당 처리하는 세션 수.                  |
| `EVALUATOR_POLLING_INTERVAL_SECS`  | `10`    | 비동기 폴링 기본 주기.                        |
| `EVALUATOR_REQUEST_TIMEOUT_MS`     | `30000` | 요청별 평가자 타임아웃.                        |
| `EVALUATOR_MAX_ATTEMPTS`           | `5`     | 최종 실패 전 전달 시도 횟수.                    |
| `EVALUATOR_CONFIG_REFRESH_SECS`    | `300`   | `/config` 갱신 주기.                     |
| `EVALUATOR_MAX_POLL_DURATION_SECS` | `3600`  | 비동기 폴링 최대 실제 시간(wall-clock).         |

서버는 배포 전역 평가자를 사용하는 조직을 제한할 수도 있습니다. 엔드포인트, 토큰, 재시도, 조직 게이트 변경은 운영자 구성으로 처리하고 변경 후 서버를 재시작하거나 롤링 재시작하세요.

## 보안 및 운영

* 트래픽이 신뢰할 수 없는 네트워크 경계를 통과하는 경우 평가자를 HTTPS 뒤에 배치합니다.
* 비어 있지 않은 베어러 토큰을 구성하고 두 서비스에서 동일하게 유지합니다.
* 토큰이나 요청 페이로드에서 민감한 전체 프롬프트를 로그에 남기지 않습니다.
* 동기 핸들러는 멱등성(idempotent)을 유지합니다. 재시도 시 요청이 반복될 수 있습니다.
* 프로덕션에서는 비동기 작업 상태를 프로세스 메모리 외부에 저장합니다.
* 안정적인 점수 키를 반환합니다. 키 이름을 변경하면 기존 계열을 변경하는 것이 아니라 새 차트 계열이 생성됩니다.

SDK는 `eval received`, `eval responded`, `job lookup`, `config returned`, `auth rejected`, 핸들러 예외 등의 구조화된 라이프사이클 로그를 방출합니다. 로깅 핸들러는 직접 구성하지 않으므로 호스트 애플리케이션의 로깅 구성을 사용하세요.
