西部AI小镇-构建自主虚拟世界

news2024/11/20 2:41:24

在这里插入图片描述

背景

未来曜文有接入市场上所有面向chatGPT开发的应用,例如开源聊天组件,西部小镇等

内容介绍

  • 生成代理起床,做早餐,然后去上班;艺术家作画,作家写作;他们形成意见、互相关注并发起对话;
  • 他们在计划第二天时会记住并反思过去的日子。
  • 为了实现生成代理,描述了一种架构,该架构扩展了大型语言模型,以使用自然语言存储代理经验的完整记录,随着时间的推移将这些记忆合成为更高级别的反射,并动态检索它们以规划行为。
  • 实例化生成代理来填充受《模拟人生》启发的交互式沙箱环境,最终用户可以使用自然语言与一个由 25 个代理组成的小镇进行交互。在评估中,这些生成代理会产生可信的个人和紧急社交行为:例如,从一个用户指定的单一想法开始,即一个代理想要举办情人节派对,代理在接下来的两个时间里自主地传播派对邀请几天,结识新朋友,互相约出参加聚会的日期,并协调在正确的时间一起出现在聚会上。我们通过消融证明,我们的代理架构的组成部分——观察、规划和反思——每一个都对代理行为的可信度做出了至关重要的贡献
  • 该AI应用的价值在于我们有GPT的能力,很吸引眼球,不具有实际产品价值,更像是一种构想
  • 但是架构思路值得参考,可以将思路延申到实际业务场景,例如构建面试准备,用户可以安全地排练困难的、充满冲突的对话

部署

基础

代码仓库:https://github.com/joonspk-research/generative_agents
论文地址:https://arxiv.org/pdf/2304.03442.pdf
语言:javascript/python3.9
框架:Bootstrap/django/openai

设置环境

要设置您的环境,您需要生成一个utils.py包含 OpenAI API 密钥的文件并下载必要的软件包。

步骤1.生成Utils文件

在reverie/backend_server文件夹(所在reverie.py位置)中,创建一个名为的新文件utils.py,并将以下内容复制并粘贴到该文件中:

openai_api_key = "sk-xxx"
openai_api_base = "http://10.9.115.77:50000/v1" # 零时添加的
# Put your name
key_owner = "<jack>"

maze_assets_loc = "../../environment/frontend_server/static_dirs/assets"
env_matrix = f"{maze_assets_loc}/the_ville/matrix"
env_visuals = f"{maze_assets_loc}/the_ville/visuals"

fs_storage = "../../environment/frontend_server/storage"
fs_temp_storage = "../../environment/frontend_server/temp_storage"

collision_block_id = "32125"

# Verbose 
debug = True

替换为您的 OpenAI API 密钥和您的姓名。

步骤2.安装requirements.txt

安装requirements.txt文件中列出的所有内容(我强烈建议首先像往常一样设置 virtualenv)。关于 Python 版本的说明:我们在 Python 3.9.12 上测试了我们的环境。

  • 构建镜像
# Use the specified Python version
FROM python:3.9.12

RUN echo "deb https://mirrors.aliyun.com/debian/ buster main contrib non-free" > /etc/apt/sources.list && \
    echo "deb https://mirrors.aliyun.com/debian/ buster-updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb https://mirrors.aliyun.com/debian/ buster-backports main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb https://mirrors.aliyun.com/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list

# Install supervisor to manage multiple processes
RUN apt-get update && apt-get install -y supervisor

# Set the working directory
WORKDIR /app

# Copy the requirements.txt file into the container
COPY requirements.txt ./

# Install the Python dependencies from requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Copy the entire application (both environment and backend server)
COPY . /app

# Create a supervisor configuration file
RUN echo '[supervisord]' > /etc/supervisor/conf.d/supervisord.conf && \
    echo 'nodaemon=true' >> /etc/supervisor/conf.d/supervisord.conf && \
    echo '[program:environment_server]' >> /etc/supervisor/conf.d/supervisord.conf && \
    echo 'command=python environment/frontend_server/manage.py runserver 0.0.0.0:8000' >> /etc/supervisor/conf.d/supervisord.conf && \
    echo '[program:simulation_server]' >> /etc/supervisor/conf.d/supervisord.conf && \
    echo 'command=python reverie/backend_server/reverie.py' >> /etc/supervisor/conf.d/supervisord.conf

# Expose the port the environment server will run on
EXPOSE 8000

# Start supervisor, which will manage both the environment server and the simulation server
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

运行模拟

要运行新的模拟,您需要同时启动两个服务器:环境服务器和代理模拟服务器。

