【AWS Summit Japan 2026】ワークフローオーケストレーターにおける複雑性と非決定性のコントロール [CNS454] セッションレポート

記事タイトルとURLをコピーする

はじめに

こんにちは。アプリケーションサービス部エデュケーショナルサービス課の山本です。😺

2026年6月25日・26日に幕張メッセで開催された AWS Summit Japan 2026 に参加してきました。本記事は、2日目(6/26)に聴講したブレイクアウトセッション CNS454「ワークフローオーケストレーターにおける複雑性と非決定性のコントロール」(アマゾン ウェブ サービス ジャパン合同会社 ソリューションアーキテクト)のレポートです。

ワークフローは、最初は数ステップの単純な構成でも、複数の AWS サービスをまたぐ処理やリトライ・ロールバックが増えるにつれ、複雑さが見えないまま増殖していきます。本セッションは、その複雑性をどう可視化・構造化するか、そして生成 AI エージェントがもたらす 「非決定性」 という新しい複雑さにどう向き合うかを、設計パターンとして整理してくれる内容でした。

セッションは大きく2部構成でした。

  • 前半: 肥大化したワークフローを分解し、複雑さを可視化・構造化する設計パターン
  • 後半: 生成 AI エージェントの「非決定性」という新たな複雑さと、決定論的なワークフロー × 非決定論的なエージェントの組み合わせパターン

この記事では前半・後半の両方をまとめます(後半「生成 AI エージェント」のスライド画像は、手元に届き次第差し込みます)。

対象サービス: AWS Step Functions / AWS Lambda durable functions / Amazon MWAA 関心領域: 生成 AI・サーバーレス・Lambda ベースのアプリケーション


ワークフロー実装の選択肢: 汎用ソリューションと業務特化

まず整理として、AWS でワークフローを実装する際の選択肢が示されました。大きく 汎用ソリューション業務特化ソリューション に分かれます。

AWS でワークフローを実装する場合の選択肢(汎用ソリューションと業務特化ソリューション)

  • 汎用ソリューション(どんなワークフローにも使える)
    • AWS Step Functions
    • AWS Lambda durable functions
    • Amazon MWAA(Amazon Managed Workflows for Apache Airflow)
  • 業務特化ソリューション(特定用途に最適化)
    • AWS CodePipeline(CI/CD)
    • AWS Batch(バッチ処理)
    • Amazon SageMaker Pipeline(ML パイプライン)
    • AWS Glue(ETL)
    • AWS Systems Manager Automation(運用自動化)

業務特化のサービスは「その用途ならまずこれ」という最適解になりますが、汎用的なオーケストレーションでは前者3つが主役になります。本セッションは、この汎用ソリューションの Step Functions / Lambda durable functions / MWAA を軸に進みました。


Step Functions と Lambda durable functions の使い分け

最初の比較は Step Functions と Lambda durable functions です。「どちらか一方」ではなく ハイブリッドで併用することも視野に、使いやすい方を選ぶ というのが大事なメッセージでした。

Step Functions は「AWS サービス・システム横断」、durable functions は「アプリロジック内」

スライドでの整理は次のとおりです。

AWS Step Functions AWS Lambda durable functions
主戦場 AWS サービス・システム横断 アプリロジック内
特徴 GUI で作成 / AWS サービス統合 / JSON で記述 / ランタイム更新不要 慣れた言語で記述 / 既存コード活用 / コーディングツールとの相性 / 型チェック可能

Lambda durable functions とは(補足)

Lambda durable functions は re:Invent 2025(2025年12月) に発表された比較的新しい機能です。公式ドキュメントによると、最大1年間 にわたる耐障害性のあるマルチステップ・ワークフローを、使い慣れたプログラミング言語で書けるのが特徴です(Lambda durable functions)。

仕組みは チェックポイント / リプレイ です。中断や障害から再開する際、コードは先頭から再実行されますが、完了済みの処理(チェックポイント)はスキップして保存済みの結果を使うため、長時間実行でも一貫性が保たれます。コードのなかでは2つの「durable operations」を使います。

  • Steps: ビジネスロジックを実行する単位。組み込みのリトライと進捗追跡が付く
  • Waits: 実行を課金なしで中断する。人手承認(human-in-the-loop)や外部依存のポーリングのように「待つ」処理に最適

