Handler Mode

Handler Mode

HTTP 엔드포인트가 없는 AI 앱을, Confident Agent가 로컬에서 실행하는 handler 함수를 구현해 연결하는 방식이에요. HTTP 엔드포인트가 없는 AI 앱을 Confident AI에 연결할 수 있게 해줘요.

출처: 문서

본문

AI Connection을 URL에 연결하는 대신, Confident Agent가 사용자 환경 안에서 실행하는 작은 handler 함수를 구현해요. Confident AI는 에이전트의 기존 아웃바운드 터널로 입력을 보내고, 함수가 로컬에서 출력을 만들면 에이전트가 이를 다시 릴레이해요.

Handler Mode는 Enterprise 기능이며 Confident Agent 기반으로 동작해요. AI 앱의 코드와 데이터는 네트워크 밖으로 나가지 않아요. 들어오는 것은 Confident AI가 생성한 입력뿐이고, 나가는 것은 앱의 출력뿐이에요.

Handler Mode를 언제 쓸까 (When to Use Handler Mode)

호출 가능한 서비스로 노출되지 않은 앱을 평가하거나 레드팀하고 싶을 때 Handler Mode를 사용하세요.

  • 파이프라인이 앞에 API가 없는 내부 스크립트·노트북·라이브러리일 때
  • 엔드포인트를 만들고 호스팅하는 것이(내부적으로도) 평가 하나에 비해 더 많은 작업일 때
  • 보안·규정상 입력을 제자리에서 처리해야 하고, 인바운드가 없으며 Confident AI가 코드를 호스팅하지 않아야 할 때

앱에 이미 HTTP 엔드포인트가 있다면 표준 AI Connection을 — 아니면 방화벽 뒤의 프라이빗 엔드포인트라면 기본 전달(forwarding) 모드의 Confident Agent를 — 사용하세요.

동작 방식 (How It Works)

에이전트는 전달 모드와 똑같이 WebSocket Secure (WSS)로 아웃바운드 연결을 맺어요. 차이는 요청이 도착했을 때죠. 내부 URL로 전달하는 대신 에이전트가 handler 함수를 호출하고 그것이 반환하는 것을 릴레이해요.

sequenceDiagram
    participant P as Your Pipeline (imported)
    participant H as handler()
    participant A as Confident Agent
    participant C as Confident AI

    A->>C: Connect outbound (WSS/443)
    Note over A,C: WebSocket tunnel established

    C->>A: Send evaluation input
    A->>H: handler(request)
    H->>P: Call your app in-process
    P-->>H: Output
    H-->>A: return output
    A-->>C: Relay output back
    Note over C: Evaluation continues

handler는 에이전트가 시작될 때 한 번 import 되므로, 모델 로딩·클라이언트 생성 같은 비싼 설정이 한 번만 일어나요. 그 후 함수는 같은 장수명 연결 위에서 입력마다 한 번씩 호출돼요.

요구사항 (Requirements)

  • 에이전트를 실행하는 머신에서 포트 443 (WSS)의 아웃바운드 인터넷 접근
  • 파이프라인을 import 할 수 있는 런타임 (그 의존성이 설치된)
  • 인바운드 포트를 열 필요 없음

빠른 시작 (Quick Start)

handler는 호출하는 앱과 같은 런타임에서 실행되므로, 파이프라인이 쓰여진 언어의 탭을 선택해요. Python과 TypeScript는 파일에서 handler를 로드하고, Go·Java·Rust는 라이브러리로 코드에서 handler를 등록하며, 그 외 언어는 작은 로컬 엔드포인트와 에이전트의 전달 모드로 연결해요.

Python

에이전트 설치 (Install the agent)

파이프라인과 같은 환경에 PyPI의 Confident Agent를 설치해요. 러너와 handler 데코레이터가 함께 배포돼요.

pip install confident-agent

handler 작성 (Write your handler)

confident_handler.py 같은 파일을 만들고, 하나의 함수에 @handler를 붙여요. 함수는 Request를 받아 앱의 출력을 담은 Response를 반환해요. 기존 파이프라인을 직접 import 해 호출하면 되고, 접착 코드(glue)만 작성하면 돼요.

from confident_agent import handler, Request, Response
from my_company.pipeline import summarize  # your existing code

@handler
def summarize_handler(request: Request) -> Response:
    return Response(
        output=summarize(request.input, request.context),
    )