步骤1.启动环境服务器

  • 同样,该环境是作为 Django 项目实现的,因此,您需要启动 Django 服务器。为此,首先导航到命令行environment/frontend_server(这是所在位置)。manage.py然后运行以下命令:

  • python manage.py runserver 0.0.0.0:8000

  • 然后,在您最喜欢的浏览器上,转到http://localhost:8000/。如果您看到一条消息“您的环境服务器已启动并正在运行”,则表明您的服务器运行正常。确保环境服务器在运行模拟时继续运行,因此请保持此命令行选项卡打开!(注意:我建议使用 Chrome 或 Safari。Firefox 可能会产生一些前端故障,尽管它不应该干扰实际的模拟。)

步骤 2. 启动模拟服务器

  • 打开另一个命令行(您在步骤 1 中使用的命令行应该仍在运行环境服务器,因此请保持原样)。导航到reverie/backend_server并运行reverie.py.
    python reverie.py

  • 这将启动模拟服务器。将出现命令行提示,询问以下内容:“输入分叉模拟的名称:”。要与 Isabella Rodriguez、Maria Lopez 和 Klaus Mueller 启动 3 代理模拟,请输入以下内容:
    base_the_ville_isabella_maria_klaus

  • 然后提示将询问“输入新模拟的名称:”。输入任何名称来表示您当前的模拟(例如,现在只需“测试模拟”即可)。
    test-simulation

保持模拟器服务器运行。此时会显示如下提示:“输入选项:”

步骤 3. 运行并保存模拟

在浏览器上,导航到http://localhost:8000/simulator_home。您应该会看到超人前传的地图,以及地图上的活跃特工列表。您可以使用键盘箭头在地图上移动。请保持此选项卡打开。要运行模拟,请在模拟服务器中键入以下命令以响应提示“输入选项”:
run

备注

def get_embedding(text, model="text-embedding-ada-002"):
    text = text.replace("\n", " ")
    if not text:
        text = "this is blank"
    return [-0.006929283495992422, -0.005336422007530928] # chatglm暂时没有支持该接口,多以暂时替换写死
    return openai.Embedding.create(
        input=[text], model=model)['data'][0]['embedding']

部署效果

http://wiki.enflame.cn/download/attachments/167180013/image2023-8-25_11-33-47.png?version=1&modificationDate=1692934428036&api=v2
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

原理

总结论文贡献

In sum, this paper makes the following contributions:
• Generative agents, believable simulacra of human behavior
that are dynamically conditioned on agents’ changing experiences and environment. 生成型智能体
• A novel architecture that makes it possible for generative
agents to remember, retrieve, reflect, interact with other
agents, and plan through dynamically evolving circumstances.
The architecture leverages the powerful prompting capabilities of large language models and supplements those capabilities to support longer-term agent coherence, the ability
to manage dynamically evolving memory, and recursively
produce higher-level reflections. 一种新颖的架构,使生成代理能够记忆,检索,反映,与其他代理交互,并通过动态发展的环境进行计划
• Two evaluations, a controlled evaluation and an end-to-end
evaluation, that establish causal effects of the importance
of components of the architecture, as well as identify breakdowns arising from, e.g., improper memory retrieval. 两个评估,一个受控的评估和一个端到端评估,它们建立了体系结构组件重要性的因果关系,以及识别由不适当的内存检索引起的故障。
• Discussion of the opportunities and ethical and societal risks
of generative agents in interactive systems. We argue that
these agents should be tuned to mitigate the risk of users
forming parasocial relationships, logged to mitigate risks
stemming from deepfakes and tailored persuasion, and applied in ways that complement rath 生成代理的机会和伦理及社会风险

论文解读

代理角色和角色间的交流

Smallville中有25个独特的代理居民社区。每个代理都由一个简单的精灵形象代表。我们编写了一个自然语言段落来描述每个代理的身份,包括他们的职业和与其他代理的关系,作为种子记忆。例如,John Lin的描述如下
John Lin is a pharmacy shopkeeper at the Willow
Market and Pharmacy who loves to help people. He
is always looking for ways to make the process
of getting medication easier for his customers;
John Lin is living with his wife, Mei Lin, who
is a college professor, and son, Eddy Lin, who is
a student studying music theory; John Lin loves
his family very much; John Lin has known the old
couple next-door, Sam Moore and Jennifer Moore,
for a few years; John Lin thinks Sam Moore is a
kind and nice man; John Lin knows his neighbor,
Yuriko Yamamoto, well; John Lin knows of his
neighbors, Tamara Taylor and Carmen Ortiz, but
has not met them before; John Lin and Tom Moreno
are colleagues at The Willows Market and Pharmacy;
John Lin and Tom Moreno are friends and like to
discuss local politics together; John Lin knows
the Moreno family somewhat well — the husband Tom
Moreno and the wife Jane Moreno.
John Lin是Willow市场和药店的一名药店店主,他热爱帮助人们。他总是在寻找让顾客获得药物更加便捷的方式;John Lin与妻子Mei Lin和儿子Eddy Lin一起生活,Mei Lin是一名大学教授,Eddy Lin正在学习音乐理论;John Lin非常爱他的家人;John Lin认识隔壁老夫妇Sam Moore和Jennifer Moore已经有几年了;John Lin认为Sam Moore是个善良友好的人;John Lin很熟悉他的邻居Yuriko Yamamoto;John Lin知道他的邻居Tamara Taylor和Carmen Ortiz,但没有见过他们;John Lin和Tom Moreno是Willows市场和药店的同事;John Lin和Tom Moreno是朋友,喜欢一起讨论当地政治;John Lin对Moreno家庭有一定的了解——丈夫Tom Moreno和妻子Jane Moreno

