에이전트 서버

에이전트 서버는 에이전트 코드를 서비스로 전환하는 라이브러리입니다. 에이전트 루프를 HTTP 서버로 감싸고, 클라이언트가 에이전트를 실행하기 위해 호출하는 API를 정의하며, 클라이언트 연결을 관리하고, 실행 중단 시 어떤 일이 일어나는지 결정합니다. 에이전트 서버는 에이전트 런타임에서 실행됩니다. 레이어들이 어떻게 맞물리는지 알고 싶다면 Azure Databricks에 에이전트 배포를 참고하세요.

새로운 에이전트의 경우, Databricks는 AgentKit이 제공하며 이 페이지에서 설명하는 에이전트 서버를 추천합니다. 레거시 에이전트 서버와 비교하려면 Azure Databricks의 에이전트 서버 비교를 참조하세요.

Requirements

  • Python 3.10 이상입니다.
  • AgentKit이 포함된 databricks-agentbricks 패키지. agentbricks init로 만든 프로젝트는 agentbricks init를 의존성으로 선언합니다.

AgentKit

AgentKit은 Agent Runtime에서 실행되는 에이전트를 구축하는 Agent Bricks 라이브러리입니다. 에이전트를 지원하는 에이전트 서버와 에이전트 메모리, 에이전트 세션, 추적, 인증을 위한 클라이언트 및 헬퍼를 제공합니다. Agent Bricks CLI로 생성하는 프로젝트는 기본적으로 AgentKit을 사용합니다.

에이전트 서버

AgentKit은 DurableAgentServer 클래스를 통해 에이전트 서버를 제공합니다. 에이전트 서버는 에이전트 루프를 HTTP 서버로 감싸 인보케이션 API를 제공하고, 각 실행을 추적하며, 크래시나 재시작으로 인한 중단된 실행을 복구합니다. 이 콘솔은 다음과 같은 기능을 제공합니다.

  • 모든 요청 모드에 대해 하나의 API: 동기, 스트리밍, 백그라운드 호출, 스트림 재연결까지 모두 동일한 핸들러가 제공합니다.
  • 멱등 호출: 클라이언트가 생성한 호출 ID는 재시도 요청이 중복 실행을 시작하지 않도록 보장합니다.
  • 순서 세션: 같은 세션 내 호출은 한 번에 하나씩, 순서대로 실행됩니다.
  • 지속 실행 상태: 배포 시 실행 상태, 이벤트, 결과는 워커 재시작에도 유지됩니다.
  • 크래시 복구: 서버가 중단된 실행을 감지하고 재시도를 시작합니다.
  • 요청-사용자 권한 부여: 도구는 요청을 보낸 사용자의 권한에 따라 행동할 수 있습니다.
  • 커스텀 엔드포인트: 에이전트 서버는 FastAPI 애플리케이션이기 때문에 자신만의 경로를 추가할 수 있습니다.

에이전트킷에 포함된 내용

AgentKit은 databricks_agentkit 바로 그 Python 라이브러리입니다. 다음을 내보냅니다:

Export Description
DurableAgentServer, InvocationContext 에이전트 서버와 그것이 호출 및 복구 핸들러에게 전달하는 컨텍스트
AgentKitClient 에이전트 메모리와 에이전트 세션 저장소를 위한 클라이언트입니다. 저장소를 생성하고 가져오며, 저장소의 메모리와 세션을 SessionStore, SessionItem, MemoryStore, Session, MemorySearchResult, 및 Memory 객체로 노출합니다.
configure_tracing, start_trace 에이전트에 MLflow 추적을 설정하고, 작업 단위를 대상으로 trace를 시작하세요.
workspace_client, workspace_headers 에이전트 환경에서 인증된 Databricks SDK WorkspaceClient를 만들거나 직접 HTTP 호출을 위한 인증 헤더를 받으세요.
list_ai_gateway_model_services 에이전트가 Unity 게이트웨이를 통해 호출할 수 있는 모델 서비스를 나열하세요.

라이브러리에는 생성된 템플릿이 각 프레임워크를 세션 스토어와 연결하는 데 사용하는 databricks_agentkit.langgraph 및 databricks_agentkit.openai에 있는 프레임워크 헬퍼도 포함되어 있습니다. 메모리 및 세션 API에 대해서는 에이전트 메모리 및 에이전트 세션을 참조하세요.

에이전트를 등록하세요

