Unity之使用火山引擎实现文字提问流式回复
文字提问
设置参数apiKey
调用Request方法,传入对话内容
注册事件,接收回复内容
usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.Networking;/// <summary>/// 文本提问/// </summary>publicclassTextQuestions:MonoBehaviour{stringbaseUrl="https://ark.cn-beijing.volces.com/api/v3/chat/completions";stringapiKey="";[Header("模型")][SerializeField]stringmodel="doubao-seed-2-0-code-preview-260215";[Header("深度思考")][SerializeField]stringthinking="disabled";[Header("模型回答最大长度(单位token)")][SerializeField]intmaxTokens=4096;[Header("思考消耗")][SerializeField]stringreasoningEffort="minimal";publiceventAction<string,bool>onReceive;publiceventActiononCompleted;publiceventActionOnError;voidOnReceive(stringcontent){varrespone=JsonUtility.FromJson<ResponeChatMessage>(content);onReceive?.Invoke(respone.choices[0].delta.content,respone.choices[0].finish_reason=="stop");}voidOnCompleted(){onCompleted?.Invoke();}publicvoidRequest(List<Message>messages){RequestChatrequestMessages=newRequestChat{messages=messages,model=model,thinking=newThinkingType(){type=thinking,},max_tokens=maxTokens,reasoning_effort=reasoningEffort,};stringjsonData=JsonUtility.ToJson(requestMessages);StartCoroutine(PostChat(jsonData));}IEnumeratorPostChat(stringjsonData){using(UnityWebRequestrequest=newUnityWebRequest(baseUrl,UnityWebRequest.kHttpVerbPOST)){byte[]bodyRaw=System.Text.Encoding.UTF8.GetBytes(jsonData);request.uploadHandler=newUploadHandlerRaw(bodyRaw);vartTSDownload=newTTSDownload();tTSDownload.OnObjectReceived+=OnReceive;tTSDownload.OnComplete+=OnCompleted;request.downloadHandler=tTSDownload;request.SetRequestHeader("Content-Type","application/json");request.SetRequestHeader("Authorization","Bearer "+apiKey);yieldreturnrequest.SendWebRequest();if(request.result!=UnityWebRequest.Result.Success){Debug.LogError("请求失败:"+request.error);OnError?.Invoke();}tTSDownload.OnObjectReceived-=OnReceive;tTSDownload.OnComplete-=OnCompleted;}}}[Serializable]publicclassRequestChat{publicstringmodel;publicList<Message>messages;publicThinkingTypethinking;publicintmax_tokens;publicstringreasoning_effort;publicboolstream=true;}[Serializable]publicclassThinkingType{publicstringtype;}[Serializable]publicclassMessage{publicstringrole;publicstringcontent;publicstringthinking;}[Serializable]publicclassResponeChatMessage{publicChoices[]choices;}[Serializable]publicclassChoices{publicMessageDeltadelta;publicstringfinish_reason;publicintindex;}[Serializable]publicclassMessageDelta{publicstringcontent;publicstringrole;}拓展DownloadHandler
usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Text;usingUnityEngine;usingUnityEngine.Networking;publicclassTTSDownload:DownloadHandlerScript{privateStringBuilderbuffer=newStringBuilder();publiceventAction<string>OnObjectReceived;publiceventActionOnComplete;publicTTSDownload():base(newbyte[4096]){}protectedoverrideboolReceiveData(byte[]data,intdataLength){stringchunk=Encoding.UTF8.GetString(data,0,dataLength);buffer.Append(chunk);ProcessBuffer();returntrue;}privatevoidProcessBuffer(){stringcontent=buffer.ToString();intsplitStartIndex=-1;intbraceCount=0;intlastProcessed=0;for(inti=0;i<content.Length;i++){if(content[i]=='{'){if(braceCount==0)splitStartIndex=i;braceCount++;}elseif(content[i]=='}'){braceCount--;if(braceCount==0&&splitStartIndex!=-1){stringobj=content.Substring(splitStartIndex,i-splitStartIndex+1);OnObjectReceived?.Invoke(obj);splitStartIndex=-1;lastProcessed=i+1;}}}if(lastProcessed>0)buffer.Remove(0,lastProcessed);}protectedoverridevoidCompleteContent(){OnComplete?.Invoke();}}