代理角色之间的交流

代理通过它们的行动与世界互动,并通过自然语言与彼此互动。在沙盒引擎的每个时间步骤中,代理会输出一个自然语言语句,描述它们当前的行动,例如“Isabella Rodriguez正在写她的日记”、“Isabella Rodriguez正在查看她的电子邮件”、“Isabella Rodriguez正在和她的家人通电话”或“Isabella Rodriguez正在准备睡觉”。然后,这个语句被翻译成影响沙盒世界的具体动作。该动作在沙盒界面上显示为一组表情符号,提供了一个俯视图中行动的抽象表示。为了实现这一点,系统采用了一个语言模型将行动翻译成一组表情符号,出现在每个代理的话泡中。例如,“Isabella Rodriguez正在写她的日记”显示为📝,而“Isabella Rodriguez正在查看她的电子邮件”则显示为📧。通过点击代理人物,可以访问行动的完整自然语言描述

Isabella: 我还在权衡利弊,但是我和Sam Moore讨论了选举。你对他有什么看法?
Tom: 说实话,我不喜欢Sam Moore。我认为他与社区脱节,不把我们的利益放在心上

与环境的交互

  • Smallville拥有一个小村庄普遍具备的设施,包括咖啡馆、酒吧、公园、学校、宿舍、房屋和商店。它还定义了子区域和对象,使这些空间具有功能性,例如房子里的厨房和厨房里的炉子。所有作为代理人主要居住地的空间都配备了床、桌子、衣柜、架子、浴室和厨房
  • 用户和代理人可以像在沙盒游戏The Sims中那样影响这个世界中的物体状态。例如,当代理人在睡觉时,床会被占用,当代理人用完材料做早餐时,冰箱会变空。最终用户还可以通过自然语言重写代理人周围物体的状态来重新塑造Smallville中代理人的环境。例如,在早上Isabella在做早餐时,用户可以通过输入指令来将厨房炉子的状态从“开启”更改为“着火”,如下所示:“<Isabella的公寓:厨房:炉子>正在燃烧。” Isabella会在下一刻注意到这一点,然后去关闭炉子并重新制作自己的早餐。同样,如果用户在Isabella进入浴室时将淋浴头的状态设置为“漏水”,她会从客厅拿出工具来修理漏水

例子:生活中的一天

  • 从单段描述开始,代理人开始计划他们的一天。随着时间在沙盒世界中流逝,他们的行为随着这些代理人彼此交互和与世界互动、建立记忆和关系以及协调联合活动而不断演变

在这里插入图片描述

  • 一位生成式角色John Lin的一天。约翰早上6点左右醒来,完成他的早晨常规活动,包括刷牙、淋浴和吃早餐。他简短地与妻子Mei和儿子Eddy交流后,便出门开始他的工作日。我们通过在代理人John Lin上演示生成型代理人的行为来跟踪系统输出的过程(图3)。在林家中,约翰是第一个在早上7点醒来的人。他刷牙、洗澡、穿衣服、吃早餐,并在客厅的餐桌上查看新闻。在早上8点,Eddy紧随其后,匆忙从床上起来准备上课。他追上约翰,就在他准备出门时:

约翰:早上好,Eddy。你睡得好吗?
Eddy:早上好,爸爸。是的,我睡得很好。
约翰:太好了。你今天在做什么?
Eddy:我正在为我的课程创作一首新的音乐作品。它要在本周交作业,所以我正在努力完成它。但我觉得做这个很有趣!
约翰:听起来很不错!

  • 不久之后,Eddy出门了,梅醒来并加入了约翰的谈话。梅问起她的儿子,约翰回忆起他们刚刚的谈话:

