はじめに
今回は新登場のLambdaのDurable Functionsを試してみました。
従来のLambda関数とは違い、途中で処理を中断し、再開することが可能になります。
また、最初は提供リージョンはオハイオのみでしたが、この度東京を含む14を含むリージョンでも利用可能になりました。
Durable Functionとは
参考:https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html
Durable Functions はcheckpoint, replay, waitを持っているのがポイントになります。
wait
関数が指定した時間待機したり、外部APIの呼び出しなどを待つ処理を書けます。
この待っている間はLambda自体は止まっているので課金はされません。
この待ちの時間が最大1年間になっているということです。
checkpoint
各処理ステップごとに内部的に進捗を保存します。
途中で中断やエラーが起きても、すでに終わったステップはやり直さずに次へ進めることができます。
replay
待ちや中断のあと、再び Lambda が呼ばれるときは最初からコードが走っているように見えますが、
すでに完了したステップはスキップされて、その結果が返されます。
この結果を使って処理を進めるので、途中で止まっても結果が失われることはありません。 
サンプル
公式サンプルを参考に試してみました。
from aws_durable_execution_sdk_python import (
DurableContext,
durable_execution,
durable_step,
)
from aws_durable_execution_sdk_python.config import Duration
@durable_step
def validate_order(step_context, order_id):
step_context.logger.info(f"Validating order {order_id}")
return {"orderId": order_id, "status": "validated"}
@durable_step
def process_payment(step_context, order_id):
step_context.logger.info(f"Processing payment for order {order_id}")
return {"orderId": order_id, "status": "paid", "amount": 99.99}
@durable_step
def confirm_order(step_context, order_id):
step_context.logger.info(f"Confirming order {order_id}")
return {"orderId": order_id, "status": "confirmed"}
@durable_execution
def lambda_handler(event, context: DurableContext):
order_id = event['orderId']
# Step 1: Validate order
validation_result = context.step(validate_order(order_id))
# Step 2: Process payment
payment_result = context.step(process_payment(order_id))
# Wait for 10 seconds to simulate external confirmation
context.wait(Duration.from_seconds(10))
# Step 3: Confirm order
confirmation_result = context.step(confirm_order(order_id))
return {
"orderId": order_id,
"status": "completed",
"steps": [validation_result, payment_result, confirmation_result]
}
以下のようなテストイベントを実施しました。
{
"orderId": "order-12345"
}
context.wait(Duration.from_seconds(10))
ここで10秒待つことで「外部からの確認待ち」をそれっぽく再現しています。 
大事なのは、wait() 中は 実行を止めて待つということ。
待ちが終わると Lambda がもう一度呼ばれて、処理を再開します(裏では replay されます)。
結果
実行状態を見ると以下のようになっています。
真ん中あたりで10停止してから再実行しています。
Step Functionsとの違いは?
一番気になるのはStep Functionsとの使い分けではないでしょうか?
まず結論として、
- 処理の中心が「コード」なら Durable Functions
- 処理の中心が「ワークフロー定義」なら Step Functions
となります。
Durable Functionsが向いているケース
Durable Functions は、Lambda の延長線でワークフローを書きたい場合に強いです。
- 処理全体をコードとして自然に書きたい
- if / for / try-except などの分岐をそのまま使いたい
- 人の承認待ち、外部イベント待ちなど
- 途中で止まって再開する処理を書きたい
- Step Functions を書くほど大げさではない
実際、wait() を 1 行入れるだけで
途中で止まって、後から再開する Lambdaが書けるのはかなり楽になると感じました。
Step Functionsが向いているケース
逆に、Step Functionsが向いているケースはどのようなものがあるでしょうか?
Step Functionsはワークフローそのものを設計・可視化したい場合に向いています。
Pythonなどではなく、ASL(Amazon States Language)で定義する分、
コードは増えますがフロー全体を視覚的にはくできるため、「何が起きているか」は非常に分かりやすいです。
使い分けのイメージ
-
個人開発・PoC・小規模な業務処理
→ Durable Functions -
業務システムなどの割と大きめのワークフロー
→ Step Functions -
まず Durable Functions で作って、複雑化したら Step Functions に移行
→ 現実的でおすすめ
使ってみて
Durable Functions は、「Step Functions ほどではないけど、Lambda1発ではつらい」
という ちょうど中間の隙間を埋める存在だと感じました。
特に AI エージェントや人の介在する処理では、「待つ」「再開する」が自然に書けるのはかなり相性が良いです。
さいごに
ということで、今更感ありますが、東京リージョンでも対応したとのことで改めてDurable Functionsを試してみました。
使い込むことでよりAIのワークフローの作り込みが面白くなってきそうです。
さて、そんなAIエージェントのワークフローについてですが、投稿日(12/20)にあるイベント、AI Builders Dayにて登壇します。
今回取り上げたDurable Functionsを含めた、AIエージェントのワークフローの検討について話す予定です。
ぜひみなさん会場でお会いしましょう!
参考