SDK は JavaScript / TypeScript / Python / Java で提供され、Lambda のイベントハンドラーをラップして DurableContext を受け取り、通常のシーケンシャルなコードとして書ける、という開発体験です。

公式の使い分け指針Lambda doc) - durable functions: Lambda の中で動き、ワークフローがビジネスロジックと密結合しているアプリ開発向け - Step Functions: スタンドアロンのサービス。ビジュアル設計、220 以上のサービスへのネイティブ統合、ゼロ保守が必要な「サービス横断のオーケストレーション」向け

詳細比較は公式の Durable functions or Step Functions が参考になります。

セッションの「Step Functions = サービス横断 / durable functions = アプリロジック内」という整理は、公式の指針ともきれいに一致しています。

ハイブリッドで組み合わせる: .waitForTaskToken と durable functions SDK

スライドのサブタイトルにあった 「ハイブリッドで使用することも視野に、使いやすいサービスを」 が、個人的にいちばん実務に効くメッセージでした。Step Functions と durable functions は二者択一ではなく、外側の骨格は Step Functions、内側の重い業務ロジックは durable functions という役割分担で組み合わせられます。その「のりしろ」になるのが、両者がそれぞれ持つ コールバック(待ち受け)の仕組み です。

2つの「コールバックを待つ」仕組み

おもしろいのは、Step Functions と durable functions が ほぼ対称な「トークンを渡して待ち、返ってきたら再開する」設計 になっている点です。名前が違うだけで、考え方は同じです。

AWS Step Functions Lambda durable functions
待ち受けの仕組み .waitForTaskToken(Wait for a Callback with Task Token) Callback 操作createCallback / waitForCallback
待っている間 最大1年ポーズ(Standard ワークフロー) 中断中はコンピュート課金なし
再開のトリガー SendTaskSuccess / SendTaskFailure にトークンを返す SendDurableExecutionCallbackSuccess / SendDurableExecutionCallbackFailure にコールバックID を返す
トークンの取得 コンテキストオブジェクト $$.Task.Token createCallback の戻り値(コールバックID)
主な用途 サービス/外部システム/人手承認の完了待ち コード内での人手承認・外部処理の完了待ち

Step Functions の .waitForTaskToken

.waitForTaskToken は、Resource ARN の末尾に .waitForTaskToken を付けることで、タスクトークンが返ってくるまでそのステートを一時停止する仕組みです(Discover service integration patterns in Step Functions)。トークンはコンテキストオブジェクトの $$.Task.Token から取得します。

たとえば課題2で分割した「リスク処理」を、長時間かかるコードとして durable function に委譲したい場合は、次のように Lambda を .waitForTaskToken で呼び出します(イメージ)。

"リスク処理(durable function へ委譲)": {
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
  "Parameters": {
    "FunctionName": "risk-durable-function",
    "Payload": {
      "input.$": "$",
      "taskToken.$": "$$.Task.Token"
    }
  },
  "Next": "マーケ処理"
}

この状態に入ると Step Functions はポーズし、呼び出された durable function 側が処理を終えて SendTaskSuccess(失敗時は SendTaskFailure)にトークンを返すまで先に進みません。なお、相手がトークンを返さないまま止まると永久に待ち続けてしまうので、ハートビートタイムアウトを設定して保険をかけておくのが定石です。

⚠️ タスクトークンは 同一 AWS アカウント内 のプリンシパルからしか返せません(別アカウントからの SendTaskSuccess は無効)。

durable functions 側の Callback 操作

一方、durable function の中で「人の承認」や「外部の支払い確定」を待ちたいときは、SDK の Callback 操作 を使います(Callback - AWS Durable Execution SDK)。createCallback でコールバックID を払い出して外部に渡し、await で結果を待つだけです。待っている間はコンピュート課金が発生しません

import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const [callbackPromise, callbackId] = await context.createCallback("wait-for-approval");

    // コールバックID を外部(承認システムなど)へ渡す
    await sendApprovalRequest(callbackId, event.requestId);

    // ここで実行を中断。外部が結果を返すまで課金されない
    const result = await callbackPromise;
    return { approved: true, result };
  },
);

