LLM语音交互:Unity语音交互——关键词检测篇。(新手入门)

本文作者分享了在开发Hololens2应用中,集成大语言模型LLM时实现关键词检测功能的过程,包括初期的简单方案、UnityEvent优化及后续的代码扩展,旨在帮助新手理解并解决开发中的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我之前一直在做Hololens2集成大语言模型(LLM)的开发,看我之前的博文有提过。今天主要是记录一下我在进行关键词检测功能开发中遇到的一些坎和经验,本次博文也是面向新手。(不过可能有些细节不注意到,可能解释的不是很详细,欢迎大家评论提问)

1.全流程介绍

首先LLM语音识别我目前将它分为几个部分进行功能开发:

语音转文本用的是Azure云服务,这个其实有很多教程都讲到过。然后后面文本转语音也是Azure云服务。至于LLM部分我之前的博文(http://t.csdnimg.cn/ltpUY)提到了,本次只介绍关键词检测功能的实现。关键词检索这里的功能主要分为两个部分,

  1. 检索到有关键词则调用响应的方法(比如触发“打开聊天记录”关键词,则触发相关方法,并输出文本text2:“好的,已帮你打开聊天记录”。并将该文本转为语音进行输出。)
  2. 未检索到关键词,则将文本输入到LLM里,然后LLM再输出答案text3,最后文本转语音。这部分内容的完成可以看我之前的博文。

本篇文章主要是讲解其中的关键词检测部分的脚本思路,此外大家同理也可以全程用GPT来帮助写代码。

2.关键词检索初步方案

一开始我的打算就很简单,就是如下所示:

    private int biaozhi = 0;

    private void Update()
    {
        if(needPost)
        {
            Debug.Log("调用LlmTalk");
            llmTalk.LlmTalk(inputText);
            needPost = false;
        }
        // 检查biaozhi是否有变化
        if (biaozhi != previousBiaozhi)
        {
            needPost = false;
            // 如果biaozhi变化,执行相应的动作
            if (biaozhi == 1)
            {
                *******
                ************
                *********
                animator.Play(animationName1);
                Answer2Log("好的,已帮你打开聊天记录");
            }

    private void HandleRecognitionSuccess(string recognizedText)
    {
        string modifiedText = "user:" + recognizedText ;
        TextLibrary.Instance.AddText(modifiedText);
        Debug.Log($"识别到的文本: {modifiedText}");

        //聊天UI
        if (recognizedText.Contains("查看聊天记录")|| recognizedText.Contains("打开聊天记录") || recognizedText.Contains("打开聊天界面") || recognizedText.Contains("查看聊天界面"))
        {
            Debug.Log("触发了“查看聊天记录”关键词");
            biaozhi = 1;
        }
        else
        {
            needPost = true;
            inputText = recognizedText;
            Debug.Log("无关键词,请求大语言模型");
        }
    }

首先先解释这个代码中的总体输入输出:
  private void HandleRecognitionSuccess(string recognizedText)

这里面的recognizedText就是从语音转文本模块获取到的文本,而llmTalk.LlmTalk(inputText);就是将文本送给大语言模型LLM的执行语句,其中inputText就是输出文本。其实这里recognizedTextinputText内容是一样的。

我用“状态”来表示关键词触发的情况,因为我的关键词触发算是一个Toggle类别(也就是开关类别)。比如开启目标检测呀,关闭目标检测呀之类的。所以我就在语音转文字后开始调用HandleRecognitionSuccess函数,recognizedText为语音转文本后的“文本”。通过Contains()来检测关键词。接着设置状态标准符:int biaozhi,若检测到状态变化则调用相应的函数。这里面的Answer2Log()方法是我自己编写的文本转语音的函数。

3.方案优化

但是我发现到最后需要识别的关键词太多了,而且,每个关键词检测到后调用的函数都需要在代码里面填写,太复杂了,最主要是有时候自己都忘了有哪些关键词,要到代码里找关键词。

后来关于这个问题我问了一下GPT,结果发现他给出了UnityEvent的方案,如下:

using UnityEngine.Events;


public class KeywordChecker : MonoBehaviour
{

    public UnityEvent OpenLog;
    public UnityEvent CloseLog;
}
    if (biaozhi == 1)
    {
        OpenLog?.Invoke();
        animator.Play(animationName1);
        Answer2Log("好的,已帮你打开聊天记录");
    }

首先如代码中所示的,有两个关键词检测:“打开聊天记录”,“关闭聊天记录”。所以我取名OpenLog,CloseLog。唯一的不同就是状态biaozhi变为“1”时,调用的函数我用OpenLog?.Invoke();进行调用,这里在界面中是这样的,大家发现了没,这个Unity的自带的功能就和我们在给按钮button设置点击事件一样简单,这样的方法不用在代码里面幸幸苦苦的调用了,直接在界面里面拖拽,一方面省事,另一方面还可以在界面中查看代码运行的流程。

但是最后我还是发现了几个问题:首先时这个UnityEvent事件不能自己增加,我们只能在一个OpenLog对象里添加。这样一来我想要增加其他的关键词绑定就很麻烦。

给GPT的问题:

现在我是用    public UnityEvent OpenLog;功能,可以在界面中拖拽对象进行方法调用,我觉得很方便,因为这样很省事,但是有一点不好,监听的事件只能在代码中添加,我希望事件数量同样可以在界面中添加

后来我修改代码如下:

public class EventList
{
    public List<UnityEvent> events = new List<UnityEvent>();
}

public class docQADemo : MonoBehaviour
{
    public EventList myEvents;
}

这样就可以添加事件的个数,不过我们还需要增加一个功能:那就是给每个element()都添加一个关键词内容的编辑功能。所以就改成了下面这个:

现在可以在界面中添加关键词内容以及自动性回复内容。

下面是我问GPT的问题:

    private int biaozhi = 0;

    private void Update()
    {
        if(needPost)
        {
            Debug.Log("调用LlmTalk");
            llmTalk.LlmTalk(inputText);
            needPost = false;
        }
        // 检查biaozhi是否有变化
        if (biaozhi != previousBiaozhi)
        {
            needPost = false;
            // 如果biaozhi变化,执行相应的动作
            if (biaozhi == 1)
            {
                *******
                ************
                *********
                animator.Play(animationName1);
                Answer2Log("好的,已帮你打开聊天记录");
            }

    private void HandleRecognitionSuccess(string recognizedText)
    {
        string modifiedText = "user:" + recognizedText ;
        TextLibrary.Instance.AddText(modifiedText);
        Debug.Log($"识别到的文本: {modifiedText}");

        //聊天UI
        if (recognizedText.Contains("查看聊天记录")|| recognizedText.Contains("打开聊天记录") || recognizedText.Contains("打开聊天界面") || recognizedText.Contains("查看聊天界面"))
        {
            Debug.Log("触发了“查看聊天记录”关键词");
            biaozhi = 1;
        }
        else
        {
            needPost = true;
            inputText = recognizedText;
            Debug.Log("无关键词,请求大语言模型");
        }
    }

这是我现在的代码,我希望它能够通过拖拽的方式在界面中选择触发事件的函数。
但是关键词内容和监听事件的个数都需要在代码中修改,所以现在我添加了一个类:

public class KeywordEvent
{ 
    public string keyword;
    
    public UnityEvent responseEvent; 
} 
在主类中声明了: 
[SerializeField] 
private List<KeywordEvent> keywordEvents = new List<KeywordEvent>(); 
这样就可以在Unity界面中编辑事件个数和关键词内容了,而我现在需要你帮我修改源代码,
使得脚本能够对recognizedText进行关键词检测并执行相应的事件。

其实我们从最初版本到现在的版本都很好理解,就是从上图变成了下图

4.源码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 可在界面中自定义关键词以及触发的函数
/// </summary>
[System.Serializable]
public class KeywordEvent
{
    public string keyword;
    public string responseWord;
    public UnityEvent responseEvent;
}

public class docQADemo : MonoBehaviour
{
    public SpeechRec speechRec;
    public LLMTalk llmTalk;
    public TextToSpeech textToSpeech;
    private string inputText = "";
    [SerializeField]
    private List<KeywordEvent> keywordEvents = new List<KeywordEvent>();

    // 状态符,用于标记需要触发的事件ID,初始值为-1表示无事件
    private int currentEventId = -1;
    private bool needPost = false;
    private void Start()
    {
        if (speechRec != null)
        {
            speechRec.OnRecognition2KeyWord += HandleRecognitionSuccess;
        }
    }

    private void Update()
    {
        if (currentEventId != -1) // 检查是否有事件需要被触发
        {
            keywordEvents[currentEventId].responseEvent?.Invoke(); // 触发事件
            if(keywordEvents[currentEventId].responseWord!=null)
            {
                Answer2Log(keywordEvents[currentEventId].responseWord);
            }
            currentEventId = -1; // 重置状态符,等待下一个事件
        }
        if (needPost) // 检查是否有事件需要被触发
        {
            Debug.Log("请求LLM:" + inputText);
            llmTalk.LlmTalk(inputText); // 调用 llmTalk.LlmTalk 方法处理未触发关键词的文本
            needPost = false;
        }
    }

    private void HandleRecognitionSuccess(string recognizedText)
    {
        string modifiedText = "user:" + recognizedText;
        TextLibrary.Instance.AddText(modifiedText);
        for (int i = 0; i < keywordEvents.Count; i++)
        {
            if (recognizedText.Contains(keywordEvents[i].keyword))
            {
                Debug.Log($"触发了“{keywordEvents[i].keyword}”关键词");
                currentEventId = i; // 设置状态符为当前关键词事件的索引 
                break; // 找到后立即中断循环
            }
        }
        if (currentEventId == -1) // 检查是否有事件需要被触发
        {
            needPost = true;
            inputText = recognizedText;
            Debug.Log("无关键词,请求大语言模型");
        }

    }
    public void Answer2Log(string aText)
    {
        string answerText = aText;
        textToSpeech.ConvertTextToSpeech(answerText);
        string modifiedText = "robot:" + "\n" + answerText + "\n";
        TextLibrary.Instance.AddText(modifiedText);
    }



    private void OnDestroy()
    {
        if (speechRec != null)
        {
            speechRec.OnRecognition2KeyWord -= HandleRecognitionSuccess;
        }
    }
}

其中Answer2Log()是我写的一个文本转语音的函数。

<think>好的,用户想了解人机交互相关的技术、应用和研究。首先我需要整理人机交互的基本概念,确保定义准确,可能需要引用现有的资料。比如引用[2]和[3]都提到了HCI的定义,可以结合起来说明。 接下来,技术分类是关键。用户可能希望了解当前主流的技术,比如自然用户界面、语音识别、手势识别,以及机器学习在其中的作用。需要提到引用[1]和[3]中的手势识别和机器视觉的应用,说明这些技术如何促进人机交互的发展。 应用场景部分,要覆盖多个领域,比如智能家居、医疗、教育和游戏。引用[2]提到了游戏交互设计,可以具体展开。同时,引用[3]中的例子如阿尔法狗,能体现AI在HCI中的重要性。 研究热点需要突出当前的前沿方向,比如情感计算、脑机接口和AR/VR。这里可以联系引用[4]中的大规模语言模型,说明伦理问题和技术结合的趋势。 伦理与挑战部分,引用[4]的分析方法,强调隐私和算法偏见的问题,这样用户能全面了解HCI的复杂性。 最后,相关问题的生成要覆盖技术实现、应用案例、伦理挑战和研究方法,帮助用户深入探索。需要确保问题有层次,从基础到进阶,引导用户进一步学习。 检查引用是否准确,每个引用标记是否对应正确的内容。比如引用[1]是关于手势识别的,引用[3]提到机器视觉,要正确关联到相应的技术部分。同时,确保回答结构清晰,符合用户要求的中文回答和LaTeX格式的正确使用,比如技术术语用$符号包裹,如$HCI$系统。 最后通读一遍,确保逻辑连贯,没有技术错误,并且自然融入引用,避免生硬。这样用户就能全面理解人机交互的技术和应用,并找到进一步研究的方向。</think>### 人机交互技术、应用与研究综述 人机交互(Human-Computer Interaction, $HCI$)是以用户为中心的技术体系,融合心理学、计算机科学、设计学等多学科,旨在构建高效、自然、安全的交互系统[^2][^3]。 #### 一、核心技术分类 1. **自然用户界面(NUI)** 通过手势、语音、眼动等自然行为控制设备,例如: - 手势识别:基于机器视觉的$RGB-D$传感器捕捉三维手势轨迹[^1] - 语音交互:结合$NLP$(自然语言处理)实现对话系统 - 眼动追踪:利用$SVM$(支持向量机)算法分析注视点 2. **增强现实(AR)与虚拟现实(VR)** 采用$SLAM$(同步定位与地图构建)技术实现虚实融合,如医疗手术导航系统。 3. **智能体交互** 基于$LLM$(大规模语言模型)的对话代理,如ChatGPT[^4]。 #### 二、典型应用场景 | 领域 | 案例 | 技术支撑 | |------------|-------------------------------|------------------------------| | 智能家居 | 手势控制灯光 | 机器视觉+卷积神经网络($CNN$) | | 医疗康复 | 脑机接口辅助瘫痪患者交流 | EEG信号分析+深度学习 | | 教育培训 | AR化学实验模拟 | Unity3D引擎+空间计算 | | 游戏娱乐 | 体感游戏《Just Dance》 | 惯性传感器+运动捕捉算法[^2] | #### 三、前沿研究方向 1. **情感计算** 通过$fMRI$(功能磁共振成像)和微表情分析构建情感模型,例如: $$ E_{score} = \sum_{i=1}^n w_i \cdot f(x_i) $$ 其中$w_i$为情感特征权重,$x_i$为生理信号参数。 2. **脑机接口(BCI)** 使用$EEG$(脑电图)解码运动意图,最新研究显示解码准确率可达$92\%$。 3. **伦理与隐私** 大规模语言模型带来的数据偏见问题需采用$DP$(差分隐私)技术。 #### 四、开发流程示例 ```python # 基于OpenCV的手势识别代码片段 import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 肤色检测阈值处理 mask = cv2.inRange(hsv, (0,30,60), (20,150,255)) contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 轮廓分析逻辑... ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值