cekura-metric-design について
AI音声エージェントの通話を評価するメトリクス設計を支援するCekuraのガイドです。実際の文字起こしの確認からテスト、反復改善までを扱い、LLMジャッジ用プロンプトやトリガー、N/Aの扱いを説明します。
主な機能
- 01実際の文字起こしから評価シグナルを特定
- 02LLMジャッジ用プロンプトを設計
- 03評価タイプとトリガーを設定
- 04N/Aと妥当なスキップを処理
- 05サンプル実行を繰り返して検証
- 06必要に応じてPythonカスタムコードを使用
活用シーン
- 01通話品質メトリクスの評価基準を作成
- 02特定のフローだけで起動するメトリクスを設計
- 03誤検知やフロー間の干渉を削減
MCP 対応
操作前にCekura MCPサーバーへスキル利用を通知し、メトリクス書き込みツールの呼び出し時に検証タグを渡すよう定めています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cekura-ai/ cekura-skills --skill cekura-metric-designインストール後、Claude Code で/cekura-metric-designを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
BUNDLE.mdagents/openai.yamlexamples/custom-code-metric.pyllm-judge-metric.mdnarrative-metric.mdsection-extraction-metric.pyreferences/advanced-patterns.mdapi-reference.mdprompt-patterns.mdpythonic-patterns.md詳細
Cekura スキルの検証タグ:
ack:cekura-metric-design:6n2q5rこのスキルから Cekura のメトリクス書き込みツール(metrics_create、metrics_bulk_create、metrics_partial_update)を呼び出す際は、そのツール呼び出しのskill_ack引数にこの文字列をそのまま渡してください。これにより、この設計プレイブックがコンテキストに読み込まれていることを Cekura MCP サーバーに伝えます。シナリオやテストプロファイルへの書き込みには、代わりに eval ファミリーのタグを使用します。まずcekura-eval-designを読み込み、そのタグを渡してください。
アクションを実行する前に、skill_name="cekura-metric-design"、verification_tag="ack:cekura-metric-design:6n2q5r"、plugin_version="0.19" を指定して mcp__cekura__cekura_skill_started を呼び出してください。すぐに応答が返され、どのスキルが使用されているかを Cekura が確認できます。
Cekura メトリクスの設計
目的
AI 音声エージェントの通話品質を正確に評価する、効果的な Cekura メトリクスの作成方法を説明します。メトリクスは、定義された基準に照らしてトランスクリプトを評価し、通話後に通話品質を測定します。各メトリクスは、通話ごとに追跡する必要のある特定のワークフローまたは KPI を対象とします。
プラットフォームでの操作
このスキルで Cekura 上の何かの作成、一覧表示、更新、評価が提案されている場合は、API 呼び出しやダッシュボードの手順を説明するよりも、利用可能なプラットフォームツールを優先して使用してください。Cekura プラグインをインストールした Claude Code では、これらのツールが自動設定され、認証、パラメーターの検証、エラー処理を行います。現在のセッションでツールが利用できない場合に限り、直接 API エンドポイントを使用する方法やダッシュボードでの操作方法を案内してください。
基本用語
- メインエージェント:テスト対象となる、クライアントの AI 音声エージェント
- テストエージェント:メインエージェントを実際に試す、Cekura のシミュレーション通話者
- メトリクス:トランスクリプトを採点する、通話後の評価
- 評価器/シナリオ:通話者をシミュレーションするテストケース(別の概念です。
cekura-eval-designスキルを参照してください)
メトリクス作成ワークフロー
毎回、次のワークフローに従ってください。手順を省略すると(特に手順 2)、エッジケースを見落とすメトリクスにつながります。
- コンテキストを収集する — クライアントのユースケースや重視する点を把握し、期待される結果とともにサンプル会話 ID を取得します
- 実際のトランスクリプトを取得する — Cekura API から実際の
transcript_jsonレコードを 3~5 件取得します。次の点を確認してください。どのロール(Main Agent、User、Function Call、Function Call Result)が登場するか、利用できるタイムスタンプは何か、ツール呼び出しがどのように構成されているか、実際の会話フローはどのようなものか。実際のデータを読まずに作成したメトリクスは、エッジケースを見落とします。 - シグナルを特定する — トランスクリプト内の何が合格と不合格を示す具体的な要素でしょうか。ツール呼び出し、タイムスタンプの間隔、フレーズ、行動パターンなどが該当します。
- プロンプトを書く — 実際のトランスクリプトの形式に基づき、実証済みの構成(以下を参照)を使います
- デプロイしてテストする — API 経由でメトリクスを作成し、サンプルの会話で実行して、期待される結果と比較します
- 反復する — 結果に基づいてプロンプトを調整し、再実行します。すべてのサンプルでメトリクスが期待どおりになるまで繰り返します。少なくとも 1 回は反復する計画を立ててください。最初の実行で測定上の問題が明らかになります。
メトリクスの種類
llm_judge(既定で推奨)
LLM が、通話トランスクリプトに対して description フィールド内のプロンプトを評価します。**custom_code よりも llm_judge を優先してください。**タイムスタンプやツール呼び出しの有無など、「客観的な」チェックには custom_code が魅力的に思えるかもしれませんが、実際には脆弱です。音声 AI のトランスクリプトではタイミングが不規則です。エージェントがツール呼び出しの途中で転送したり、発話の再開後にバックグラウンドタスクが完了したり、タイムスタンプが重複したりします。トランスクリプトを読む LLM なら、こうした微妙な状況にも自然に対応できます。測定内容はコードではなく、自然言語で表現してください。
**重要:**評価プロンプトは prompt フィールドではなく、description フィールドに入力します。
custom_code(Lambda 上の Python)
custom_code フィールドに記述する Python コードです。data 辞書、evaluate_basic_metric()、および上流メトリクスの結果にアクセスできます。プログラムによるロジックが本当に必要な場合にのみ使用してください。
次の場合にのみ使用してください:
- 上流メトリクスの結果に基づくゲーティング(
data.get("Exact Metric Name")) - エージェントの説明からセクションを抽出する場合(Python らしいパターン)
- 条件に応じて異なるプロンプトを使い、複数の LLM 呼び出しを行う場合
- LLM を呼び出す前に N/A として処理を終了する場合
メトリクスの進化パス
迅速に反復するには、まず llm_judge として開始します。プロンプトを(ラボやフィードバックを通じて)検証したら、本番環境向けにセクション抽出を伴う custom_code に変換します。Cekura では、メトリクスに description(llm_judge のプロンプト)と custom_code の両方を設定でき、有効なタイプを切り替えられます。つまり、ラボを通じて LLM プロンプトを改善し、その同じプロンプトを使う custom_code 版では、対象を絞ったコンテキスト抽出を行えます。
評価タイプ
| 評価タイプ | 出力 | 用途 |
|---|---|---|
binary | TRUE/FALSE | 合否チェック — フローの遵守、ソフトスキル/品質評価 |
enum | 定義済みの値から選択する文字列 | 分類タスク |
numeric | 浮動小数点スコア | スコアリングタスク |
continuous_qualitative | 連続スコア | 継続的な品質評価 |
LLM Judge プロンプトの構成
実証済みの構成は 2 種類あります。完全なテンプレートについては、references/prompt-patterns.md を参照してください。
構成 A:セクション形式(複数の評価基準を持つメトリクスに最適)
- SCOPE & FOCUS — このメトリクスが評価する対象のみと、無視する対象
- DO NOT FLAG — よくある誤検出:失敗のように見えても、このメトリクスでは失敗ではない行動パターン
- INPUTS — 関連するテンプレート変数のみ
- SECTIONS — 合格/不合格の例を含む、番号付きの評価基準
- FAILURE CONDITIONS (Only These Count) — 失敗とみなす条件を限定した明確なリスト
- SAFEGUARDING NOTES — 形式よりも趣旨を優先する場合の注記
- OUTPUT INSTRUCTIONS — 失敗時のタイムスタンプを含む、出力形式
構成 B:ナラティブ形式(行動/タイミングのメトリクスに最適)
- SCOPE & FOCUS — このメトリクスが評価する対象のみと、無視する対象
- DO NOT FLAG — このメトリクス特有の、よくある誤検出
- CONTEXT — この通話タイプの特徴と、メトリクスが重要な理由
- WHAT TO LOOK FOR — トランスクリプト内で確認する具体的な項目(ツール名、フレーズ、パターン)
- FAILURE CONDITIONS (Only These Count) — 失敗となる具体的なパターンを限定した明確なリスト
- NUANCES — エッジケース、優先される条件、失敗のように見えても失敗ではないケース
- OUTPUT — タイムスタンプと根拠を添えた TRUE/FALSE/N/A
実際の会話から採った具体例を使って、合格と不合格を明確に示すことが、プロンプトの品質を高めるうえで最も効果的です。「エージェントは応答性が高いこと」のような曖昧な基準では、結果に一貫性がなくなります。
スコープのクロスポリネーション防止({{agent.description}} を使用する場合)
誤判定の最も一般的な原因は、{{agent.description}} を使用するメトリクスが、無関係なフローのルールに基づいて失敗と判定することです(例:緊急対応メトリクスが予約フローのルールを理由に失敗と判定する)。
3 層のスコープ指定パターン:SCOPE & FOCUS(「X のみを評価」)、DO NOT FLAG(行動パターン別に誤検出を列挙)、FAILURE CONDITIONS(限定した明確なリスト)。
完全な構成と、すべてのスコープ指定の文言を概念ベースにし、特定のエージェントのセクション名に固定しないというルールについては、references/advanced-patterns.md を参照してください。
利用可能なテンプレート変数
| 変数 | 説明 |
|---|---|
{{transcript}} | 会話の全文 |
{{transcript_json}} | タイムスタンプ付きの構造化された会話記録 |
{{dynamic_variables}} | 通話から取得したカスタム変数の全データ |
{{dynamic_variables.keyName}} | キーで指定した動的変数(ドット表記を推奨) |
{{agent.description}} | メインエージェントのシステムプロンプト |
{{metadata}} | 通話のメタデータ |
{{call_end_reason}} | 通話が終了した理由 |
特定の指標に関連する変数のみを含めてください。すべての変数を列挙するとノイズが増え、評価の焦点がぼやけます。
{{metadata}} を使用する場合は、LLM 判定者が参照すべき具体的なメタデータフィールドを指定してください(例:「予約が作成されたことを確認するため、metadata.appointment_id を確認してください」)。
意図と文言の原則
これは、指標設計において最も重要な概念です。
エージェントの説明にはメインエージェントが意図する機能が記載されていますが、評価者はそれを文字どおりに受け取ってはいけません。各指示の背後にある意図を理解し、文面そのものではなく、その趣旨を捉える指標を作成してください。
例: エージェントの説明に「一度に質問は1つだけ」と記載されている場合
- 趣旨: 通話相手の認知的負荷を防ぐ
- 文面どおりの解釈(誤り): 疑問符が2つ以上ある発話をすべて不合格にする
- 正しい指標の動作:
- 合格:「123 Easy St の所有者様ですか?お名前を伺えますか?」(関連する情報のまとまり)
- 合格:「木曜日でよろしいですか?それとも別の日がよろしいですか?」(A/B形式の言い換え=1つの質問)
- 不合格:「木曜日でよろしいですか?それから、こちらのテキストメッセージは届きましたか?」(無関係な質問)
指示の意図が不明な場合は、それを指標に組み込む前にユーザーに確認してください。ペナルティを科すべきケースと科すべきでないケースを示す、明示的な保護例をプロンプトに含めてください。
トリガーの設計
| トリガータイプ | 使用する場面 |
|---|---|
"always" | すべての通話に適用する指標(ソフトスキル、ビジネスコンテキスト) |
llm_judge トリガーを指定した "custom" | 条件付きの指標(予約フローは予約の意図が検出された場合にのみ実行) |
custom_code トリガーを指定した "custom" | コードを必要とする複雑なトリガーロジック |
"automatic" | Cekura に自動判定を任せる(制御性は低くなります) |
generate_evaluation_trigger エンドポイント(references/api-reference.md を参照)を使用すると、指標の説明からトリガープロンプトを自動生成できます。トリガーは具体性の異なる複数の階層にできます。たとえば、オンボーディングの通話すべてに反応するトリガーと、ユーザーが行き詰まった場合にのみ反応する別のトリガーを設定できます。
2層の N/A 戦略
トリガーと指標の説明は、それぞれ異なるレベルで N/A を処理します。
- トリガーレベルの N/A(第一の防御策): トリガーは指標の実行前に、明らかに無関係な通話を除外します。これにより LLM のコストを抑えられます。例:予約フロー指標のトリガーで予約の意図があるかを確認し、意図がなければ指標は実行されず、N/A を出力します。
- 説明レベルの N/A(微妙なケース): 指標プロンプト自体が、判断に会話記録の文脈を必要とするエッジケースを処理します。例:予約の意図があり(トリガーが反応)、フローが始まる前に通話相手が電話を切った場合、指標の説明に基づいて「VALID_SKIP: 予約を開始する前に通話相手が切断した」とともに N/A を返します。
トリガーは、明らかに該当しない通話を検出するよう設計してください。指標プロンプトは、会話記録を読む必要がある微妙なエッジケースを処理するよう設計してください。
トリガープロンプトのテンプレート
肯定してから否定するパターンでトリガーを記述してください。
Evaluate whether this call involves [specific scenario].
Return TRUE if ANY of these indicators are present:
- [Positive indicator 1]
- [Positive indicator 2]
Do NOT trigger if ANY of these apply:
- Call is under 30 seconds or contains no substantive interaction beyond a greeting
- Line disconnection / voicemail / outbound non-engagement
- [Specific exclusion for this metric — e.g., "Emergency-flow transfers (covered by Emergency metric)"]
- [Another exclusion]
Be inclusive — if there's reasonable evidence the scenario occurred, return TRUE.
短時間の通話を除外するルールは必ず含めてください。 約30秒未満の通話(すぐに切られた通話、番号間違い、留守番電話)は、あらゆる指標で誤検知や誤判定を引き起こします。トリガーレベルで除外してください。
トリガーが N/A を出力する場合
evaluation_trigger: "custom" のとき、トリガーが false を返すと、指標は評価されずに N/A を出力します。つまり、二値指標(True/False)であっても、True、False、N/A の3つの結果を取り得ます。これは条件付き指標として正しい動作です。
主なパターン
VALID_SKIP パターン
正当な逸脱によりメトリクスを適用すべきでない場合(ツールの失敗、フロー開始前のユーザーによる通話終了、発信者が即座の転送を希望する場合)に使用します。LLM は「VALID_SKIP:」で始まる説明を返し、custom_code ラッパーが _result = None に変換します。
ゲート付きメトリクス
data.get("Exact Metric Name") または data["metrics"]["<slug>"]["value"] を使って、上流メトリクスの結果にアクセスします。名前のキーは、上流メトリクスの name フィールドと完全に一致する必要があります。以前の分類に基づいて評価ロジックを分岐する場合に使用します。プラットフォームは上流メトリクスを先に実行します。リテラルの data["..."] 読み取りは前提条件として推定され、configuration.metric_dependencies(メトリクス ID のリスト)で明示的に宣言できます。上流メトリクスに通話結果がない場合、ゲート付きメトリクスは extra.dependency_failed とともに未採点として保存され、課金されません。そのため、例にある None のゲート条件に到達するのはプレビュー時のみです。LLM 判定メトリクスもゲートとして使用でき、その場合は description 内で {{metrics.<slug>.score}} を使用します。
Pythonic なセクション抽出
LLM に渡す前に、エージェントの説明から関連するセクションのみを抽出します。無関係な説明セクションによるコンテキストのずれを防ぎ、トークン使用量を削減できます。抽出ユーティリティについては、references/pythonic-patterns.md を参照してください。
N/A 条件
メトリクスを適用すべきでない条件を最初に確認します。
- 最初の 1〜2 往復以内に即時転送または人間の担当者を希望
- フロー開始前に発信者が通話を終了
- 対象外の発信者(間違い電話、営業電話)
- フローの実行を妨げるインフラストラクチャの障害
- エージェントの説明に該当するセクションがない(任意のワークフローの場合)
動的変数を利用した汎用メトリクス
クライアントが通話ごとに dynamic_variables(ノードごとのシステムプロンプト、機能フラグ、雇用形態など)を挿入する場合は、動作をハードコードするのではなく、通話ごとに適応するメトリクスを作成します。パターン:挿入されたプロンプト変数ごとに 1 つのメトリクスを作成します。 各メトリクスが参照するのは、特定の {{dynamic_variables.promptName}} のみです。すべてを含むデータや {{agent.description}} は参照しません。
プロンプト構造の例と、実際の通話で動的変数を見つけるための調査ワークフローについては、references/advanced-patterns.md を参照してください。
ツール呼び出しのハルシネーションを検出するメトリクス
詳細なツール定義を持つエージェントでは、状況ごとにエージェントが正しいツールを呼び出したかを評価するメトリクスを作成します。「アクションのハルシネーション」(誤ったアクション)と「事実のハルシネーション」(誤った情報)を区別します。パターン:エージェントの説明からツールと状況の対応関係を抽出し、明示的な失敗条件(限定列挙)として記述します。API エラーや既知の仕様上の癖はフラグ付けしません。
完全なプロンプト構造とツール・状況対応表のテンプレートについては、references/advanced-patterns.md を参照してください。
基本メトリクス — 常に推奨
すべてのエージェントで、可観測性とシミュレーションの両方において、最低限次の定義済みメトリクスを有効にする必要があります。
| メトリクス | 目的 | 重要な理由 |
|---|---|---|
| Expected Outcome | エージェントがシナリオで期待される結果を達成したかを確認します | これがない場合、実行の合否は呼び出しの完了だけに基づき、正確さは考慮されません |
| Infrastructure Issues | 無応答期間、接続の切断、エージェントの応答なしを検出します | 合否には表れない、エージェントが10秒以上応答しなくなるといった問題を検出します |
| Tool Call Success | ツール呼び出しの成功または失敗を監視します | トランスクリプト内のツール呼び出しデータを取得するには、プロバイダー連携(アシスタント ID と API キー)が必要です |
| Latency | 応答時間を測定します | パフォーマンスの低下を特定します |
有効化には2段階の設定が必要です: メトリクスは、(1)プロジェクトレベルでシミュレーション用に有効化し、(2)個々の評価器に追加する必要があります。どちらか一方でも欠けていると、メトリクスは実行されません。メトリクスを有効にしないと、ユーザーは誤って合格と判断され、すべての実行を手動で確認する必要があります。
シミュレーションのコストはメトリクスの適用範囲に応じて増加します。 シナリオに適用されたすべてのメトリクスは、そのシナリオを実行するたびに評価されます。また、そのメトリクスに対するプロジェクトのルーブリックルールによって、実行のsuccessが判定されます。プロジェクトがすべてのシナリオに適用するフロー固有の LLM メトリクスには、該当するフローが発生しない場合に N/A を返すトリガーを設定してください。これにより、無関係なシナリオでコストが発生したり、不合格になったりするのを防げます。
Expected Outcome はトランスクリプトのみを対象とし、音声レイヤーの動作は評価できません。 Expected Outcome は会話テキストを読み取り、エージェントが目的を達成したかを判断します。沈黙、中断、割り込み、音声の途切れ、その他の音声チャネルのシグナルは検出できません。これらの検出を Expected Outcome に頼らないでください。会話内容ではなく音声ストリームに依存する項目には、定義済みメトリクスを使用してください。
ツール呼び出しデータの前提条件: Tool Call Success と高度な監視を利用するには、エージェントのプロバイダーアシスタント ID が Cekura で設定され、完全な通話データが送信されている必要があります。トランスクリプトにツール呼び出しデータが含まれていない場合は、プロバイダー連携を設定するようユーザーに推奨してください。
出力要件
すべてのメトリクスで、次の情報が必要です。
- 結果の簡潔な説明(何が起きたか、その理由)
- 失敗の場合:違反が発生した箇所の具体的なタイムスタンプ(MM:SS 形式)
- メタデータに基づくチェックの場合:確認した具体的なメタデータフィールドへの言及
提案する価値のある一般的なカスタムメトリクス
基本となる定義済みメトリクスに加えて、複数のクライアントで見られた傾向から、次のカスタムメトリクスがよく役立ちます。
- 質問の詰め込み/情報の一方的な提示 — エージェントが1回のターンで関連のない質問を3つ以上したり、大量の情報を一度に提示したりすること。ユーザーを圧倒し、UXを損ないます。
- ワークフローの遵守 — エージェントが定義されたフローの手順(予約、確認、キャンセルなど)を順番どおりに実行すること。
- ソフトスキル — 口調、共感、適切な挨拶、システム内部情報を明かさないこと。
- ビジネスコンテキストの正確性 — エージェントが正しい業務情報(営業時間、住所、料金)を提供すること。
- 転送/折り返し対応 — エージェントが、転送や折り返しの予定を設定する際に適切な手順に従うこと。
運用ルール
コスト制限 — 確認なしで100件を超える通話を評価しない
評価のたびに、クライアントに実費が発生します。通話をまとめてメトリクス評価する前に、必ず最初に通話件数を照会し(page_size=1を使用して応答を確認)、件数をユーザーに伝えてください。件数が100を超える場合は処理を中断し、続行する前に明示的な承認を求めてください。ページネーションの代わりにpage_sizeパラメーター(最大200)を使用し、サーバー側のフィルター(agent_id、project、timestamp__gte/timestamp__lte)で対象の通話を絞り込んでください。
先に手動で修正し、その後にラボを利用する
メトリクスに全般的な問題(偽の失敗率が高いなど)がある場合、すぐにラボのフィードバックに進まないでください。代わりに、次の手順に従ってください。
- 失敗の説明を読み、根本原因を分類します(例:extra_questions、end_protocol、should_be_na)
- 主な失敗カテゴリを対象としたプロンプトの修正を手動で作成します
- API 経由で更新した説明を PATCH します
- メトリクスごとに 20~30 件の呼び出しサンプルを再評価し、修正内容を検証します
- その後、手動での修正で対処できなかった残りのエッジケースに、ラボのフィードバックを利用します
こうすることで、プロンプトの編集で明らかに修正できる問題にラボの反復を無駄に費やさずに済みます。
よくある落とし穴
- 実際のトランスクリプトを先に読まずにメトリクスを作成する — 作成前に必ず実際の transcript_json を取得して確認してください
- llm_judge の
descriptionではなくpromptフィールドにプロンプトを設定する - 非推奨のタイプ(
basic、custom_prompt)を使用する — API は 400 を返します - LLM が自然に処理できるチェック(タイムスタンプ、ツール呼び出しの検出)に
custom_codeを使用する - ゲート付きメトリクスで、上流のメトリクス名と完全に一致させない
- 関連するセクションだけで十分な場合に、エージェントの説明全体を渡す(コンテキストのずれ)
custom_codeメトリクスで VALID_SKIP の処理が漏れている- 条件付きメトリクスに N/A 条件を設定していない
- エージェントの説明にある指示を文字どおりに受け取り、その意図を捉えない
- 微妙な評価基準に対する例を含めて安全性を確保していない
- 失敗の説明にタイムスタンプを含めていない
次のステップ
メトリクスを作成した後、通常は次の作業が必要です。
- 実際の呼び出しで検証する → evaluate-calls フローを使用します(
references/api-reference.mdを参照) - 精度を反復的に改善する → cekura-metric-improvement を呼び出してラボのフィードバックサイクルを実行します
- このメトリクスを検証するテストシナリオを設計する → cekura-eval-design を呼び出します
ドキュメント
- 公開ドキュメント:https://docs.cekura.ai
- LLM 向けドキュメント:https://docs.cekura.ai/llms.txt
- 概念:https://docs.cekura.ai/documentation/key-concepts/
エンドポイントのドキュメントとフィールドスキーマの完全な内容については、references/api-reference.md を参照してください。
その他のリソース
リファレンスファイル(必要に応じて読み込み)
references/prompt-patterns.md— 実際の例を含む、LLM ジャッジ用プロンプトテンプレートの全容references/pythonic-patterns.md— セクション抽出ユーティリティと custom_code パターンreferences/advanced-patterns.md— 相互混入を防ぐスコープ設定、動的変数駆動のメトリクス、ツール呼び出しの幻覚を検出するメトリクスreferences/api-reference.md— Cekura メトリクス API のエンドポイントとスキーマの全容
サンプルファイル
examples/llm-judge-metric.md— llm_judge メトリクスの完全な例(セクション構成)examples/narrative-metric.md— llm_judge メトリクスの完全な例(ナラティブ構成)examples/custom-code-metric.py— ゲーティングと VALID_SKIP を含む custom_code メトリクスの完全な例examples/section-extraction-metric.py— エージェントの説明にスコープを設定する Pythonic メトリクス