外部システムが SendDurableExecutionCallbackSuccess(または ...Failure)にコールバックID を添えて呼び出すと、バックエンドが新しい invocation を起動し、中断地点から replay で再開してくれます。作成・送信・待機を1つにまとめた waitForCallback というショートカットも用意されています。SDK は JavaScript / TypeScript / Python / Java で提供されます。

組み合わせると何がうれしいか

両者をつなぐと、こんな流れが「ポーリングや独自の状態管理なし」で書けます。

sequenceDiagram
    participant SFN as Step Functions(骨格)
    participant DF as durable function(業務ロジック)
    participant Ext as 外部システム / 人

    SFN->>DF: lambda:invoke.waitForTaskToken<br/>($$.Task.Token を渡す)
    Note over SFN: トークンが返るまでポーズ
    DF->>DF: Steps で多段処理<br/>(リトライ・チェックポイント)
    DF->>Ext: createCallback で承認待ち
    Note over DF: 中断中は課金なし
    Ext-->>DF: SendDurableExecutionCallbackSuccess
    DF->>DF: replay で再開し処理を完了
    DF-->>SFN: SendTaskSuccess(taskToken)
    Note over SFN: 次のステートへ
  • Step Functions は「どのドメインを、どの順で呼ぶか」「失敗したらどの Fail state に落とすか」という サービス横断の制御とビジュアル化 に専念できる
  • durable functions は「慣れた言語・型チェック・外部ライブラリ」で 重い業務ロジックと長時間の待ち を引き受けられる
  • 両者を .waitForTaskToken × タスクトークンでつなぐと、最大1年の待ちでも、ポーリングや独自の状態管理を書かずに 済む

「使い分け」だけでなく「組み合わせ」まで踏み込めると、課題2のワークフロー分割でも、各チームの子ワークフローの中身を Step Functions / durable function のどちらで作るかを、チームの得意な書き方に合わせて選べるようになります。


Amazon MWAA / MWAA Serverless

3つ目の汎用ソリューションが Amazon MWAA です。

MWAA と MWAA Serverless。2025年11月にサーバーレス版が登場

ポイントは次のとおりです。

  • 幅広い業界で10年以上使われた Apache Airflow の知見をそのまま活用できる
  • Python / YAML でワークフローを構築
  • デプロイ形態は MWAA(プロビジョンド)MWAA Serverless の2種類
  • 2025年11月に MWAA Serverless が登場し、アイドルコストが不要に

MWAA Serverless とは(補足)

MWAA Serverless は 2025年11月 に発表された新しいデプロイオプションです(Introducing Amazon MWAA Serverless)。Airflow 環境の運用オーバーヘッドをなくし、実際のワークフロー実行時間にのみ課金されます。従来の MWAA が常時稼働の環境に対して時間課金だったのに対し、アイドルコストが不要・前払いなしになったのが大きな違いです。

公式ドキュメント(What is Amazon MWAA Serverless?)から、押さえておきたい特徴を補足します。

  • Apache Airflow v3 + Python 3.12 ベース
  • ワークフローは YAML(DAG factory 形式) で定義。AWS operator に対応し、既存の Python DAG を変換するオプションもある
  • ワークフロー単位の IAM 権限VPC 分離。各ワークフローが専用の実行ロールと Worker を持ち、最小権限で動かせる
  • トレードオフ: Airflow UI へのアクセスはなし(監視はログ経由)。また各タスクが実行前に自前でコンピュートを起動するため、起動時間が発生する

MWAA と Step Functions の使い分け

汎用ソリューションのなかでも、MWAA と Step Functions は比較されやすい組み合わせです。

MWAA と Step Functions の比較

観点 AWS Step Functions Amazon MWAA
開発スタイル GUI で作成 コードベースでの開発
連携先 AWS サービス統合 AWS 外との Operator も存在
記述言語 JSON で記述 Python で記述
インフラ サーバーレス インフラが必要 ※
計算環境 別途 Lambda で用意 Worker で実行
スケール/スケジュール スケールが柔軟 スケジュール実行が柔軟

※ MWAA Serverless も存在しますが、本スライドでは(プロビジョンド版の)MWAA と比較しています。

ざっくり言えば、AWS サービスを疎結合につなぐサーバーレスなオーケストレーションは Step FunctionsPython 資産や AWS 外連携を含む複雑なデータパイプラインを柔軟なスケジュールで回すなら MWAA、という住み分けです。