agentbricks init로 프로젝트를 생성하면 CLI가 대신 이 작업을 해줍니다. 생성된 runtime/main.py는 서버를 생성하고 템플릿의 호출 및 복구 핸들러를 등록하므로, 에이전트 코드 agent/만 편집하면 됩니다. 이 섹션의 단계를 따라 기존 에이전트를 가져오거나 직접 핸들러를 작성하세요.

DurableAgentServer를 생성하고 비동기 호출 핸들러 @app.invoke를 등록합니다. 핸들러는 요청의 input와 호출 컨텍스트를 받아 JSON 직렬화 가능한 결과를 반환합니다. 진행 상황을 이벤트로 context.emit 게시하세요.

from databricks_agentkit import DurableAgentServer, InvocationContext

app = DurableAgentServer()


@app.invoke
async def invoke(input, context: InvocationContext) -> dict:
    await context.emit({"type": "status", "message": "Looking that up"})
    answer = await run_my_agent(input, session_id=context.session_id)
    return {"answer": answer}

하나의 호출 핸들러를 등록할 수 있고, 호출 핸들러가 없으면 서버가 시작되지 않습니다. 핸들러는 모든 요청 모드를 지원합니다: 클라이언트는 결과를 기다리거나, 이벤트를 스트리밍하거나, 백그라운드에서 실행할지 선택합니다.

서버를 로컬에서 실행하려면 agentbricks dev로 시작하세요. agentbricks init로 생성한 프로젝트에는 Uvicorn으로 서버를 실행하는 엔트리포인트와 배포 후 동일한 엔트리포인트를 시작하는 app.yaml 파일이 포함됩니다.

호출 컨텍스트

핸들러의 두 번째 인수는 다음과 같습니다: InvocationContext

Attribute Description
invocation_id 이 호출을 위해 클라이언트가 보낸 ID입니다.
session_id 호출이 속한 세션 또는 클라이언트가 세션을 보내지 않은 경우 None
attempt 시도 횟수. 첫 번째 시도는 1입니다.
is_recovery True 복구 핸들러가 대체 시도를 실행할 때.
emit(event) JSON 이벤트를 저장하고, 스트리밍 클라이언트에게 전달하며, 스트림 내 이벤트의 위치를 반환합니다.
request_auth 에이전트에 요청-사용자 권한 부여가 필요한 경우의 요청-사용자 자격 증명 확인자 그렇지 않으면 None입니다.

호출 API

DurableAgentServer는 /api/invocations에서 호출 API를 제공합니다:

  • POST /api/invocations 호출이 시작된다. 기본적으로 요청은 결과를 기다립니다. 이벤트를 Server-Sent Events로 수신하도록 background 설정하거나, 상태 URL을 즉시 반환하도록 stream 설정하세요.
  • GET /api/invocations/<id> 호출의 상태를 반환하고, 호출이 완료된 후에는 출력을 반환합니다.
  • GET /api/invocations/<id>/events?after=<event-id> 저장된 이벤트를 스트리밍하여 클라이언트가 연결이 끊긴 후 다시 연결할 수 있도록 합니다.

요청 필드, 예제, 응답 형식에 대해서는 Azure Databricks에 배포된 에이전트 쿼리를 참조하세요.

멱등성

클라이언트는 매번 호출할 때마다 UUID id 를 보냅니다. 서버는 호출 기록을 유지하면서 ID를 멱등성 키로 취급합니다: 같은 요청을 다시 보내면 에이전트를 다시 실행하는 대신 기존 호출을 반환합니다. 다른 요청에 ID를 재사용하면 409 오류가 반환됩니다.

Sessions

클라이언트는 session_id를 보내 호출을 하나의 대화로 그룹화할 수 있습니다. 서버는 세션 ID를 input와 별도로 저장하고, 이를 핸들러에 context.session_id로 전달하며, 동일한 세션 ID를 공유하는 호출은 한 번에 하나씩 순서대로 실행합니다. 서버는 호출 ID나 입력만으로 세션을 추론하지 않습니다. 세션 ID가 없으면 호출은 세션리스입니다.

실행 상태

DurableAgentServer 각 호출의 요청, 상태, 하트비트, 이벤트 및 결과를 런타임 스토어에 저장합니다.

  • 로컬 개발: agentbricks dev 프로세스 내 Runtime Store를 사용합니다. 호출 API도 동일하게 동작하지만, 프로세스가 중단되면 실행 상태가 손실되고, 서버는 중단된 작업을 재시작하지 않습니다.
  • 배포된 에이전트: agentbricks deploy는 각 배포의 런타임 스토어를 위해 Azure Databricks가 관리하는 Lakebase 프로젝트에서 전용 데이터베이스를 프로비저닝하고, 재배포 시 이를 재사용합니다. Runtime Store에서 자신의 Lakebase 프로젝트를 사용할 수 없고, 직접 생성하거나 바인딩하지도 않습니다. 결과와 이벤트는 워커 재시작 후에도 유지되며, 에이전트의 모든 인스턴스는 상태 및 재연결 요청을 처리할 수 있습니다. agentbricks deployments delete 배포와 함께 런타임 스토어를 제거합니다.

