AI 질의응답
선택한 AI 서비스 제공자에게 텍스트 질문을 보내고, 반환된 질문 식별자로 콜백을 연결한 뒤 누적 또는 증분 방식의 답변을 표시합니다.
Animated workflow
AI 질의응답 요청 수명 주기
요청 식별자는 동기 반환값 또는 콜백으로 받을 수 있으며, 이후 스트리밍 답변 갱신과 하나의 종료 콜백이 이어집니다.
사전 요구 사항
AIBudsAISDK를 초기화하고 등록된 서비스 제공자를 선택한 뒤 필요한 경우 인증을 완료합니다.- 선택한 서비스 제공자가
AIAskingServiceAPI를 구현하는지 확인합니다. - 콜백에서 수행하는 UI 작업은 메인 큐로 전달합니다.
AI를 활용해 구현
AI로 구현
AI로 이 워크플로 구현
공식 “AIBuds AI 질의응답 구현” 스킬을 사용해 앱에 맞게 구현하세요.
https://docs-aibuds.github.io/ko/skills/implement-aibuds-ai-asking을 읽고 지침을 따르세요. 이 스킬로 “AIBuds AI 질의응답 구현”을 이 iOS 프로젝트에 구현하고 검증하세요.API Reference
프레임워크
AIBudsAI.xcframework
가져오기
- Swift
- Objective-C
import AIBudsAI
import AIBudsAIFoundation#import <AIBudsAI/AIBudsAI-Swift.h>선언
- Swift
- Objective-C
/// 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?/// Sends a text question and streams answer updates.
///
/// - Parameters:
/// - question: The question or prompt to send.
/// - config: Configuration for this request.
/// - onStartAnswering: Called when the provider starts answering.
/// - onAnswer: Returns the question ID, delta text, accumulated text, and
/// whether this is the final answer update.
/// - onFinishAnswering: Called when answering finishes successfully.
/// - onError: Called for synchronous validation or provider errors.
/// - Returns: The question identifier when created; otherwise `nil`.
+ (NSString * _Nullable)sendQuestion:(NSString * _Nonnull)question
config:(AIBudsAIAskingConfig * _Nonnull)config
onStartAnswering:(void (^ _Nullable)(NSString * _Nullable))onStartAnswering
onAnswer:(void (^ _Nullable)(NSString * _Nonnull, NSString * _Nullable, NSString * _Nullable, BOOL))onAnswer
onFinishAnswering:(void (^ _Nullable)(NSString * _Nonnull))onFinishAnswering
onError:(void (^ _Nullable)(NSString * _Nonnull, NSError * _Nonnull))onError;send 및 AIAskingConfig를 참고하세요.
설정
AIAskingConfig.specifiedAgent는 선택 사항이며 서비스 제공자마다 다릅니다. 제공자의 기본 agent 선택을 사용하려면 nil로 두세요. Demo의 agent 식별자가 다른 계정이나 제공자에서도 유효하다고 가정하면 안 됩니다.
사용 예제
다음 예제는 AIAskingDemoController와 같은 방식으로 누적된 전체 답변 또는 증분 답변을 처리하고, 가장 최근의 비어 있지 않은 질문 식별자를 유지하며, 마지막 답변 갱신과 요청 완료를 구분합니다.
- Swift
- Objective-C
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 ?? activeQuestionIDNSString *question =
[self.input stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
if (question.length == 0)
return;
AIBudsAIAskingConfig *config = [[AIBudsAIAskingConfig alloc] init];
config.specifiedAgent = self.selectedAgentID;
__block NSString *activeQuestionID = nil;
__block NSString *answer = @"";
NSString *returnedID = [AIBudsAISDK sendQuestion:question
config:config
onStartAnswering:^(NSString *questionID) {
dispatch_async(dispatch_get_main_queue(), ^{
activeQuestionID = questionID ?: activeQuestionID;
});
}
onAnswer:^(NSString *questionID, NSString *deltaText, NSString *fullText, BOOL isFinal) {
dispatch_async(dispatch_get_main_queue(), ^{
activeQuestionID = questionID;
answer = fullText ?: [answer stringByAppendingString:deltaText ?: @""];
[self renderAnswer:answer isFinalUpdate:isFinal];
});
}
onFinishAnswering:^(NSString *questionID) {
dispatch_async(dispatch_get_main_queue(), ^{
activeQuestionID = questionID;
[self setAsking:NO];
});
}
onError:^(NSString *questionID, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (questionID.length > 0)
activeQuestionID = questionID;
[self setAsking:NO];
[self showError:error];
});
}];
activeQuestionID = returnedID ?: activeQuestionID;오류 처리
요청 생성 전 검증에 실패하면 send가 nil을 반환하면서 onError를 동기적으로 호출할 수 있습니다. 이 경우 오류 콜백의 질문 식별자는 비어 있습니다. 요청이 진행되는 동안 중복 전송을 막고 두 종료 콜백 모두에서 UI 상태를 복원하세요.
참고
isFinal은 마지막 스트리밍 답변 갱신을 나타냅니다. 요청이 성공적으로 끝났는지는onFinishAnswering으로 판단하세요.- 서비스 제공자는
fullText,deltaText또는 둘 다 반환할 수 있습니다. 누적 텍스트가 중복되지 않도록fullText를 우선 사용하세요. - 현재 공개 API는 진행 중인 질의응답 요청을 취소하는 메서드를 제공하지 않습니다.