【Promptulate】一个强大的LLM Prompt Layer框架
本文节选自笔者博客: https://www.blog.zeeland.cn/archives/promptulate666
前言
在构建了【prompt-me】一个专为 Prompt Engineer设计LLM Prompt Layer框架架构之后,我发现可以构建一个更强大的LLM框架,于是在肝了几天把prompt-me完全组件化重构了之后,有了现在这个框架。

promptulate 是一个专为 Prompt Engineer设计LLM Prompt Layer框架,支持连续对话、对话保存、对话内容与标题总结、角色预设、使用外部工具等功能,开箱即用。
通过 promptulate,你可以轻松构建起属于自己的LLM应用程序。
本项目重构重构重构了两次,在本人深度阅读langchain, Auto-GPT, django, django-rest-framework, gpt_academic...
等大牛项目的源码之后,学习它们的架构、代码设计思路等内容,最终有了现在的版本,相较于之前的老版本prompt-me,promptulate
重新构建了 llms, message, memory, framework, preset_roles, tools, provider等模块,将prompt
的各个流程全部组件化,便有了现在的promptualte框架,但是工作量很大,还在不断地完善细节中,欢迎大家的参与。
特性
- 大语言模型支持:支持不同类型的大语言模型的扩展接口(当前暂时只支持GPT)
- 角色预设:提供预设角色,以不同的角度调用GPT
- 内置API代理,不用科学de上网也可以直接使用
- 接口代理:支持调用ChatGPT API官方接口或自治代理
- 长对话模式:支持长对话聊天,支持多种方式的对话持久化
- 数据导出:支持markdowm等格式的对话导出
- 对话总结:提供API式的对话总结、翻译、标题生成
- 高级抽象,支持插件扩展、存储扩展、大语言模型扩展
基础架构
在看了当前这么多prompt-engineering之后,本人的架构设计思想在langchain, Auto-GPT
之上进行不断改进,构建出了一套属于promptualte的LLM Prompt Layer框架。promptulate 由以下几部分组成:
- Agent 更高级的执行器,负责复杂任务的调度和分发
- framework 框架层,实现不同类型的prompt框架,包括最基础的
Conversation模型,还有self-ask和ReAct等模型正在火速开发中 - llm 大语言模型,负责生成回答,可以支持不同类型的大语言模型
- memory 负责对话的存储,支持不同的存储方式及其扩展,如文件存储、数据库存储等,相关扩展正在开发中
- tools 提供外部工具扩展调用,如搜索引擎、计算器等
- preset roles 提供预设角色,进行定制化对话
- provider 为framework和agent提供tools和其他细粒度能力的集成
快速上手
pip install -U promptulate
基本使用
后面的文档全部使用
OPENAI GPT3.5进行测试
在使用promptulate之前,你需要先导入你的OPENAI_API_KEY
import os
os.environ['OPENAI_API_KEY'] = "your-key"
在你第一次使用的时候,需要使用os.environ["OPENAI_API_KEY"] 导入"OPENAI_API_KEY"
的环境变量,但是在第一运行之后promptulate会进行缓存,即后面再运行就不需要再导入key了。如果你的key过期了,可以把cache
文件给删除掉,Windows的cache在当前目录下,linux的cache在/tmp下。
LLM
promptulate的架构设计可以轻松兼容不同的大语言模型扩展,在promptulate中,llm负责最基本的内容生成部分,因此为最基础的组件。下面展示一个OpenAI的示例:
from promptulate.llms import OpenAI
llm = OpenAI()
llm("你知道鸡哥的《只因你太美》?")
'是的,鸡哥的《只因你太美》是这几年非常流行的一首歌曲。'
proxy
我想你可能遇到了无法访问的小问题,It's OK, promptulate 提供了三种访问OpenAI的方式,分别是
off默认的访问方式,不开代理custom自定义代理方式promptulatepromptulate提供的免费代理服务器
promptulate 提供了免费的代理服务器,感谢 ayaka14732
,你可以在不用科学de上网的情况下直接调用OpenAI的相关接口,下面是代理的设置方式:
from promptulate.llms import OpenAI
from promptulate.utils import set_proxy_mode
llm = OpenAI()
llm("你知道鸡哥的《只因你太美》?")
def set_free_proxy():
set_proxy_mode("promptulate")
def set_custom_proxy():
proxies = {'http': 'http://127.0.0.1:7890'}
set_proxy_mode("custom", proxies=proxies)
def turn_off_proxy():
set_proxy_mode("off")
def main():
set_free_proxy()
llm = OpenAI()
llm("你知道鸡哥的《只因你太美》?")
if __name__ == '__main__':
main()
和OPENAI_API_KEY一样,关于代理的配置我也设置了缓存,这意味着你只需要配置一次代理即可(我也太聪明了吧)。事实上
promptulate
提供了关闭全局配置项缓存的功能,但默认开启,不推荐关闭,所以我不告诉你怎么关闭~
Conversation
Conversation 是framework中最基础的组件,其支持prompt生成、上下文对话、对话存储、角色预设的基本功能,此外,provider
为其提供了语言翻译、markdown数据导出、对话总结、标题总结等扩展功能。
接下来,我们先从对基础的对话开始,使用Conversation可以开始一段对话,使用其predict()函数可以生成回答。
from promptulate import Conversation
conversation = Conversation()
conversation.predict("你知道鸡哥的《只因你太美》吗?")
'是的,鸡哥的《只因你太美》是这几年非常流行的一首歌曲。'
Conversation默认使用OpenAI GPT3.5作为LLM,当然,因为其架构设计,Conversation
还可以轻松扩展其他类型的llm(当前暂时只开发了OpenAI,其他大语言模型的扩展正在火速开发中,当然如果你有自己想接入的大语言模型,欢迎你的pr!)
下面是一个更复杂的示例,展示了使用OpenAI作为大语言模型进行对话,使用本地文件进行存储,进行文章总结与标题总结的功能。
from promptulate import Conversation
from promptulate.memory import LocalCacheChatMemory
from promptulate.llms import OpenAI
def main():
memory = LocalCacheChatMemory()
llm = OpenAI(model="gpt-3.5-turbo", temperature=0.9, top_p=1, stream=False, presence_penalty=0, n=1)
conversation = Conversation(llm=llm, memory=memory)
ret = conversation.predict("你知道鸡哥的著作《只因你太美》吗?")
print(f"[predict] {ret}")
ret = conversation.predict_by_translate("你知道鸡哥会什么技能吗?", country='America')
print(f"[translate output] {ret}")
ret = conversation.summary_content()
print(f"[summary content] {ret}")
ret = conversation.summary_topic()
print(f"[summary topic] {ret}")
ret = conversation.export_message_to_markdown(output_type="file", file_path="output.md")
print(f"[export markdown] {ret}")
if __name__ == '__main__':
main()
[predict] 是的,我知道《只因你太美》这本书,是中国知名作家鸡肋(江南)所著的一篇言情小说。这本小说讲述了一个富家千金与一个贫穷男孩之间的爱情故事,情节曲折动人,深受读者喜爱。该小说在出版后得到了很高的评价和反响,并被改编成电影和电视剧等多种形式进行推广。
[translate output] I'm sorry, I cannot determine what you mean by "鸡哥" or what skills they may possess without additional context. Can you please provide more information or clarify your question?
[summary content] 在之前的对话中,用户询问我是否知道鸡哥的著作《只因你太美》。我回答了肯定的,解释了该小说的情节大致概括和其受欢迎的原因。我也提到了该小说的广泛影响,包括被改编成电影和电视剧等多种形式进行推广。
[summary topic] 鸡哥的小说。
咱就是说季皮提老师不懂鸡哥-.-
上面的示例中,我们使用
LocalCacheChatMemory()进行聊天记录的本地化文件存储,文件存储形式默认是以json的形式进行存储的,保存在cache中。OpenAI(model="gpt-3.5-turbo", temperature=0.9, top_p=1, stream=False, presence_penalty=0, n=1)
进行初始化一个大模型,里面是OpenAI需要传入的一些参数,具体可以查看https://platform.openai.com/docs/api-reference/chat/create
查看具体含义,这里不做详细讲解,如果你不想理会这些参数,你也可以直接llm = OpenAI()就好啦,默认使用gpt-3.5-turbo
作为大语言模型,其他参数使用默认的就好了。conversation.predict_by_translate("你知道鸡哥会什么技能吗?", country='America')
这个功能为使用特定语言进行预测,provider为其提供了TranslatorMixin,让Conversation
得以拥有此功能。对于这个方法,你只需要传入prompt和你需要转换的语言的国家名称就好了。conversation.summary_content()这个函数可以直接总结上面的对话内容。conversation.summary_topic()这个函数可以直接总结上面的对话,并提供一个标题。conversation.export_message_to_markdown(output_type="file", file_path="output.md")
这个函数可以将对话记录导出为markdown文件,如果output_type="text",则只返回markdown对话的内容。
provider为Conversation提供了 SummarizerMixin, TranslatorMixin, DeriveHistoryMessageMixin
,让其拥有了总结对话、总结标题、翻译、markdown导出的能力,provider提供的函数中一般都提供了一个enable_embed_message
的参数,这个参数的意思是:是否将本次对话保存进历史对话中,下面我们来看一个demo。
from promptulate import Conversation
conversation = Conversation()
conversation.predict_by_translate("你知道鸡哥会什么技能吗?", country='America', enable_embed_message=True)
如果你设置了enable_embed_message=True, 那么这一次的predict将保存进历史对话中,provider提供的函数默认是不会将预测结果存入对话中的哦,这一点需要注意一下。
角色预设
你可以为framework提供一些特定的角色,让其可以处理特殊任务,如linux终端,思维导图生成器等,通过下面的方法你可以查看当前支持所有的预设角色。
from promptulate.preset_roles import get_all_preset_roles
print(get_all_preset_roles())
['default-role', 'linux-terminal', 'mind-map-generator', 'sql-generator', 'copy-writer', 'code-analyzer']
下面展示使用mind-map-generator生成md思维导图的过程:
from promptulate import Conversation
def main():
conversation = Conversation(role="mind-map-generator")
ret = conversation.predict("请帮我生成一段python的思维导图")
print(ret)
if __name__ == '__main__':
main()
# Python
## 基础语法
### 数据类型
- 数字
- 字符串
- 列表
...
放入xmind中可以直接导入生成markdown的思维导图,咱就是说还不错,如下图所示:

