谈大语言模型动态思维流程编排

news2024/11/26 4:20:31

        尽管大语言模型已经呈现出了强大的威力,但是如何让它完美地完成一个大的问题,仍然是一个巨大的挑战。

    需要精心地给予大模型许多的提示(Prompt)。对于一个复杂的应用场景,编写一套完整的,准确无误的提示,并不容易。另一方面,尽管大模型已经具备了一些拆解问题,一步步解接的能力。但是就目前而言,这种分析,推理能力还是不能能准确地做出推理

  另一方面,对于大多数特定的问题而言,人类本身具有了成熟,有效的分析问题,解决问题的能力。我们出生起,就不断地学习如何一步步地拆解问题,通过步步地解决小问题,最终解决一个复杂的问题。

  许多的研究者提出了各种提示大模型拆解问题的方法。例如  计划和解题(Plan-and-Solve Prompting),反思 ReAct 等等。但是不同的问题,有不同的解决思路。我们从小在学校里解决应用题时,老师总是教我们解题思路。对于各种问题,大模型需要能够动态地做出解题方法。使用静态的提示来实现动态地计划是十分复杂,。在笔者看来,使用计算机语言来动态规划大模型解决问题的思路更加有效。

从实例谈起

     我们计划编写一个增强个人记忆力的大模型应用,该项目叫做 回忆(Recall)。在这个应用中,使用者要不断地告诉大模型一些关于个人的信息。例如:

  •       个人简历:包括姓名,性别,出身日期,出生地,家庭成员,教育和工作简历等等。
  •       个人爱好:自己的爱好,包括饮食,业余爱好,购物的品牌等等
  •      个人活动:比如一些主要的活动,比如逛街,朋友聚会,就医等等活动。
  •       备忘录:一些需要备忘的事情,例如 我的衣服放在哪里了。每天吃什么药等等。

      这个项目貌似比较简单,与windows AI PC 中的Recall ,开源项目Rewind 有相似之处。按照网络上的各种大模型架构的方法,主要使用如下方式

  •      使用大模型的Memory 功能实现对话的记忆
  •     将用户的个人信息,爱好,个人活动写入Vector 数据库中,使用RAG 技术在会话过程中读取相关信息
  •     构建ReAct Agent 进行 Action -Throught-Observation 的过程
  •    调用合适的工具(Agent Tools)

 vector 数据库 可以使用内存Memory  也可以使用永久VectorDB ,例如Croma VectorDB。

大模型我们测试了下列几种:

  1. openai
  2. 本地 llama-3
  3. 文心一言
  4. kimi
  5. 零一万物

但是结果并不令人满意,主要表现在如下几个方面

  •  并非所有的大模型都支持 Function Call,Agent,Memory ,RAG等功能的API。 
  • Vector 数据库要使用Embedding 功能实现text -splite .耗费的时间很长。
  • Momory 功能是将输入和回答都一股脑地存储了起来。会造成某些噪声混乱。
  • 简单的提问查询Vector数据库时,无法精切地匹配数据库的内容。
  • ReAct 的效果并不理想,有时后会乱想,反复地循环。明明得到了结果,却无法停止对话。
  • 延时长,耗费的token 多。

 实验下来,openai 效果最好,其它国内的大模型或多多少地出现问题。

观点

经过一段时间的实验之后,我们对大模型应用进行了新的思考,形成了下面几个观点:

  • 让大模型分层思考

         将复杂的问题分解为若干的小问题,通过解决小问题,最后解决大问题。这种方式具有如下的优点:

                -大模型回答简单的问题,有利于保证其确定性

                -使提示工程变得简单

                    提示也被分解成小提示,小问题的提示更具有针对性

                -不依赖具体的大模型API

                   简单地使用chat 就可以。 

                 -有利于采纳本地小模型与远程大模型相结合  ,降低使用大模型的成本,提高响应时间

  •    使用程序设计的方法动态地编排大模型的思维过程

          对于特定的一类问题,可以实现根据人类的经验,制定一套完整的思维过程。这样做的优点:

                -融入了人类的思维方式,更具有针对性。推理的速度更快

                -有利于对大模型的回答做确定性判断

                -有利于对大模型的回答做确定性验证

动态思维的流程

我们继续使用上面的实例来讨论动态思维流程。

  1. 判断语句是陈述句,还是询问句
  2. 如果是陈述句,内容要存储到数据库中,如果是提问句,那么要从数据库中获取相关的信息
  3. 为了对信息做分类,要判断陈述或者提问的内容的分类。
  4. 如果是其它类型的提问,就直接有大模型回答

思维流程的编排方法 

