콘텐츠로 이동
Study Notekagent · kmcp

Agent — Declarative와 BYO

결론부터
  • Agent는 작성 방식이 둘이다. Declarative는 지시문·모델·tool을 YAML에 적으면 kagent runtime이 실행하고, BYO는 우리가 만든 container image를 kagent가 배포만 한다.
  • Declarative Agent의 능력은 tools에 적은 tool 이름으로 정해진다. 적지 않은 tool은 쓸 수 없다.
  • BYO image는 8080 포트에서 A2A 서버로 응답해야 한다. 그 밖의 내부 구현은 kagent가 관여하지 않는다.
  • 위험한 tool은 requireApproval에 넣어 실행 전에 사람의 승인을 받게 한다.
이 장에서 처음 나오는 말5개
Declarative Agent
지시문·모델·tool을 리소스에 적기만 하면 kagent가 준비한 runtime image가 실행하는 Agent다. 코드를 쓰지 않는다.
BYOBring Your Own
LangGraph·CrewAI·ADK 등으로 직접 만든 Agent를 container image로 가져오는 방식이다.
system message
Agent의 역할과 행동 규칙을 적은 지시문이다. 모든 대화의 맨 앞에 붙어 모델에 전달된다.
HITLHuman-in-the-Loop
Agent가 tool을 실행하기 전에 멈추고 사람의 승인이나 답을 기다리는 방식이다.
Agent Card
A2A에서 Agent가 자기 이름·설명·skill을 알리는 JSON 문서다. 호출하는 쪽이 먼저 읽는다.

큰 그림에서 Agent 리소스 하나가 Deployment와 호출 주소가 된다는 것을 봤다. 이 페이지는 그 리소스 안에 무엇을 적는지를 본다. 읽고 나면 “이 Agent를 Declarative로 만들지 BYO로 만들지”와 “manifest의 어느 필드가 Agent의 능력을 정하는지”에 답할 수 있다.

같은 Agent kind지만 spec.type에 따라 kagent가 맡는 범위가 다르다 (API reference).

DeclarativeBYO
우리가 주는 것지시문·모델·tool 목록 (YAML)container image
대화 loop를 돌리는 것kagent의 ADK runtime image우리 코드
모델 연결ModelConfig 참조image 안에서 직접. env로 key 주입
tool 연결tools에 선언. kagent가 주입image 안에서 직접
kagent가 해 주는 것배포 + 실행 + session 저장 + HITL배포 + A2A 중계
맞는 경우지시문과 tool 조합으로 충분한 업무 Agent분기·상태·외부 연동이 복잡해 코드가 필요한 Agent

판단 기준은 단순하다. YAML로 표현되면 Declarative, 안 되면 BYO다. Declarative가 리뷰하기 쉽다 — PR의 diff가 곧 Agent가 할 수 있는 일의 변화다. BYO는 image 안을 봐야 한다.

# 설명용 예제
apiVersion: kagent.dev/v1alpha2
kind: Agent
metadata:
name: hr-helper
namespace: agents
spec:
description: 휴가·근태 규정을 안내하고 본인 신청 내역을 조회한다
type: Declarative
declarative:
runtime: go
modelConfig: litellm-default
systemMessage: |
너는 인사 규정을 안내하는 Agent다.
조회 tool의 결과에 없는 내용은 추측하지 않는다.
tools:
- type: McpServer
mcpServer:
name: portal-api-mcp
kind: MCPServer
toolNames:
- get_my_leave_requests

네 덩어리로 읽는다.

필드뜻자세히
runtimeAgent Pod가 쓸 ADK 구현. go 또는 python아래 runtime 절
modelConfig같은 namespace의 ModelConfig 이름. 생략하면 default-model-configModelConfig
systemMessage지시문. systemMessageFrom으로 ConfigMap에서 읽을 수도 있다아래 지시문 절
tools쓸 수 있는 tool 서버와 tool 이름. 최대 20개Tool 연결

지시문은 조각으로 재사용할 수 있다

섹션 제목: “지시문은 조각으로 재사용할 수 있다”