梅:Eddy已经去上学了吗?
约翰:是的,他刚刚离开。他正在为他的课程创作一首音乐作品。
梅:哦,太棒了!告诉我详情。
约翰:我想他非常喜欢这个!他说他做这个很开心。
梅:太好了!我为他感到骄傲。

  • 随着他们结束了谈话,梅和约翰开始准备。梅去教课并写研究论文,而约翰在上午9点前在Willow Market和Pharmacy开设他的药房柜台。

突发的社会行为

  • 通过彼此互动,Smallville中的生成型角色交换信息、建立新的关系并协调联合活动。扩展之前的工作[79],这些社交行为是突发的,而不是预先编程的
  • 例如预先设置好的计划,也可能发生变化

信息扩散

当代理人注意到彼此时,他们可能会进行对话 - 在这样做时,信息可以从一个代理人传播到另一个代理人。例如,在杂货店的Sam和Tom之间的对话中,Sam告诉Tom他参加了当地选举的候选资格:

Sam:嘿,Tom,最近怎么样?
Tom:不错,谢谢。有什么事吗?
Sam:嗯,我想和你谈谈某件事。事实上,我正在参加即将到来的地方选举,竞选市长。
Tom:真的吗?太好了!你为什么要竞选?
Sam:我已经参与本地政治多年,我真的觉得我可以改变我们的社区。另外,我还想给大家带来新的想法和观点

  • 那天晚些时候,当Sam离开后,从另一个消息来源得知了这个消息的Tom和John讨论了Sam赢得选举的机会。

John: 我听说Sam Moore参加了本地选举竞选市长。你觉得他赢得选举的机会大吗?
Tom: 我认为他有很大机会。他一直在社区努力工作,我认为他会得到很多支持。你觉得呢?
John: 我认为他参选很棒。我很好奇还有谁在竞选,选举最后会是怎样的结果。

  • 渐渐地,Sam的候选人资格成为了镇上的话题,一些人支持他,另一些人仍未决定

关系记忆

Smallville中的智能体随着时间形成新的关系,并记住他们与其他智能体的互动。例如,Sam一开始不认识Latoya Williams。在Johnson公园散步时,Sam遇到了Latoya,他们互相介绍,并且Latoya提到她正在进行一个摄影项目:“我在这里拍一些照片,是我正在做的一个项目。”在之后的互动中,Sam与Latoya的互动表明了对那次互动的记忆,他问道“嗨,Latoya,你的项目进展如何?”她回答:“嗨,Sam,进展得很好!”

协调

生成式智能体角色互相协调。在霍布斯咖啡馆,Isabella Rodriguez打算在2月14日的下午5点到7点举办情人节派对。从这个种子开始,智能体开始在霍布斯咖啡馆或其他地方邀请朋友和顾客参加派对。然后,Isabella在13日下午装饰咖啡馆,为派对做准备。Maria是Isabella的亲密朋友和常客,她来到了咖啡馆。Isabella请求Maria帮助她为派对做装饰,而Maria同意了。Maria的角色描述提到她喜欢Klaus。当晚,Maria邀请她的暗恋对象Klaus参加派对,而他很高兴地接受了邀请。

情人节当天下午5点,包括Klaus和Maria在内的五个智能体角色来到霍布斯咖啡馆,享受派对的氛围。在这种情况下,最终用户只设置了Isabella举办派对的初始意图和Maria对Klaus的暗恋,社交行为(传播消息、装饰、邀请、到达派对并在派对上互动)是由智能体架构发起的。
在这里插入图片描述

生成式智能体架构

在这里插入图片描述
整体结构:如上图,智能体感知(perceive,比如小明在花园散步、小红7点吃了早餐)环境,所有感知都被保存在智能体经验的综合记录中,称为记忆流(memory stream)。基于它们的感知,智能体检索(retrieve)相关的记忆(retrieved memories),然后使用这些检索到的记忆来确定一个行为(act,比如做早餐)。这些检索到的记忆也被用来形成长期计划(plan,比如明天的计划),并产生更高层次的反思(reflect),这些都被输入到记忆流中以备将来使用。act、plan和reflect是通过提示大语言模型获得的结果

是不是有点知识库的感觉
Memory好比人的大脑一样

记忆和检索

在这里插入图片描述
通过Recency、Importance、Relevance三个维度来计算score,给每条记忆打分。用得分高的记忆来构建prompt。
在这里插入图片描述
Recency: 给最近访问过的内存对象赋一个更高的分数
Importance 通过给agent认为重要的内存对象分配更高的分数来区分普通记忆和核心记忆。例如,在房间里吃早餐这样的普通事件的重要性得分很低,而与另一半分手的重要性得分很高
Relevance : 我们使用语言模型来生成每个内存的文本描述的嵌入向量,通过向量计算相关程度,计算相关性,作为记忆的嵌入向量和查询记忆的嵌入向量之间的余弦相似度