可以用程序或者图形方式来编排大模型的思维流程,在我们的实验中,采取了工业控制领域中功能块的编排方法。

      基于我们的经验,决定借用IEC61499 事件功能块的概念和方法,这样做的另一个意图是实现语言功能块和IEC61499 功能块的融合。

IEC61499 的基本概念包括:

  • 基本功能块
  • 复合功能块
  • 功能块网络

       IEC61499 功能块由事件输入,事件输出,数据输入和数据输出。事件用来控制程序执行 的流程,数据用来表示数据的流动。

 

大语言功能块内部由大语言模型来回答一个特定的问题。 其内部结构如下:

大模型思维流程

       大语言思维流程由大语言功能块网络组成,通过功能块网络运行时解释执行。功能块共享环境信息,环境信息包含了基本信息(对话者的姓名, 今天几号,星期几等等)和功能块通过数据库中提取的信息。一个功能块系统的结构如下

实验平台

   为了实验langFunctionblock 的想法,我们简单地搭建列一个实验平台:

  • 基于Nodejs/Javascript
  • 基于langchain库
  • 一个Javascript 实现的功能块运行时
  • 一组基于大模型的功能块
  • 不依赖大模型的API
App架构

实例的功能块网络 

功能块

InputMessage

输入用户提问的功能块,当用户输入消息时。该功能块产生:

  • Output 事件
  • OutMessage 数据

应用程序通过 WriteData 和Execution  调用该功能块。

设置InputMessage和OutMessage功能块的主要目的是使功能块具有一个统一的入口和出口。

Check

主要判断输入语句是询问句还是陈述句。

Memory

该功能块判断陈数句内容的类型:个人信息,事件,备忘录,然后将语句的类型,语句和时间标签存储到MongoDB 数据库中。

Recall

该功能块判断陈数句内容的类型:个人信息,事件,备忘录,然后从数据库中读出相应类型的数据,添加在环境信息中。

Basic

  这是一个基本大模型的功能块,将InMessage 结合环境信息一起构成Prompt 询问大模型,回答输出到OutMessage

OutMessage

 该模块将信息返回给对话者。

程序的实例

Check功能块

class Check {

  constructor(Parameters) {

    this.Name = Parameters.Name;
    this.Type = "CheckType";
    this.model = Parameters.Model
    this.ModelType = Parameters.ModelType
  }
  async Executive(runtime, EventType) {
    if (EventType == "Invoke") {
      console.log("Invoke:" + this.ModelType)
      console.log(this.InMessage)
      const Prefix = `请将下列语句分为下列几类:询问,陈述,请求。`
      const Suffix = `。请以JSON形式输出语句的类型 :JSON的格式为:
                {
                    class:"语句的类型"
                   }
                   如果无法判断语句的类型,直接输出 {class:"其它"}`
      const Prompt = Prefix + this.InMessage + Suffix
      const completion = await this.model.chat.completions.create({
        messages: [
          {
            "role": "user",
            "content": Prompt,
          }],
        model: this.ModelType,
      });

      const Content = await completion.choices[0].message.content
      const JSonContent = JSON.parse(Content.replace("```json\n", "").replace("```", ""))
      console.log(JSonContent.class)
      if (JSonContent.class == "询问") {
        this.OutMessage = this.InMessage
        await runtime.WriteOutputData({ FBName: this.Name, DataName: "OutMessage", Value: this.OutMessage })
        await runtime.EventNotify({ FBName: this.Name, EventName: "Ask" })

      }
      else if (JSonContent.class == "陈述") {
        this.OutMessage = this.InMessage
        await runtime.WriteOutputData({ FBName: this.Name, DataName: "OutMessage", Value: this.OutMessage })
        await runtime.EventNotify({ FBName: this.Name, EventName: "Statment" })

      } else if (JSonContent.class == "请求") {

        this.OutMessage = this.InMessage;
        await runtime.WriteOutputData({ FBName: this.Name, DataName: "OutMessage", Value: this.OutMessage })
        await runtime.EventNotify({ FBName: this.Name, EventName: "Request" })

      }
      else {

        this.OutMessage = this.InMessage
        await runtime.WriteOutputData({ FBName: this.Name, DataName: "OutMessage", Value: this.OutMessage })
        await runtime.EventNotify({ FBName: this.Name, EventName: "Ask" })
      }

    }
  }
  async WriteData(Name, Value) {
   
    if (Name == "InMessage") {
      this.InMessage = Value;
   
    }
  }
  async ReadData(Name) {
    if (Name == "OutMessage")
      return this.OutputMessage;
  }
}

主程序