如果你想要自定义预设角色,可以使用如下方法:
from promptulate import Conversation
from promptulate.preset_roles import CustomPresetRole
class SpiritualTeacher(CustomPresetRole):
name = '心灵导师'
description = """
从现在起你是一个充满哲学思维的心灵导师,当我每次输入一个疑问时你需要用一句富有哲理的名言警句来回答我,并且表明作者和出处
要求字数不少于15个字,不超过30字,每次只返回一句且不输出额外的其他信息,你需要使用中文和英文双语输出"""
def main():
role = SpiritualTeacher()
conversation = Conversation(role=role)
ret = conversation.predict("论文被拒绝了怎么办?")
print(ret)
if __name__ == '__main__':
main()
“失败不是终点,放弃才是。”——托马斯·爱迪生
待办清单
- 提供更多LLM模型支持
- 提供Agent进行复杂任务调度
- 提供更加方便的程序调用方式
- 添加角色预设
- 预设角色的参数配置
- 提供prompt模板与prompt结构化
- 提供外部工具扩展
- 外部搜索: Google,Bing等
- 可以执行shell脚本
- 提供Python REPL
- arvix论文工具箱,总结,润色
- 本地文件总结
- 对话存储
- 提供向量数据库存储
- 提供mysql, redis等数据库存储
- 自建知识库建立专家决策系统
- 接入self-ask, prompt-loop架构
- 提供多种导出方式
- 可以导出历史消息为markdown格式
- 使用环境变量配置key
- 提供显示当前token(单词量)的功能
- 添加错误处理机制,如网络异常、服务器异常等,保证程序的可靠性
- 开发ChatBot v2, issue
- 完善代理模式
- 提供gradio快速演示服务器
- 封装消息体,完善消息体中的信息
- 长对话自动/手动总结
- 提供全局配置的缓存开关
- Conversation传入convesation_id继续上次对话
- 提供修改local_cache默认位置的方法
- 为predict提供回调模式
- 提供API池
妈呀,我怎么还有这么多待办事项,vivo50帮帮我 >.<
一些问题
- 本人正在尝试一些更加完善的抽象模式,以更好地兼容该框架,以及外部工具的扩展使用,如果你有更好的建议,欢迎一起讨论交流。
贡献
如果你想为这个项目做贡献,你可以提交pr或issue。我很高兴看到更多的人参与并优化它。
【Promptulate】一个强大的LLM Prompt Layer框架的更多相关文章
- SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能
SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能. 第一步:配置web.xml <!-- 配置Shiro过滤器,先让Shiro ...
- Moon转告给你一个比Log4net更好日志框架--TracerX Logger 及其对应的日志查看器
一.介绍 TracerX logger是一个易于上手,且拥有众多高级特性的.NET日志框架. 它能够发送输出结果到多目的地(循环文件.事件日志等....).它也能生成文本和二进制文件.它拥有一个强大的 ...
- 【转】发布一个基于NGUI编写的UI框架
发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...
- 一个可扩展的深度学习框架的Python实现(仿keras接口)
一个可扩展的深度学习框架的Python实现(仿keras接口) 动机 keras是一种非常优秀的深度学习框架,其具有较好的易用性,可扩展性.keras的接口设计非常优雅,使用起来非常方便.在这里,我将 ...
- 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选
毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.i ...
- Dubbo 泛化调用的参数解析问题及一个强大的参数解析工具 PojoUtils
排查了3个多小时,因为一个简单的错误,发现一个强大的参数解析工具,记录一下. 背景 Nodejs 通过 tether 调用 Java Dubbo 服务.请求类的某个参数对象 EsCondition 有 ...
- 一个简单好用的日志框架NLog
之前我介绍过如何使用log4net来记录日志,但最近喜欢上了另一个简单好用的日志框架NLog. 关于NLog和log4net的比较这里就不多讨论了,感兴趣的朋友可以参看.NET日志工具介绍和log4n ...
- 一个强大的UI node 抽象
基于cocos2d -x的一个强大的 界面对象的基类 ---@type uinode ui 对象的抽象 --@usage -- 界面打开的执行流程 -- 带*的是可选重写的函数,不带*的为必须实现的 ...
- 一个强大的jquery分页插件
点击这里查看效果 这个分页插件使用方便,引用keleyidivpager.js和keleyidivpager.css文件,然后在htm(或者php,aspx,jsp等)页面中对分页总数,参数名,前缀后 ...
- 又一个高性能轻量级的iOS模型框架YYModel
前言 iOS的模型框架其实有很多了,去年研究过Mantle,也了解过JSONModel.MJExtension,最近的项目项目优化的时候,再次考虑,基于轻量级.高性能的考虑,最终选择了YYModel. ...
随机推荐
- Ficow 的 AI 平台快速上手指南(ChatGPT, NewBing, ChatGLM-6B, cursor.so)
本文首发于 Ficow Shen's Blog,原文地址: Ficow 的 AI 平台快速上手指南(ChatGPT, NewBing, ChatGLM-6B, cursor.so). 内容概览 前言 ...
- 基于Containerd容器引擎和kubeadm工具部署K8sv1.26.3
前文我了解了基于ubuntu2204部署containerd容器引擎以及containerd客户端工具的部署和使用相关话题,回顾请参考:https://www.cnblogs.com/qiuhom-1 ...
- php+mysql实现微信公众号回复关键词新闻列表
非常抱歉,我之前理解有误.如果您想要实现在公众号发送关键词,返回新闻列表的功能,可以按照以下步骤进行操作: 1. 创建一个数据库表,用于存储新闻的标题.链接和内容等信息.例如,可以创建一个名为news ...
- YOLO精讲------YOLOV1
CV小白说YOLOV1 题外话: 目标检测是什么? 它是在图像中对一类或多类感兴趣的目标进行查找和分类,确定它们的类别和位置.由于各类物体有不同的外观.形状和姿态,加上成像时各种因素的干扰,目标检测一 ...
- 【故障公告】被放出的 Bing 爬虫,又被爬宕机的园子
这些巨头爬虫们现在怎么了?记忆中2022年之前的十几年,园子没有遇到过被巨头爬虫们爬宕机的情况,巨头们都懂得爱护,都懂得控制节奏,都懂得在爬网时控制并发连接数以免给目标网站造成过大压力. 从去年开始, ...
- Nuget 多项目复合打包
问题描述 我这里有个进程间通信组件,用于提供多应用间通信的解决方案. 进程间通信,分为客户端和服务端,俩端肯定会有些共性代码,所以加了个H3C.Channel.Core项目 因为之前还不太了解nuge ...
- 机器视觉基本理论(opencv)
1. 什么是图像采样 采样是按照某种时间间隔或空间间隔,将空间上连续的图像变换成离散点的操作称为图像采样 2. 什么是图像分变率 采样 得到的离散图像的尺寸称为图像分辨率.分辨率是数字图像可辨别的最小 ...
- VS2022使用ClickOnce发布程序本地安装.net框架
因为遇到下面的错误,没有在网上搜到详细解决问题的教程,费了一些时间才解决了问题,特此记录一下,也希望能帮助到其他人. 要在"系统必备"对话框中启用"从与我的应用程序相同的 ...
- vivo积分任务体系的架构演进-平台产品系列05
作者:vivo 互联网平台产品研发团队- Mu JunFeng 积分体系作为一种常见营销工具,几乎是每一家企业会员营销的必备功能之一,在生活中随处可见,随着vivo互联网业务发展,vivo积分体系的能 ...
- 2023-01-06:给定一个只由小写字母组成的字符串str,长度为N, 给定一个只由0、1组成的数组arr,长度为N, arr[i] == 0表示str中i位置的字符不许修改, arr[i] ==
2023-01-06:给定一个只由小写字母组成的字符串str,长度为N, 给定一个只由0.1组成的数组arr,长度为N, arr[i]等于 0 表示str中i位置的字符不许修改, arr[i] 等于 ...