反思

当只有原始的观察记忆时,生成式智能体很难进行泛化或推理。考虑这样一种情况,用户问Klaus Mueller:“如果你必须选择一个你认识的人与之共度一小时,你会选择谁?”只有观察性记忆的智能体只会选择和Klaus互动最频繁的人:他的大学宿舍邻居Wolfgang。不幸的是,Wolfgang和Klaus只是偶尔擦肩而过,没有深入的交流。更理想的回答需要智能体从Klaus在研究项目上花费的时间的记忆中进行泛化,生成一个更高层次的反思,即Klaus对研究充满热情,同时也能够认识到Maria在自己的研究中付出了努力(尽管在不同的领域),从而产生一个反思,即他们有共同的兴趣爱好。通过以下方法,当问及Klaus要和谁共度时光时,Klaus选择Maria而不是Wolfgang
在这里插入图片描述

对话原理

智能体在彼此互动时进行对话。我们通过智能体对彼此的记忆来生成他们的对话

[智能体概述描述]
现在是2023年2月13日下午4:56。
约翰·林的状态:约翰提前下班回到家。
观察结果:约翰看到Eddy在他的工作场所周围散步。
从约翰的记忆中总结相关的背景信息:
Eddy Lin是约翰的儿子。Eddy Lin正在为他的课程作曲。Eddy Lin喜欢在思考或听音乐时在花园里散步。
约翰正在询问Eddy关于他的作曲项目。他会对Eddy说什么?

结果是:“嘿,Eddy,你为课程的作曲项目进展如何?”从Eddy的角度来看,John开始对话被视为一个他可能想要做出反应的事件。因此,就像John一样,Eddy检索并总结了他与John的关系以及与John在对话中的最后一句话可能相关的记忆。如果他决定回应,我们将使用他总结的记忆和当前的对话历史来生成Eddy的话语:

[智能体概述描述]
现在是2023年2月13日下午4:56。
Eddy Lin的状态:Eddy正在他的工作场所周围散步。
观察结果:John正在与Eddy开始对话。
从Eddy的记忆中总结相关的背景信息:
John Lin是Eddy Lin的父亲。John Lin很关心Eddy Lin的学校工作,并且对了解更多。John Lin知道Eddy Lin正在进行一项音乐作曲。
以下是对话历史记录:
John: 嘿,Eddy,你为课程的作曲项目进展如何?
Eddy会如何回应John?

这将生成Eddy的回应:“嘿,爸爸,进展得很顺利。我一直在花园里散步,以便放松大脑并获得一些灵感。”使用相同的机制生成对话的继续,直到两个智能体中的一个决定结束对话。

从结构化的世界环境到自然语言,再回到结构化的世界环境

  • 反应大语言模型结构化能力,目前国内大模型还无法满足

伦理和社会影响

  • 风险:本身虚拟世界的社交就是错误的影响
  • 风险:生成代理可能加剧与生成人工智能相关的现有风险,例如深度伪造、虚假信息生成和定制诱导
  • 风险:过度依赖,开发人员或设计师可能会使用生成代理,从而取代人类和系统利益相关者在设计过程中的作用

代码解读

"""
File: gpt_structure.py
Description: Wrapper functions for calling OpenAI APIs.
"""
import json
import random
import openai
import time

from utils import *

openai.api_key = openai_api_key
openai.api_base = openai_api_base


def temp_sleep(seconds=0.1):
    time.sleep(seconds)


def ChatGPT_single_request(prompt):
    temp_sleep()

    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}]
    )
    return completion["choices"][0]["message"]["content"]


# ============================================================================
# #####################[SECTION 1: CHATGPT-3 STRUCTURE] ######################
# ============================================================================

def GPT4_request(prompt):
    """
    Given a prompt and a dictionary of GPT parameters, make a request to OpenAI
    server and returns the response.
    ARGS:
      prompt: a str prompt
      gpt_parameter: a python dictionary with the keys indicating the names of
                     the parameter and the values indicating the parameter
                     values.
    RETURNS:
      a str of GPT-3's response.
    """
    temp_sleep()

    try:
        completion = openai.ChatCompletion.create(
            model="gpt-4",
            messages=[{"role": "user", "content": prompt}]
        )
        return completion["choices"][0]["message"]["content"]

    except:
        print("ChatGPT ERROR")
        return "ChatGPT ERROR"


