›_ 프롬프트 글리프와 색상이 있는 상태 점). 레일을 클릭하거나 ⌘J / Ctrl+J를 눌러 전체 채팅 패널로 확장할 수 있습니다. 확장된 패널은 왼쪽 가장자리를 드래그하여 320~640픽셀 사이에서 크기 조정이 가능하며, 선호하는 너비는 새로고침 후에도 유지됩니다.
이 기능은 소규모 내부 agent 컨테이너(Claude Agent SDK 기반)로 실행되며, 대시보드만 접근할 수 있습니다. 기본적으로 비활성화되어 있으며, LLM 엔드포인트를 구성하기 전까지는 표시되지 않습니다.
가능한 것과 불가능한 것
- 요청한 사용자가 볼 수 있는 운영 데이터를 읽습니다. 이벤트, 평가, 세션, 평가 작업 큐, 저장된 쿼리, 저장된 대시보드를 사용자의 읽기 권한에 따라 요청별로 범위를 제한합니다. 읽기 도구는 즉시 실행됩니다.
- 쓰기는 작업별 승인이 필요합니다. 저장된 쿼리(
create_saved_query,update_saved_query)를 작성하고, 읽기 전용 역할로 초안 SQL을 실행하여 유효성을 검사하며(run_query), 해당 쿼리로 대시보드를 조립할 수 있습니다(create_dashboard,update_dashboard,add_query_to_dashboard). 각 쓰기 작업은 채팅 내 승인 / 거부 / 질문하기 프롬프트에서 일시 정지됩니다. SDK는 운영자가 승인을 클릭하기 전까지 도구를 호출하지 않습니다. 삭제는 어시스턴트에서 절대 사용할 수 없으며, 파괴적인 작업은 운영자만 수행할 수 있습니다. - 초안 SQL은 사용자 작성 SQL과 동일한
sql_guard검증 및 읽기 전용 역할을 거칩니다(SELECT/WITH만 허용, 다중 명령문 불가). 실행은 쿼리가 참조하는 테이블에 따라 라우팅됩니다. 분석 테이블(이벤트, 평가, 세션)을 참조하는 쿼리는 조직의 읽기 전용 ClickHouse 사용자로 실행되고(행 정책으로 해당 조직에 범위 제한, 10초 실행 제한, 10만 행 제한), 관계형 테이블만 참조하는 쿼리는 읽기 전용 Postgres 역할로 실행됩니다(10초, 1만 행). 어시스턴트는 데이터 접근 범위를 확장할 수 없으며, 운영자가 이미 가진 쿼리 범위 내에서만 작성할 수 있습니다. - 전용 어시스턴트 키(아래 참조)를 사용하여 고정된 권한 세트로 초기화됩니다. 모델이 오작동하더라도 해당 범위를 초과할 수 없습니다.
- 각 대시보드 사용자는 어시스턴트를 보고 사용하려면
agent:use권한이 필요합니다. 도구는 요청별로 사용자 자신의 데이터 권한에 맞게 필터링되므로,events:read사용자는 이벤트 도구를 사용할 수 있지만dashboards:write도구는 사용할 수 없습니다.
페이지 인식 AI 도크: /queries에서는 작성기, 그 외에서는 채팅
오른쪽 어시스턴트 도크는 페이지를 인식합니다. 모델 선택기, 대화 기록, 모델 상태 점, 채팅 입력창은 변경되지 않지만, 빈 상태 템플릿 칩, 플레이스홀더 텍스트, 사용자 메시지가 전달되는 백엔드 엔드포인트는 현재 라우트에 따라 자동으로 전환됩니다. 도크는 “현재 보고 있는 페이지의 AI 도우미”가 됩니다.
페이지별로 선택되는 두 가지 백엔드(칩별 오버라이드 가능).
| 라우트 | 페이지 기본 백엔드 | 이유 |
|---|---|---|
/queries, /queries/new | POST /api/agent/compose-sql (도구 루프 없음) | 사용자가 처음 시작하는 경우이며, 1초 이하의 첫 토큰 SQL이 에디터로 직접 스트리밍됩니다 |
/queries/<id> (기존) | POST /api/agent/chat (전체 도구 루프 어시스턴트), 페이지 기본값 | 자유롭게 입력된 메시지에서 사용자가 뭐든 물어볼 수 있어야 하며(“설명해줘”, “이게 뭐 하는 건지?”), 리팩터 칩은 칩별 kind로 compose-sql을 다시 선택합니다 |
| 그 외 모든 페이지 | POST /api/agent/chat (전체 도구 루프 어시스턴트) | 읽기 도구 + 승인 게이트 쓰기 도구 |
/queries/<id>의 칩은 명시적인 kind를 가지므로 단일 페이지에서 두 흐름을 원활하게 혼합할 수 있습니다. 기본 칩 세트는 두 개의 chat 칩(explain the query on screen, what does this query do?)과 다섯 개의 compose-sql 칩(parameterize by date range, add a status='error' filter 등)으로 구성됩니다. 자유롭게 입력된 메시지는 페이지 기본값(채팅)으로 처리되므로, “이게 왜 이렇게 느리지?”와 같은 질문은 산문 답변을 받고, parameterize by date range 칩을 클릭하면 작성 엔드포인트를 통해 SQL을 수정합니다.
작성기가 편집 모드로 실행될 때(사용자가 /queries/<id>에 있거나 이미 제안된 SQL이 로드된 /queries/new에 있어 비어 있지 않은 currentSql을 감지), 시스템 프롬프트가 “새 쿼리 작성”에서 “제공된 SQL을 최소한으로 수정: 테이블 선택, 컬럼 이름, 조인 구조, 별칭, 들여쓰기 유지”로 전환됩니다. 모델에는 별도의 before/after 예제(파라미터화, 필터 추가, 시간별 버킷으로 변환)가 제공되므로, 칩 클릭 리팩터는 에디터의 SQL을 처음부터 다시 작성하는 것이 아니라 최소한의 diff를 생성합니다.
작성 칩 클릭(또는 /queries/new에서 자유롭게 입력) → SQL이 ```sql 펜스 블록으로 어시스턴트 메시지에 스트리밍됩니다. 스트림이 완료되는 순간, Monaco가 현재 라우트에 마운트되어 있으면 에디터가 자동으로 diff 뷰로 전환됩니다(왼쪽에 원본, 오른쪽에 제안, 상단에 ▾ AI가 편집을 제안했습니다 표시, 하단에 수락 / 거부 버튼). 사용자는 diff를 보기 위해 에디터에 삽입 버튼을 찾거나 클릭할 필요가 없습니다. 삽입 버튼은 SQL 블록 아래에 수동 재실행 트리거로 여전히 렌더링되며(거부 후 또는 사용자가 다른 곳으로 이동했다가 돌아왔을 때 유용), 에디터 외 페이지(예: 저장된 쿼리 목록)에서는 유일한 경로입니다. 이 경우 SQL을 sessionStorage에 저장하고 /queries/new로 이동하며, 새로 마운트된 에디터가 마운트 시 저장소를 읽어 동일한 diff 뷰를 엽니다.
제안된 SQL이 에디터에 이미 있는 것과 바이트 단위로 동일한 경우(변경 없는 편집), 자동 열기는 건너뜁니다. 빈 diff는 표시하지 않습니다. 에디터에 삽입 버튼도 이 경우 아무런 동작을 하지 않습니다.
사용자가 /queries/new에서 제안을 수락하면 툴바의 기본 작업이 create 대신 **save**로 표시됩니다. SQL은 어시스턴트로부터 전달받은 것이므로, 사용자의 심리 모델은 “처음부터 작성”이 아닌 “마무리”입니다. 레이블은 도크가 SQL을 삽입하면 한 번 변경되어 페이지 이동 전까지 save로 유지됩니다. /queries/<id>에서는 버튼이 항상 save였으므로 변화가 없습니다.
/queries 외에서는 도크가 이전과 동일하게 작동합니다: 도구 승인 카드와 함께 전체 채팅, 페이지 컨텍스트 인식, 인용.
권한 / 게이팅. 작성 엔드포인트는 사용자별 queries:run 권한으로 게이팅됩니다(읽기에 해당; 사용자는 여전히 수락 및 실행을 클릭해야 하며, 실행은 Rust 서버의 기존 sql_guard + references_ch_tables 라우팅을 거칩니다). 채팅 엔드포인트는 agent:use로 게이팅됩니다. 두 경로 모두 agent 컨테이너에 LLM 연결이 구성되어 있어야 합니다. 구성되지 않은 경우 도크는 두 경로 모두에서 “이 배포에서 어시스턴트가 구성되지 않았습니다” 배너를 표시합니다.
거부. 작성기는 읽기 전용 분석 쿼리로 충족할 수 없는 요청을 거부하고, SQL 대신 -- REFUSE: <한 문장 이유>를 반환합니다. 데이터를 쓰거나 분석 뷰 외부 테이블(api_keys, users, dashboards, saved_queries, evaluation_jobs)에 접근하는 요청을 거부하며, 작성 경로에서 순수 산문 요청(“설명해줘”, “이게 뭐 하는 건지?”)도 거부합니다. 이러한 요청은 채팅 경로에 속하며, 채팅에서 산문 답변을 제공합니다. 도크는 어시스턴트 메시지에 인라인 빨간색 오류 칩으로 거부 문자열을 렌더링하며, 아무것도 삽입되지 않습니다.
모델 선택. 채팅 경로와 공유됩니다. 도크 헤더의 모델 선택기는 두 엔드포인트 모두에 적용됩니다(작성 호출은 선택된 모델을 에이전트 서비스의 resolveModel()로 전달합니다). AGENTEYE_AGENT_MODELS에 여러 모델이 나열된 경우, 운영자는 작성기에는 Haiku급 옵션을, 채팅에는 Sonnet급 옵션을 혼합할 수 있으며, 사용자는 대화별로 선택할 수 있습니다.
페이지별 템플릿. 각 페이지마다 고유한 템플릿(헤드라인, 본문, 플레이스홀더 텍스트, 제안 칩)이 있어 도크가 현재 페이지에 맞게 적응합니다. 특정 라우트에서 제공되는 칩은 작성기가 최적화된 의도에 매핑되므로, 제안을 클릭하면 예상한 편집이 수행됩니다.
비활성화. 채팅 경로와 동일합니다. 도크와 작성기 모두 agent 컨테이너와 LLM 연결로 게이팅됩니다. 특정 사용자에게 채팅 전용 동작을 원하면 queries:run 권한을 제거하세요(에디터의 실행 버튼도 비활성화됩니다). 작성기 전용 동작을 원하면 해당 사용자의 역할에서 agent:use를 제거하고, 사용자가 직접 작성한 SQL을 실행할 수 있도록 queries:run을 별도로 다시 추가하세요.
활성화 방법
agent 서비스는 Docker Compose 파일 및 Kubernetes 매니페스트에 포함되어 있습니다. 어시스턴트를 활성화하려면 (1) LLM 엔드포인트와 (2) 어시스턴트의 전용 데이터 키를 제공하세요.
1. LLM 연결 선택
다음 중 하나를 선택하고agent 서비스에 해당 변수를 설정하세요:
a) Anthropic 직접 연결
@<slug>/<model>로 지정하면 슬러그가 프로바이더와 자격증명 라우팅을 처리하므로 가상 키가 필요하지 않으며, Portkey API 키만 있으면 됩니다. 에이전트는 x-portkey-api-key만 전송하고 Portkey 게이트웨이를 가리키면 Portkey가 나머지를 처리합니다. (일반 모델 이름은 “x-portkey-config or x-portkey-provider header is required” 오류가 발생합니다. @slug/ 접두사가 키 전용 방식을 가능하게 합니다.) 셀프 호스팅 게이트웨이의 경우 PORTKEY_BASE_URL을 설정하세요.
슬러그 대신 요청별 라우팅을 선호한다면, 일반 AGENTEYE_AGENT_MODEL과 함께 PORTKEY_VIRTUAL_KEY=<vk> (또는 PORTKEY_CONFIG=<id>)를 설정하세요.
c) 기타 Anthropic 호환 게이트웨이 (LiteLLM, 셀프 호스팅 등)
AGENTEYE_AGENT_MODEL로 기본 모델을 선택적으로 고정할 수 있습니다(기본값 claude-sonnet-4-6). 사용자가 여러 모델 중 선택하게 하려면 AGENTEYE_AGENT_MODELS에 쉼표로 구분된 허용 목록을 설정하세요(예: @anthropic-prod/claude-opus-4-7,@anthropic-prod/claude-sonnet-4-6). 그러면 채팅 헤더에 모델 선택기가 나타나고 각 사용자의 선택이 기억됩니다. 에이전트는 이 허용 목록에 있는 모델만 호출합니다.
2. 어시스턴트 키 제공
임의의 시크릿을 생성하여 agent에는AGENTEYE_API_KEY로, server에는 AGENT_API_KEY로 동일한 값을 제공하세요. 서버가 시작될 때 이를 dashboard-assistant라는 이름의 전용 키로 다음 고정 권한 세트와 함께 초기화합니다: events:read, evaluations:read, dashboards:read, dashboards:write, queries:read, queries:write, queries:run. 쓰기 권한은 승인 게이트 도구를 통해서만 사용됩니다(위의 “가능한 것과 불가능한 것” 참조). 수동 키 생성 단계나 관리자 키는 필요하지 않습니다. 권한 세트는 서버에 고정되며, 초기화된 키는 보호됩니다: 키 API를 통해 비활성화하거나 재생성할 수 없습니다. 값을 변경하고 서버를 재시작하여 교체하세요. 관리자/대시보드 키를 재사용하지 마세요.
AGENTEYE_API_KEY를 agenteye-agent 시크릿에 넣으면 서버 Deployment가 동일한 값을 AGENT_API_KEY로 읽습니다.
3. 대시보드↔에이전트 공유 토큰 설정
대시보드와 agent 서비스 모두에 동일한AGENTEYE_AGENT_TOKEN을 설정하세요. 대시보드는 내부 에이전트 서비스를 호출할 때 이를 제시하며, 에이전트는 이 토큰 없이는 호출을 거부합니다.
4. 사용자 접근 권한 부여
관련 대시보드 운영자에게agent:use 권한을 부여하세요(enterprise-docs/api-keys.md 참조). 이 권한이 없는 사용자는 어시스턴트를 볼 수 없습니다.
LLM 엔드포인트와 읽기 전용 키를 설정한 후 server(읽기 전용 키 초기화)와 agent 서비스를 재시작하세요. agent:use 사용자라면 오른쪽 가장자리에 어시스턴트 도크가 기본적으로 접힌 채로 나타납니다. 레일을 클릭하거나 ⌘J / Ctrl+J를 눌러 확장하세요.
환경 변수 참조
agent 서비스에 설정:
| 변수 | 용도 |
|---|---|
PORTKEY_API_KEY | Portkey를 통한 라우팅 (에이전트가 이 값으로 게이트웨이 연결을 구성) |
PORTKEY_VIRTUAL_KEY | Anthropic 자격증명에 대한 Portkey 가상 키 (키에 기본 설정이 있는 경우 선택사항) |
PORTKEY_CONFIG / PORTKEY_BASE_URL | Portkey 명명된 구성 / 셀프 호스팅 Portkey 게이트웨이 URL (선택사항) |
PORTKEY_PROVIDER | Portkey 프로바이더 슬러그 — PORTKEY_VIRTUAL_KEY / PORTKEY_CONFIG와 함께 사용하는 세 번째 라우팅 옵션 (둘 다 설정되지 않은 경우에만 사용) |
ANTHROPIC_API_KEY | Anthropic 직접 접근 (게이트웨이 / Bedrock / Vertex 대안) |
ANTHROPIC_AUTH_TOKEN | x-api-key 대신 Authorization: Bearer로 인증하는 게이트웨이의 Bearer 토큰 (선택사항) |
ANTHROPIC_BASE_URL | Portkey 외 게이트웨이 엔드포인트 |
ANTHROPIC_CUSTOM_HEADERS | Portkey 외 게이트웨이의 추가 헤더: 줄바꿈으로 구분된 Name: Value 줄 (JSON 아님) |
CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX | Bedrock / Vertex를 통한 라우팅 |
AGENTEYE_AGENT_MODEL | 기본 모델 ID (기본값 claude-sonnet-4-6) |
AGENTEYE_AGENT_MODELS | 채팅 헤더에서 사용자가 선택할 수 있는 모델의 쉼표로 구분된 허용 목록. 단일 고정 모델의 경우 설정하지 마세요. 위의 기본값이 포함되어 있지 않으면 자동으로 추가됩니다. |
AGENTEYE_AGENT_MAX_CONCURRENCY | 파드당 최대 동시 채팅 수 (기본값 4). 초과 요청은 429를 받습니다 |
AGENTEYE_API_KEY | 어시스턴트의 데이터 키. 서버의 AGENT_API_KEY와 동일한 값으로 설정하세요. 서버는 시작 시 고정된 범위 권한 세트로 초기화합니다(2단계 참조). |
AGENTEYE_AGENT_TOKEN | 대시보드와의 공유 시크릿 |
AGENTEYE_SERVER_URL | AgentEye 서버 URL (기본값 http://server:8080) |
AGENTEYE_AGENT_ALLOW_NO_ORG | 멀티테넌시. 기본적으로 비활성화(페일 클로즈): 어시스턴트는 조직 컨텍스트가 없는 /chat 요청을 400으로 거부합니다. 실행하는 모든 도구가 하나의 조직에 범위가 지정되기 때문입니다. 대시보드는 조직 인식 상태가 되면 항상 해당 컨텍스트를 전송하므로, 일반적으로 설정하지 않아도 됩니다. 아직 조직 인식이 되지 않은 대시보드가 조직 인식 에이전트와 통신하는 과도기적 롤아웃 중에만 1로 설정하세요. 이 경우 어시스턴트가 거부 대신 default 조직으로 폴백합니다. 대시보드 업그레이드가 완료되면 제거하세요. |
AGENTEYE_AGENT_MAX_STEPS | 답변당 최대 도구 사용 단계 수 (기본값 8) |
AGENTEYE_AGENT_TIMEOUT_MS | 전체 /chat 요청 타임아웃(모든 모델 턴 + 도구 단계), 밀리초 단위 (기본값 90000). SQL 도구는 자체 10초 제한이 있습니다 |
AGENTEYE_AGENT_SELF_TELEMETRY | 1로 설정하면 어시스턴트 자체 실행을 AgentEye에 기록합니다 |
AGENTEYE_TELEMETRY_API_KEY | 자체 계측을 위한 별도의 events:add 전용 키 |
AGENTEYE_AGENT_ENV | 어시스턴트 자체 텔레메트리에 적용되는 환경 태그 (기본값 prod) |
dashboard 서비스에 설정:
| 변수 | 용도 |
|---|---|
AGENTEYE_AGENT_URL | 대시보드가 에이전트 서비스에 접근하는 주소. 번들된 Kubernetes 매니페스트와 Compose 파일은 이를 http://agent:9100으로 설정합니다. 설정하지 않으면 어시스턴트가 완전히 숨겨집니다. |
AGENTEYE_AGENT_TOKEN | 에이전트의 토큰과 일치해야 합니다 |
텔레메트리 및 사용자 질문 확인
프롬프트 내용은 기본적으로 자체 시스템 내에 유지됩니다. 세 가지 레이어:- 대화 저장소: 모든 프롬프트와 답변이 AgentEye 데이터베이스에 저장됩니다(사용자별, 비공개). 어시스턴트의 기록 전환기에서 다시 불러올 수 있습니다. 사용자가 무엇을 질문하는지에 대한 영구적인 기록입니다.
- 제품 분석: 대시보드는 메타데이터만 기록합니다(어시스턴트 사용 빈도, 도구 수, 지연 시간). 프롬프트 텍스트는 이 경로에 절대 포함되지 않습니다.
- 자체 계측(선택사항):
AGENTEYE_AGENT_SELF_TELEMETRY=1을 설정하고(그리고events:add전용AGENTEYE_TELEMETRY_API_KEY추가) 어시스턴트가 자체 실행을dashboard-assistant에이전트로 AgentEye에 기록하도록 하세요. 그러면 다른 모든 것에 사용하는 세션/이벤트 뷰에서 사용자 프롬프트와 어시스턴트의 추론 과정을 확인할 수 있습니다. 참고: 해당 이벤트는events:read권한이 있는 모든 사람에게 표시됩니다. 범위가 너무 넓다면 이 기능을 비활성화하세요.
비활성화 방법
다음 중 하나를 수행하면 어시스턴트가 비활성화됩니다(도크 레일이 사라집니다):- 대시보드에서
AGENTEYE_AGENT_URL설정 해제, 또는 - 에이전트에 LLM 엔드포인트를 구성하지 않음(
ANTHROPIC_API_KEY/ 게이트웨이 / Bedrock / Vertex 없음), 또는 agent서비스를 아예 배포하지 않음.
보안 요약
- 자동 쓰기 없음: 어시스턴트의 쓰기 도구(
create_saved_query,update_saved_query,create_dashboard,update_dashboard,add_query_to_dashboard)는 운영자가 채팅 내 승인 버튼을 명시적으로 클릭하지 않으면 실행할 수 없습니다. SDK의 사전 호출 게이트는 승인이 백채널을 통해 에이전트에 도달하기 전까지 도구를 차단합니다. 이 게이트를 비활성화하는 설정은 없습니다. - 고정된 좁은 데이터 범위: 어시스턴트는 서버에서 권한 세트가 고정된 전용 키로 서버에 인증합니다(
events:read,evaluations:read,dashboards:read,dashboards:write,queries:read,queries:write,queries:run). 작성할 수 있는 쓰기 작업은 저장된 쿼리와 대시보드뿐이며, 서버는 모델이 시도하는 것과 관계없이 해당 범위 외의 모든 것을 거부합니다. - 삭제 기능 없음: 키는 삭제 권한을 가지지 않으며 삭제 도구가 노출되지 않습니다. 운영자는 어시스턴트가 아닌 대시보드 UI를 통해 삭제합니다.
- 내부 전용: 에이전트는 공개 라우트가 없으며, 공유 토큰이 있는 대시보드만 호출할 수 있습니다. (Kubernetes에서는 NetworkPolicy가 에이전트가 AgentEye 서버와 LLM 엔드포인트에만 접근하도록 제한합니다.)
- 사용자별 범위 지정:
agent:use사용자만 어시스턴트를 사용할 수 있으며, 각 사용자의 읽기 권한에 맞는 도구만 제공됩니다. - 원시 HTML 없음 / 링크 유출 없음: 답변은 정제된 마크다운으로 렌더링되며 외부 링크는 무력화됩니다.