A 社のステートマシン: 肥大化していくワークフロー

ここから本題の「複雑性のコントロール」に入ります。題材として、最初は単純だったワークフローが肥大化していった A 社のステートマシン が示されました。

サインアップイベントを処理する、肥大化した A 社のステートマシン

サインアップイベントを処理するワークフローが、メール検証・特典計算・プラン別ルーティング(Enterprise / Pro / Free のプロビジョニング)・不正/与信チェック・CRM 登録……と機能追加を重ねるうちに、次のような問題を抱えていきました。

  • ステート数の肥大化
  • 複雑なロジックの記載
  • 複数チームにまたがるフロー
  • 開発生産性の低下

「あるある」な光景です。このあとセッションでは、ここで挙がった問題を 課題1(ロジックの混入)課題2(複数チームにまたがる処理) に切り分けて、それぞれの解決パターンを提示していきました。

課題1: オーケストレーターにロジックが記載される

1つ目の課題は、オーケストレーター(ステートマシン)の中に複雑なロジックが直書きされてしまうことです。

Choice state の Condition に、複雑なメール検証ロジックが直書きされている

例として示されたのは、Choice state「メール検証」の Condition です。メールアドレスの正規表現チェックと、使い捨てメールドメインの除外リストが、JSONata 式としてステートマシン定義の中にそのまま書かれていました(イメージ)。

"Condition": "{% $contains($user.email, /^[^@\s]+@[^@\s]+\.[^@\s]+$/)
  and ($substringAfter($user.email, '@') in
    ['disposable.example.com', 'tempmail.example.net',
     'throwaway.example.org', 'fakeinbox.example.com']) = false %}",

これが引き起こす問題は次のとおりです。

  • 複雑な検証ロジックが Choice state の中に存在する
  • 検証の抜けもれが起きやすい
  • メンテナンスが困難(テストもしづらい)

解決: ロジックは Lambda で処理する

解決策はシンプルで、ロジックをオーケストレーターから Lambda(コード)側に追い出すことです。

検証ロジックを Lambda に移すことで得られるメリット

ロジックを Lambda に持っていくことで得られるメリットとして、次の3点が挙げられました。

  • 外部ライブラリの使用(メール検証ライブラリなどを活用できる)
  • シンタックスハイライト(普通のコードとして読み書きできる)
  • 関数によるまとめ(再利用・単体テストがしやすい)

オーケストレーターは「流れの制御」に専念し、「何をするか」のロジックは Lambda に置く。役割分担をはっきりさせる、という設計原則ですね。

flowchart LR
    subgraph Before["Before: ロジックが混入"]
        A1["Choice state<br/>(複雑な Condition 直書き)"]
    end
    subgraph After["After: 関心の分離"]
        B1["Lambda<br/>検証ロジック"] --> B2["Choice state<br/>(結果で分岐するだけ)"]
    end
    Before -.リファクタリング.-> After
    style A1 fill:#ffcdd2,stroke:#c62828,color:#000
    style B1 fill:#c8e6c9,stroke:#2e7d32,color:#000
    style B2 fill:#c8e6c9,stroke:#2e7d32,color:#000

課題2: 複数のチームに分かれた処理

2つ目の課題は、1本の長いワークフローに、複数チーム(ドメイン)の処理が直列で詰め込まれていることです。A 社の例では、リスク部門・マーケティング部門・プロダクト部門の処理が一つのステートマシンに同居していました。

複数ドメインの処理が直列に存在することの問題

直列に複数ドメインが並ぶことで、次の問題が生じます。

  • エラーが他チームへ波及する
  • 他チームの出力形式に依存する
  • デプロイの煩雑化(1本のステートマシンを複数チームで触る)

解決: ワークフローの分割

解決策は、ワークフローをチーム/ドメインの単位で分割することです。提示された手段は3つでした。

ワークフロー分割の3つの手段

  • ネストされたワークフロー(Step Functions から子ステートマシンを StartExecution で呼ぶ)
  • Amazon SQS を経由したロジック(キューで疎結合にする)
  • AWS Lambda durable function(アプリロジック側で完結させる)