Response 객체는 항상 출력을 담고, 검색 컨텍스트·도구 호출·멀티 턴 state도 포함할 수 있어요. 출력만 필요한 경우 일반 문자열을 반환하는 축약형도 여전히 쓸 수 있어요.

에이전트 실행 (Run the agent)

handler 파일을 가리키며 프로젝트 API 키로 인증해 에이전트를 시작해요. handler가 파이프라인을 import 하므로, 파이프라인과 같은 Python 환경 — 앱이 이미 쓰는 것과 같은 virtualenv, conda env, 컨테이너 — 에서 실행하세요. 이게 handler mode를 실행하는 권장 방식이에요.

CONFIDENT_API_KEY=<your-api-key> confident-agent --handler confident_handler.py

그게 명령어 전부예요. 구성할 URL이나 포트가 없어요. 에이전트가 Confident AI로 아웃바운드 연결하고, 테스트 런이 앱의 출력이 필요할 때 handler 함수를 직접 호출해요.

대신 Docker로 실행하기 (Running with Docker instead)

팀이 모든 것을 컨테이너로 배포하는 경우에만 Docker를 사용하세요. 기본 confidentai/confident-agent 이미지에는 에이전트만 들어 있고 — 파이프라인의 의존성이 없어 — handler를 마운트하면 import 시 실패해요(자체 패키지에서 ModuleNotFoundError). 대신 우리 이미지를 기반으로 코드와 의존성을 추가한 자체 이미지를 빌드하세요.

FROM confidentai/confident-agent
USER root
COPY . /app
RUN pip install -r /app/requirements.txt
USER confident

빌드한 뒤 실행해요. Docker에서는 CLI 플래그 대신 같은 두 설정을 환경 변수로 전달해요.

docker build -t my-company/confident-handler .

docker run -d \
  -e CONFIDENT_API_KEY=<your-api-key> \
  -e CONFIDENT_HANDLER=/app/confident_handler.py \
  my-company/confident-handler

에이전트가 연결되면 AI Connection 설정에서 연결 상태가 Agent connected로 바뀌어요.

AI Connection 생성하기 (Create the AI Connection)

Project Settings(프로젝트 설정) → AI Connections에서 New AI Connection을 클릭하고, 이름을 주고 Target을 **Confident Agent (Handler)**로 설정해요. 구성할 엔드포인트 URL은 없어요. 저장한 뒤 테스트해 보세요.

TypeScript

TypeScript SDK는 같은 request/response 계약을 바탕으로 Python SDK를 미러링하며, request 필드는 camelCase예요(request.retrievalContext는 request.retrieval_context가 아니라요).

에이전트 설치 (Install the agent)

파이프라인과 같은 프로젝트에 npm의 Node 에이전트를 설치해요.

npm install confident-agent

handler 작성 (Write your handler)

handler.ts 같은 파일을 만들고 하나의 handler를 등록해요. 함수는 Request를 받아 앱의 출력을 담은 Response를 반환해요. 기존 파이프라인을 직접 import 해 호출해요.

import { handler, type Request, type Response } from "confident-agent";
import { summarize } from "./pipeline"; // your existing code

handler(
  (request: Request): Response => ({
    output: summarize(request.input, request.context),
  }),
);

Response 객체는 항상 출력을 담고 retrievalContext, toolsCalled, state도 포함할 수 있어요. 문자열을 반환하는 출력 전용 축약형도 여전히 쓸 수 있어요.

에이전트 실행 (Run the agent)

handler 파일을 가리키며 프로젝트 API 키로 인증해 에이전트를 시작해요. handler가 파이프라인을 import 하므로 파이프라인과 같은 프로젝트에서 실행하세요.

CONFIDENT_API_KEY=<your-api-key> npx confident-agent --handler ./handler.ts

.ts handler 파일을 직접 로드하려면 Node.js ≥ 22.18 (네이티브 TypeScript 타입 스트리핑)이 필요해요. 이전 Node 버전에서는 handler를 .js로 컴파일한 뒤 --handler로 그 파일을 가리키세요.

confident-agent 패키지는 ESM 전용이에요. 프로젝트의 package.json이 "type": "module"을 설정하지 않으면 Node는 handler 파일을 CommonJS로 로드하고 import가 Cannot use import statement outside a module로 실패해요. package.json에 "type": "module"을 추가하거나, handler 파일을 handler.mts(.mts는 항상 ES 모듈로 취급)로 이름 지으세요. Request·Response 같은 타입 전용 export는 위 예시처럼 type 키워드로 import 해야 해요. Node의 타입 스트리핑은 일반 named import를 지우지 않거든요.