def ChatGPT_request(prompt):
    """
    Given a prompt and a dictionary of GPT parameters, make a request to OpenAI
    server and returns the response.
    ARGS:
      prompt: a str prompt
      gpt_parameter: a python dictionary with the keys indicating the names of
                     the parameter and the values indicating the parameter
                     values.
    RETURNS:
      a str of GPT-3's response.
    """
    # temp_sleep()
    try:
        completion = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": prompt}]
        )
        return completion["choices"][0]["message"]["content"]

    except:
        print("ChatGPT ERROR")
        return "ChatGPT ERROR"


def GPT4_safe_generate_response(prompt,
                                example_output,
                                special_instruction,
                                repeat=3,
                                fail_safe_response="error",
                                func_validate=None,
                                func_clean_up=None,
                                verbose=False):
    prompt = 'GPT-3 Prompt:\n"""\n' + prompt + '\n"""\n'
    prompt += f"Output the response to the prompt above in json. {special_instruction}\n"
    prompt += "Example output json:\n"
    prompt += '{"output": "' + str(example_output) + '"}'

    if verbose:
        print("CHAT GPT PROMPT")
        print(prompt)

    for i in range(repeat):

        try:
            curr_gpt_response = GPT4_request(prompt).strip()
            end_index = curr_gpt_response.rfind('}') + 1
            curr_gpt_response = curr_gpt_response[:end_index]
            curr_gpt_response = json.loads(curr_gpt_response)["output"]

            if func_validate(curr_gpt_response, prompt=prompt):
                return func_clean_up(curr_gpt_response, prompt=prompt)

            if verbose:
                print("---- repeat count: \n", i, curr_gpt_response)
                print(curr_gpt_response)
                print("~~~~")

        except:
            pass

    return False


def ChatGPT_safe_generate_response(prompt,
                                   example_output,
                                   special_instruction,
                                   repeat=3,
                                   fail_safe_response="error",
                                   func_validate=None,
                                   func_clean_up=None,
                                   verbose=False):
    # prompt = 'GPT-3 Prompt:\n"""\n' + prompt + '\n"""\n'
    prompt = '"""\n' + prompt + '\n"""\n'
    prompt += f"Output the response to the prompt above in json. {special_instruction}\n"
    prompt += "Example output json:\n"
    prompt += '{"output": "' + str(example_output) + '"}'

    if verbose:
        print("CHAT GPT PROMPT")
        print(prompt)

    for i in range(repeat):

        try:
            curr_gpt_response = ChatGPT_request(prompt).strip()
            end_index = curr_gpt_response.rfind('}') + 1
            curr_gpt_response = curr_gpt_response[:end_index]
            curr_gpt_response = json.loads(curr_gpt_response)["output"]

            # print ("---ashdfaf")
            # print (curr_gpt_response)
            # print ("000asdfhia")

            if func_validate(curr_gpt_response, prompt=prompt):
                return func_clean_up(curr_gpt_response, prompt=prompt)

            if verbose:
                print("---- repeat count: \n", i, curr_gpt_response)
                print(curr_gpt_response)
                print("~~~~")

        except:
            pass

    return False


def ChatGPT_safe_generate_response_OLD(prompt,
                                       repeat=3,
                                       fail_safe_response="error",
                                       func_validate=None,
                                       func_clean_up=None,
                                       verbose=False):
    if verbose:
        print("CHAT GPT PROMPT")
        print(prompt)

    for i in range(repeat):
        try:
            curr_gpt_response = ChatGPT_request(prompt).strip()
            if func_validate(curr_gpt_response, prompt=prompt):
                return func_clean_up(curr_gpt_response, prompt=prompt)
            if verbose:
                print(f"---- repeat count: {i}")
                print(curr_gpt_response)
                print("~~~~")

        except:
            pass
    print("FAIL SAFE TRIGGERED")
    return fail_safe_response


# ============================================================================
# ###################[SECTION 2: ORIGINAL GPT-3 STRUCTURE] ###################
# ============================================================================

def GPT_request(prompt, gpt_parameter):
    """
    Given a prompt and a dictionary of GPT parameters, make a request to OpenAI
    server and returns the response.
    ARGS:
      prompt: a str prompt
      gpt_parameter: a python dictionary with the keys indicating the names of
                     the parameter and the values indicating the parameter
                     values.
    RETURNS:
      a str of GPT-3's response.
    """
    temp_sleep()
    try:
        response = openai.Completion.create(
            model=gpt_parameter["engine"],
            prompt=prompt,
            temperature=gpt_parameter["temperature"],
            max_tokens=gpt_parameter["max_tokens"],
            top_p=gpt_parameter["top_p"],
            frequency_penalty=gpt_parameter["frequency_penalty"],
            presence_penalty=gpt_parameter["presence_penalty"],
            stream=gpt_parameter["stream"],
            stop=gpt_parameter["stop"], )
        return response.choices[0].text
    except:
        print("TOKEN LIMIT EXCEEDED")
        return "TOKEN LIMIT EXCEEDED"


