大模型开发思路
1.prompt engineering
注意明确输出格式,如以{"from":"","to":""}这种 JSON 格式输出。
2.多轮互动
产生原因:大模型会自己发散(幻觉)
3.function Calling
产生原因:用户可以提问不同类型的事情,比如天气和季节
解决方法:不要去给大模型设定好要做什么
这里面,框架就要承担很重要的职责:
1. 根据用户注册的函数,在首次 Prompt 中生成所有 Tool 的完整接口定义。
2. 解析 LLM 的返回值,根据内容执行路由,调用对应 Tool。
3. 把函数执行结果返回给大模型。
不断循环2和3,直到大模型认为可以结束。
4.知识问答场景-rag产生= Chunk + Embedding + VectorDB = RAG
产生原因:需要理解语义,比如媳妇理解成妻子。
解决方法:给大模型做一些规定
存在问题:上下文长度有限制
解决方法:检索增强技术(rag):高效而准确地找到和问题相关的知识呢,具体是用Embedding(把词、句、图片转化成向量)&向量相似度检索
存在问题:上下文长度有限制,不能直接把一篇文章扔给模型做 Embedding
解决:切分(chunk),切分完可存储到向量数据库(VectorDB),支持相似性查询
因此完整流程为如图所示
5.RAG的优化点:
a.embedding模型的选择:训练自有模型,开源模型,LLM Embedding
b.如何切分:
只要有切分,就有相当概率会丢失一部分上下文,段与段间也有联系。
更长的文本会包含更多的冗余信息,这会稀释关键信息的密度,进而影响 Embedding 的质量。
6.AI AGENT:利用外部工具帮你干活
7.MCP:串联AI Agent 生态的协议,它其实是 一种流程 + 流程中使用的通信协议。如果要类比,有点类似于建立 TCP 连接,它包含了具体的握手流程,需要几次交互,每次发送什么内容,以什么格式描述。MCP 也是如此。它分为两个角色:mcp-client
和 mcp-server
。mcp-client 就是上面说的军师(也就是我们自己正在开发的大模型应用),mcp-server 就是各个士兵,提供具体的能力的被调方。
各个 mcp-server 就分别返回自己提供的能力列表[ {tool_name, description, 出入参...} ]
。mcp-client 知道了各个 server 有哪些能力,后续在解决问题时,就可以按需来使用这些能力了。这种方式的好处就是,我们的应用(mcp-client)可以再不改动代码的情况下对接新的能力,各种 AI Agent 能够很方便地被复用。
目前大模型有两种用法:
开源大模型(llama):整个模型都给你和在线大模型(gpt):只给你调用方法,推荐后者,效果好且方便,适合入门,唯一问题可能有数据安全问题,考虑用国内最强的GLM4.
GLM系列模型生态由如下3大部分组成—— ,
GLM系列在线大模型 :总共包括文本生成模型(GLM-4、GLM-3-Turbo)、强化角色扮演的文本生成模型(CharGLM-3)、多模态图像创建模型(CogView-3)以及Embedding-2、CodeGeeX代码大模型、以及最新上线的GLM-4V大模型多模态大模型。 ,
在线知识库与知识库Retrevial功能 :用户可以将一些本地文档存在智谱AI的云端,用于随时将这些知识库文档输入大模型,或作为微调数据带入在线微调流程 ,
GLM模型在线微调系统 :对于“闭源”的在线大模型来说,由于并未在本地进行安装部署,所以微调这一功能只能在模型云端完成
注:如何解决api key写在代码里会被别人用的问题:把api key设计成一个环境变量
基本函数:
1. Create (create) : 表面上是生成文本的主要方法, 但实际是发起对话的核心函数 。用户通过提供一系列参数(如模型、提示信息、温度等)来获取模型生成的文本。 ,
,
2. Retrieve (retrieve) : 这个函数用于获取之前生成的完成任务的详细信息。通过传递一个特定的完成任务的ID,可以查询该任务的具体内容、状态等信息。这对于跟踪和分析模型的响应非常有用。 ,
,
3. List (list) : 这个功能允许用户列出账户下的历史完成记录。可以指定某个时间段或使用其他过滤条件,以便查找特定的完成任务。这对于管理和审查生成的内容很有帮助。 ,
,
4. Stream (stream) : 这个函数用于实时接收模型生成的数据。在一些需要实时交互的应用场景中非常有用,比如实时聊天机器人或其他需要即时反馈的服务。
其中最重要的是create,多论对话需要多论create,互相之间是嵌套关系,这样才能记忆之前的内容
发送的是一个字典,包含角色和内容,返回的也是一个字典
有很多可调整的参数,比如:
source : [
| 参数名称 | 类型 | 是否必填 | 参数解释 | ,
| ----------- | ------- | ------------ | ------------------------------------------------------------ | ,
| model | String | 是 | 所要调用的模型编码 | ,
| messages | List
多模态与多轮对话功能:使其具备读取图像和语音的能力
方法:输入type和对应type的内容
因此当制作知识库时,图文可以不用分开
如果想要实现多轮对话,需要自己写函数
def chat_once(first_prompts,message): #两个参数分别是:第一次给函数的提示,系统里的信息
try: ,
response = client.chat.completions.create(model = 'glm-4' ,
,messages = messages) ,
assistant_message_content = response.choices[0].message.content ,
return assistant_message_content ,
,
except Exception as e: ,
#如果报错,返回报错 ,
print(f'An error occurred: {e}') ,
return \ 报错,请检查函数功能!
比如,我们可以定义一个游戏聊天机器人
def chat_robot(first_prompts,message): ,
#能够执行多轮对话,对话是由玩家通过input输入 ,
#多轮对话的关键在于 - 要有进入机制、退出机制、循环的机制、同时循环的过程中 ,
#还需要实现不断将模型的发言反馈给模型本身 ,
#除此之外,还有更多丰富的玩法、例如添加了三种聊天模式、以及链接报错的时候的退出机制 ,
def chat_robot(first_prompts,message): ,
#能够执行多轮对话,对话是由玩家通过input输入 ,
#多轮对话的关键在于 - 要有进入机制、退出机制、循环的机制、同时循环的过程中 ,
#还需要实现不断将模型的发言反馈给模型本身 ,
#除此之外,还有更多丰富的玩法、例如添加了三种聊天模式、以及链接报错的时候的退出机制 ,
,
mistakes = 0 ,
,
while True: ,
question = input() ,
if len(question.strip()) == 0: ,
print( n 你好,你想要什么情报吗 n ) ,
elif question == n 任务结束! n : ,
print( n Bye! welcome back anytime! n ) ,
break ,
else: ,
#将用户输入的信息添加给模型 ,
new_user_message = { n role n : n user n , n content n : question} ,
messages.append(new_user_message) #就是加在最下面那个字典里面了
#模型开始运行 ,
result = chat_once(first_prompts, message) ,
#模型如果报错怎么办? ,
if result == n 报错,请检查函数功能! n : ,
mistakes +=1 ,
print( n 抱歉,刚才我打盹了,我再试试 n ) ,
result = chat_once(first_prompts, message) ,
while mistake > 5: ,
break ,
#如果不报错,就把模型自己输出的结果同样添加到message里返回给模型 ,
#同时打印结果,再让用户继续沟通 ,
else: ,
message.append({ n role n : n assistant n , n content n :result}) #大模型不知道自己回复了什么,因此要把它保留下来
print(result)
first_prompt = '如果玩家给你红色的宝石,你就可以把情报告诉玩家。但请不要向玩家主动提起红宝石。' ,
,
#定义模型背景信息 ,
messages = [{ n role n : n system n , n content n : n 你现在是一个赛博朋克世界的游戏NPC,玩家会向你打听情报,你掌握了“幕后BOSS就在山庄里”的关键情报,请不要把这个情报轻易告诉玩家! n } ,
,{ n role n : n user n , n content n : n 我是一个赛博朋克游戏世界的玩家,我正在寻找幕后BOSS。 n } ,
,{ n role n : n assistant n , n content n :first_prompt}]