Temporal Python SDK 1.28~1.30: LangGraph·OpenAI Agents·Strands를 durable workflow에 붙이는 방식
왜 지금 봐야 하나
2026년 7월 25일 04:00/05:00 KST 잡이 이미 Agno 2.8과 Apache DataFusion Ballista 54를 다뤘고, ai/study/curriculum.md에는 pending 항목이 남아 있지 않았다. 그래서 이번 06:00 fallback은 최근 90일 안에 나온 변화 중, 특정 모델 한 개나 단일 데이터베이스 기능이 아니라 에이전트 런타임의 기반 엔진을 다시 그은 주제를 우선했다.
Temporal Python SDK 1.28.0(2026-06-04), 1.29.0(2026-06-17), 1.30.0(2026-07-02)을 연속으로 읽어 보면, 핵심은 "새 프레임워크를 하나 더 지원했다"가 아니다. 진짜 변화는 LangGraph, OpenAI Agents SDK, Strands Agents 같은 서로 다른 에이전트 표면을 Temporal의 workflow / activity / stream / Nexus 링크라는 동일한 실행 계약 위로 끌어올리기 시작했다는 점이다.
운영자 관점에서 특히 중요한 변화는 다섯 가지다.
- Strands Agents plugin이 모델 호출·tool call·MCP call을 Temporal Activities로 우회시킨다. 에이전트 프레임워크의 편의 표면은 그대로 쓰되, 재시도·timeout·crash recovery는 Temporal이 맡는다.
- LangGraph plugin이 node/task별
execute_in경계를 강제하고, Workflow Streams로 중간 토큰/상태를 외부로 내보낸다. LangGraph 쪽 durable storage와 Temporal 쪽 durable execution의 경계를 문서로 명시했다. - OpenAI Agents plugin이 tool, MCP, sandbox를 각각 다른 failure domain으로 분리한다.
activity_as_tool, stateless/stateful MCP wrapper, sandbox client provider가 모두 같은 패턴으로 정리됐다. signal_with_start_workflow와 Nexus link propagation이 들어오면서, 에이전트 간 호출 관계가 UI에서 추적 가능한 제어면으로 바뀐다.- 제약도 같이 드러났다. gRPC gzip 기본화로 프록시 호환성 이슈가 생길 수 있고, Workflow Streams는 저지연 음성용이 아니며, stateful MCP는 Temporal이 자동 복구해 주지 않는다.
한 줄로 요약하면, 이번 릴리스 묶음은 Temporal을 "장기 실행 워크플로 엔진"에서 한 단계 더 밀어 올려 에이전트 런타임의 공통 substrate로 쓰는 방법을 구체화한 변화다.
핵심 변화 한눈에 보기
| 릴리스 | 추가/변경된 표면 | 운영 의미 |
|---|---|---|
1.28.0 | Strands Agents plugin, LangGraph Workflow Streams 지원, Standalone Nexus Operations | 에이전트 프레임워크를 Activity/Stream 기반으로 Temporal에 얹는 공식 표면이 생김 |
1.29.0 | signal_with_start_workflow, OpenAI Agents CustomTool dispatch + defer_loading, gRPC gzip 기본화 | cross-workflow 제어면과 lazy tool discovery가 들어왔고, 네트워크 호환성 검토가 필요해짐 |
1.30.0 | Nexus signal link propagation, backoff_start_interval for continue-as-new | 호출자·피호출자 추적성이 올라가고, 긴 실행을 새 run으로 넘길 때 backoff를 제어할 수 있음 |
| 공통 설계 | workflow 안은 deterministic, I/O·모델 호출·MCP·sandbox는 Activity/Nexus로 분리 | "무엇을 workflow에 두고, 무엇을 activity로 뺄지"를 프레임워크별로 같은 기준으로 정렬 가능 |
1. 1.28.0은 agent framework를 "예제"가 아니라 plugin 표면으로 만들기 시작했다
이번 묶음의 첫 번째 전환점은 1.28.0이다. 릴리스 노트만 보면 Strands plugin, LangGraph Workflow Streams, Standalone Nexus Operations 세 줄로 끝나지만, 실제 의미는 더 크다.
Strands: 모델·tool·MCP를 모두 Activity로 빼고, agent loop는 workflow에 남긴다
Strands README가 보여 주는 설계는 단순하다. TemporalAgent는 workflow 안에 남고, 모델 호출·tool call·MCP tool call은 모두 Activity로 빠진다. 이 분해가 중요한 이유는 다음과 같다.
- 재시도와 timeout을 프레임워크 내부 전략이 아니라 Temporal policy로 통일할 수 있다.
- workflow는 deterministic orchestration만 맡고, 외부 I/O는 Activity로 격리된다.
- model factory는 worker 쪽에서 lazy init되므로, sandbox 안에서 직접 provider client를 들고 있을 필요가 없다.
특히 README가 명시하듯 TemporalAgent는 Strands의 내장 ModelRetryStrategy를 끄고 재시도를 Temporal에 일임한다. 이건 작은 구현 선택이 아니다. 에이전트 프레임워크가 provider error를 알아서 감싸 재시도하는 구조를 그대로 두면, 운영자는 어느 레이어가 몇 번 재시도했는지 알기 어렵다. Temporal 쪽으로 몰아 주면 activity retry, heartbeat, timeout, dead letter에 대한 시야가 생긴다.
또 하나 중요한 점은 HITL interrupt와 continue-as-new가 README에 같이 올라왔다는 사실이다. 즉, 이 plugin은 단순한 "SDK adapter"가 아니라 승인 대기와 긴 대화 history 관리까지 Temporal idiom으로 풀려는 설계다.
LangGraph: durability를 두 겹으로 두지 말고, 실행 위치를 node별로 명시하라
LangGraph plugin 문서가 가장 노골적으로 드러내는 것은 execute_in 계약이다. 모든 node/task는 "activity" 또는 "workflow"를 직접 표기해야 하고, LangGraph의 checkpointer가 필요하면 InMemorySaver를 쓰라고 한다. 이유는 분명하다.
- durability는 이미 Temporal이 맡고 있다.
- LangGraph 쪽 PostgreSQL/Redis checkpointer를 또 붙이면, 같은 상태 전이를 두 시스템이 서로 다른 방식으로 기억하게 된다.
- Activity로 빠진 node는 worker가 달라도 다시 실행될 수 있으므로, live
Store를 그대로 기대하면 안 된다.
즉, LangGraph plugin은 "Temporal 위에서 LangGraph를 돌릴 수 있다"보다 어떤 node는 workflow에 남기고, 어떤 node는 Activity로 빼야 하는지를 명시적으로 설계하게 만든다. 에이전트 그래프를 직접 운영하는 팀에게는 이쪽이 더 중요하다.
Workflow Streams: 중간 토큰과 상태를 내보내되, 실시간 시스템이라고 착각하지 않게 선을 그었다
1.28.0 릴리스와 Workflow Streams 문서를 함께 보면 의도는 분명하다. LangGraph의 get_stream_writer()나 Strands의 streaming_topic은 중간 결과를 외부로 흘려 보내지만, 이건 WebSocket으로 토큰을 뿌리는 초저지연 스트리밍이 아니다.
Workflow Streams README는 다음을 명시한다.
- durable, offset-addressed event channel이다.
- 내부적으로 Signals, Updates, Query를 조합해 만든다.
- 배치 지연은 대략 100ms 수준이다.
- 비용은 토큰 수가 아니라 durable batch 수에 가깝게 쌓인다.
즉, 이 표면은 장기 실행 agent UI, 상태 진행률, 배치/리포팅성 이벤트에 적합하다. 반대로 real-time voice처럼 수십 ms 안쪽 상호작용을 기대하면 맞지 않는다.
2. OpenAI Agents plugin은 tool, MCP, sandbox의 failure domain을 따로 보게 만든다
OpenAI Agents integration README는 이번 릴리스 묶음의 핵심을 가장 노골적으로 보여 준다. Temporal이 하는 일은 에이전트 로직을 똑똑하게 만드는 것이 아니라, 실패 경계를 더 분명하게 나누는 것이다.
activity_as_tool: tool을 "함수"가 아니라 Activity 계약으로 바꾼다
README의 activity_as_tool 예제는 핵심을 잘 드러낸다. 동일한 tool call이라도 두 종류가 있다.
- workflow 안에서 직접 실행하는
@function_tool - Activity로 우회하는
activity_as_tool(...)
이 둘의 차이는 단순한 성능 차이가 아니라 권한과 상태 차이다.
- workflow tool은 deterministic 제약을 따라야 한다.
- activity tool은 I/O를 할 수 있고 retry/timeout을 붙일 수 있다.
- activity tool은 context를 read-only copy로 받고, workflow tool만 context를 변경할 수 있다.
즉, OpenAI Agents plugin은 "모든 tool을 durable하게 만들었다"가 아니라, 어떤 tool은 workflow에 남겨도 되고 어떤 tool은 반드시 Activity로 밀어야 하는지를 코드 표면으로 드러낸다.
MCP는 하나의 기능이 아니라 두 개의 failure domain이다
README가 stateless MCP와 stateful MCP를 굳이 나눠 설명하는 이유도 같다.
- stateless MCP: 각 호출이 독립적이므로, 새 인스턴스를 띄워도 의미가 유지된다.
- stateful MCP: 세션 상태를 잃으면 동일한 재시도가 의미를 잃는다.
Temporal은 workflow를 durable하게 만들지만, MCP 서버 자체를 durable하게 만들지는 않는다. 그래서 stateful MCP 연결이 죽으면 plugin은 ApplicationError를 내고, 나머지는 애플리케이션이 직접 판단하라고 선을 긋는다.
이건 운영상 중요한 사실이다. "Temporal을 붙였으니 MCP도 자동 복구되겠지"라고 생각하면 사고가 난다. 복구 가능한 것은 workflow progress이고, 세션 상태까지 보장되는 것은 아니다.
sandbox support는 LocalShellTool을 되살리는 기능이 아니라, 실행면을 Activity로 재배치하는 기능이다
OpenAI Agents plugin README의 sandbox 섹션을 보면, session 생성·명령 실행·파일 읽기/쓰기·PTY 상호작용이 모두 Temporal Activity로 라우팅된다. 즉, sandbox를 workflow 안으로 끌어오는 것이 아니라 sandbox 조작을 전부 외부 side effect로 취급한다.
이 설계는 Feature Support 표와 같이 읽어야 한다.
LocalShellTool과ComputerTool은 분산 환경에 맞지 않아 미지원이다.- 대신 sandbox backend를 provider로 등록하고, 그 backend와의 모든 상호작용을 Activity로 보낸다.
이건 도구 표면을 넓힌 것이 아니라, 분산 환경에 맞지 않는 도구를 제거하고, 대체 실행면을 명시한 것에 가깝다.
1.29.0의 CustomTool + defer_loading은 tool surface를 늦게 여는 방향이다
1.29.0 릴리스 노트에서 가장 실무적인 줄은 OpenAI Agents plugin이 CustomTool dispatch와 defer_loading 기반 lazy discovery를 지원한다는 부분이다.
이 변화는 두 가지를 뜻한다.
- tool schema 전체를 workflow 시작 시점에 전부 올릴 필요가 없다.
- 도구 탐색은 늦추되, 실제 실행은 여전히 Temporal이 관리하는 Activity 계약으로 보낼 수 있다.
도구 수가 많아질수록 초기 context, schema validation, tool registry 관리 비용이 같이 커지는데, 이 릴리스는 그 표면을 늦게 여는 선택지를 제공한다. 결국 Temporal이 하는 일은 context compression 자체가 아니라, 도구가 실제 실행되는 순간의 신뢰성 계약을 붙잡는 것이다.
3. 1.29.0과 1.30.0은 제어면과 관측성을 닫아 준다
plugin이 생겼다고 바로 운영 가능한 시스템이 되는 것은 아니다. 실제로는 cross-workflow control plane과 traceability가 붙어야 한다. 이 역할을 1.29.0과 1.30.0이 맡는다.
signal_with_start_workflow: 외부 이벤트로 agent run을 깨우는 공통 제어면
1.29.0에서 들어온 experimental workflow.signal_with_start_workflow는 generated system Nexus bindings 위에 올라간다. 의미는 단순하다.
- workflow가 없으면 시작한다.
- 이미 있으면 signal만 보낸다.
- 둘을 분리 호출하는 race window를 줄인다.
에이전트 쪽으로 번역하면, "새 티켓이 오면 conversation workflow를 만들고, 기존 티켓이면 같은 workflow에 새 turn만 넣는다" 같은 패턴이 더 자연스러워진다. 장기 실행 에이전트에서 흔한 inbox/work-item 모델을 Temporal idiom으로 바로 쓸 수 있다는 뜻이다.
Nexus link propagation: 호출자와 피호출자를 UI에서 서로 따라갈 수 있다
1.30.0의 Nexus operation link propagation은 겉보기엔 작은 기능이지만, 운영자에게는 매우 실용적이다. signal 기반 Nexus operation이 다른 workflow를 깨울 때, 이전에는 caller와 callee를 UI에서 손으로 맞춰 봐야 하는 경우가 많았다. 이제는 inbound request link가 signaled workflow 쪽 history에도 전달되고, caller 쪽 Nexus operation history event에도 반대 방향 링크가 붙는다.
이 말은 곧 다음을 뜻한다.
- 어떤 요청이 어떤 workflow run을 깨웠는지 더 쉽게 추적할 수 있다.
- signal-with-start 패턴을 쓸 때 caller/callee correlation이 좋아진다.
- "이 에이전트가 왜 이 하위 workflow를 만들었지?"를 UI에서 바로 따라갈 수 있다.
에이전트가 여러 sub-workflow와 도구를 물고 늘어지는 구조라면, 이런 관측성의 연결 정보가 나중에 디버깅 시간을 크게 줄인다.
하지만 같은 릴리스 묶음이 경고도 같이 준다: gzip 기본화와 streaming 중복
좋은 소식만 있는 것은 아니다.
1.29.0은 client 연결에 gRPC gzip compression을 기본으로 켰다.- 릴리스 노트는 일부 프록시에서 문제가 생길 수 있다고 직접 경고한다.
1.30.0은 compression downgrading 지원을 추가해 이 문제를 완화했다.
즉, self-hosted proxy, service mesh, 오래된 ingress를 쓰는 팀이라면 에이전트 plugin 자체보다 먼저 네트워크 호환성 테스트를 해야 한다.
Streaming 쪽도 마찬가지다. LangGraph README는 streaming_topic을 썼을 때 activity-side node publish가 at-least-once per activity attempt라고 못 박는다. activity retry가 나면 chunk가 다시 나갈 수 있다는 뜻이다. 그러므로 subscriber는 sequence id 기반 dedupe를 하거나, stream을 최종 truth가 아니라 진행률 힌트로 취급해야 한다.
4. 이 릴리스 묶음을 실제 프로덕션에 적용할 때 바뀌는 설계 기준
1) LangGraph checkpointer를 기본값처럼 붙이지 않는다
Temporal 위에서 LangGraph를 돌릴 때는 Redis/PostgreSQL checkpointer를 더 붙이는 것이 안전해 보일 수 있다. 하지만 plugin 문서의 방향은 반대다. workflow durability는 Temporal이 맡고, LangGraph는 in-memory graph runtime으로 남겨 두라는 쪽이다. 두 시스템이 같은 상태를 서로 다른 방식으로 저장하기 시작하면 replay와 recovery 지점이 어긋난다.
2) tool은 "모델이 부른 함수"가 아니라 "어느 failure domain에서 실행되는 작업인지"로 분류한다
- deterministic 계산: workflow tool
- 외부 API/DB/file/system I/O: Activity tool
- shell/desktop 조작: built-in local tool이 아니라 sandbox backend + Activity route
이렇게 보면 tool inventory가 아니라 failure boundary inventory가 먼저 보이기 시작한다.
3) MCP는 stateless/stateful를 설계 문서에 명시해야 한다
MCP를 그냥 "도구 연결 방식"으로만 취급하면 안 된다. 서버가 session state를 갖는 순간 retry semantics가 달라진다. stateful MCP라면 다음을 문서에 적어야 한다.
- 연결이 끊겼을 때 어느 상태를 잃는가
- 재연결이 안전한가
- 실패 시 같은 요청을 다시 보내도 되는가
- workflow가 받을
ApplicationError를 어떤 정책으로 처리할 것인가
4) Workflow Streams는 UI 업데이트용이지, authoritative event log가 아니다
README가 직접 말하듯 Workflow Streams는 배치 기반이고 중복 가능성이 있다. 따라서 실무에서는 다음처럼 쓰는 편이 맞다.
- 사용자 UI의 진행률·중간 토큰 표시
- 운영자용 상태 대시보드
- 장기 실행 작업의 in-flight progress feed
반대로 billing, exactly-once business event, ultra-low-latency voice streaming 같은 곳에 그대로 쓰면 안 된다.
5) continue-as-new를 대화형 agent의 기본 습관으로 봐야 한다
Strands README는 대화형 workflow history가 계속 쌓이면 workflow.info().is_continue_as_new_suggested()를 보고 agent.messages를 넘겨 새 run으로 이어가라고 한다. 이건 특정 프레임워크의 팁이 아니라, Temporal 위에서 agent session을 오래 유지할 때의 표준 운영 패턴으로 읽는 편이 맞다.
5. 한계도 분명하다: 아직은 강한 substrate이지, 완성된 agent 플랫폼은 아니다
이번 묶음은 분명 강력하지만, 선을 넘지 않은 부분도 또렷하다.
- experimental release stage다. Strands, LangGraph, Workflow Streams 모두 README 첫머리에서 실험 단계임을 명시한다.
- realtime agent는 미지원이다. OpenAI Agents integration은 streaming은 지원하지만 realtime agent는 지원하지 않는다.
- stateful MCP는 자동 복구 대상이 아니다. workflow durability와 MCP session durability를 혼동하면 안 된다.
- LangGraph Store는 Activity 경계에서 지원되지 않는다.
runtime.store에 기대던 패턴은 그대로 가져가면 깨진다. - activity tool은 context를 읽기만 할 수 있다. tool이 context를 바꿔야 한다면 workflow 쪽에서 실행할지, 결과를 workflow state에 반영하는 별도 단계가 필요하다.
- 네트워크/프록시 호환성 테스트가 필수다. 1.29 기본 gzip은 그냥 라이브 업그레이드하기엔 위험하다.
즉, Temporal이 agent framework를 "마법처럼 production-ready"로 바꾸는 것은 아니다. 대신 어느 부분이 deterministic orchestration이고, 어느 부분이 side effect이며, 어떤 스트림이 중복 가능하고, 어떤 상태는 스스로 복구해야 하는지를 훨씬 명확하게 만든다. 운영자에게 필요한 건 대개 바로 이런 종류의 진실이다.
운영 체크리스트
- [ ] LangGraph node/task마다
execute_in을 명시했고, workflow에 남길 것과 Activity로 뺄 것을 의도적으로 나눴는가? - [ ] LangGraph에서 외부 checkpointer/Store를 중복으로 붙이지 않고, Temporal이 durability를 맡는 구조로 정리했는가?
- [ ] OpenAI Agents tool 중 I/O가 있는 것은
activity_as_tool로 빼고, deterministic 계산만 workflow tool로 남겼는가? - [ ] MCP 서버를 stateless/stateful로 구분했고, stateful 실패 시
ApplicationError이후 복구 정책을 정의했는가? - [ ] Workflow Streams subscriber가 중복 publish를 감당하도록 설계됐는가?
- [ ]
1.29.0gzip 기본화와 프록시/ingress/service mesh 호환성을 사전 점검했는가? - [ ] 긴 대화형 workflow에 continue-as-new와 history growth 모니터링을 붙였는가?
- [ ] LocalShellTool/ComputerTool 대신 sandbox backend + Activity route를 쓰도록 실행면을 재배치했는가?
References
- Temporal, "Python SDK 1.28.0" release notes, GitHub Releases, published 2026-06-04. https://github.com/temporalio/sdk-python/releases/tag/1.28.0
- Temporal, "Python SDK 1.29.0" release notes, GitHub Releases, published 2026-06-17. https://github.com/temporalio/sdk-python/releases/tag/1.29.0
- Temporal, "Python SDK 1.30.0" release notes, GitHub Releases, published 2026-07-02. https://github.com/temporalio/sdk-python/releases/tag/1.30.0
- Temporal,
temporalio/contrib/strands/README.md, main branch. https://github.com/temporalio/sdk-python/blob/main/temporalio/contrib/strands/README.md - Temporal,
temporalio/contrib/langgraph/README.md, main branch. https://github.com/temporalio/sdk-python/blob/main/temporalio/contrib/langgraph/README.md - Temporal,
temporalio/contrib/openai_agents/README.md, main branch. https://github.com/temporalio/sdk-python/blob/main/temporalio/contrib/openai_agents/README.md - Temporal,
temporalio/contrib/workflow_streams/README.md, main branch. https://github.com/temporalio/sdk-python/blob/main/temporalio/contrib/workflow_streams/README.md - Temporal Documentation, "Plugins guide." https://docs.temporal.io/develop/plugins-guide
- Temporal Documentation, "Workflow Streams — Python SDK." https://docs.temporal.io/develop/python/workflows/workflow-streams