|
作者:donxGPTs全景解析GPTs是什么GPTs是OpenAI在2023年11月发布的新版本,具有可定制性和完成特定任务的强大功能。它提供了一种新的方式来使用ChatGPT,可以让用户根据自己的需求定制化,并与其他用户共享。以下是OpenAI对它的能力介绍。YoucannowcreatecustomversionsofChatGPTthatcombineinstructions,extraknowledge,andanycombinationofskills.(现在您可以创建定制版的ChatGPT,将指令、额外知识和任意技能组合起来。)GPTs提供了一种更智能、更个性化的体验,无需每次都进行教育,使用户能够更快地获得答案。它可以通过组合指令、额外知识和任意技能,来适应各种场景。用户可以通过OpenAI的平台创建自己的GPT,并与其他用户共享。但是GPTs提供的方式是让所有人都可以得到定制版的ChatGPT,用户可以根据自己的生活,工作,学习等不同的场景,制定适合自己的ChatGPT,并且可以和其他人进行共享。任何人都可以通过OpenAI的平台搭建自己的GPTs,用户不需要懂得编程或者技术,只要拥有自己的idea,就可以创建属于自己的GPTs。创建GPT的过程简单且直观。用户可以通过对话形式,为GPT提供指令和额外的知识库,然后选择所需的能力,例如联网、绘图、分析数据等。这可以在OpenAI的搭建平台上进行尝试。例如,OpenAI提供了如下一些GPTs,例如数据分析GPTs:支持上传文件,并且执行代码进行数据分析GameTimeGPTs:支持对桌游或者卡牌游戏进行解释等OpenAI提供了GPTs商店(暂时还没有第三方的GPTs)方便用户进行GPTs的分享和使用。GPTs的引入方便了用户可以更大限度地使用OpenAIChatGPT的能力。可以快速地根据自己的需求定制ChatGPTOpenAI相信最好的GPTs,肯定是由社区创建的,所以它选择成为一个平台,只有最终的基础的插件或者功能它会开发,其他的能力均由开发者研发。开发者可以将将GPT和内部数据库等进行连接,从而获取数据企业版用户可以创建内部的GPTs构建一个完整的GPTs应用登陆OpenAI网站,选择Explore,然后再MyGPTs中选择createaGPTs.有两种方式可以进行GPTs的创建:通过对话的方式进行,选择Create通过配置的方式进行,选择Configure只需要将需要的配置进行设置,就能得到一个想到的GPTs的能力。例如下面设置的一个游戏GPTs,我们通过配置,使得GPT可以进行数据分析,并且可以使用WebBrowsing:网页浏览能力CodeInterpreter:代码编写以及执行能力下图是这个数据分析助手的一个demo情况,用户可以在两三分钟内快速实现一个AI助手。GPTs的问题与漏洞GPTs安全性存在一定的问题,网上有针对GPTs提示词泄露攻击,并且可以得到结果。具体可以查看OpenAI的GPTs提示词泄露攻击与防护实战GPTs暂无私有化部署,并且在微软AzureAPI中不支持AI的数据安全问题是无法保证的,目前有传言认为Sam的出走是因为在产品商业化和AI安全性的选择导致的(参考)。AssistantsAPI 全景解析AssistantsAPI允许用户在自己的应用中通过API实现类似GPTs的AI助理,目前支持的能力和GPTs一样(截止2023年11月12日),允许接入三种不同类型的tools:代码解释器(CodeInterpreter)知识库集成(Retrieval)函数调用(Functioncalling)通过构建AI助手,用户可以通过指令(instructions)设置助手的角色和能力。然后,AI助手将利用其强大的大语言模型能力、各种工具(tools)和知识库来回答用户的问题。AssistantsAPI 实践案例用户可以通过Assistantplayground进行AssistantsAPI的探索,参考以下教程使用API进行AIAssistant集成。通常进行AssistantsAPI集成需要一下四个步骤:首先创建一个AI助手(Assistant)。通过自定义指令(custominstructions)进行AI助手能力定义,实现AI助手的形象和能力定位。选择基础模型,可以选择GPT-3.5、GPT-4等作为基础模型。选择扩展能力tools例如codeinterpreter,retrieval以及其他的functioncall工具。创建一个对话(Thread)进行一个交流。在对话中传入消息(Messages),进行提问。在对话中进行执行(Run),AIAssistant会自动运行相关的tools。下面的例子会一步一步进行AIAssistant的构建。步骤1:创建一个AI助手一个AIassistant可以通过下面的几个参数进行配置:指令(Instructions):针对AI助手和模型,定制他们的表现和响应行为。模型(Model):提供了各种供选择的GPT-3.5或者GPT-4模型,包括自己进行精细调校的模型。如果希望使用信息检索工具(Retrievaltool),则需要采用gpt-3.5-turbo-1106或者gpt-4-1106-preview模型。工具(Tools): AssistantAPI支持使用OpenAI自行开发的CodeInterpreter编码解释器以及Retrieval召回工具。函数(Functions):API支持用户使用自定义的函数作为额外工具使用,类似OpenAI的functioncalling特性。在这个例子中,我们会创建一个自己的数学导师,使用到CodeInterpreter能力:# Upgrade to ython SDK v1.2 with pip install --upgrade openaiassistant = client.beta.assistants.create( name="Math Tutor", # 助手的名字 instructions="You are a personal math tutor. Write and run code to answer math questions.", #助手能力 tools=[{"type": "code_interpreter"}], #助手的工具 model="gpt-4-1106-preview" #模型选择)步骤2: 创建一个对话Thread一个Thread就代表了一个对话。OpenAI建议每个用户在开始对话的时候都创建一个Thread,把所有用户相关的内容和文件都通过在Thread创建Message完成。可以将Thread理解为与AI助手创建的一个对话窗口,所有的对话行为都在这个Thread中进行。thread = client.beta.threads.create()Threads本身并无大小限制,因此你可以在单个Thread对话中发送任意数量的消息(Messages)。API会自动对请求的消息进行适当的处理,以确保请求满足模型的最大窗口长度限制,如通过截断等方式进行调整。步骤3:在对话(Thread)中传入消息(Message)一个消息可以包含用户的文本输入,还有可能包含用户上传的文件。尽管目前还不支持,但OpenAI将在不久的将来添加这一功能。message = client.beta.threads.messages.create( thread_id=thread.id, #需要传入的Thread ID role="user", content="I need to solve the equation `3x + 11 = 14`. Can you help me?")如果现在你展示在对话Thread中的所有消息,你会看到这条消息被加入到了对话中:{ "object": "list", "data": [ { "created_at": 1696995451, "id": "msg_4rb1Skx3XgQZEe4PHVRFQhr0", "object": "thread.message", "thread_id": "thread_34p0sfdas0823smfv", "role": "user", "content": [{ "type": "text", "text": { "value": "I need to solve the equation `3x + 11 = 14`. Can you help me?", "annotations": [] } }], ...步骤4:执行AI助手为了得到AI助手的结果,你需要创建一个Run对象,这使得AI助手可以获取对话的消息,并决定是使用工具(tools)回答用户的问题,还是仅仅依赖模型自身的能力进行问题解答。当AI得到答案,会在对话(Thread)的消息列表中加入角色(*role="assistant"*)的一个回复。run = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id, instructions="Please address the user as Jane Doe. The user has a premium account.")步骤5:展示AI助手的回复当我们需要获取AI回复的时候,可以对Run对象进行不断的查询,获取当前执行的状态。run = client.beta.threads.runs.retrieve( thread_id=thread.id, run_id=run.id)当状态码==completed时,代表AI已经完成回复,并且可以在Thread中看到AI的回答。messages = client.beta.threads.messages.list( thread_id=thread.id)最后我们就可以把内容展示给用户,下面是一个例子。AI给出了两个回答(role==assistant)可以通过运行步骤RunSteps,获取执行的中间状态,从而提供给用户中间结果以及使用的tools等信息。步骤*layground今天调试和测试开发者可以在Playground中进行调试和测试,具体如下,其具体的能力和GPTs比较相似,只是可以看到更多的debug信息。也是可视化的具体界面。AssistantsAPI工作机制剖析AssistantAPI的目标是帮助开发者更高效地开发出功能强大的AI助手,这些助手可以有效地利用OpenAI提供的多项能力以及用户自身构建的工具。AI助手可以调用OpenAI的模型,并通过特定的指令来定义助手的行为特性和能力。AI助手可以同时调用多个工具tools,这些工具可以是OpenAI自己开发的工具,例如like Codeinterpreter 和 Knowledgeretrieval 也可以是用户自己通过 Functioncalling自己实现的工具。这样,AI助手就能拓宽其解决问题的能力范围。AI助手可以访问持久化的对话,新引入的对话Thread功能简化了AI应用的对话管理工作。用户只需要创建一次对话(Thread),就可以在后续快速地访问并与其进行对话,并轻松获取答案,这样就无需再关心模型对对话窗口的限制。AI助手可以访问多种类型的文件。AI助手可以在初始化创建时访问文件,或是在对话初始化的时候获取文件。它也可以在使用工具时创建新的文件,然后在之后的调用中引用这些文件。AIAssistant的重要对象概念从我们上述的讲解内容中,我们可以很清楚,AI助手API的调用主要由Assistant、Thread、Message、Run和RunStep这五个对象组成对象(OBJECT)含义助手对象(Assistant)调用OpenAI模型的任务型AI,该AI具备访问tools的能力对话(Thread)用户和AI之间的对话。Thread对话存储消息,并且自动处理文本长度超出限制的问题消息(Message)消息由用户或者AI产生,可以包含文本,(暂时不支持),或者文件。消息在一个Thread对话中以有序列表形式存储执行(Run)通过AI助手对某个对话进行显式执行。AI助手根据自身的配置信息和Thread中的消息内容,调用不同的工具(tools),从而得出回复。执行得到的结果会被存储在Thread的消息中,作为AI的回复执行步骤(RunStep)执行(Run)的中间过程详细记录。包括AI使用了哪些tool,或者产生了哪些消息。这个对象可以帮助开发者理解AI如何得出最终的结果创建一个AIAssistant对象创建一个AI助手对象非常简单,只需要指定使用的语言model,然后通过instruction指令规定AI助手的性格以及能力(或者是目标)。name:AI助手的名字instructions:该参数指定了AI的性格以及目标或者能力,这个很重要,会影响AI助手的输出可靠性。tools:list,可以传入最多128个tools,可以使用OpenAI自己的CodeInterpreter和retrieval工具,或者是自己构建的第三方functioncalling.file_ids:list,文件的ID,这里传入的文件ID可以将文件传给CodeInterpreter和retrieval使用。文件需要通过File 的上传接口 进行上传,并且需要将接口的purpose 设置成 assistants.一个AI助手可以使用最多20个文件。每个文件最多512M。文件上传:file = client.files.create( file=open("speech.py", "rb"), purpose='assistants')AI助手创建:assistant = client.beta.assistants.create( name="Data visualizer", instructions="You are great at creating beautiful data visualizations. You analyze data present in .csv files, understand trends, and come up with data visualizations relevant to those trends. You also share a brief text summary of the trends observed.", model="gpt-4-1106-preview", tools=[{"type": "code_interpreter"}], file_ids=[file.id])管理对话和消息对话(Thread)和消息(Messages)代表了AI助手和用户的聊天。一个对话中消息的个数是没有限制的,一旦消息的内容超过了模型可以处理的最长的窗口长度,Thread会自动舍弃最旧的消息,包含尽可能多的消息内容。(注意,该策略OpenAI可能会更新)Thread和Messages的创建如下:thread = client.beta.threads.create( messages=[ { "role": "user", "content": "Create 3 data visualizations based on the trends in this file.", "file_ids": [file.id] } ])messages可以有如下两种角色(role):user:用户消息assistant:AI助手的回复messages消息可以包含文本,,以及文件。但是目前的API暂时不支持消息,相信很快就能支持消息注解MessageannotationsAI助手返回的消息可能会包含Messageannotations,存储在content的对象中。注解(Annotations)提供了如何解析消息的信息;目前支持两种不同的注解:file_citation:该注解是 retrieval 工具提供的,它定了了参考的内容的来源。file_path:该注解是 code_interpreter 工具提供,指定了参考文件的地址目录。当返回的内容有注解的时候,我们需要进行解析,将其转化成用户可以理解的文本,例如下面的代码可以将参考文本以及下载链接进行解析,方便用户理解回复。# Retrieve the message objectimport openai as clientmessage = client.beta.threads.messages.retrieve( thread_id="...", message_id="...")# Extract the message contentmessage_content = message.content[0].textannotations = message_content.annotationscitations = []# Iterate over the annotations and add footnotesfor index, annotation in enumerate(annotations): # Replace the text with a footnote message_content.value = message_content.value.replace(annotation.text, f' [{index}]') # Gather citations based on annotation attributes if (file_citation := getattr(annotation, 'file_citation', None)): cited_file = client.files.retrieve(file_citation.file_id) citations.append(f'[{index}] {file_citation.quote} from {cited_file.filename}') elif (file_path := getattr(annotation, 'file_path', None)): cited_file = client.files.retrieve(file_path.file_id) citations.append(f'[{index}] Click to download {cited_file.filename}') # Note: File download functionality not implemented above for brevity# Add footnotes to the end of the message before displaying to usermessage_content.value += '\n' + '\n'.join(citations)执行(Run)和执行步骤(RunSteps)当我们需要AIAssistant对用户问题进行回复,,需要创建一个Run对象,该对象包含了两个参数:thread_id:之前创建的Thread的idassistant_id:该AIAssistant的idrun = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id)通常情况下,我们在创建Assistant对象的时候,已经指定了model和tools,但是我们仍可以在创建执行对象(Run)的时候,进行重新指定。run = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id, model="gpt-4-1106-preview", instructions="additional instructions", tools=[{"type": "code_interpreter"}, {"type": "retrieval"}])注意:file_ids不可以在执行中进行修改,需要使用修改Assistant的API进行修改执行的生命周期(Runlifecycle)Run对象有不同的状态获取进度Pollingforupdates为了可以及时获取执行的进度,可以设置定时获取 retrievetheRun 执行状态。你可以获取每次Run的执行状态,从而决定下一步该做什么。目前还不支持streaming的输出(2023-11-12日)对话锁Threadlocks当执行对象Run处于进行中in_progress的状态的时候,对话Thread对象会被锁上,这意味着:新消息不能加到对话中新的执行Run不能被创建执行步骤Runsteps当执行进入in_progress后,会有下面四种可能的状态,分别是完成失败取消超时执行步骤Runsteps可能耗时比较长,为了能了解执行的细节,我们可以通过step_details 这个字段进行观察,包含了两种类型的内容:message_creation:展示了产生了什么消息tool_calls:展示了使用了什么tool限制目前是beta版本,将会持续解决后续这些如下问题支持流式输出支持通知的功能,可以在无需轮询的情况下共享对象状态更新支持DALL·E作为工具支持用户上传ToolsCodeInterpreterCodeInterpreter(代码解释器)允许AssistantAPI去创建并且执行代码。这个代码解释器能力,支持多种文件处理,以及代码执行。代码解释器能够通过代码运行,完成多种困难的任务,并且能解决很多GPT地薄弱能力,例如数学能力等。CodeInterpreter支持如果发现自己的代码执行失败了,会通过多轮重试,直到执行成功。开启CodeInterpreter如果需要开启CodeInterpreter能力,只需要在tools参数中加入CodeInterpreter,如tools=[{"type":"code_interpreter"}]即可。import openai as clientassistant = client.beta.assistants.create( instructions="You are a personal math tutor. When asked a math question, write and run code to answer the question.", model="gpt-4-1106-preview", tools=[{"type": "code_interpreter"}])模型之后会选择是否使用CodeInterpreter去运行用户的请求。在CodeInterpreter中传入文件CodeInterpreter可以解析多种不同类型的文件,所以当你需要处理大量的数据时,AIAssistant允许你传入自己的文件进行分析。注意:上传的文件需要设置purpose='assistants'# Upload a file with an "assistants" purposeimport openai as clientfile = client.files.create( file=open("speech.py", "rb"), purpose='assistants')# Create an assistant using the file IDassistant = client.beta.assistants.create( instructions="You are a personal math tutor. When asked a math question, write and run code to answer the question.", model="gpt-4-1106-preview", tools=[{"type": "code_interpreter"}], file_ids=[file.id])如果需要指定对话级别的文件访问(即改文件只在这个对话中可以被访问),则可以使用如下的代码:thread = client.beta.threads.create( messages=[ { "role": "user", "content": "I need to solve the equation `3x + 11 = 14`. Can you help me?", "file_ids": [file.id] } ])文件最大可以支持512MB,z支持的格式包含 .csv, .pdf, .json 和其他格式知识库获取KnowledgeRetrieval知识库获取是克服ChatGPT知识储备时效性问题,以及数据私有化的有效手段,例如利用知识库获取能力,可以把业务数据知识库集成到GPT中。开发者可以将文件(知识库)上传到AI助手中,OpenAI会自动化对文档进行分块,加索引(index)以及embedding存储和实现向量化检索。所以不需要用户自己进行这一系列操作就可以完成知识库检索的能力。开启知识库检索Assistant如果需要开启知识库增强,只需要在初始化中的tools加入tools=[{"type":"retrieval"}]参数。assistant = client.beta.assistants.create( instructions="You are a customer support chatbot. Use your knowledge base to best respond to customer queries.", model="gpt-4-1106-preview", tools=[{"type": "retrieval"}])工作原理模型会自动地根据你的输入进行内容的选择,主要的召回逻辑如下:短文档直接传入GPT对于长文档进行向量化召回FunctionCalling跟ChatGPT的CompletionAPI一样,AssistantAPI也支持functioncalling。FunctionCalling允许你将函数的描述告诉AI助手,包含了函数的定义以及参数等,然后AI助手会智能调用。但是AssistantAPI不会直接调用函数,而是将函数的参数和函数返回,等待你提交函数调用结果,才会进行下一步的执行。定义函数首先需要按照如下的样例递交函数定义{ "type": "function", # 类型一定是function "function": { "name": "getCurrentWeather", # 函数名 "description": "Get the weather in location", #函数的描述 "parameters": { # 函数的参数 "type": "object", "properties": { "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"}, "unit": {"type": "string", "enum": ["c", "f"]} }, "required": ["location"] } } }然后将函数的参入AssistantAPI的tools参数中。例如下面的例子,定义了一个天气机器人,可以获取天气信息。包含了两个函数:getCurrentWeather:获取城市的天气getNickname:获取城市别名assistant = client.beta.assistants.create( instructions="You are a weather bot. Use the provided functions to answer questions.", model="gpt-4-1106-preview", tools=[{ "type": "function", "function": { "name": "getCurrentWeather", "description": "Get the weather in location", "parameters": { "type": "object", "properties": { "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"}, "unit": {"type": "string", "enum": ["c", "f"]} }, "required": ["location"] } } }, { "type": "function", "function": { "name": "getNickname", "description": "Get the nickname of a city", "parameters": { "type": "object", "properties": { "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"}, }, "required": ["location"] } } }])获取调用的函数当 初始化一个执行(Run) 的时候,如果调用了一个function,则会进入到pending的状态。需要你进行提交函数的结果。模型支持并发调用,参考 parallelfunctioncalling如下的返回结果,可以看到required_action是需要提交的函数调用的函数名和参数。这里面可以获取callid,用于提交使用函数结果使用。{ "id": "run_3HV7rrQsagiqZmYynKwEdcxS", "object": "thread.run", "assistant_id": "asst_rEEOF3OGMan2ChvEALwTQakP", "thread_id": "thread_dXgWKGf8Cb7md8p0wKiMDGKc", "status": "requires_action", "required_action": { "type": "submit_tool_outputs", "submit_tool_outputs": { "tool_calls": [ { "id": "call_Vt5AqcWr8QsRTNGv4cDIpsmA", # 返回的call id,用于提交使用 "type": "function", "function": { "name": "getCurrentWeather", "arguments": "{\"location\":\"San Francisco\"}" } }, { "id": "call_45y0df8230430n34f8saa", "type": "function", "function": { "name": "getNickname", "arguments": "{\"location\":\"Los Angeles\"}" } } ] } },...提交函数结果需要对于每个函数都进行 提交函数输出 ,对于每个输出的结果需要提交给哪个函数,则是对应了函数调用返回的required_action中的tool_call_id。具体的代码如下。run = client.beta.threads.runs.submit_tool_outputs( thread_id=thread.id, # 对话id run_id=run.id, # 执行id tool_outputs=[ { "tool_call_id": call_ids[0], # call id "output": "22C", }, { "tool_call_id": call_ids[1], "output": "LA", }, ])LangChain集成AssistantAPI截止2023-11-15日,LangChain集成API还只是一个实验版本langchain-experimental,未有正式版本。所以需要使用的读者,可以使用如下版本:!pip install -U -q "langchain==0.0.331rc2" langchain-experimental "openai>=1.1"import osos.environ["OPENAI_API_KEY"] = 'YOUR OPENAI KEY'# !pip install -U -q "langchain==0.0.331rc2" langchain-experimental "openai>=1.1"from langchain_experimental.openai_assistant import OpenAIAssistantRunnableimport openai as clientfile = client.files.create( file=open("TEST.csv", "rb"), purpose='assistants')interpreter_assistant = OpenAIAssistantRunnable.create_assistant( name="data analysis assistant", instructions="You are a profession data analysis. When asked a question, write and run ython code to answer the question.", tools=[{"type": "code_interpreter"}], file_ids=[file.id], model="gpt-4")output = interpreter_assistant.invoke( {"content": "最近2周活跃表现最突出的是哪一天?", "file_ids": [file.id] })output其他更多的内容可以参考:langchaincookbook使用curl调用AssistantAPI具体可以参考如下的JupyterNotebookCapabilities和Actions我们在创建GPTs的时候,可以给GPTs提供多种不同的能力Knowledge:知识库Capabilities(内置能力):包含了OpenAI提供的基础能力,主要包含了,这些能力都是最重要最基础的,所以OpenAI选择自己做。WebBrowsing(网络浏览能力)DALLEImageGeneration(生成能力)CodeInterpreter(代码能力)Actions:动作,指的是GPTs的其他能力,类似于额外的能力插件,OpenAI不可能帮用户把所有的业务需求的能力都提供了额,所以它提供了一个接口,方便用户可以使用规定的接口协议,给GPT提供额外的能力。目前Actions采用的是OpenAPI的接口协议,方便GPT调用外部的API。具体的使用可以参考下面教程。GPTs与AssistantAPI的比较与差异虽然GPTs和AssistantAPI都是为了创建自定义的AI助手创建的,到那时两者的方法和使用的场景不同。referenceGPTs有着简单易用的前端交互,可以很快速地方便小白用户快速搭建AI助手,可以快速地验证方案和效果,并且可以很快速的在GPTs的商店中进行分享。然而,AssistantAPI需要通过API的方式进行操作,虽然可以使用AssistantAPI的Assistantplayground进行配置使用,但是其主要的目的还是为开发者提供一个API方式,方便开发者可以在在自己的应用中,快速集成这些能力。参考资料Youtube:OpenAIAssistantsAPI极简入门(附LangChain集成)OpenAIAssistantsAPIwithLangChainlangchaincookbookAssistantplaygroundintroducingGPTsOpenAIAssistantsAPIDifferenceofGPT’sandAssistantsOpenAIAnnouncesGPTs&Assistants.Whatisthedifference?
|
|