項目地址:
GitHub | wfts-ai-chathttps://github.com/HiMeditator/wfts-ai-chat
前言
最近一個基于 AI 的聊天游戲 Whispers from the Stars(群星低語)的 Demo 版本發布了。《Whispers from the Star》是一款科幻主題互動游戲。背景設定在太空,玩家需要通過文本、語音等形式與受困星球的游戲角色 Stella 實時互動,核心目標是協助她成功撤離險境。

在這個游戲中玩家可以和游戲中的女主進行較為流暢的交流。初見這個游戲讓我對 AI 聊天產生了興趣,我想試試用大模型來玩這個游戲是什么效果。因此我最近花了幾天開發了一個項目,可以捕獲游戲女主的發言,并調用大模型生成對應的回答。然后再調用語音生成模型,將回答音頻輸入到游戲中,實現用大模型玩游戲的效果。我還做了一個視頻,感興趣的可以去看看
用AI玩AI聊天游戲!用個人開發的AI聊天項目游玩蔡浩宇AI游戲【星之低語】https://www.bilibili.com/video/BV1unbXzDEjW
項目簡介
wfts-ai-chat 是一個嘗試使用云端模型來游玩 AI 游戲《Whispers from the Stars》的項目。該項目可以獲取和識別游戲主角的發言,并針對主角的求助調用大模型生成回答的音頻,從而實現使用大模型來游玩游戲的效果。
該項目僅支持 Windows 系統。本項目目前沒有推出發行版,用戶需要克隆倉庫并自行搭建開發環境來運行項目。或者等待后續推出的發行版。
本項目使用了多個阿里云的云端模型(語音識別模型、大語言模型、語言合成模型)。要使用這些模型首先需要獲取阿里云百煉平臺的 API KEY,然后將 API KEY 添加到軟件設置中或者配置到環境變量中。
Python 后端開發
核心流程
Python 后端程序需要完成的核心任務是:
- 獲取游戲角色語音
- 調用模型轉換為文本內容
- 調用大語言模型生成回答
- 調用音頻合成合成轉換為音頻
- 將音頻輸入到游戲中
- 重復上述流程
我之前做過一個實時字幕軟件(見上一篇博客),因此獲取角色音頻部分已經有了基本現成的代碼。 主要思路是使用 PyAudioWPatch 庫來獲取系統的實時音頻輸出。
有了音頻后,項目調用了阿里云的 Gummy 模型來實現實時文本識別。將得到的識別的文本內容整理和拼接起來就得到了游戲主角的發言內容。
然后結合精心編寫的系統提示詞(如下圖),將這些內容發送大模型(目前使用的 qwen-max),就能得到大模型針對游戲場景的回答。

得到回答的內容后再次調研語音合成模型,將大模型的回答合成為音頻內容。這里使用的語音合成模型是阿里云的?cosyvoice-v2,這個模型可以選擇輸出音頻的參數和音色,效果還不錯。
然后是需要將合成的音頻輸出到麥克風,這樣游戲才能捕捉到用戶的發言。但是無法通過 Python 直接將音頻輸出到麥克風,因此這里使用了 VB Cable 音頻驅動軟件。VB Cable 可以創建虛擬的音頻設備(CABLE Input 和 CABLE Output),用戶輸入到 CABLE Input 的音頻會被輸出到 CABLE Output 中。

因此將游戲的音頻輸入設備改為 CABLE Output 就能獲取到 Python 程序輸入到 CABLE Input 中的音頻了。但是需要注意的是,輸入設置為?CABLE Output 游戲會在開始時檢測不到麥克風。需要先改為默認麥克風,然后待游戲開始后再將音頻輸入設備改回 CABLE Output就可以了。

