12. 보류한 결정 — durable execution
이 장에서 처음 나오는 말3개
durable executionDurable Execution- process가 재시작돼도 기록된 실행 history에서 중단 지점부터 이어 가는 실행 방식이다.
activityWorkflow Activity- LLM·tool·외부 API처럼 비결정적 작업을 workflow가 예약하고 결과를 기록하는 실행 단위다.
보류한 결정Deferred Decision- 지금 답하지 않되 재개 조건과 후보를 기록해 두는 설계 결정. 층의 삭제가 아니라 도입 시점의 유예다.
Runtime 결정은 둘로 나뉜다
섹션 제목: “Runtime 결정은 둘로 나뉜다”runtime을 고른다는 한 문장 안에는 서로 다른 결정 두 개가 들어 있다. 이 둘을 섞으면 “durable workflow가 필요할지 모르니 Dapr도 깔아 두자” 같은 선납이 생긴다.
- 결정 A — workload lifecycle. 누가 Pod를 만들고 살리고 호출 표면을 제공하는가. 온프렘의 기준선은 어댑터가 Deployment를 직접 만드는 맨 Kubernetes고, 기본 후보는 kagent(8~11장), AWS 쪽은 AgentCore(13장)다.
- 결정 B — execution durability. 중단된 다단계 실행을 누가 기록하고 이어 주는가. 이 장의 주제이고, 답은 **지금은 “없음”**이다.
두 결정은 독립이다. durable engine의 worker는 결국 컨테이너 안의 일반 process라서, 결정 B를 나중에 재개해도 결정 A에서 고른 kagent BYO Pod나 어댑터가 만든 Deployment 위에 그대로 얹을 수 있다. 반대로 어느 durable engine도 결정 A를 대신 풀어 주지 않는다 — Agent 전용 배포 control plane은 Temporal에도 Dapr에도 없다.
실행 계약은 조합한다
섹션 제목: “실행 계약은 조합한다”현재 모든 AgentVersion은 다음처럼 명시적인 none profile을 가진다.
runtimeTargetRequirement: zone: restrictedexecutionProfile: durability: none failureRecovery: restart-from-beginning결정 B를 재개하면 target을 temporal로 바꾸지 않는다. 예를 들어 같은 kagent BYO Deployment에
Temporal worker를 넣고 다음 profile을 결합한다.
executionProfile: durability: temporal workflowContractVersion: wf-finance-approval-v3 taskQueueRef: tq_finance_restricted workerCompatibility: pinnedRuntimeAdapter는 Pod·Service와 provider endpoint를 만들고, 별도 DurabilityCoordinator는 engine namespace,
worker registration, history·payload policy와 compatibility를 검증한다. Deployment.providerRef는 계속 workload를
가리키며 durability engine ID는 execution binding에 둔다.
왜 보류하는가
섹션 제목: “왜 보류하는가”durable execution이 주는 것은 분명하다. LLM 판단·tool 호출을 activity 경계로 기록해 process가 죽어도 완료된 step을 재사용하고, 며칠짜리 승인 대기를 중단된 workflow로 표현할 수 있다. 그런데도 지금 도입하지 않는 이유는 두 가지다.
첫째, 수요가 아직 확인되지 않았다. step 단위 복구가 필요한 다단계 업무 Agent가 실제로 등록되기 전에 도입하면, 기반 비용을 선납하고 쓰임은 가정으로 남는다. 이 덱의 세 번째 축(최소 공통분모로 깎지 않기)과 같은 논리로, 필요 없는 층을 미리 들이지도 않는다.
둘째, 선납 비용이 크다. Dapr 경로는 control plane 서비스들과 대상 Agent Pod의 sidecar, workflow state store를 함께 들여야 하고 Dapr Agents는 Python framework다. Temporal 경로는 sidecar가 없지만 server·persistence·visibility·worker deployment·보안·upgrade를 운영해야 한다. 어느 쪽이 더 가벼운지는 기존 조직 역량과 HA·보존 요구를 넣기 전에는 결론낼 수 없고, “혹시 필요할지 모르니”로 정당화되지 않는다.
“없음”의 실행 계약
섹션 제목: ““없음”의 실행 계약”보류는 공짜가 아니다. durable engine이 없는 동안 플랫폼은 다음 계약으로 버틴다.
- 실패한 다단계 실행은 처음부터 재시도한다. step 중간 결과를 재사용하지 않는다. 요청-응답형 대화 Agent에는 문제가 없고, 긴 pipeline일수록 재시도 비용이 커진다.
- 장기 대기 업무는 중단된 workflow가 아니라 상태 + 재invocation으로 모델링한다. 승인 대기나
외부 event를 기다리는 업무는 backend DB에 업무 상태를 기록하고, 승인 완료·event 도착이
Trigger로 별도 invocation을 시작하는 모양으로 설계한다. Agent process가 기다리며 상주하지 않는다. - tool idempotency는 그대로 필수다. gateway retry와 처음부터 재시도 때문에 같은 tool 호출이 반복될 수 있다. 결제·승인·삭제 tool의 idempotency key와 업무 system의 중복 방지는 durable engine의 유무와 무관한 요구다.
재개 조건
섹션 제목: “재개 조건”보류한 결정에는 다시 여는 조건이 붙어야 한다. 다음 중 하나가 실제 등록 수요와 acceptance test로 확인되면 이 장을 다시 연다.
- 실패 후 처음부터 재시도하는 비용(시간·token·업무 영향)이 수용 불가한 다단계 업무 Agent
- 상태 + 재invocation 모델로 표현하기에 분기·보상 처리가 너무 복잡해진 장기 업무
- step별 retry 정책과 실행 history 감사가 규제·감사 요구로 필요한 업무
“있으면 좋겠다”는 재개 조건이 아니다. 18장의 결정 기록과 같은 방식으로, 어떤 Agent가 어떤 test를 통과하지 못해 재개하는지를 증거로 남긴다.
재개 시 후보 — Temporal과 Dapr Agents
섹션 제목: “재개 시 후보 — Temporal과 Dapr Agents”| 비교 축 | Temporal | Dapr Agents on Kubernetes |
|---|---|---|
| 실행 모델 | workflow·activity를 SDK로 작성, worker는 일반 process | DurableAgent가 LLM·tool 호출을 Dapr Workflow로 기록 |
| 새로 운영할 것 | server 서비스들 + persistence DB(Postgres 지원). sidecar 없음 | Dapr control plane·모든 Pod의 sidecar·workflow state store |
| 언어 | Go·Java·TypeScript·Python 등 — 포털 backend(Node/TS)와 같은 언어 가능 | Python framework |
| 라이선스 | server·SDK 모두 MIT, self-host 상용 무료 | Apache 2.0 (CNCF) |
| agent 통합 | OpenAI Agents SDK 통합 GA 등 framework 통합 제공 | framework 자체가 agent 전용 |
| 결정 A에 주는 것 | 없음 — workload 배포는 여전히 어댑터 몫 | 없음 — 일반 Pod에 sidecar 주입, Agent CR/controller 없음 |
| worker·code versioning | replay compatibility와 worker rollout 전략을 별도 검증 | Dapr·framework upgrade가 실행 중 instance에 미치는 영향 검증 |
| HA·RPO/RTO | service·persistence·visibility의 복제와 장애 전환 설계 | control plane·state store의 복제와 장애 전환 설계 |
| 민감 data | history payload codec·retention·archival 정책 | state store 암호화·retention·삭제 정책 |
| multi-tenancy | namespace·task queue·worker identity 경계 검증 | Kubernetes namespace·Dapr App ID·component scope 경계 검증 |
| 운영 증거 | server·SDK metric, sequential upgrade, history growth | sidecar·placement·state store metric, component upgrade |
현재 가정에서는 sidecar가 없고 포털 backend와 같은 TypeScript SDK를 쓸 수 있는 Temporal이 잠정 선두다. MIT는 self-host license fee 제약을 줄일 뿐 보안·운영·vendor review를 끝내 주지 않는다. Temporal self-hosted guide는 production에서 security, monitoring, visibility, upgrade, archival과 replication을 별도 운영 항목으로 둔다. Dapr Agents는 조직이 Dapr control plane과 component 운영을 이미 표준화했거나 Python agent framework 자체의 통합 가치가 클 때 역전할 수 있다.
재개 시 PoC는 어느 후보든 같은 것을 검증한다. process 재시작 뒤 같은 workflow instance가 이어지는지, LLM·tool activity의 retry가 idempotency key와 함께 side effect를 중복시키지 않는지, HITL 승인 대기 상태가 재시작 뒤에도 유지되는지, incompatible worker version을 안전하게 배포하는지, workflow history와 대화 memory·업무 audit의 보존 기간을 분리했는지다. 여기에 장애 전환 RTO·RPO, history 증가량, 암호화·삭제, tenant 간 격리와 월 운영 시간을 같은 fixture로 측정한다.
어느 후보든 바뀌지 않는 것
섹션 제목: “어느 후보든 바뀌지 않는 것”결정 B를 재개해도 이 덱의 구조는 그대로다.
- durable engine은 substrate지 Agent control plane이 아니다. 등록·승인·ACL·catalog는 여전히 포털 backend가 소유한다.
- 6장의 RuntimeAdapter contract는 그대로다. 별도 durability port와 execution binding이 추가되고, 기존 workload target의 secret·identity mapping은 유지된다.
- placement policy는 data zone과 workload capability로 target을 고르고, execution policy는 recovery 요구와 worker hosting capability를 비교한다. 두 결과를 하나의 Deployment 구성으로 조합한다.
- workload identity·mTLS 같은 Dapr의 부가 기능은 durable execution의 근거가 되지 못한다. 그 자리는 ServiceAccount·NetworkPolicy가 이미 맡고 있다.
12장 요약
섹션 제목: “12장 요약”- runtime 결정은 workload lifecycle(결정 A)과 execution durability(결정 B)로 나뉜다. 결정 A의 온프렘은 맨 Kubernetes 기준선과 kagent 후보를 PoC로 판정하고 AWS 후보는 AgentCore며, 결정 B는 보류한다.
- 보류하는 동안 실패는 처음부터 재시도하고, 장기 대기 업무는 backend 상태 + Trigger 재invocation으로 모델링하며, tool idempotency는 그대로 강제한다.
- 재개 조건은 실제 등록 수요와 acceptance test다. “있으면 좋겠다”로 재개하지 않는다.
- 재개 시 Temporal은 현재 가정의 잠정 선두이고 Dapr Agents는 기존 Dapr 기반과 framework 통합 가치에 따라 역전할 수 있다. 어느 쪽도 Agent control plane이나 RuntimeAdapter를 대신하지 않는다.
참고 자료
섹션 제목: “참고 자료”- Temporal server LICENSE — server·SDK의 MIT 라이선스.
- Temporal self-hosted guide — self-host 구성 요소와 persistence 선택.
- Temporal + OpenAI Agents SDK — agent 실행을 durable하게 만드는 통합.
- Dapr Agents 소개 — v1.0 상태와 durable execution·배포 성격.
- Dapr Workflow activity — at-least-once와 idempotency 요구.
- Dapr sidecar — Kubernetes annotation 기반 sidecar 주입과 운영 기반.