• 问题来源:

大语言模型与人聊天那是行云流水般的自然,但如果是要大语言模型去Call别的系统,也就是让大语言模型与应用程序聊天,那就有点意思了!

比如说:金融量化接口向外公布了一系列API,你问大语言模型:请查询我的持仓?

大模型把这个操作需求,从【人话】转换成一系列的【API指令】,帮你发送查询命令,收到数据后,再把【查询结果】用【人话】反馈给你。

在Unity里面,你的虚拟仿真实验里,有一大堆实验步骤相关的信息和状态,当用户通过【AI助理】问:接下来的实验步骤是啥?

你可能会把【整个实验步骤信息表】喂给LLM,然后通过LLM自己去检索答案。

那么,万一用户说:请跳过当前步骤,执行后面的步骤。

此时此刻,你是不是应该反思,LLM是时候与应用程序进行交互了。

在这里插入图片描述

一、【和人聊天】 与 【与应用程序聊天】

  • 盖棺定论:

    • LLM 和人聊天 = 语言是目的
    • LLM 和程序聊天 = 语言只是接口
  • LLM能听懂人话,那么它能把人话变成API指令吗?

    • 使用可控输出:采用【Prompt提示词约束】,【Grammar 约束】、【GrammarJSON约束】

二、如何与应用程序聊天

  • LLM能听懂人话,这是没问题的!
  • 那么,如何用人话来跟你的应用程序进行交互呢?
  • 你告诉LLM你要干啥,LLM把你的人话翻译成API指令,然后,你在把API指令转发给程序
  • LLM如何把人话变成指令——使用输出约束

三、如何让LLM输出符合约束格式的指令信息

1、输出约束的种类

  • (1)总体来讲,包含【软约束】和【硬约束】。

    • 【软约束】: 就是规劝约束,比如给LLMCharacter的面板指定它的prompt,或者每次聊天的时候,用文字提醒他要输出什么格式的内容。
    • 【硬约束】就是强制约束,通过Grammar、GrammarJSON两个字段来约束,让模型按照规定的格式来输出。
      在这里插入图片描述
  • (2)两种约束方式的异同(ChatGPT整理):

维度 软约束(Prompt) 硬约束(Grammar / GrammarJSON)
本质 给模型“建议”或“提示”如何输出 限制模型生成的 token / 输出结构
发生阶段 理解 / 推理阶段 解码 / 生成阶段
输出控制方式 模型自觉遵守 模型物理上无法违反
是否可被违反 ✅ 可能 ❌ 不可能
输出形式 自然语言 枚举值 / JSON 结构
可验证性 ❌ 难以验证 ✅ 天然可验证
工程稳定性 中 / 低 极高
抗干扰能力 弱(受上下文、温度、对抗输入影响大) 强(无上下文污染、温度影响小)
适合对象 人类阅读 / 教学 / 引导 程序消费 / API 调用 / 状态机 / Function Call
典型角色 ChatCharacter、RAGCharacter IntentCharacter(Grammar)、ActionCharacter(GrammarJSON)
作用 提供角色身份、语气、思维引导 保证输出格式正确、可解析、可直接驱动程序
是否保证语义正确 ❌ 不保证 ❌ 也不保证(只保证形式正确)
常见误区 当做硬规则使用 不存在(生成器级别约束)

2、LLMCharacter中与Grammar与GrammarJSON相关的几个变量有啥什么关联?

  • (1)面板上的变量
    • Grammar (string类型)
    • GrammarJSON(string类型)
      在这里插入图片描述
/// <summary> grammar file used for the LLMCharacter (.gbnf format) </summary>
[Tooltip("grammar file used for the LLMCharacter (.gbnf format)")]
[ModelAdvanced] public string grammar = null;
/// <summary> grammar file used for the LLMCharacter (.json format) </summary>
[Tooltip("grammar file used for the LLMCharacter (.json format)")]
[ModelAdvanced] public string grammarJSON = null;
  • (2)代码里面的变量
    • grammarString (string类型)
    • grammarJSONString (string类型)
/// <summary> the grammar to use </summary>
[Tooltip("the grammar to use")]
public string grammarString;
/// <summary> the grammar to use </summary>
[Tooltip("the grammar to use")]
public string grammarJSONString;
  • (3)逻辑关系溯源
    在启动的时候,Awake()里面进行初始化和赋值
    在这里插入图片描述

处理的过程:
通过面板配置参数,初始化真正的字段。

grammarString = Fn(Grammar)
grammarJSONString = Fn(GrammarJSON)

从给定的代码逻辑来看,面板参数配置的信息是路径,而是二选一的操作,具体操作如下:

protected virtual void InitGrammar()
{
    grammarString = "";
    grammarJSONString = "";
    if (!String.IsNullOrEmpty(grammar))
    {
        grammarString = File.ReadAllText(LLMUnitySetup.GetAssetPath(grammar));
        if (!String.IsNullOrEmpty(grammarJSON))
            LLMUnitySetup.LogWarning("Both GBNF and JSON grammars are set, only the GBNF will be used");
    }
    else if (!String.IsNullOrEmpty(grammarJSON))
    {
        grammarJSONString = File.ReadAllText(LLMUnitySetup.GetAssetPath(grammarJSON));
    }
}

2、Grammar和GrammarJSON使用场景

用户提出的问题,合并成以下几类:

  • (1)GPT普通聊天:与LLM聊天
  • (2)实验知识提问:基于RAG知识库的问题
  • (3)实验过程交互:与程序进行交互操作
    • A、查询实验状态:获取实验状态
    • B、更改实验状态:更改实验状态在这里插入图片描述
用户提问
    ↓
IntentCharacter (Grammar单项选择(意图分类器))
    输出 intent → Chat / KnowledgeQA / QueryState / ModifyState
    ↓
分流
    ├─ Chat → 直接文本输出
    ├─ KnowledgeQA → RAG检索 → 文本输出
    └─ QueryState / ModifyState → ActionCharacter (GrammarJSON)
         输出 JSON 参数
         ↓
      Unity 执行对应操作
         ↓
      返回执行结果
         ↓
      (可选)ActionCharacter生成用户可读说明

四、总结

如图~~
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