def generate_prompt(curr_input, prompt_lib_file):
    """
    Takes in the current input (e.g. comment that you want to classifiy) and
    the path to a prompt file. The prompt file contains the raw str prompt that
    will be used, which contains the following substr: !<INPUT>! -- this
    function replaces this substr with the actual curr_input to produce the
    final promopt that will be sent to the GPT3 server.
    ARGS:
      curr_input: the input we want to feed in (IF THERE ARE MORE THAN ONE
                  INPUT, THIS CAN BE A LIST.)
      prompt_lib_file: the path to the promopt file.
    RETURNS:
      a str prompt that will be sent to OpenAI's GPT server.
    """
    if type(curr_input) == type("string"):
        curr_input = [curr_input]
    curr_input = [str(i) for i in curr_input]

    f = open(prompt_lib_file, "r")
    prompt = f.read()
    f.close()
    for count, i in enumerate(curr_input):
        prompt = prompt.replace(f"!<INPUT {count}>!", i)
    if "<commentblockmarker>###</commentblockmarker>" in prompt:
        prompt = prompt.split("<commentblockmarker>###</commentblockmarker>")[1]
    return prompt.strip()


def safe_generate_response(prompt,
                           gpt_parameter,
                           repeat=5,
                           fail_safe_response="error",
                           func_validate=None,
                           func_clean_up=None,
                           verbose=False):
    if verbose:
        print(prompt)

    for i in range(repeat):
        curr_gpt_response = GPT_request(prompt, gpt_parameter)
        if func_validate(curr_gpt_response, prompt=prompt):
            return func_clean_up(curr_gpt_response, prompt=prompt)
        if verbose:
            print("---- repeat count: ", i, curr_gpt_response)
            print(curr_gpt_response)
            print("~~~~")
    return fail_safe_response


def get_embedding(text, model="text-embedding-ada-002"):
    text = text.replace("\n", " ")
    if not text:
        text = "this is blank"
    return [-0.006929283495992422, -0.005336422007530928]
    return openai.Embedding.create(
        input=[text], model=model)['data'][0]['embedding']


if __name__ == '__main__':
    gpt_parameter = {"engine": "text-davinci-003", "max_tokens": 50,
                     "temperature": 0, "top_p": 1, "stream": False,
                     "frequency_penalty": 0, "presence_penalty": 0,
                     "stop": ['"']}
    curr_input = ["driving to a friend's house"]
    prompt_lib_file = "prompt_template/test_prompt_July5.txt"
    prompt = generate_prompt(curr_input, prompt_lib_file)


    def __func_validate(gpt_response):
        if len(gpt_response.strip()) <= 1:
            return False
        if len(gpt_response.strip().split(" ")) > 1:
            return False
        return True


    def __func_clean_up(gpt_response):
        cleaned_response = gpt_response.strip()
        return cleaned_response


    output = safe_generate_response(prompt,
                                    gpt_parameter,
                                    5,
                                    "rest",
                                    __func_validate,
                                    __func_clean_up,
                                    True)

    print(output)

  • 代码块中主要使用chatgpt中大模型格式化数据的能力进行指令汇总,一般模型不具有这种能力

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

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

相关文章

window如何实时刷新日志文件

1 安装windows git 下载地址&#xff1a;Git - Downloading Package (git-scm.com) 2 打开git bash 输入tail.exe -f 日志文件路径

yo!这里是Linux权限入门理解

目录 前言 权限概念 权限管理 分类 1.用户 2.文件&&目录 表示 设置 1.chmod指令 2.chown指令 3.chgrp指令 4.umask指令 粘滞位 后记 前言 对于Linux基本指令&#xff0c;基本上就是操作文件或者目录&#xff0c;但是&#xff0c;是谁可以操作文件或目录&…

8个月打磨,打造出的全能工具箱,让你事半功倍!

这款工具叫即时工具&#xff0c;目前有网页端和客户端可以下载至本地离线使用&#xff0c;区别在于客户端采用原生适配性能更好&#xff0c;网页端需要上传至服务器或浏览器内部处理。 体验地址&#xff1a;点击直达 一、为什么会开发这个工具 综合性和多功能性&#xff1a;…

MySQL数据库 索引、事务、储存引擎

索引 索引的概念 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址&#xff08;类似于C语言的链表通过指针指向数据记录的内存地址&#xff09;。 使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索引表找…

harbor升级后镜像项目访问无权限问题

