콘텐츠로 이동
Study NoteAgent 배포 플랫폼

6. Adapter contract

결론부터
좋은 adapter는 차이를 지우지 않고 차이가 나타나는 한 곳을 만든다
이 장에서 처음 나오는 말3개
portPorts and Adapters
핵심 domain이 외부 제품을 직접 호출하지 않고 정해진 interface를 통해 연결하는 구조다.
capability profileCapability Profile
target이 지원하는 protocol·architecture·network·session·storage 특성을 기계가 읽을 수 있게 표현한 값이다.
idempotencyIdempotency
같은 배포 요청을 여러 번 보내도 resource가 중복 생성되지 않고 같은 결과에 수렴하는 성질이다.
Platform Core가 RuntimeAdapter port로 세 어댑터를 부르고 각 어댑터의 제품 resource가 하나의 Normalized DeploymentStatus로 돌아오며, durability port는 현재 none이고 재개 시 후보만 점선으로 붙어 있는 구조

platform core는 Kubernetes client나 AWS SDK를 import하지 않는다. adapter가 provider credential, retry, eventual consistency와 error message를 소유한다. 맨 Kubernetes·kagent·AgentCore는 workload를 만드는 같은 port의 구현이다. 보류한 durable execution 층은 이 port의 세 번째 구현이 아니다. 별도 durability port가 ExecutionProfile을 검증하고, 선택한 RuntimeAdapter가 만든 workload 안의 worker와 조합한다.

operation입력출력·약속
validateversion, target지원 여부와 고칠 수 있는 이유. 외부 변경 없음
planversion, target, current생성·변경·삭제될 논리 resource. 외부 변경 없음
deployapproved version, target, idempotency keydeployment와 providerRef
getStatusdeploymentnormalized state, health, provider detail link
stopdeployment, drain policy새 invocation 차단과 session 처리 결과
setTrafficready deployments, weightsprovider가 지원할 때만 endpoint-version traffic 반영
deletedeployment, retention policyruntime resource 제거. domain record는 유지

실제 invocation은 별도 RuntimeInvoker port로 분리할 수 있다. 배포 credential과 호출 credential의 권한 범위가 다르고, streaming·session 처리는 control API보다 request path에 가깝기 때문이다.

PublicationRouter.switchActiveDeployment(publicationId, deploymentId)는 platform core의 operation이다. adapter가 provider-native traffic split을 지원하면 setTraffic으로 구현을 보조할 수 있지만, 어느 Deployment가 회사 catalog의 active version인지 결정하지 않는다. 따라서 publication rollback과 provider resource repair를 같은 rollback method로 합치지 않는다.

runtime:
protocol: a2a
artifact:
kind: OCI_IMAGE # CONFIG_BUNDLE | CODE_ZIP
uri: registry.company/agents/report
digest: sha256:...
architecture: amd64
configuration:
promptBundleDigest: sha256:...
knowledgeBindings:
- knowledgeVersionId: knv_hr_policy_2026_08
retrievalPolicyVersion: rpv_3
policyBundleVersion: pbv_12
effectiveConfigHash: sha256:...
executionProfile:
durability: none
resources:
cpu: "1"
memory: 2Gi
network:
zone: restricted
egressProfiles: [model-internal, finance-mcp]
session:
mode: stateful
maxDuration: 30m
secrets:
- logicalRef: finance-read-token

여기에 Kubernetes nodeSelector나 AWS subnet ID를 넣지 않는다. target policy가 zone과 capability를 실제 namespace, subnet, security group, execution role로 번역한다. CODE_ZIP은 AgentCore 같은 일부 target만 지원하는 artifact extension이고, portable production 기본값은 immutable OCI digest다.

여러 provider의 모든 기능을 공통 boolean으로 만들면 어느 쪽도 제대로 쓰지 못한다. target은 다음처럼 자신을 설명한다.

capabilities:
protocols: [http, mcp, a2a]
architectures: [arm64]
isolation: session-microvm
maxSessionDuration: 8h
privateIngress: true
privateEgress: true
persistentFilesystem: supported
trafficSplit: endpoint-version

placement policy는 version requirement와 capability를 비교한다. 필수 capability가 없으면 validate 단계에서 거부한다. 선택 기능이면 warning과 degradation을 명시하고 owner가 승인하게 한다.

공통 상태는 적게 둔다.

PENDING → PROVISIONING → READY → DRAINING → STOPPED
↘ DEGRADED
↘ FAILED
어느 상태에서든 provider 조회 실패 → UNKNOWN

provider 원문 상태와 reason은 버리지 않는다. FAILED만 반환하면 운영자가 ImagePullBackOff인지 ECR ARM64 불일치인지 알 수 없다. normalized reasonCode와 redacted providerMessage, provider console/log link를 함께 준다.

deploy timeout 뒤 같은 요청을 재시도해도 resource가 하나만 생겨야 한다. provider resource에는 deploymentId label/tag를 붙이고, create 전에 그 key로 조회한다. adapter 호출은 request transaction 하나로 완료된다고 가정하지 않고 reconciler가 반복한다.

삭제도 같은 원칙을 쓴다. provider resource가 이미 없으면 성공으로 수렴하되, 다른 deployment가 소유한 shared resource는 지우지 않는다.

logical secret은 adapter가 target별 reference로 바꾼다.

공통 의도맨 Kubernetes targetkagent targetAgentCore target
runtime workload identityKubernetes ServiceAccountKubernetes ServiceAccountAgentCore workload/execution role
secret referenceSecret/Vault injectionSecret/Vault injectionSecrets Manager·AgentCore Identity provider
private CASecret volume·image trust storeSecret volume·ModelConfig TLSartifact trust store·private endpoint 설정
egress policyNetworkPolicy·proxyNetworkPolicy·proxysecurity group·VPC endpoint·route

secret value를 adapter DB나 provider tag에 복제하지 않는다. target이 늘어나면 이 표에 column이 하나 추가될 뿐 공통 의도 행은 그대로다 — 그것이 logical reference를 쓰는 이유다.

모든 adapter는 같은 test suite를 통과해야 한다.

  • 같은 idempotency key 두 번 배포
  • 지원하지 않는 architecture와 protocol 거부
  • create 성공 뒤 응답 유실을 재현하고 복구
  • ready → invoke → stop → invoke 거부
  • provider resource 수동 삭제 뒤 drift 감지
  • log와 trace에 공통 correlation field 존재

platform integration suite는 별도로 새 Deployment를 만든 뒤 publication pointer를 전환·복귀하고, adapter의 stop·delete가 Publication을 암묵적으로 바꾸지 않는지 검사한다. durability를 재개하면 같은 RuntimeAdapter suite를 재사용하고 별도 execution recovery suite를 추가한다.

  • platform core와 provider SDK 사이에 배포와 호출 port를 둔다.
  • publication pointer 전환은 platform core, provider traffic 조정은 adapter의 선택 capability다.
  • 공통 spec에는 의도, target에는 실제 인프라 mapping을 둔다.
  • capability negotiation으로 backend 고유 기능을 보존한다.
  • adapter는 idempotency, eventual consistency, provider error 번역을 책임지고 durability는 별도 port로 조합한다.