
1. 项目缘起当AI大模型遇见开源硬件最近在捣鼓行空板这块国产的开源硬件开发板确实挺有意思集成了屏幕、Wi-Fi、麦克风和扬声器开箱即用非常适合做物联网和AIoT的原型验证。我就在想现在ChatGPT这类大语言模型这么火能不能把它“塞”进这块小小的板子里让它变成一个离线的、能说会画的AI小助手比如我对着它说“画一只在月球上打太极的熊猫”它就能现场生成一张图片或者我让它写一首关于夏天的诗它也能立刻创作出来。这听起来像是把云端AI的能力“本地化”和“实体化”了对于教育、创意原型、智能交互设备开发来说是个非常酷的探索方向。这个想法并非天方夜谭。行空板本身运行着完整的Linux系统通常是Debian并且有Python环境支持。而目前虽然无法直接将庞大的GPT-4等模型完整部署到资源有限的边缘设备上但我们可以通过API调用、或者部署一些轻量级的开源模型如一些较小的LLM或文生图模型来实现类似功能。更实际、更通用的路径是让行空板作为一个智能终端去调用云端强大的AI能力如OpenAI的API或国内可访问的同类大模型API并将生成的结果文本或图片在本地屏幕上呈现出来结合板载的麦克风和扬声器实现语音交互。这本质上是一个“边缘计算云端智能”的融合项目。接下来我将详细拆解如何一步步实现这个“ChatGPT与行空板融合”的项目涵盖从环境准备、模型服务接入包括云端API和本地轻量化模型的两种思路、核心应用开发文生文、文生图到最终集成与交互设计的全过程。你会发现即使没有深厚的AI算法背景利用现有的工具和清晰的思路你也能亲手打造一个属于自己的桌面AI伙伴。2. 行空板开发环境深度配置要让行空板跑起AI应用第一步就是打好基础搭建一个稳定且功能完备的Python开发环境。行空板官方镜像通常已经预置了Python3和pip但为了支持复杂的AI应用我们还需要进行一些强化。2.1 系统基础与网络配置拿到行空板连接电源和显示器或通过VNC远程桌面首先确保系统是最新的。通过终端执行更新命令是一个好习惯sudo apt update sudo apt upgrade -y网络连接至关重要因为后续我们很可能需要调用云端API。确保行空板已经连接到Wi-Fi或有线网络并能正常访问互联网。你可以通过ping www.baidu.com来测试网络连通性。如果处于需要代理的网络环境需要在系统或Python请求层面进行配置但请注意这必须严格在合法合规的范围内进行仅用于访问公开、合法的国际技术服务接口并确保所有操作符合所在地法律法规。2.2 Python虚拟环境与核心依赖安装为了避免污染系统Python环境也为了方便管理不同项目的依赖强烈建议使用venv创建独立的虚拟环境。# 创建一个名为‘ai_assistant’的虚拟环境 python3 -m venv ~/ai_assistant_env # 激活虚拟环境 source ~/ai_assistant_env/bin/activate激活后命令行提示符前会出现(ai_assistant_env)字样。接下来安装核心Python包。我们将使用openai库用于调用OpenAI官方API或兼容API的国内服务、requests用于网络请求、Pillow用于图像处理以及行空板GUI编程常用的pinpong库如果使用官方UI库或tkinter/PyQt5。pip install --upgrade pip pip install openai requests Pillow注意直接安装openai库默认指向OpenAI官方服务。如果你计划使用国内提供的、兼容OpenAI API协议的大模型服务例如一些云厂商提供的服务安装方式相同但在后续代码中需要修改API的base_url。务必从服务商的官方文档获取正确的接入点和API Key。2.3 音频处理能力加持让AI能听会说行空板自带麦克风和扬声器要实现语音交互我们需要让AI能“听到”我们说话语音转文本STT并能“说出”回答文本转语音TTS。这里有几个轻量级的方案云端方案推荐精度高使用各大云服务商提供的语音识别和合成API如百度语音、阿里云、腾讯云等。优点是识别和合成质量高开发简单。需要在对应平台开通服务获取API Key和Secret。安装对应的SDK即可例如百度的baidu-aip。pip install baidu-aip本地轻量级方案离线资源占用低对于离线或隐私要求高的场景可以部署本地模型。语音识别可以考虑Vosk它是一个离线开源语音识别工具包支持多种语言有小尺寸模型适合行空板。文本转语音可以使用pyttsx3或gTTS需要联网。Vosk的安装稍复杂需要下载模型文件。pip install vosk # 随后需要从Vosk官网下载适合的中文小模型解压到项目目录中。 pip install pyttsx3在本项目中为了演示完整性我将以“云端API处理音频本地处理逻辑”的混合架构为例。这样既能保证核心AI能力的质量又能将交互逻辑运行在本地。3. 双轨制AI能力接入策略这是项目的核心。我们有两种主要的路径为行空板注入“智能”云端API调用和本地模型部署。我将详细分析两者的优劣和实操步骤。3.1 路径一云端API调用主流、高效这是最直接、效果最好的方式。行空板作为客户端通过互联网向AI服务提供商发送请求获取生成的文本或图片。3.1.1 文生文Chat Completion以使用OpenAI格式的API为例。首先你需要一个有效的API Key。如果你使用国内服务请替换api_base。import openai import os # 配置API Key和Base URL如果使用国内服务 openai.api_key os.getenv(OPENAI_API_KEY) # 建议将key放入环境变量不要硬编码在代码中 # 如果使用国内兼容服务可能需要设置api_base # openai.api_base https://api.xxx.com/v1 def chat_with_gpt(prompt, modelgpt-3.5-turbo): try: response openai.ChatCompletion.create( modelmodel, messages[{role: user, content: prompt}], max_tokens500, temperature0.7, ) return response.choices[0].message.content.strip() except Exception as e: return f请求出错: {e} # 测试 if __name__ __main__: question 用一百字介绍行空板 answer chat_with_gpt(question) print(answer)关键参数解析model: 指定使用的模型。gpt-3.5-turbo性价比高响应快。gpt-4能力更强但更贵更慢。国内服务商会有自己的模型名。max_tokens: 限制生成内容的最大长度。需注意输入的prompt和输出的completion共同消耗token。设置过低会导致回答被截断。temperature: 控制输出的随机性0.0到2.0。值越低如0.2输出越确定、保守值越高如0.8输出越随机、有创意。对于事实问答建议低一些对于创意写作可以调高。3.1.2 文生图Image Generation同样OpenAI提供了DALL-E模型接口。国内也有一些服务提供文生图API。from openai import OpenAI import requests from io import BytesIO from PIL import Image client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) def generate_image(prompt, size512x512): try: response client.images.generate( modeldall-e-2, # 或 dall-e-3 promptprompt, sizesize, n1, ) image_url response.data[0].url # 下载图片到内存 img_data requests.get(image_url).content img Image.open(BytesIO(img_data)) return img except Exception as e: print(f生成图片出错: {e}) return None # 测试生成图片并保存 if __name__ __main__: img_prompt 一只戴着眼镜、在敲代码的卡通猫赛博朋克风格 image generate_image(img_prompt, 1024x1024) if image: image.save(generated_cat.png) print(图片已保存。)注意事项成本与速率限制API调用是收费的并且有每分钟/每天的请求次数限制Rate Limit。在代码中必须做好异常处理如捕获openai.error.RateLimitError并考虑增加重试逻辑或请求队列避免因超出限制导致程序崩溃。网络稳定性行空板的网络环境必须稳定。在代码中加入超时timeout设置和重试机制是必要的。隐私与合规如果你处理的是敏感信息需要考虑数据上传至云端服务的隐私政策。对于企业或个人敏感项目需谨慎评估。3.2 路径二本地轻量化模型部署离线、可控如果你希望完全离线运行或者对延迟、成本有极端要求可以尝试在行空板上部署轻量级模型。这对行空板的算力CPU/内存是巨大挑战只能运行非常小的模型。3.2.1 本地文生文模型可以考虑使用通过llama.cpp或ollama量化后的微型模型例如TinyLlama、Phi-2的量化版。首先需要在PC上将模型量化成GGUF格式如q4_04位量化然后移植到行空板。在行空板上安装llama.cpp这需要从源码编译过程耗时且可能遇到依赖问题。sudo apt install build-essential cmake git clone https://github.com/ggerganov/llama.cpp cd llama.cpp make下载并运行量化模型将量化好的模型文件如tinyllama-1.1b-chat-v1.0.Q4_0.gguf拷贝到行空板。运行方式通常是通过命令行调用。./main -m ./models/tinyllama.gguf -p 你好请介绍一下你自己。 -n 128在Python中你可以用subprocess模块来调用这个命令行程序并解析其输出。这种方式速度较慢生成质量远低于GPT-3.5但可以离线工作。3.2.2 本地文生图模型在行空板上运行Stable Diffusion几乎是不可行的。但可以尝试极简的对抗生成网络GAN模型或者使用diffusers库运行超小型的扩散模型如CompVis/ldm-text2im-large-256生成256x256的小图。即便如此单次推理也可能需要数十秒到分钟级且内存消耗巨大。实操建议对于绝大多数行空板项目强烈推荐采用“云端API为主本地逻辑为辅”的架构。本地部署模型更适合作为技术验证和极限探索难以达到实用的交互体验。我们的项目将主要基于云端API方案进行构建。4. 构建交互式AI应用核心模块有了AI能力引擎接下来我们需要构建行空板上的应用程序将输入文本/语音转化为AI请求并将输出文本/图片/语音展示出来。4.1 图形用户界面GUI设计行空板支持多种GUI库。这里以Python自带的tkinter为例因为它无需额外安装且足够用于本项目的界面。import tkinter as tk from tkinter import scrolledtext, ttk, messagebox from PIL import Image, ImageTk import threading class AIAssistantApp: def __init__(self, root): self.root root self.root.title(行空板AI助手) self.root.geometry(800x600) # 创建主框架 main_frame ttk.Frame(root, padding10) main_frame.grid(row0, column0, sticky(tk.W, tk.E, tk.N, tk.S)) # 输入区域 input_label ttk.Label(main_frame, text输入你的指令:) input_label.grid(row0, column0, stickytk.W, pady(0,5)) self.input_text scrolledtext.ScrolledText(main_frame, width70, height5) self.input_text.grid(row1, column0, columnspan2, pady(0,10)) self.input_text.insert(tk.END, 例如写一个关于星空的小故事或者画一幅夏日海滩的风景画) # 模式选择 mode_label ttk.Label(main_frame, text选择模式:) mode_label.grid(row2, column0, stickytk.W, pady(0,5)) self.mode_var tk.StringVar(valuechat) chat_radio ttk.Radiobutton(main_frame, text文生文对话, variableself.mode_var, valuechat) image_radio ttk.Radiobutton(main_frame, text文生图, variableself.mode_var, valueimage) chat_radio.grid(row3, column0, stickytk.W) image_radio.grid(row3, column1, stickytk.W) # 按钮 self.submit_btn ttk.Button(main_frame, text发送, commandself.on_submit) self.submit_btn.grid(row4, column0, pady10) self.clear_btn ttk.Button(main_frame, text清空, commandself.clear_all) self.clear_btn.grid(row4, column1, pady10) # 输出区域 - 使用Notebook实现标签页切换 self.output_notebook ttk.Notebook(main_frame) self.output_notebook.grid(row5, column0, columnspan2, sticky(tk.W, tk.E, tk.N, tk.S), pady(10,0)) # 文本输出标签页 self.text_output_frame ttk.Frame(self.output_notebook) self.output_notebook.add(self.text_output_frame, text文本回复) self.output_text scrolledtext.ScrolledText(self.text_output_frame, width85, height15, statedisabled) self.output_text.pack(filltk.BOTH, expandTrue) # 图片输出标签页 self.image_output_frame ttk.Frame(self.output_notebook) self.output_notebook.add(self.image_output_frame, text生成图片) self.image_label ttk.Label(self.image_output_frame) self.image_label.pack() # 状态栏 self.status_var tk.StringVar(value就绪) status_bar ttk.Label(root, textvariableself.status_var, relieftk.SUNKEN, anchortk.W) status_bar.grid(row1, column0, sticky(tk.W, tk.E)) # 初始化时隐藏图片标签页 self.output_notebook.hide(1) # 索引1是图片标签页 def on_submit(self): 处理提交按钮事件 user_input self.input_text.get(1.0, tk.END).strip() if not user_input: messagebox.showwarning(提示, 请输入内容) return mode self.mode_var.get() self.submit_btn.config(statedisabled) self.status_var.set(AI正在思考...) # 在新线程中执行AI请求避免界面卡死 thread threading.Thread(targetself.process_ai_request, args(user_input, mode)) thread.daemon True thread.start() def process_ai_request(self, prompt, mode): 在新线程中处理AI请求 try: if mode chat: response_text chat_with_gpt(prompt) # 调用之前定义的函数 self.update_text_output(response_text) # 可以在这里添加文本转语音播放 # tts_speak(response_text) elif mode image: image generate_image(prompt) # 调用之前定义的函数 if image: self.update_image_output(image) else: self.update_text_output(图片生成失败请检查提示词或网络。) except Exception as e: self.update_text_output(f处理过程中发生错误: {e}) finally: self.root.after(0, self.reset_ui) # 回到主线程更新UI def update_text_output(self, text): 更新文本输出区域 self.output_text.config(statenormal) self.output_text.delete(1.0, tk.END) self.output_text.insert(tk.END, text) self.output_text.config(statedisabled) # 确保显示文本标签页 self.output_notebook.select(0) def update_image_output(self, pil_image): 更新图片输出区域 # 调整图片大小以适应显示区域 display_width 600 w_percent display_width / float(pil_image.size[0]) h_size int(float(pil_image.size[1]) * float(w_percent)) resized_image pil_image.resize((display_width, h_size), Image.Resampling.LANCZOS) photo ImageTk.PhotoImage(resized_image) self.image_label.config(imagephoto) self.image_label.image photo # 保持引用防止被垃圾回收 # 切换到图片标签页 self.output_notebook.select(1) def reset_ui(self): 重置UI状态 self.submit_btn.config(statenormal) self.status_var.set(就绪) def clear_all(self): 清空输入和输出 self.input_text.delete(1.0, tk.END) self.output_text.config(statenormal) self.output_text.delete(1.0, tk.END) self.output_text.config(statedisabled) self.image_label.config(image) self.output_notebook.select(0) self.status_var.set(已清空) if __name__ __main__: root tk.Tk() app AIAssistantApp(root) root.mainloop()这个GUI框架提供了文本输入、模式选择对话/画图、标签页切换的文本和图片输出区域以及状态栏。关键点在于使用threading来避免网络请求阻塞主界面使用PILPillow来处理和显示生成的图片。4.2 语音交互集成为了让应用更自然我们可以增加语音输入和输出功能。这里以使用百度语音API为例展示如何集成。from aip import AipSpeech import pyaudio import wave import os # 百度语音API配置 (需要在百度AI开放平台申请) APP_ID 你的App ID API_KEY 你的API Key SECRET_KEY 你的Secret Key client AipSpeech(APP_ID, API_KEY, SECRET_KEY) def record_audio(filename, record_seconds5): 录制音频并保存为WAV文件 CHUNK 1024 FORMAT pyaudio.paInt16 CHANNELS 1 RATE 16000 p pyaudio.PyAudio() stream p.open(formatFORMAT, channelsCHANNELS, rateRATE, inputTrue, frames_per_bufferCHUNK) frames [] print(正在录音...) for i in range(0, int(RATE / CHUNK * record_seconds)): data stream.read(CHUNK) frames.append(data) print(录音结束) stream.stop_stream() stream.close() p.terminate() wf wave.open(filename, wb) wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b.join(frames)) wf.close() return filename def speech_to_text(audio_file_path): 将WAV音频文件转换为文本 with open(audio_file_path, rb) as fp: audio_data fp.read() result client.asr(audio_data, wav, 16000, {dev_pid: 1537}) # 1537为普通话输入法模型 if result[err_no] 0: return result[result][0] else: print(f语音识别失败: {result}) return None def text_to_speech(text, output_fileoutput.mp3): 将文本转换为语音并保存为MP3 result client.synthesis(text, zh, 1, {vol: 5, per: 0}) # per0为女声1为男声 if not isinstance(result, dict): # 合成成功返回二进制失败返回dict with open(output_file, wb) as f: f.write(result) return output_file else: print(f语音合成失败: {result}) return None # 在GUI类中增加语音按钮和对应方法 def add_voice_controls(self): voice_btn ttk.Button(self.main_frame, text 语音输入, commandself.start_voice_input) voice_btn.grid(row2, column2, padx5) speak_btn ttk.Button(self.main_frame, text 播放回答, commandself.speak_output) speak_btn.grid(row4, column2, padx5) def start_voice_input(self): thread threading.Thread(targetself._record_and_transcribe) thread.daemon True thread.start() def _record_and_transcribe(self): audio_file temp_recording.wav record_audio(audio_file, 5) text speech_to_text(audio_file) if text: self.root.after(0, lambda: self.input_text.insert(tk.END, text)) self.status_var.set(语音识别完成) os.remove(audio_file) # 删除临时文件 def speak_output(self): text_to_speak self.output_text.get(1.0, tk.END).strip() if text_to_speak: thread threading.Thread(targettext_to_speech, args(text_to_speak, response.mp3)) thread.daemon True thread.start() # 这里可以添加播放MP3的代码例如使用pygame或subprocess调用aplay/mpg123 # os.system(mpg123 response.mp3)集成语音后用户就可以通过麦克风直接提问并让AI用语音回答体验更接近智能音箱。5. 项目集成、优化与部署将上述所有模块组合在一起就构成了一个完整的行空板AI助手应用。但在最终交付前还需要进行一系列优化和固化工作。5.1 应用结构化与配置管理将代码模块化分离成不同的文件例如ai_client.py封装API调用、gui_app.py主界面、voice_engine.py语音处理、config.py配置文件。在config.py中使用配置文件或环境变量来管理API密钥等敏感信息切勿将密钥硬编码在代码中。# config.py import os from dotenv import load_dotenv # 可以使用python-dotenv管理.env文件 load_dotenv() class Config: OPENAI_API_KEY os.getenv(OPENAI_API_KEY) OPENAI_API_BASE os.getenv(OPENAI_API_BASE, https://api.openai.com/v1) BAIDU_APP_ID os.getenv(BAIDU_APP_ID) BAIDU_API_KEY os.getenv(BAIDU_API_KEY) BAIDU_SECRET_KEY os.getenv(BAIDU_SECRET_KEY) # 图片保存路径 IMAGE_SAVE_DIR ./generated_images5.2 性能优化与用户体验请求队列与异步处理当用户快速连续点击时应该将请求加入队列顺序处理或者取消上一个未完成的请求避免混乱。本地缓存对于相同的文本生成请求可以将其结果文本或图片缓存到本地文件或SQLite数据库中并设置过期时间。下次遇到相同请求时直接返回缓存结果节省API调用次数和等待时间。图片预览优化生成高分辨率图片后在行空板的小屏幕上显示原图可能很慢。可以先生成一个快速、低分辨率的预览图显示同时后台下载高清原图并保存。错误处理与用户提示网络超时、API额度不足、内容过滤等错误都需要被优雅地捕获并在界面上给出清晰、友好的提示而不是抛出晦涩的异常信息。开机自启动为了让行空板开机即运行AI助手可以将主程序脚本添加到系统服务如systemd或用户的启动脚本~/.bashrc或~/.config/autostart/中。5.3 安全与成本控制API密钥安全如前所述使用环境变量或加密的配置文件。对于开源项目务必使用.gitignore文件忽略包含密钥的配置文件。设置用量告警在AI服务提供商的后台设置每月预算和用量告警防止意外超支。输入过滤对用户输入进行基本的过滤防止注入恶意或无意义的提示词消耗API额度。合规性检查确保生成的内容符合法律法规和社会公序良俗。一些API服务本身带有内容安全过滤器但本地逻辑也可以增加一层简单的关键词过滤。5.4 扩展思路从应用到智能体AI Agent当前应用是一个简单的“一问一答”或“一令一图”模式。你可以将其升级为一个具有记忆和任务分解能力的简单AI Agent。对话记忆将每次对话的历史记录用户输入和AI回复保存到一个上下文中并在下次提问时一并发送给AI从而实现连续对话。注意上下文长度有限制需要管理历史窗口例如只保留最近10轮对话。简单任务规划例如用户说“帮我查一下天气然后根据天气推荐一首歌”。你可以先让AI将指令分解为子任务[“查询当前天气” “根据‘晴天’或‘雨天’等关键词推荐一首应景的歌曲”]。然后程序依次执行调用天气API获取天气再将天气情况作为新的提示词发送给AI请求歌曲推荐。工具调用Function Calling利用大模型支持的工具调用功能让AI可以主动请求调用你预先定义好的函数如get_weather(location)search_web(query)。这需要更复杂的程序结构来解析AI的请求并执行对应函数。6. 实测中的典型问题与解决方案在将这套系统部署到行空板并实际运行的过程中我遇到了几个颇具代表性的问题这里分享出来希望能帮你提前避坑。6.1 网络波动导致的API请求失败行空板通过Wi-Fi连接网络环境不如台式机稳定。直接使用requests或openai库的默认设置在网络抖动时很容易抛出超时异常导致程序卡住或崩溃。解决方案增加重试机制使用tenacity或backoff库为请求函数添加指数退避重试。from tenacity import retry, stop_after_attempt, wait_exponential import openai retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, min4, max10)) def robust_chat_with_gpt(prompt): # ... 原有的请求代码 return response设置合理超时在请求中明确设置连接超时和读取超时。import openai openai.api_requestor.TIMEOUT (3.05, 30) # (连接超时, 读取超时) 单位秒添加网络状态检测在发送请求前先执行一个快速的网络连通性检查如ping一个稳定地址。6.2 内存不足与图片处理瓶颈当处理从API返回的高清图片如1024x1024时PIL加载、缩放、转换ImageTk.PhotoImage的操作可能会消耗大量内存。在长时间运行或连续生成多张图片后行空板可能出现内存不足OOM的情况导致程序被系统终止或界面卡死。解决方案及时释放资源在显示完一张图片并准备加载下一张时显式地删除对上一张图片的引用。# 在更新图片的函数中 if hasattr(self, ‘current_photo‘): del self.current_photo # 删除旧的PhotoImage引用 self.current_photo ImageTk.PhotoImage(resized_image) self.image_label.config(imageself.current_photo)优化图片处理流程请求API时如果只是用于屏幕预览可以优先选择较小尺寸如512x512。使用Image.thumbnail()方法进行缩放它比resize()更节省内存因为会保持纵横比并在原图上操作。考虑将图片保存到磁盘后直接使用文件路径在界面上显示某些GUI库支持而不是始终将整个图片对象保存在内存中。监控内存使用可以添加一个简单的内存监控线程当内存使用超过阈值如80%时主动清理缓存或提醒用户。6.3 语音功能的延迟与回声问题在集成语音功能时我发现从说完话到识别出文字有大约2-3秒的延迟包括录音、压缩、上传、识别、返回。此外如果扬声器音量过大可能会被麦克风再次收录形成回声导致识别错误或循环触发。解决方案优化录音参数使用更低的采样率如16000Hz和单声道CHANNELS1录制减少音频文件大小缩短上传时间。使用流式语音识别如果API支持边录音边上传识别可以显著降低端到端延迟。但这需要API和SDK的支持实现更复杂。回声消除物理隔离尽量使用外接麦克风并远离扬声器。软件降噪在录音后、发送前可以使用pydub等库进行简单的降噪处理。但更有效的是在录音时使用声学回声消除AEC算法这通常需要音频驱动或硬件支持。交互设计规避在录音期间暂时静音或大幅降低扬声器音量。识别完成后再恢复音量进行语音播报。6.4 界面响应与多线程陷阱使用threading将耗时操作网络请求、语音识别放到后台线程是正确的。但一个常见的陷阱是在子线程中直接操作Tkinter UI组件这会导致程序随机崩溃因为Tkinter不是线程安全的。解决方案统一使用after方法所有更新UI的操作都必须通过root.after(delay, callable)方法在主线程中调度执行。我在前面的GUI示例代码中已经使用了这种方法。# 在子线程中 result some_long_running_task() # 错误self.output_text.insert(tk.END, result) # 可能导致崩溃 # 正确 self.root.after(0, lambda: self.update_ui_with_result(result))使用线程安全队列子线程将结果放入一个queue.Queue主线程定期检查队列并取出结果更新UI。这是一种更结构化的方式。考虑异步编程对于Python 3.7可以使用asyncio和tkinter的结合例如asyncio的事件循环与Tkinter的mainloop集成但这比多线程更复杂。经过这些优化和问题修复后一个稳定、可用、体验良好的AI文生图、文生文应用就在行空板上跑起来了。它不仅仅是一个演示更是一个可以在此基础上无限扩展的智能交互平台原型。你可以为其增加新的技能模块连接更多的硬件传感器如摄像头、温湿度传感器让它真正成为一个看得见、听得懂、会思考的实体AI助手。