メインコンテンツまでスキップ

AI 問答

選択中の AI プロバイダーへテキストで質問を送り、返された質問 ID と各コールバックを対応付けながら、回答の全文または差分を表示します。

Animated workflow

AI 問答リクエストのライフサイクル

質問 ID は同期的に返る場合とコールバックで届く場合があり、その後に回答の逐次更新と終了コールバックが届きます。

ホストアプリ

質問を検証

入力の前後にある空白を除去し、空のプロンプトはリクエスト作成前に除外します。

ホストアプリ

エージェントを設定

必要に応じて、プロバイダー固有のエージェント ID を選択します。

AI サービス

質問を送信

AIBudsAISDK.send を呼び出し、同期的に返された ID があれば保持します。

開始コールバック

回答を開始

プロバイダーが回答を開始した時点で質問 ID を取得します。

AI サービス → アプリ

回答を逐次受信

fullText があれば優先して使用し、なければ deltaText を追加します。

差分または全文
確定結果

完了または失敗

終了コールバックを受けて UI を再度有効にし、リクエスト状態を終了します。

終了判定には onFinishAnswering または onError を使用します。isFinal は回答更新の最終回を示すだけです。

前提条件

  • AIBudsAISDK を初期化し、登録済みプロバイダーを選択して、必要な認証を完了していること。
  • 選択中のプロバイダーが AIAskingServiceAPI を実装していること。
  • コールバックを受けて行う UI 更新はメインキューへ切り替えること。

AI を活用して実装

AI で実装

AI でこのワークフローを実装

公式の「AIBuds AI 質問応答の実装」スキルを使い、アプリに合わせて実装します。

https://docs-aibuds.github.io/ja/skills/implement-aibuds-ai-asking を読み、その指示に従ってください。このスキルで「AIBuds AI 質問応答の実装」をこの iOS プロジェクトに実装し、検証してください。
公式スキルを見る

API リファレンス

フレームワーク

AIBudsAI.xcframework

インポート

Swift
import AIBudsAI
import AIBudsAIFoundation

宣言

Swift
/// Sends a text question to the currently selected AI service and receives
/// the answer as a stream of updates.
///
/// - Parameters:
///   - question: The question or prompt to send.
///   - config: Configuration for the request. Defaults to `.default`.
///   - onStartAnswering: Called when the service starts answering. The
///     question identifier may be `nil` if it has not yet been assigned.
///   - onAnswer: Called for each answer update.
///     - questionId: The identifier of the question being answered.
///     - deltaText: Newly generated text in this update, if available.
///     - fullText: The accumulated answer text, if available.
///     - isFinal: `true` when this is the final answer update.
///   - onFinishAnswering: Called when answering finishes successfully.
///   - onError: Called when validation fails or the provider reports an error.
/// - Returns: The question identifier when the request is created; otherwise `nil`.
public static func send(question: String,
                          config: AIAskingConfig = .default,
                onStartAnswering: ((_ questionId: String?) -> Void)? = nil,
                        onAnswer: ((
                            _ questionId: String,
                            _ deltaText: String?,
                            _ fullText: String?,
                            _ isFinal: Bool
                        ) -> Void)? = nil,
               onFinishAnswering: ((_ questionId: String) -> Void)? = nil,
                         onError: ((_ questionId: String, _ error: Error) -> Void)? = nil) -> String?

sendAIAskingConfig を参照してください。

設定

AIAskingConfig.specifiedAgent は任意指定で、プロバイダー固有です。nil の場合はプロバイダーの通常のエージェント選択が使われます。Demo のエージェント ID を別のアカウントやプロバイダーでも利用できるとは限りません。

使用例

次の例は AIAskingDemoController に沿って、回答の全文と差分のどちらにも対応し、最後に取得した空でない質問 ID を保持します。また、回答更新の最終回とリクエスト完了を区別して処理します。

Swift
let question = input.trimmingCharacters(in: .whitespacesAndNewlines)
guard !question.isEmpty else { return }

let config = AIAskingConfig()
config.specifiedAgent = selectedAgentID

var activeQuestionID: String?
var answer = ""

let returnedID = AIBudsAISDK.send(
    question: question,
    config: config,
    onStartAnswering: { questionID in
        DispatchQueue.main.async {
            activeQuestionID = questionID ?? activeQuestionID
        }
    },
    onAnswer: { questionID, deltaText, fullText, isFinal in
        DispatchQueue.main.async {
            activeQuestionID = questionID
            if let fullText {
                answer = fullText
            } else if let deltaText {
                answer += deltaText
            }
            render(answer: answer, isFinalUpdate: isFinal)
        }
    },
    onFinishAnswering: { questionID in
        DispatchQueue.main.async {
            activeQuestionID = questionID
            setAsking(false)
        }
    },
    onError: { questionID, error in
        DispatchQueue.main.async {
            if !questionID.isEmpty { activeQuestionID = questionID }
            setAsking(false)
            show(error)
        }
    }
)

activeQuestionID = returnedID ?? activeQuestionID

エラー処理

リクエスト作成前の検証に失敗すると、sendnil を返し、onError を同期的に呼び出すことがあります。この場合、エラーコールバックの質問 ID は空です。処理中は重複送信を防ぎ、どちらの終了コールバックからも UI 状態を復元できるようにしてください。

注意事項

  • isFinal は回答更新の最終回を示します。リクエストの正常完了は onFinishAnswering で判定してください。
  • プロバイダーは fullTextdeltaText、またはその両方を返す場合があります。蓄積済みテキストの重複を避けるため、fullText を優先してください。
  • 現在の公開 API には、実行中の問答リクエストをキャンセルするメソッドがありません。