import express from 'express';
import path from 'path'
import url from 'url'
//import fs from 'fs'
import OpenAI from 'openai';
import {RunTime} from "./RunTime/RunTime.mjs"
const API_BASE = "https://api.lingyiwanwu.com/v1"
const API_KEY = "xxxxxxxxxxxxxxxxxxx"
const openai = new OpenAI({
    apiKey: API_KEY,
    baseURL:API_BASE,
    model: "yi-large",
  temperature: 0
  });
  
  const router = express.Router();
  const app = express();
  const __filename = url.fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);
// var upload = multer({ dest: './documents' })
  app.use(express.static(path.join(__dirname, 'public')));
  app.use(express.json())
  router.get('/index', function (req, res) {
      res.sendFile(path.join(__dirname + '/views/indexB.html'));
  });
  router.post('/Request', async function (req, res) {
    Request = req.body;
    console.log(Request)
    const Method = Request.Method;
    const Message = Request.Message;
    console.log(Method);
    console.log(Message);
   
    const result = await RunFBNetwork(Message)
    
    res.send(JSON.stringify({
        Method: "SendMessage",
        Message: result
    }))
})
app.use('/', router);
  //RunTime Initialize 
console.log("llm FunctionBlock Runtime Ver 1.0")
const runtime=new RunTime();
runtime.InitializeFunctionBlickList();
runtime.LoadFBNetwork(openai); 
app.listen(process.env.port || 3000);
console.log('Running at Port 3000');

 async function RunFBNetwork(InputMessage){
  console.log("llm FunctionBlock Runtime Ver 1.0")
  //RunTime Initialize 
  runtime.InitializeMongoDB()
  runtime.InitializeEnvironment()
 await runtime.WriteInputData({FBName:"InMessage",DataName:"InMessage",Value:InputMessage})
 await runtime.Executive({FBName:"InMessage",EventType:"Request"})
 //Running....
 await runtime.run()
 const Output=await runtime.ReadFBData({
   FBName:"OutMessage",
   DataName:"OutMessage"})
   console.log(Output)
   return (Output)
}

结果

        经过我们的初步测试,结果要比采用大模型的memory,RAG,ReAct Agent等方式要好。主要表现为准确率高,速度快。

  •   将复杂的问题拆解成为小问题更有效
  • 对于特定的应用场景,能够利用人类分析问题的经验,动态地编写思维流程要比简单的将复杂任务交给大模型更好。效果远远超过ReAct Agent
  • 功能块及其功能块网络适合大模型思维流程的编排。

 感兴趣的读者可以进一步共同探讨。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1897858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu 24.04 上安装 Kubernetes,超级详细的教程!