여러 Agent가 같은 안전 규칙을 지시문에 복사해 넣으면 규칙을 바꿀 때 전부 고쳐야 한다. prompt template은 공통 조각을 ConfigMap에 한 번 두고 {{include "별칭/key"}}로 끌어온다. controller가 배포 시점에 조각을 펼쳐서 넣는다.

# 발췌
declarative:
promptTemplate:
dataSources:
- kind: ConfigMap
name: company-prompts
alias: company
systemMessage: |
너는 {{.AgentName}}이다.
{{include "company/safety-rules"}}

Secret은 참조할 수 없다. 지시문은 모델 provider로 전송되므로 비밀 값이 섞이지 않게 막은 것이다.

Declarative Agent의 runtime은 둘이고 v0.10부터 Go가 기본이다.

Go ADKPython ADK
시작 시간약 2초약 15초
자원 사용낮다높다
채팅 파일 첨부지원미지원
고를 때기본. 빠른 시작과 낮은 비용CrewAI·LangGraph 등 Python 생태계 기능이 필요할 때

기본값은 버전에 따라 바뀐 적이 있으므로 manifest에 runtime을 명시한다. PR에서 의도가 보이고, 업그레이드 때 runtime이 조용히 바뀌지 않는다.

Deployment 설정도 같은 리소스에 적는다

섹션 제목: “Deployment 설정도 같은 리소스에 적는다”

자원 요청, 환경 변수, annotation은 spec.declarative.deployment에 적는다 (Deployment configuration).

# 발췌
declarative:
deployment:
env:
- name: LOG_LEVEL
value: info
deploymentAnnotations:
argocd.argoproj.io/sync-wave: "5"

annotations는 Pod template에, deploymentAnnotations는 Deployment 자체에 붙는다. Argo CD의 sync-wave처럼 GitOps 도구가 읽는 값은 뒤쪽에 둔다.

BYO는 image와 환경 변수만 적는다. BYO 예제의 형태다.

# 설명용 예제
apiVersion: kagent.dev/v1alpha2
kind: Agent
metadata:
name: contract-reviewer
namespace: agents
spec:
description: 계약서 초안을 조항별로 검토한다
type: BYO
byo:
deployment:
image: registry.example.com/agents/contract-reviewer@sha256:...
imagePullSecrets:
- name: registry-credentials
env:
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: litellm-agent-key
key: api-key

kagent가 image에 기대하는 것은 하나다 — 8080 포트에서 A2A 프로토콜로 응답할 것 (API reference). 그러면 controller가 Declarative Agent와 같은 주소(/api/a2a/{namespace}/{name}/)로 중계한다.

BYO에서는 tools·modelConfig를 kagent가 주입하지 않는다. tool 연결은 image 안의 코드가 직접 하고, 임직원 토큰 전파도 Declarative와 방법이 다르다. project를 만들고 로컬에서 시험하는 순서는 BYO Agent 로컬 개발 흐름에서 다룬다.

BYO Agent가 쓰는 tool은 리소스에 없다

섹션 제목: “BYO Agent가 쓰는 tool은 리소스에 없다”

BYOAgentSpec의 필드는 deployment 하나뿐이다 (API reference). tools나 toolNames를 적는 자리가 없어서, Agent 리소스만 봐서는 이 Agent가 어떤 tool을 쓰는지 알 수 없다. Declarative처럼 tool 이름 단위의 allowlist를 manifest에 걸 수도 없다.

kagent 밖에서 알아내거나 제한하는 방법은 다음과 같다.

방법알 수 있는 것한계
source 저장소 리뷰코드가 연결하는 MCP 서버와 고른 tool. kagent init으로 만든 project라면 kagent.yaml의 MCP 서버 목록과 agent.py의 tool filterimage가 그 commit에서 만들어졌다는 보장이 따로 필요하다(digest 고정, build 주체 통제)
manifest의 env·Secret 참조어떤 자격을 쥐고 있는가그 자격으로 무엇을 하는지는 보이지 않는다
NetworkPolicy의 egressPod가 닿을 수 있는 목적지아는 것이 아니라 제한하는 것이다. 허용된 서버 안에서 어떤 tool을 부르는지는 모른다
MCP 서버·backend의 로그실제로 호출된 tool과 호출자사후 확인이고 우리가 운영하는 서버에 한한다
Agent CardAgent가 스스로 밝힌 skill자기 신고라 실제 코드와 다를 수 있다