分割後のステートマシンは、親ワークフローが各チームの子ワークフロー(プロダクト処理 → リスク処理 → マーケ処理 → 通知処理)を順に呼び出し、それぞれが Catch で自分の Fail state に落ちる構成になっていました。エラーの波及が止まり、チームごとに独立してデプロイ・テストできるのがポイントです。

チームごとにネストされた子ワークフローに分割された状態

flowchart TB
    Start([Start]) --> Format["Pass: サインアップイベント整形"]
    Format --> Product["Step Functions: StartExecution<br/>プロダクト処理"]
    Product -->|Catch| PF["Fail: プロダクト処理失敗"]
    Product --> Risk["Step Functions: StartExecution<br/>リスク処理"]
    Risk -->|Catch| RF["Fail: リスク処理失敗"]
    Risk -->|Catch| Block["Fail: 不正検知ブロック"]
    Risk --> Marke["Step Functions: StartExecution<br/>マーケ処理"]
    Marke -->|Catch| MF["Fail: マーケ処理失敗"]
    Marke --> Notify["Step Functions: StartExecution<br/>通知処理"]
    Notify --> Done([Succeed: 完了])
    style Product fill:#e1bee7,stroke:#6a1b9a,color:#000
    style Risk fill:#b2dfdb,stroke:#00695c,color:#000
    style Marke fill:#bbdefb,stroke:#1565c0,color:#000

親ワークフローは「どのチームの処理を、どの順で呼ぶか」だけを担い、各チームの中身(子ワークフロー)には踏み込まない。チーム境界=ワークフロー境界にそろえる、という分割の考え方です。


後半: 生成 AI エージェントの「非決定性」をどうコントロールするか

ここまでの前半は「決定論的なワークフロー」の複雑さをどう抑えるか、という話でした。後半は、生成 AI エージェントがもたらす 「非決定性」 という新しい複雑さに踏み込みます。

エージェントの「非決定性」とは何か

これまで扱ってきたワークフローは 決定論的(deterministic) でした。同じ入力を与えれば、毎回同じ経路をたどり、同じ結果になります。だからこそテストや監査がしやすい。

一方、生成 AI エージェントは 非決定論的(non-deterministic) です。LLM が推論で次の行動を決めるため、同じ入力でも、たどる経路や出力が変わりうる。これが「新しい複雑さ」の正体です。前半で見た「ステートが増える」「ロジックが絡まる」といった複雑さとは種類が違い、そもそも振る舞いが一意に定まらないという難しさが加わります。

2つのオーケストレーションモデル: ルールベース と AI-native

AWS のプリスクリプティブガイダンスでは、この違いを 2つのオーケストレーションモデル として整理しています(Orchestration models: From rule-based to AI-native)。

ルールベース・オーケストレーション AI-native オーケストレーション
代表 AWS Step Functions 生成 AI エージェント(Amazon Bedrock など)
性質 決定論的・監査可能 非決定論的・ゴール駆動
流れの決め方 明示的なステップと条件分岐 LLM が文脈から自律的に推論・計画・判断
向くもの 構造が決まった処理 意図に応じて手順が変わる処理

セッション要旨にあった 「AI Workflows とエージェンティック AI」 も、この対比に対応します。

  • AI Workflows: 決まった流れの中に AI の処理(モデル呼び出しなど)を組み込む。骨格は決定論的
  • エージェンティック AI: エージェント自身が次の手を決める。骨格から非決定論的

組み合わせパターン: 決定論的な骨格 × 非決定論的な判断

セッションの主題は、決定論的なワークフローと、非決定論的なエージェントをどう組み合わせるか でした。考え方は前半とまったく同じで、「決まった流れ」を骨格にしつつ、「判断が必要な部分」だけをエージェント(非決定論的なコンポーネント)に閉じ込める という役割分担です。

前半の「ロジックは Lambda に追い出す」「ワークフローを分割する」という原則が、AI でもそのまま効きます。ポイントは 非決定性をワークフロー全体に広げないこと。非決定論的な判断は「エージェント」という箱の中に局所化し、その外側は決定論的なワークフローで制御・監査します。