런타임 스토어는 서버의 실행 상태를 보유합니다. 이는 에이전트가 대화 기록과 장기 기억을 위해 사용하는 세션 및 메모리 저장소와는 별개입니다.

충돌 복구

워커 충돌 또는 재시작으로 중단된 실행을 복구하려면, @app.recover에 복구 핸들러를 등록하세요. 배포된 서버가 런의 하트비트가 멈췄다고 감지하면, 사용 가능한 워커에 대한 교체 시도를 시작하고 원래 입력으로 복구 핸들러를 호출합니다.

@app.recover
async def recover(input, context: InvocationContext) -> dict:
    # Resume from the agent's last checkpoint in the session store,
    # or replay the input if that's safe for your agent.
    return await resume_my_agent(input, session_id=context.session_id)

복구 핸들러를 등록하지 않으면 자동 복구가 꺼지고, 서버가 시작될 때 서버가 경고를 기록합니다.

복구는 다음과 같이 진행됩니다:

  • 회복 시작 시: 실행 중인 각 시도는 몇 초마다 하트비트를 전송합니다. 예를 들어, 워커가 충돌하거나 재시작되거나 재배치 중에 교체되어 하트비트가 멈추면, 서버는 몇 초 내에 오래된 실행을 감지하고 교체 시도를 시작합니다.
  • 복구가 시작되지 않을 때: 핸들러가 예외를 제기하면 호출이 실패하고 서버는 다시 시도하지 않습니다. 복구는 에이전트 코드의 오류가 아니라 중단된 작업자에 적용됩니다.
  • 시도 횟수: 서버가 복구 시도 횟수를 제한하지 않습니다. 교체 시도마다 context.attempt가 1씩 증가합니다. 여러 번 시도한 후 멈추려면, 복구 핸들러에서 context.attempt를 확인하고 오류를 발생시키세요.
  • 수동 복구: 수동으로 복구를 트리거할 수 없습니다. 동일한 호출 ID로 요청을 다시 보내면 새 시도를 시작하는 대신 기존 호출을 반환합니다.

복구는 동일한 호출에 대해 에이전트 코드를 여러 번 실행할 수 있습니다. 중단된 시도는 교체 시도가 시작되기 전에 이미 외부 시스템을 호출했을 수 있으므로, 해당 호출이 멱등성을 갖도록 하세요.

사용자 권한 요청

기본적으로 에이전트의 도구는 앱의 서비스 주체의 권한을 가지고 실행됩니다. 요청을 보낸 사용자의 권한으로 도구를 실행하려면 agent.toml에서 사용자 권한을 선언하세요:

  • 관리되는 도구의 경우 도구 항목에 auth = "user"을 설정하세요. MCP 서버, 샌드박스 및 Genie 에이전트용 agentbricks tools add 명령어는 기본적으로 auth = "user"를 작성합니다. 앱 신원을 사용하려면 Pass --auth app를 사용하세요.

  • 코드로 작성한 도구의 경우, 요구사항과 에이전트 브릭스가 추론할 수 없는 API 범위를 선언하세요:

    [auth.user]
    required = true
    additional_api_scopes = ["sql"]
    

에이전트가 사용자 승인을 요구할 때, DurableAgentServer는 신뢰할 수 있는 Databricks Apps 요청 헤더에서 사용자의 자격 증명을 읽어 현재 활성 시도 동안에만 메모리에 저장합니다. 런타임 스토어는 자격 증명을 저장하지 않습니다. 핸들러에서 사용자용 작업 공간 클라이언트를 context.request_auth에서 받으세요:

@app.invoke
async def invoke(input, context: InvocationContext) -> dict:
    user_client = context.request_auth.client_for("user")
    me = user_client.current_user.me()
    return {"answer": f"Hello, {me.user_name}"}

client_for("app") 앱의 서비스 프린시펄을 사용하는 클라이언트를 반환합니다. 시도가 끝나면 리졸버가 닫히므로, 클라이언트를 저장하는 대신 핸들러 내부에서 호출하세요. 에이전트를 로컬에서 agentbricks dev 실행할 때는 client_for("user")는 로컬 자격 증명을 사용합니다.