AI Connection 생성하기 (Create the AI Connection)

Project Settings(프로젝트 설정) → AI Connections에서 New AI Connection을 클릭하고, 이름을 주고 Target을 **Confident Agent (Handler)**로 설정해요. 구성할 엔드포인트 URL은 없어요. 저장한 뒤 테스트해 보세요.

Go

Go는 런타임에 파일에서 코드를 로드하지 못하므로 --handler 플래그가 없어요. 대신 handler mode는 라이브러리 기반이에요. confidentagent.Handler(Go에서 @handler 데코레이터에 해당)로 코드에서 handler를 등록하고 자체 main에서 에이전트를 시작해요.

에이전트 설치 (Install the agent)

파이프라인을 담은 프로젝트에 pkg.go.dev의 Go 모듈을 추가해요.

go get github.com/confident-ai/confident-agent/go

handler 작성 및 에이전트 실행 (Write your handler and run the agent)

handler를 하나 등록한 뒤 Run()을 호출해요. handler는 Request를 받아 앱의 출력을 담은 Response를 반환하고, 문자열 반환은 출력 전용 축약형으로 사용할 수 있어요.

package main

import (
    "log"

    confidentagent "github.com/confident-ai/confident-agent/go"
)

func main() {
    confidentagent.Handler(func(request confidentagent.Request) (any, error) {
        return confidentagent.Response{
            Output: summarize(request.Input, request.Context),
        }, nil // your existing code
    })

    if err := confidentagent.Run(); err != nil {
        log.Fatal(err)
    }
}

프로젝트 API 키로 빌드·실행해요. 구성할 URL이나 포트는 없어요.

CONFIDENT_API_KEY=<your-api-key> go run .

AI Connection 생성하기 (Create the AI Connection)

Project Settings(프로젝트 설정) → AI Connections에서 New AI Connection을 클릭하고, 이름을 주고 Target을 **Confident Agent (Handler)**로 설정해요. 구성할 엔드포인트 URL은 없어요. 저장한 뒤 테스트해 보세요.

Java

Java는 스크립트 파일에서 handler를 로드할 수 없으므로 handler mode는 라이브러리 기반이에요. com.confident-ai:confident-agent에 의존하고 Decorator.handler(...)(Java에서 @handler 데코레이터에 해당)로 handler를 등록한 뒤 자체 엔트리 포인트에서 에이전트를 시작해요.

에이전트 설치 (Install the agent)

파이프라인을 담은 프로젝트에 의존성을 추가해요.

<dependency>
  <groupId>com.confident-ai</groupId>
  <artifactId>confident-agent</artifactId>
  <version>1.0.1</version>
</dependency>

handler 작성 및 에이전트 실행 (Write your handler and run the agent)

handler를 하나 등록한 뒤 에이전트를 시작해요. handler는 Request를 받아 앱의 출력을 담은 Response를 반환하고, String 반환은 출력 전용 축약형으로 사용할 수 있어요.

import static ai.confident.agent.handler.Decorator.handler;

import ai.confident.agent.RelayAgent;
import ai.confident.agent.schemas.Request;
import ai.confident.agent.schemas.Response;

public class MyAgent {
    public static void main(String[] args) throws InterruptedException {
        handler((Request request) -> {
            return new Response(
                summarize(request.input, request.context)
            ); // your existing code
        });

        RelayAgent.createAgent().start();
    }
}

프로젝트 API 키로 실행해요. 구성할 URL이나 포트는 없어요.

CONFIDENT_API_KEY=<your-api-key> java -jar my-agent.jar

AI Connection 생성하기 (Create the AI Connection)

Project Settings(프로젝트 설정) → AI Connections에서 New AI Connection을 클릭하고, 이름을 주고 Target을 **Confident Agent (Handler)**로 설정해요. 구성할 엔드포인트 URL은 없어요. 저장한 뒤 테스트해 보세요.

Rust

Rust는 런타임에 파일에서 코드를 로드하지 못하므로 --handler 플래그가 없어요. 대신 handler mode는 라이브러리 기반이에요. 자체 바이너리에 crate를 추가하고 confident_agent::handler(Rust에서 @handler 데코레이터에 해당)로 handler 클로저를 등록한 뒤 에이전트를 실행해요.

에이전트 설치 (Install the agent)

파이프라인을 담은 프로젝트에 crates.io의 Rust crate를 추가해요.

cargo add confident-agent tokio

handler 작성 및 에이전트 실행 (Write your handler and run the agent)