具体的な接続点は次のとおりです。

  • AI ワークフローのオーケストレーション = Step Functions: OCR → 分類 → 要約 → ルーティングのような多段 AI パイプラインを、モジュール化されたステージとして組めます(Multi-stage AI workflow パターン)。Map で Bedrock 呼び出しを並列化したり、RAG を挟んだりも可能です(Orchestrate generative AI workflows with Amazon Bedrock and AWS Step Functions)。
  • 長時間 AI タスク = Lambda durable functions: 公式のユースケースにも 「モデル呼び出しを連鎖させ、人のフィードバックを挟み、長時間タスクを障害時も決定論的に扱うマルチステップ AI ワークフロー」 が挙げられています(Lambda durable functions)。前半で触れた .waitForTaskToken や Callback 操作は、human-in-the-loop(人のレビューを挟む) にそのまま使えます。
  • エージェント本体のホスティング = Amazon Bedrock AgentCore: 2025年10月に GA した、AI エージェントを動かすためのサーバーレス実行環境です(Introducing Amazon Bedrock AgentCore)。フレームワーク非依存・モデル柔軟で、セッション分離(microVM)・最大8時間の長時間実行・観測性などを提供します。Step Functions から AgentCore を呼び出せば、決定論的なワークフローの一部として「非決定論的なエージェント」を組み込めます。
flowchart LR
    subgraph Deterministic["決定論的な骨格(Step Functions / durable functions)"]
        S1["前処理<br/>整形・検証"] --> Agent
        Agent --> S2["後処理<br/>保存・通知・監査"]
    end
    Agent["非決定論的な判断<br/>AI エージェント / モデル呼び出し<br/>(Bedrock / AgentCore)"]
    HITL["人のレビュー<br/>human-in-the-loop"] -. waitForTaskToken / Callback .-> Agent
    style Agent fill:#fff3e0,stroke:#e65100,color:#000
    style HITL fill:#e3f2fd,stroke:#1565c0,color:#000

非決定論的な「判断」だけをエージェントに任せ、その前後の「決まった処理」と「人のレビュー」を決定論的なワークフローで固める。こうすると、AI を使いながらも、全体としては監査・再現・リカバリが可能 な構成にできます。前半で積み上げた「関心の分離」と「ワークフローの分割」が、そのまま非決定性のコントロールにも効く、というのが後半の納得ポイントでした。

ℹ️ 本セクションはセッション要旨と AWS 公式ドキュメントをもとに再構成しています。当日のスライド画像が手元に届き次第、各小見出しの図を差し込み、登壇者の具体例にあわせて微調整します。


まとめ

CNS454 の前半は、「オーケストレーターは流れの制御に徹し、ロジックとドメインは外に出す」 という、シンプルだが効く原則を、A 社の肥大化したステートマシンを題材に具体化してくれるセッションでした。

課題 症状 解決パターン
課題1: ロジックの混入 Choice state に複雑な検証ロジックが直書き、抜けもれ・保守困難 ロジックを Lambda へ(外部ライブラリ・テスト・再利用)
課題2: 複数チームの同居 エラー波及・出力形式依存・デプロイ煩雑 ワークフローの分割(ネスト / SQS / durable function)

サービス選定の軸も明快でした。

  • サービス横断のオーケストレーション → Step Functions
  • アプリロジックと密結合した耐久ワークフロー → Lambda durable functions
  • Airflow 資産・AWS 外連携を含むデータパイプライン → MWAA / MWAA Serverless(2025年11月にアイドルコスト不要のサーバーレス版が登場)

そして後半の 「決定論的ワークフロー × 非決定論的エージェント」 が、これからのオーケストレーション設計の肝になりそうです。非決定論的な「判断」はエージェントに局所化し、その外側を Step Functions / durable functions の決定論的なワークフローで固める——前半で積み上げた「関心の分離」と「ワークフローの分割」が、AI 時代のオーケストレーションでもそのまま効く、というのが前後半を貫くメッセージでした。

(※ 後半セクションはセッション要旨と AWS 公式ドキュメントをもとに構成しています。当日のスライド画像が届き次第、図を差し込みます。)


参考リンク

後半(生成 AI エージェント・非決定性)関連

余談

五島列島でのんびりワーケーションしてきました。

山本 哲也 ฅ^•ω•^ฅ にゃー(記事一覧)

エンジニアです。データ分析に興味あります。ฅ^•ω•^ฅ にゃー

山を走るのが趣味です。(スカイランナー)ฅ^•ω•^ฅ にゃー