一、问题背景 将环境中现运行的harbor版本升级到2.6.2版本&#xff0c;相关同事升级完&#xff0c;发现有部分镜像项目点进去报无权限问题&#xff0c;镜像项目无法使用&#xff0c;但是也有部分项目是可以正常提供使用的。 二、问题处理过程 1、根据报错反馈没权限&#xff…

【Flutter】Flutter 使用 device_info_plus 获取设备的制造商、型号等信息

【Flutter】Flutter 使用 device_info_plus 获取设备的制造商、型号等信息 文章目录 一、前言二、安装和基本使用三、实际业务中的用法四、完整示例五、总结 一、前言 在这篇博客中&#xff0c;我将为你介绍一个非常实用的 Flutter 插件&#xff1a;device_info_plus。这个插件…

基于SSM+vue框架的校园代购服务订单管理系统源码和论文

基于SSMvue框架的校园代购服务订单管理系统源码和论文070 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 在新发展的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&am…

调查问卷平台哪家好?

在如今的数字化时代&#xff0c;问卷调查已成为企业和组织了解顾客需求、员工满意度以及市场趋势的重要工具。然而&#xff0c;在众多的在线调查工具中&#xff0c;为什么我们要选择Zoho Survey&#xff1f; 一、强大的功能和灵活的问卷设计 1、多种问卷题型&#xff1a; Zo…

浪潮信息 KeyarchOS 助力 IT 企业安全管理业务完成 CentOS 迁移替换 | 龙蜥案例

前言 安全稳定是操作系统永恒的追求&#xff0c;某知名 IT 企业的安全管理业务服务于公司多个业务&#xff0c;涵盖代码安全管理平台、数字签名平台以及内部使用的多个研发平台&#xff0c;其底层运行着 CentOS 7 操作系统。随着 CentOS 各操作系统版本陆续停服&#xff0c;将…

掌握指针和数组:经典笔试题攻略(万字详解)

&#x1f341;博客主页&#xff1a;江池俊的博客 &#x1f4ab;收录专栏&#xff1a;C语言刷题专栏 &#x1f4a1;代码仓库&#xff1a;江池俊的代码仓库 &#x1f3aa;我的社区&#xff1a;GeekHub &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文章目录 前…

最新docker多系统安装技术

在Ubuntu操作系统中安装Docker 在Ubuntu操作系统中安装Docker的步骤如下。 1&#xff0e;卸载旧版本Docker 卸载旧版本Docker的命令如下&#xff1a; $ sudo apt-get remove docker docker-engine docker.io 2&#xff0e;使用脚本自动安装 在测试或开发环境中&#xff0…

聊聊敏捷实践的“个体与交互”

这是鼎叔的第七十二篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。 敏捷宣言有重要的一句话&#xff1a;个体和交互胜过过程和工具。作为工程师&#xff0c;…

【实训项目】“享学”APP设计

1.设计摘要 随着高等教育普及化程度提高&#xff0c;国家对大学生的要求也越来越高&#xff0c;在学习过程中总会遇到各种各样的阻碍&#xff0c;很多学生苦于找不到资料&#xff0c;苦于找不到适合自己的资料&#xff0c;苦于找不到能让自己提高的资料。不善交际&#xff0c;…

基于Java+SpringBoot+Vue前后端分离校园失物招领系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

简单js逆向案例(1)

文章目录 声明模块分析完整代码python实现js扣代码实现 结尾 声明 本文章中所有内容仅供学习交流&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 模块 pip install Py…

Properties 中文配置乱码问题解决

file->setting->editor-> file encoding -> 选择Default encoding for properties files-> ISO-8859-1

springcloud3 GateWay章节-Nacos+gateway动态路由负载均衡4

一 工程结构 1.1 工程 1.2 搭建gatewayapi工程 1.pom文件 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><!--gateway--&g…

HTML的label标签有什么用?

当你想要将表单元素&#xff08;如输入框、复选框、单选按钮等&#xff09;与其描述文本关联起来&#xff0c;以便提供更好的用户界面和可访问性时&#xff0c;就可以使用HTML中的<label>标签。<label>标签用于为表单元素提供标签或标识&#xff0c;使用户能够更清…

ssm端游游戏账号销售管理系统源码和论文

ssm端游游戏账号销售管理系统源码和论文069 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面…

如何更改自己电脑上的microsoft账户?

方法/步骤 1 正常我们在登录时就只有一个本地账户或者是微软账户&#xff0c;没有地方可以输入新的账号。那怎么样才能切换到其他账户或者是使用新的账户呢。 首先我们登录进入系统。然后打开用户账户添加一个新的账户。 在键盘上按winr键打开运行输入&#xff0c;输入netpl…