#

大模型游戏互动接入(iOS)
在支持AI互动的游戏当中,用户可以通过语音或者文字与大模型AI玩家进行互动
互动的前提是游戏中至少得有一个真人,再通过相应接口先加入大模型AI玩家,后续通过ISudAiAgent相关接口和大模型AI玩家进行互动
ISudAiAgent接口
接口定义:
@protocol ISudAiAgent;
/// AI Agent
@protocol ISudAiAgent <NSObject>
/// 设置房间消息监听
/// @param roomMsgListener roomMsgListener description
- (void)setOnRoomChatMessageListener:(void(^)(NSString *json))roomMsgListener;
/// 传入的音频切片是从RTC获取的PCM数据
/// PCM数据格式必须是:采样率:16000, 采样位数:16, 声道数: MONO
/// PCM数据长度可以根据效果调整,长度大: 精确度好但延时长 长度小:延时短但牺牲精确度
/// @param data pcm数据
- (void)pushAudio:(NSData *_Nonnull)data;
/// 暂停push语音数据,会将前面推送的语音数据进行句子结束返回
- (void)pauseAudio;
/// 不再进行推送语音数据时调用,用于释放当前处理语音相关上下文
- (void)stopAudio;
/// 发送文本内容
- (void)sendText:(NSString *_Nonnull)text;
@end
一、获取ISudAiAgent
加载游戏后通过ISudFSTAPP接口方法getAiAgent获取ISudAiAgent
获取ISudAiAgent接口后,可通过该接口和大模型AI玩家进行语音、文字的互动,并可设置监听来接收大模型AI玩家的回复消息。
通过ISudFSTAPP游戏实例获取ISudAiAgent实例接口:
@protocol ISudFSTAPP <NSObject>
/// 创建一个ai agent操作实例
- (id<ISudAiAgent>)getAiAgent;
@end
参考样例:
// AI代理人
@property(nonatomic, strong) id<ISudAiAgent> aiAgent;
/// 游戏开始
- (void)onGameStarted {
DDLogDebug(@"onGameStarted");
[self.vc handleGameStared];
/// 创建AI大模型互动
[self createAiAgent: self.sudFSTAPPDecorator.iSudFSTAPP];
}
- (void)createAiAgent:(id <ISudFSTAPP> )iSudFSTAPP {
// 振魂石 和 飞行棋
if (self.loadConfigModel.gameId == 1890346721291059202L || self.loadConfigModel.gameId == 1468180338417074177L) {
self.aiAgent = [iSudFSTAPP getAiAgent];
WeakSelf
/// 监听AI大模型互动信息
[self.aiAgent setOnRoomChatMessageListener:^(NSString * _Nonnull json) {
[weakSelf handleAiRoomChatMsg:json];
}];
}
}
二、添加大模型AI玩家
接口定义文档:通用状态 notifyStateChange
52. 设置游戏中的大模型AI玩家
app_common_game_add_big_scale_model_ai_players
在游戏位当中至少有一个真人时,客户端可通过该接口定义的协议格式向游戏发送消息来添加大模型AI玩家
对应的可以通过使用SudGIPWrapper模块提供交互接口将AI大模型机器人加入到游戏中,接口如下:
/// 设置游戏中的大模型AI玩家 APP_COMMON_GAME_ADD_BIG_SCALE_MODEL_AI_PLAYERS
/// @param appCommonGameAddAiPlayersModel 配置信息
- (void)notifyAppCommonGameAddBigScaleModelAPlayers:(AppCommonGameAddBigScaleModelAiPlayersModel *)appCommonGameAddAiPlayersModel;
参考样例:
// 添加大模型AI
NSMutableArray *aiPlayers = [[NSMutableArray alloc] init];
BigScaleModelAiPlayerInfoModel *aiPlayerInfoModel = [BigScaleModelAiPlayerInfoModel alloc];
aiPlayerInfoModel.userId = [NSString stringWithFormat:@"%@", @(robotInfoModel.userId)];
aiPlayerInfoModel.name = robotInfoModel.name;
aiPlayerInfoModel.avatar = robotInfoModel.avatar;
aiPlayerInfoModel.gender = robotInfoModel.gender;
aiPlayerInfoModel.aiIdStr = @"1";
[aiPlayers addObject:aiPlayerInfoModel];
AppCommonGameAddBigScaleModelAiPlayersModel *appCommonGameAddAiPlayersModel = [[AppCommonGameAddBigScaleModelAiPlayersModel alloc] init];
appCommonGameAddAiPlayersModel.aiPlayers = aiPlayers;
appCommonGameAddAiPlayersModel.isReady = YES;
[weakSelf.gameEventHandler.sudFSTAPPDecorator notifyAppCommonGameAddBigScaleModelAPlayers:appCommonGameAddAiPlayersModel];
三、文本对话
APP可选择向游戏发送文本消息与大模型AI玩家对话
通过ISudAiAgent接口方法sendText来向游戏发送文本内容
接口:
/// 发送文本内容
- (void)sendText:(NSString *_Nonnull)text;
参考样例:
- (void)sendTextToAiAgent:(NSString *)text {
if (self.aiAgent) {
[self.aiAgent sendText:text];
}
}
四、语音对话
APP可选择向游戏发送语音消息与大模型AI玩家对话
通过ISudAiAgent接口方法pushAudio来向游戏发送语音消息
pauseAudio用于暂停语音对话,stopAudio用于关闭语音对话
接口:
/// 传入的音频切片是从RTC获取的PCM数据
/// PCM数据格式必须是:采样率:16000, 采样位数:16, 声道数: MONO
/// PCM数据长度可以根据效果调整,长度大: 精确度好但延时长 长度小:延时短但牺牲精确度
/// @param data pcm数据
- (void)pushAudio:(NSData *_Nonnull)data;
/// 暂停push语音数据,会将前面推送的语音数据进行句子结束返回
- (void)pauseAudio;
/// 不再进行推送语音数据时调用,用于释放当前处理语音相关上下文
- (void)stopAudio;
参考样例:
/// 推送语音数据
- (void)pushAudioToAiAgent:(NSData *)pcmData {
if (self.aiAgent) {
[self.aiAgent pushAudio:pcmData];
}
}
/// 暂停推送语音数据
- (void)pauseAudioToAiAgent {
if (!self.aiAgent) {
return;
}
[self.aiAgent pauseAudio];
}
五、接收大模型AI玩家的消息
当APP通过语音或者文字向大模型AI玩家发送消息之后,大模型AI玩家会进行回复一条或多条消息给房间里的玩家
通过ISudAiAgent接口方法setOnRoomChatMessageListener设置监听器用于监听大模型AI玩家的回复消息
回调接口:
/// 设置房间消息监听
/// @param roomMsgListener roomMsgListener description
- (void)setOnRoomChatMessageListener:(void(^)(NSString *json))roomMsgListener;
回调消息格式样例:
{
"uid": "123456",
"audioData": "UklGRhQAAABXQVZFZm10IBAAAAA",
"content": "你好"
}
参考样例:
/// 大模型互动回调JSON数据结构
@interface AiRoomChatMsgModel : NSObject
/// 发送者id
@property(nonatomic, strong)NSString *uid;
/// base64语音数据(mp3)
@property(nonatomic, strong)NSString *audioData;
/// 文本内容
@property(nonatomic, strong)NSString *content;
@end
/// 处理大模型回调信息
/// - Parameter json: json字符串数据
- (void)handleAiRoomChatMsg:(NSString *)json {
WeakSelf
AiRoomChatMsgModel *aiRoomChatMsgModel = [AiRoomChatMsgModel mj_objectWithKeyValues:json];
NSString *audioDataBase64 = aiRoomChatMsgModel.audioData;// infoDic[@"audioData"];
NSString *playerId = aiRoomChatMsgModel.uid;// infoDic[@"userId"];
if (audioDataBase64) {
NSData *audioData = [[NSData alloc]initWithBase64EncodedString:audioDataBase64 options:0];
BOOL isPlyeByRtc = YES;
if (isPlyeByRtc) {
id audioEngine = AudioEngineFactory.shared.audioEngine;
// rtc 如果支持本地播放,则选用
if ([audioEngine respondsToSelector:@selector(playLocalAudio:)]) {
SudRtcAudioItem *audioItem = [[SudRtcAudioItem alloc]init];
audioItem.audioData = audioData;
audioItem.extra = playerId;
audioItem.playStateChangedBlock = ^(SudRtcAudioItem *item, SudRtcAudioItemPlayerState playerState) {
[weakSelf handleUserPlayerAudioState:item.extra state:playerState];
};
[audioEngine playLocalAudio:audioItem];
return;
}
}
// 自行创建播放器播放
SudAudioItem *audioItem = [[SudAudioItem alloc]init];
audioItem.audioData = audioData;
audioItem.extra = playerId;
audioItem.playStateChangedBlock = ^(SudAudioItem *item, SudAudioItemPlayerState playerState) {
[weakSelf handleUserPlayerAudioState:item.extra state:playerState];
};
[SudAudioPlayer.shared playeAudioMulti:audioItem];
}
}
当收到onRoomChatMessage回调时,大型型AI玩家的说话内容,APP根据自身产品需求来选择展示文本消息或者是播放语音消息
六、声浪控制
当APP收到下面的游戏消息时,表示APP可选择控制游戏展示对应玩家的声浪效果
接口定义文档:通用状态-游戏
69. 通知app可以开始推送麦克说话状态
mg_common_game_player_mic_state
对应SudGIPWrapper回调接口:
/// 通知APP 玩家麦克风状态准备OK MG_COMMON_GAME_PLAYER_MIC_STATE
- (void)onGameMgCommonGamePlayerMicState:(nonnull id <ISudFSMStateHandle>)handle model:(MgCommonGamePlayerMicState *)model;
收到指令之后可通过如下接口进行控制
接口定义文档:通用状态 notifyStateChange
51. app向游戏下发玩家mic状态
app_common_game_player_mic_state
对应SudGIPWrapper调用接口:
/// app通知游戏更新麦克风状态 APP_COMMON_GAME_PLAYER_MIC_STATE
- (void)notifyAppCommonGamePlayerMicState:(AppCommonGamePlayerMicState *)model;
用于控制游戏当中是否显示指定玩家的声浪,是一个开关性质的指令,开启或关闭的时候发送一次即可
参考样例:
- (void)onGameMgCommonGamePlayerMicState:(id<ISudFSMStateHandle>)handle model:(MgCommonGamePlayerMicState *)model {
self.isGamePlayerMicStateOk = YES;
for (NSString *key in self.userAudioPlayStateMap.allKeys) {
NSInteger state = [self.userAudioPlayStateMap[key] integerValue];
[self sendGamePlayerAudioState:key state:state];
}
}
/// 发送给游戏播放状态
- (void)sendGamePlayerAudioState:(NSString *)userId state:(NSInteger)state {
// 没有开启AI或者游戏没有通知玩家麦克风准备好了, 别发
if (!self.isOpenAiAgent || !self.isGamePlayerMicStateOk) {
return;
}
AppCommonGamePlayerMicState *stateModel = AppCommonGamePlayerMicState.new;
stateModel.state = SudAudioItemPlayerStatePlaying == state ? 1 : 0;
stateModel.uid = userId;
[self.sudFSTAPPDecorator notifyAppCommonGamePlayerMicState:stateModel];
}