handler 클로저를 하나 등록한 뒤 run()을 호출해요. handler는 Request를 받아 앱의 출력을 담은 Response를 반환하고, String 반환은 출력 전용 축약형으로 사용할 수 있어요.

use confident_agent::{handler, Request, Response};

#[tokio::main]
async fn main() {
    handler(|request: Request| async move {
        Ok(Response {
            output: summarize(&request.input, &request.context),
            ..Response::default()
        }) // your existing code
    });

    if let Err(e) = confident_agent::run().await {
        eprintln!("{e}");
        std::process::exit(1);
    }
}

프로젝트 API 키로 실행해요. 구성할 URL이나 포트는 없어요.

CONFIDENT_API_KEY=<your-api-key> cargo run

AI Connection 생성하기 (Create the AI Connection)

Project Settings(프로젝트 설정) → AI Connections에서 New AI Connection을 클릭하고, 이름을 주고 Target을 **Confident Agent (Handler)**로 설정해요. 구성할 엔드포인트 URL은 없어요. 저장한 뒤 테스트해 보세요.

기타 (Other)

네이티브 handler SDK가 없는 언어(Clojure 및 기타 JVM 언어, Elixir 등)는 범용 대체(universal fallback) — 작은 로컬 HTTP 엔드포인트와 에이전트의 전달 모드 — 로 연결해요. 공개적으로 노출되는 것은 없어요.

로컬 엔드포인트 노출하기 (Expose a local endpoint)

파이프라인을 작은 HTTP handler로 감싸요 — 예를 들어 Ring을 써서요. localhost에서만 듣고 있으면 돼요.