배포할 때, agentbricks deploy가 도구에 필요한 Databricks Apps 사용자 범위를 요청합니다. 기존 앱에 누락된 스코프를 추가하려면 --allow-user-scope-update를 전달하세요. Databricks 앱에서 권한 부여 구성을 참조하세요.

request-user 호출은 동일한 동기, 스트리밍, 백그라운드 및 재연결 API를 사용합니다. 서버가 사용자의 자격 증명을 저장하지 않기 때문에, 중단된 request-user 호출을 복구할 수 없습니다. 교체 시도는 핸들러가 실행되기 전에 MCP_USER_AUTH_RECOVERY_UNSUPPORTED 오류로 실패합니다.

커스텀 엔드포인트 추가

DurableAgentServer 이는 FastAPI 애플리케이션입니다. 호출 API와 함께 경로를 추가하세요. 다른 FastAPI 앱에 추가하는 것과 같은 방식으로:

@app.get("/status")
async def status() -> dict:
    return {"ready": True}

프레임워크 템플릿

agentbricks init 두 개의 디렉터리를 생성합니다:

  • agent/에는 프레임워크 코드(모델, 프롬프트, 도구)가 포함됩니다.
  • runtime/ 프레임워크를 DurableAgentServer에 연결하는 어댑터와 어댑터의 호출 및 복구 핸들러를 등록하는 진입점을 포함합니다.

어댑터는 각 호출을 프레임워크의 에이전트 루프 호출로 변환하고, 프레임워크의 출력을 이벤트와 결과로 변환합니다. 두 템플릿 모두 복구 핸들러를 등록합니다. LangGraph 템플릿은 세션 스토어의 마지막 체크포인트에서 다시 시작되며, OpenAI 에이전트 SDK 템플릿은 같은 세션에서 요청을 다시 실행합니다. 기존 에이전트를 가져오려면 어댑터와 DurableAgentServer 엔트리포인트를 추가하고, server = "agentbricks"의 [agent] 섹션에서 agent.toml을 설정하세요.

Azure Databricks 상의 에이전트 서버 비교

Azure Databricks는 세 개의 에이전트 서버를 제공합니다: AgentKit 에이전트 서버와 이전 앱 템플릿에서 사용하던 두 개의 레거시 에이전트 서버입니다.

에이전트 서버 패키지 클라이언트 API 지속 가능한 실행 에 의해 사용됨
AgentKit (DurableAgentServer, 추천) databricks_agentkit, databricks-agentbricks 패키지에 있는 /api/invocations의 Invocation API: 동기화, 스트리밍, 백그라운드 실행, 스트림 재연결을 지원하는 실행 프로비저닝을 수행하고 복구 핸들러를 통한 크래시 복구를 제공하는 런타임 스토어 agentbricks deploy Agent Bricks CLI로 생성하는 프로젝트들
LongRunningAgentServer (레거시) databricks_ai_bridge.long_running, databricks-ai-bridge[agent-server] 패키지에 있는 OpenAI 응답 API는 /responses에서, 백그라운드 실행 및 스트림 재개와 함께 설정한 Lakebase 데이터베이스의 실행 상태 충돌 후에는 새로운 시도가 중단된 시도의 이벤트 로그에서 실행을 계속합니다. agent-openai-advanced 및 agent-langgraph-advanced앱 템플릿
MLflow AgentServer (레거시) mlflow.genai.agent_server, mlflow 패키지에 있는 OpenAI 응답 API at /responses: 동기식 및 스트리밍 실행 None 기본 앱 템플릿, 예를 들어 agent-openai-agents-sdk

LongRunningAgentServer MLflow AgentServer를 확장하며, 둘 다 MLflow ResponsesAgent 인터페이스를 구현하는 에이전트를 지원합니다. 이 중 하나를 사용하는 에이전트를 배포하고 유지하려면, 레거시 에이전트 서버를 사용하는 Databricks 앱에서 에이전트 실행을 참조하세요. 이 서버들 중 어느 곳에서든 에이전트를 쿼리하려면 Azure Databricks에 배포된 에이전트 쿼리를 참조하세요.

Limitations

  • 기존 배포의 에이전트 서버를 변경할 수 없습니다. DurableAgentServer와 자신의 서버 간에 전환하려면 원하는 agentbricks init --server 옵션으로 새 프로젝트를 만들고 새 이름으로 배포하세요.
  • server에서 agent.toml 필드를 변경해도 기존 서버 코드가 DurableAgentServer로 변환되지 않습니다.
  • 요청-사용자 승인은 server = "agentbricks"이 필요합니다.

추가 리소스