실제로 통제가 되는 것은 둘이다. 닿을 수 있는 MCP 서버를 egress로 제한해 tool의 상한을 정하고, 각 MCP 서버가 호출자를 확인한다. 그래서 GitOps PR 승인에서 BYO Agent는 Declarative보다 높은 위험 등급으로 다룬다 — 리뷰 대상이 manifest의 diff가 아니라 source와 image의 출처다.

Agent가 멈추고 사람을 기다리는 경우

섹션 제목: “Agent가 멈추고 사람을 기다리는 경우”

Agent가 삭제·변경 tool을 스스로 실행하면 지시문의 실수 하나가 실제 사고가 된다. HITL은 두 가지로 사람을 끼워 넣는다.

  • tool 승인: requireApproval에 적은 tool은 실행 전에 멈추고 승인·거절을 기다린다. 거절 사유는 모델에 전달되어 다른 방법을 찾게 한다.
  • ask_user: 모든 Agent에 자동으로 붙는 내장 tool이다. 요청이 모호하면 Agent가 사용자에게 되묻는다.
# 발췌 — 조회는 바로, 신청은 승인 뒤에
tools:
- type: McpServer
mcpServer:
name: portal-api-mcp
kind: MCPServer
toolNames:
- get_my_leave_requests
- create_leave_request
requireApproval:
- create_leave_request

requireApproval의 이름은 toolNames에도 있어야 한다. 승인 화면은 kagent UI가 제공하지만, 우리 portal에서 Agent를 호출한다면 A2A 응답의 input-required 상태를 portal이 받아 승인 UI를 직접 그려야 한다.

지금 결정에 필요하지 않으면 이름과 쓸 때만 알아 둔다.

기능무엇인가언제 필요한가
SkillsOCI image·Git·S3에서 지침과 script를 불러와 Agent에 붙인다사내 runbook을 여러 Agent가 공유할 때
Memory대화에서 뽑은 정보를 vector로 저장해 다음 대화에서 찾는다대화를 넘어 기억해야 할 때. pgvector가 필요하다
Context compaction오래된 대화를 요약하거나 버려 context window를 지킨다대화가 길거나 tool 출력이 클 때
a2aConfig.skillsAgent Card에 실리는 능력 설명. 실행 코드가 아니다다른 Agent나 client가 이 Agent를 찾게 할 때
Agent Card metadataversion·iconUrl·provider 등을 Agent Card에 싣는다catalog에 버전·소유 조직을 표시할 때

배포 결과는 리소스의 condition으로 본다. 첫 MCP tool 문서의 출력 예처럼 두 condition이 순서대로 True가 된다.

conditionTrue의 뜻False일 때 먼저 볼 것
Acceptedcontroller가 spec을 받아들였고 참조를 풀었다ModelConfig·tool 서버 이름과 namespace, tool 이름 오타
ReadyDeployment의 Pod가 준비됐다image pull, Secret 누락, Pod 로그
터미널 창
kubectl -n agents get agent hr-helper -o jsonpath='{.status.conditions}'
  • Declarative Agent의 toolNames에서 tool 하나를 지운 PR이 merge되면 무엇이 바뀌는가? → controller가 Agent Pod의 설정을 다시 만들고, 그 Agent는 지운 tool을 더는 호출할 수 없다. MCP 서버 자체는 그대로다.
  • BYO Agent의 manifest만 보고 이 Agent가 어떤 tool을 쓰는지 알 수 있는가? → 알 수 없다. image 안의 코드가 정하므로 source repo를 봐야 한다. 이것이 BYO의 리뷰 비용이다.