Kubernetes 是一个免费的开源容器编排工具,它允许基于容器的应用程序的自动化部署、扩展和管理。 我们将介绍如何使用 Kubeadm 逐步在 Ubuntu 24.04 上安装 Kubernetes 此次演示中,我们将使用以下三个 Ubuntu 24.04 实例 Instance 1 : Master Node (k…

【Mathematica14.0】快速从下载安装到使用

目录 1.简介 2.下载安装 下载 安装 3.一小时掌握mathematica使用 单元模式 内置函数 符号表达式 迭代器 赋值 通配符及查找替换 函数定义 匿名函数(拉姆达表达式) 函数映射 函数式与运算符 函数自定义选项 图形可视化 交互式界面 数值…

window系统openssl开发环境搭建(VS2017)

window系统openssl开发环境搭建 VS2017 一、下载openssl二、安装openssl三、openssl项目配置3.1 配置include文件3.2 配置openssl动态库四、编写openssl测试代码五、问题总结5.1 问题 一5.2 问题二一、下载openssl https://slproweb.com/products/Win32OpenSSL.html 根据自己…

本迪戈和阿德莱德银行与MongoDB合作, 利用生成式AI对银行核心技术进行现代化改造

MongoDB公司(纳斯达克股票代码:MDB)近日宣布与本迪戈和阿德莱德银行 (Bendigo and Adelaide Bank,澳大利亚证券交易所股票代码:BEN)建立合作伙伴关系。 本迪戈和阿德莱德银行将使用MongoDB Atlas对其银行核…

自闭症孩子的语言之旅:最晚几岁会说话的探索与思考

作为在自闭症学校工作的教育者,我深知自闭症这一神经发展性障碍给孩子们带来的挑战,尤其是他们在语言发展方面的困难。自闭症孩子的语言发展轨迹各不相同,有的孩子可能早早地展现出语言天赋,而有的孩子则可能迟迟不开口。那么&…

Windows搭建本地对象存储服务MinIO并且使用springboot整合

开发文档: MinIO Windows中文文档 MinIO Object Storage for Windows (英文文档) 1、准备工作 准备一个空的文件夹,用来存放minio相关的内容; 这里是在D盘创建一个minio的文件夹; 后续所有跟MinIO相关…

【LLM】一、利用ollama本地部署大模型

目录 前言 一、Ollama 简介 1、什么是Ollama 2、特点: 二、Windows部署 1.下载 2.安装 3.测试安装 4.模型部署: 5.注意 三、 Docker部署 1.docker安装 2.ollama镜像拉取 3.ollama运行容器 4.模型部署: 5.注意: 总结 前言…

Ubuntu系统复制文件到共享文件夹出错

1、问题描述 Ubuntu系统复制文件到共享文件夹时,出现拼接文件时出错:输入/输出错误。 使用cp命令: cp -Rf XXX YYY 也是出错: cp: 写入 xxx 出错: 输入/输出错误 2、查看磁盘空间 查看磁盘空间,显示空间还有剩余…

【C语言】qsort()函数详解:能给万物排序的神奇函数

🦄个人主页:修修修也 🎏所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.qsort()函数的基本信息及功能 二.常见的排序算法及冒泡排序 三.逐一解读qsort()函数的参数及其原理 1.void* base 2.size_t num 3.size_t size 4.int (*compar)(c…

ANN文献综述

人工神经网络文献综述 摘要 人工神经网络(Artificial Neural Networks, ANNs)是由多个简单的、相互连接的处理单元组成的自适应系统,通过调整这些单元之间的连接强度,ANNs能够实现对复杂数据的建模和预测。本文综述了ANNs的基本…

进程、程序、应用程序之间的关系

文章目录 进程和程序进程和应用程序总结参考资料 进程和程序 程序:程序是存放在硬盘中的可执行文件,主要包括代码指令和数据。程序本身是一个静态的文件,只有在被操作系统加载到内存中并执行时才会变成进程。 进程:进程是程序在…

换根dp,CF 633F - The Chocolate Spree

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 633F - The Chocolate Spree 二、解题报告 1、思路分析 2600的题,但是不算很困难。 先考虑暴力做法,如何得到两条不相交的路径? 枚举删除的边,得到两棵子树…

Django自动生成Swagger接口文档 —— Python

1. 前言 当接口开发完成,紧接着需要编写接口文档。传统的接口文档通常都是使用Word或者一些接口文档管理平台进行编写,但此类接口文档维护更新比较麻烦,每次接口有变更,需要手动修改接口文档。在实际的工作中,经常会遇…

不错的用户需求访谈方法

不错的用户需求访谈方法,可以用如下的矩阵,用来引导用户访谈:

产科管理系统 专科电子病历系统源码,前后端分离架构,多家医院产科广泛运用,系统稳定,功能齐全

产科管理系统 专科电子病历系统源码,前后端分离架构,多家医院产科广泛运用,系统稳定,功能齐全 产科管理系统,特别是产科信息管理系统(Obstetrical Information Management System,简称OIMS&…

NXP i.MX8系列平台开发讲解 - 3.18 Linux tty子系统介绍(一)

专栏文章目录传送门:返回专栏目录 Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 目录 1. TTY 起源 2. Linux 系统中的TTY 2.1 Linux TTY 设备形式 2.2 Linux TTY framework 2.3 驱动核心相关文件…

一键直达:2024最新Win10系统安装包!快来下载!

对于想体验Win10系统最新功能的用户来说,寻找可靠的最新系统安装包是特别重要的。接下来系统之家小编就给大家带来2024年最新Win10系统安装包,有需要的小伙伴一键点击就能开始下载。该系统安装步骤简单易懂,无需担心任何装机经验。 推荐下载&…

浅谈k8s中cni0和docker0的关系和区别

最近在复习k8s网络方面的知识,查看之前学习时整理的笔记和文档还有过往自己总结的博客之后发现一个问题,就是在有关flannel和calico这两个k8s网络插件的文章和博客中,会涉及到cni0和docker0这两个网桥设备,但是都没有明确说明他们…

AIGI赋能未来:人工智能如何重塑电子电路学习体验

文章目录 一、掌握基础知识与技能1. 扎实理论基础2. 熟练使用工具 二、融合AI技术提升学习效率1. 利用AI辅助学习平台2. 应用AI工具进行电路设计与仿真 三、探索创新应用方向1. 关注AI与电子电路的交叉领域2. 参与开源项目和竞赛 四、培养跨学科思维1. 加强数学与计算机科学知识…

单机多网卡互通——问题跟踪+工具分析

一、背景 想搭建soft ROCE(RXE)与实体ROCE设备互联的测试环境&#xff0c;为了节省机器以及使用方便&#xff0c;预想在配备ROCE卡的主机上&#xff0c;用另一个网卡绑定soft ROCE&#xff0c;然后互通。 [ETH1 ROCE] <--------------------> [ETH2 RXE] 二、问题跟…