經過上述的流程就搞定了音頻獲取與識別、回答生成、音頻生成和輸出的全流程了,也就能實現完整的游戲流程了。
進程通信
另一個重點是 Python 程序和 Electron 程序的通信。因為軟件用戶界面是用 Electron 開發的,用戶發送的請求需要再轉發到 Python 程序中才會生效。ELectron 主程序到 Python 后端程序使用了 WebSocket 通信。用戶的請求均為指令+內容的格式。
Python 程序創建了一個線程專門處理用戶請求。Python 的主要邏輯是一個狀態機,其中 chatbot.status 表示程序當前所處狀態。Electron 主程序發送的指令主要用于修改 Python 程序所處的狀態。Python 程序的主進程通過不同的狀態來執行不同的邏輯。
def handle_client(client_socket):global chat_botwhile True:try:data = client_socket.recv(8192).decode('utf-8')if not data:continuedata = json.loads(data)if data['command'] == 'stop':if chat_bot.status == 'listen':chat_bot.stop_listening()chat_bot.status = 'stop'elif data['command'] == 'prompt':chat_bot.add_system_prompt(data['content'])elif data['command'] == 'listen':if chat_bot.status != 'ready':stderr(f'Inappropriate Status: Chatbot is not ready, current status: {chat_bot.status}.')continuechat_bot.start_listening()chat_bot.status = 'listen'elif data['command'] == 'answer':if chat_bot.status != 'listen':stderr(f'Inappropriate Status: Chatbot is not listening, current status: {chat_bot.status}.')continuechat_bot.stop_listening()chat_bot.status = 'answer'elif data['command'] == 'output':if chat_bot.status != 'synthesis':stderr(f'Inappropriate Status: Answer audio not ready, current status: {chat_bot.status}.')continuechat_bot.status = 'output'else:stderr('Command Error: Client command not found.')
然后是 Python 到 Electron 主程序的通信,Python 程序主要將當前狀態、語音識別結果和生成的回答發送給主進程。這里沒有使用 WebSocket。Python 程序是 Electron 主程序創建的,因此主程序能獲取到 Python 程序的標準輸出。所以?Python 到 Electron 主程序使用標準輸出來發送數據。
Python 程序輸出的內容為單行可以被解析為 JSON 對象的數據。Electron 主進程讀取 Python 程序的輸出,并將字符串解析為 JSON 對象,從而獲取 Python 端輸出的數據。
def stdout(text: str):stdout_cmd("print", text)def stdout_cmd(command: str, content = ""):msg = { "command": command, "content": content }sys.stdout.write(json.dumps(msg) + "\n")sys.stdout.flush()def stdout_obj(obj):sys.stdout.write(json.dumps(obj) + "\n")sys.stdout.flush()def stderr(text: str):sys.stderr.write(text + "\n")sys.stderr.flush()
Electron 程序開發
這部分主要是需要開發一個前臺控制軟件,用戶可以通過軟件界面看到 Python 后端程序所處的實時狀態、主角發言的識別結果和大模型生成的回答。用戶還需要在這個界面控制音頻識別和音頻輸出的時機。除此之外,用戶是在游戲過程中使用該軟件,因此軟件界面不能太大,不能過于影響用戶的游戲體驗。
根據上述需求,開發了一個小巧的用戶界面。整個界面是半透明的,且界面內容緊湊,完全服務于軟件需求。其中的按鈕會根據后端程序所處的不同狀態進行變化,使用更加方便。

Electron 開發部分其他沒啥可講的技術內容了,主要就是 Node.js + Vue 分別開發后端和前端,然后對接 Python 后端程序,將獲取的內容展示到前端。前端將用戶操作發送到 Node 后端,然后再轉發給 Python 程序。
項目修改
這個項目是為玩《群星低語》游戲制作的,但是稍微修改一下就可以用于和用戶來聊天。只需要將監聽系統音頻輸出改為監聽麥克風,軟件就能捕獲用戶的發言,然后根據自己的需求修改項目的系統提示詞,這樣大模型就能根據用戶的不同需求生成需要的回答。而模型的音頻輸出默認是同時輸出到默認音頻輸出的 CABLE Input,因此無需修改就能聽到合成音頻的播放。

本軟件的開發比較倉促,方案設計比較簡單。比如大模型的聊天生成直接使用完整的聊天記錄,聊天內容多,每次回答消耗的 tokens 將飛速增加,對于長對話并不劃算。而且對話內容過多模型的注意力會下降,導致回復質量下降,可能輸出意外的內容,因此目前直接使用該項目通關不太現實。項目還沒有經過嚴格的測試,魯棒性還不夠強。
項目還有很大的改進空間。不過目前市場上的類似的產品已經有很多了,完成度也更高。本項目只是一個我臨時為了玩 AI 聊天游戲而開發的不完整項目。作為一個自己開發的項目,我可以根據自己的需求對它進行多種改進,對我來說自由度更高。
最后貼一張使用該項目通過游戲第一個場景,到達第二個場景的截圖。