(require '[ring.adapter.jetty :as jetty]
         '[ring.middleware.json :refer [wrap-json-body wrap-json-response]]
         '[ring.util.response :refer [response]])

(defn handler [req]
  (let [{:strs [input context]} (:body req)]
    (response {:output (summarize input context)})))

(jetty/run-jetty
  (-> handler wrap-json-body wrap-json-response)
  {:port 8000})

전달 모드로 에이전트 실행하기 (Run the agent in forwarding mode)

같은 네트워크에서 Confident Agent를 시작해요. handler 파일은 필요 없고 아웃바운드 접근만 있으면 돼요.

docker run -d \
  -e CONFIDENT_API_KEY=<your-api-key> \
  -e CONFIDENT_WS_BASE_URL=wss://deepeval.confident-ai.com/ws/relay \
  confidentai/confident-agent

AI Connection을 로컬 엔드포인트로 연결하기 (Point an AI Connection at the local endpoint)

AI Connection을 만들고 Internal을 활성화한 뒤 엔드포인트를 로컬 URL(예: http://localhost:8000!)로 설정해요. 페이로드를 매핑하고 Actual Output Key Path를 ["output"]으로 설정해요.

The Handler

handler는 SDK에 등록된 어떤 함수든 돼요 — Python의 @handler, TypeScript와 Rust의 handler(...), Go의 confidentagent.Handler(...), Java의 Decorator.handler(...)요. 에이전트가 시작 시 이를 발견하고, 함수 이름은 자유예요. 에이전트 프로세스당 정확히 하나의 handler가 있어요. (HTTP fallback을 사용하는 언어에서는 이 섹션이 적용되지 않아요. 엔드포인트가 계약을 정의하거든요.)

Request

handler는 하나의 Request 객체를 받아요. 이 계약은 모든 네이티브 SDK에서 같은 데이터를 지니지만, 필드 이름과 타입은 각 언어의 관례를 따르요. 필요한 필드만 읽으면 되고, 사용하지 않는 필드는 무시해도 안전해요.

Python

Field Description Type
request.input The input for a single-turn golden str
request.context Context from the golden list[str]
request.retrieval_context Retrieval context from the golden list[str]
request.expected_output Expected output, when present str | None
request.turns Turn history for multi-turn evaluations list[Turn]
request.scenario Scenario for conversational goldens str | None
request.state Mutable state carried across multi-turn simulations Any
request.prompts Prompt versions attached to the connection dict[str, Any] | None
request.hyperparameters Hyperparameters attached to the connection dict[str, Any] | None
request.test_case_id Identifier for linking the test case to a trace str | None
request.turn_id Identifier for linking an individual turn to a trace str | None

TypeScript

Field Description Type
request.input The input for a single-turn golden string
request.context Context from the golden string[]
request.retrievalContext Retrieval context from the golden string[]
request.expectedOutput Expected output, when present string | null
request.turns Turn history for multi-turn evaluations Turn[]
request.scenario Scenario for conversational goldens string | null
request.state Mutable state carried across multi-turn simulations unknown
request.prompts Prompt versions attached to the connection Record<string, unknown> | null
request.hyperparameters Hyperparameters attached to the connection Record<string, unknown> | null
request.testCaseId Identifier for linking the test case to a trace string | null
request.turnId Identifier for linking an individual turn to a trace string | null

Go

Field Description Type
request.Input The input for a single-turn golden string
request.Context Context from the golden []string
request.RetrievalContext Retrieval context from the golden []string
request.ExpectedOutput Expected output, when present *string
request.Turns Turn history for multi-turn evaluations []Turn
request.Scenario Scenario for conversational goldens *string
request.State Mutable state carried across multi-turn simulations any
request.Prompts Prompt versions attached to the connection map[string]any
request.Hyperparameters Hyperparameters attached to the connection map[string]any
request.TestCaseID Identifier for linking the test case to a trace *string
request.TurnID Identifier for linking an individual turn to a trace *string

Java

Field Description Type
request.input The input for a single-turn golden String
request.context Context from the golden List<String>
request.retrievalContext Retrieval context from the golden List<String>
request.expectedOutput Expected output, when present String (nullable)
request.turns Turn history for multi-turn evaluations List<Turn>
request.scenario Scenario for conversational goldens String (nullable)
request.state Mutable state carried across multi-turn simulations Object
request.prompts Prompt versions attached to the connection Map<String, Object>
request.hyperparameters Hyperparameters attached to the connection Map<String, Object>
request.testCaseId Identifier for linking the test case to a trace String (nullable)
request.turnId Identifier for linking an individual turn to a trace String (nullable)

Rust

Field Description Type
request.input The input for a single-turn golden String
request.context Context from the golden Vec<String>
request.retrieval_context Retrieval context from the golden Vec<String>
request.expected_output Expected output, when present Option<String>
request.turns Turn history for multi-turn evaluations Vec<Turn>
request.scenario Scenario for conversational goldens Option<String>
request.state Mutable state carried across multi-turn simulations Option<Value>
request.prompts Prompt versions attached to the connection Option<Value>
request.hyperparameters Hyperparameters attached to the connection Option<Value>
request.test_case_id Identifier for linking the test case to a trace Option<String>
request.turn_id Identifier for linking an individual turn to a trace Option<String>

Response

앱의 출력을 담은 Response를 반환해요. 이 계약은 모든 네이티브 SDK에서 같은 데이터를 지니며, 언어별 필드 이름과 타입을 가져요. 출력 전용 handler에서는 일반 문자열 축약형이 계속 지원돼요.

Python

from confident_agent import handler, Request, Response

@handler
def rag_handler(request: Request) -> Response:
    result = pipeline(request.input)
    return Response(
        output=result.answer,
        retrieval_context=result.chunks,
        tools_called=result.tools,
    )
Field Description Type
output The actual output of your app (required) str
retrieval_context Retrieved chunks, for RAG metrics list[str] | None
tools_called Tools your app invoked, for tool metrics list[ToolCall] | None
state Updated state to carry into the next turn Any

TypeScript

import { handler, type Request, type Response } from "confident-agent";

handler((request: Request): Response => {
  const result = pipeline(request.input);
  return {
    output: result.answer,
    retrievalContext: result.chunks,
    toolsCalled: result.tools,
  };
});
Field Description Type
output The actual output of your app (required) string
retrievalContext Retrieved chunks, for RAG metrics string[] | null
toolsCalled Tools your app invoked, for tool metrics ToolCall[] | null
state Updated state to carry into the next turn unknown

Go

confidentagent.Handler(func(request confidentagent.Request) (any, error) {
    result := pipeline(request.Input)
    return confidentagent.Response{
        Output:           result.Answer,
        RetrievalContext: result.Chunks,
        ToolsCalled:      result.Tools,
    }, nil
})
Field Description Type
Output The actual output of your app (required) string
RetrievalContext Retrieved chunks, for RAG metrics []string
ToolsCalled Tools your app invoked, for tool metrics []ToolCall
State Updated state to carry into the next turn any

Java

handler((Request request) -> {
    var result = pipeline(request.input);
    var response = new Response(result.answer);
    response.retrievalContext = result.chunks;
    response.toolsCalled = result.tools;
    return response;
});
Field Description Type
output The actual output of your app (required) String
retrievalContext Retrieved chunks, for RAG metrics List<String>
toolsCalled Tools your app invoked, for tool metrics List<ToolCall>
state Updated state to carry into the next turn Object

Rust

handler(|request: Request| async move {
    let result = pipeline(&request.input);
    Ok(Response {
        output: result.answer,
        retrieval_context: Some(result.chunks),
        tools_called: Some(result.tools),
        state: None,
    })
});
Field Description Type
output The actual output of your app (required) String
retrieval_context Retrieved chunks, for RAG metrics Option<Vec<String>>
tools_called Tools your app invoked, for tool metrics Option<Vec<ToolCall>>
state Updated state to carry into the next turn Option<Value>

Response 필드는 자동으로 매핑되므로 output 키 경로를 구성할 필요가 없어요. 반환된 문자열도 actual output으로 직접 매핑돼요.

오류 처리하기 (Handling Errors)

handler가 오류를 던지거나 반환하면, 에이전트는 그 단일 입력에 대한 실패를 보고하고 런은 계속돼요. 나쁜 입력 하나가 전체 평가를 중단하지 않아요. 오류 메시지는 테스트 케이스에 표시되어 디버깅할 수 있어요.

Python

from confident_agent import handler, Request, Response

@handler
def summarize_handler(request: Request) -> Response:
    if not request.input:
        raise ValueError("empty input")
    return Response(
        output=summarize(request.input, request.context),
    )

TypeScript

import { handler, type Request, type Response } from "confident-agent";

handler((request: Request): Response => {
  if (!request.input) {
    throw new Error("empty input");
  }
  return {
    output: summarize(request.input, request.context),
  };
});

Go

confidentagent.Handler(func(request confidentagent.Request) (any, error) {
    if request.Input == "" {
        return nil, errors.New("empty input")
    }
    return confidentagent.Response{
        Output: summarize(request.Input, request.Context),
    }, nil
})

Java

handler((Request request) -> {
    if (request.input.isEmpty()) {
        throw new IllegalArgumentException("empty input");
    }
    return new Response(
        summarize(request.input, request.context)
    );
});

Rust

handler(|request: Request| async move {
    if request.input.is_empty() {
        return Err(HandlerError::new("empty input"));
    }
    Ok(Response {
        output: summarize(&request.input, &request.context),
        ..Response::default()
    })
});

구성 (Configuration)

Variable Description Required
CONFIDENT_API_KEY Your project API key Yes
CONFIDENT_HANDLER Path to the file containing your @handler function (Python and TypeScript only) Yes, for handler mode
CONFIDENT_WS_BASE_URL WebSocket relay URL No — defaults to wss://deepeval.confident-ai.com/ws/relay

Python과 TypeScript에서는 --handler CLI 플래그와 CONFIDENT_HANDLER 환경 변수가 동일해요. 에이전트를 실행하는 방식에 맞는 쪽을 쓰면 돼요. Go·Java·Rust에서는 handler를 코드에서 등록하므로 둘 다 적용되지 않아요.

Handler 테스트하기 (Testing Your Handler)

연결에서 Ping을 클릭해요. Confident AI가 샘플 입력 하나를 터널로 보내고, handler를 실행한 뒤 반환된 내용을 보여줘요. 초록 결과는 handler가 발견되고·실행되고·출력을 생성한다는 뜻이에요. handler를 찾지 못하거나, 던지거나, 아무것도 반환하지 않으면 전체 평가·어세스먼트를 실행하기 전에 고칠 수 있도록 오류가 표시돼요.

✅ 완료 — 엔드포인트 없이 AI 앱이 연결됐어요. 평가와 레드티밍을 실행할 준비가 됐어요.

멀티 턴 (Multi-Turn)

멀티 턴 평가에서는 request.turns가 지금까지의 대화를 담고 request.state가 이전 턴에서 반환한 것을 담아요. 업데이트된 state를 담은 Response를 반환해 정보를 앞으로 연결하세요. 전체 모델은 Multi-Turn State를 참고하세요.

다음 단계 (Next Steps)

Confident Agent

에이전트의 아웃바운드 터널 동작과, 내부 엔드포인트가 있는 앱을 위한 전달 모드에 대해 배워요.

AI Connections

전체 AI Connection 모델 — 페이로드, 출력 파싱, 헤더 등.

No-Code Red Teaming

handler로 연결된 앱을 상대로 적대적(adversarial) 어세스먼트를 실행해요.

Single-Turn Evals Without Code

플랫폼에서 연결을 상대로 데이터셋 평가를 실행해요.

더 알아보기 (Learn more)