前言 该死的培训终于结束了,这一个月在生活上发生了很多事,可能这就是身份的转变吧,也让我在人情世故方面成长了不少。刚到公司也没什么事情,暂时也没有动力搞渗透,就想着学学ai吧,这里简单介绍一下ai的基本使用和一些概念的东西,后续有时间再学学怎么调参,怎么搭建模型,希望以后随着技术的发展,可以让每个人都可以搭建属于自己的好用的大模型
基本概念 简单总结一下,后面一边理解一边改
LLM AI (Artificial Intelligence,人工智能)其实是大概念,包括任何能让机器表现出“智能行为”的技术,即机器可以基于规则、算法或数据做出决策,则都可以称作ai,大模型只是其中的一种实现方法
大模型 是一种基于深度学习 (通过多层神经网络学习复杂模式和规律的机器学习方法)的系统,它由神经网络 (由大量互相连接的计算节点组成、模拟人脑处理信息的结构)构成,通过上亿到上千亿的参数 (神经网络中可调节的权重和偏置,用来存储模式和规律)学习海量数据中的模式,从而在遇到新输入时进行预测或生成输出。
LLM 大语言模型(Large Language Model) 是大模型的一个子类,专门用于 NLP 自然语言处理(Natural Language Processing)。它可以通过学习大规模文本数据的模式和规律,从而实现对自然语言的理解和生成,语言作为思想的符号,是人类交流和表达的主要方式,因此LLM被视为是实现 通用人工智能(AGI) (即人做的机器都能做)的一个重要方向。 目前大部分LLM基于Transformer 架构构建的,Transformer是Google于2017年提出的一种全新的神经网络结构,主要用于自然语言处理。它借鉴了RNN (循环神经网络, Recurrent Neural Network)和CNN (卷积神经网络, Convolutional Neural Network)的思想。引入了注意力机制,实现 Encoder-Decoder 架构
agent agent 智能体是指能够思考-行动-观察以实现目标的自主系统,AI Agent 则是指利用 AI 技术实现的智能体 现在一般使用的是基于LLM的智能体,可以看成由两部分组成,大脑和身体,大脑即是用LLM进行推理从而作出决策,身体就是通过调用外部工具和内部工具或者函数来实现结果的执行程序
搭建简单的智能体 LangChain LangChain是一个基于语言模型开发应用程序的编程开发框架,它提供了多种模块,通过这些模块可以构建出一个简单的自主决策、能执行任务的智能体(Agent)
模型(Models):包含各大语言模型的LangChain接口和调用细节,以及输出解析机制。 提示模板(Prompts):用户每次输入的 Prompt,都会被选择性的拼接到上下文,形成新的条件,从而引导模型输出。 数据索引(Indexes):搭建动态的知识库。并使其准备好与语言模型交互(包括文档加载程序、向量存储器、文本分割器和检索器)。 记忆(Memory):通过短时记忆和长时记忆,在对话过程中存储和检索数据,让ChatBot记住你。 链(Chains):LangChain中的核心机制,以特定方式封装各种功能,并通过一系列的组合,自动而灵活地完成任务。 代理(Agents):另一个LangChain中的核心机制,通过“代理”让大模型自主调用外部工具和内部工具,使智能Agent成为可能。
基本使用 1 2 3 4 5 6 7 8 9 10 11 from langchain_openai import ChatOpenAIllm = ChatOpenAI( api_key="sk-xxx" , base_url="https://api.gptgod.online/v1/" , temperature=0.7 , max_tokens=300 , top_p=0.9 , frequency_penalty=0.5 , presence_penalty=0.3 ) print (llm.invoke("你好" ))
提示词工程 角色设定 通过提示词预先设定角色,控制输出
1 2 3 4 5 6 7 8 9 from langchain_core.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserprompt = ChatPromptTemplate.from_messages([ ("system" , "您是一个猫娘,请用可爱的语气回答问题。" ), ("user" , "{input}" ) ]) output_parser = StrOutputParser() chain = prompt | llm|output_parser print (chain.invoke({"input" : "你好呀~" }))
使用RAG搭建知识库 在现有的知识库中检索最相关的知识,然后拼接到 Prompt 里,从而获取更加准确的答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 from langchain_community.document_loaders import WebBaseLoaderfrom langchain_openai import ChatOpenAI, OpenAIEmbeddingsfrom langchain_community.vectorstores import FAISSfrom langchain_text_splitters import RecursiveCharacterTextSplitterfrom langchain.chains import create_retrieval_chainfrom langchain.chains.combine_documents import create_stuff_documents_chainfrom langchain_core.prompts import ChatPromptTemplateprompt = ChatPromptTemplate.from_template("""仅根据提供的上下文回答以下问题: <context> {context} </context> Question: {input}""" )document_chain = create_stuff_documents_chain(llm, prompt) embeddings = OpenAIEmbeddings( api_key="sk-xxx" , base_url="https://api.gptgod.online/v1/" ) docs = WebBaseLoader("https://mzh.moegirl.org.cn/%E7%8C%AB%E5%A8%98" ).load() documents = RecursiveCharacterTextSplitter().split_documents(docs) vector = FAISS.from_documents(documents, embeddings) retriever = vector.as_retriever() retrieval_chain = create_retrieval_chain(retriever, document_chain) ''' 相当于: query = "猫娘是什么?" retrieved_docs = vectorstore.similarity_search(query, k=2)#获得文本列表 context = "\n".join([doc.page_content for doc in retrieved_docs]) prompt = f""" 你是一个专业助手,以下是相关背景信息,请根据资料回答用户的问题: 资料: {context} 问题:{query} 请用简洁的中文回答。 """ response = llm.invoke(prompt) ''' response = retrieval_chain.invoke({"input" : "猫娘是什么" }) print (response["answer" ])
短期记忆 每次调用链的时候,LangChain 会把 memory 里的历史对话拼接到 Prompt,所以memory也可以看作提示词工程的一部分
1 2 3 4 5 6 7 8 9 10 11 memory = ConversationBufferMemory( memory_key="chat_history" , return_messages=True ) qa = ConversationalRetrievalChain.from_llm( llm, retriever=vectordb.as_retriever(), memory=memory) result = qa({"question" : "你好啊" }) print (result['answer' ])result = qa({"question" : "你还记得我上句话说的什么呀?" }) print (result['answer' ])
长期记忆 但是memory属于短期记忆,能记多少内容取决于模型的上下文窗口(token)大小,如果提示词加问题过长就会被强制截断 所以我们可以将历史对话储存在本地,使用embedding检索实现长期记忆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 HISTORY_FILE = "chat_history.json" def load_history (): if os.path.exists(HISTORY_FILE): with open (HISTORY_FILE, "r" , encoding="utf-8" ) as f: raw_history = json.load(f) history = [] for item in raw_history: if item["role" ] == "user" : history.append(HumanMessage(content=item["content" ])) else : history.append(AIMessage(content=item["content" ])) return history return [] def save_history (history ): raw_history = [] for msg in history: if isinstance (msg, HumanMessage): raw_history.append({"role" : "user" , "content" : msg.content}) elif isinstance (msg, AIMessage): raw_history.append({"role" : "ai" , "content" : msg.content}) with open (HISTORY_FILE, "w" , encoding="utf-8" ) as f: json.dump(raw_history, f, ensure_ascii=False , indent=2 ) retriever = vectorstore.as_retriever() history_prompt = ChatPromptTemplate.from_messages([ MessagesPlaceholder(variable_name="chat_history" ), ("user" , "{ipnut}" ), ("user" , "鉴于上述对话,生成一个搜索查询以查找与对话相关的信息" ) ]) history_aware_retriever = create_history_aware_retriever(llm, retriever, history_prompt) response_prompt = ChatPromptTemplate.from_messages([ ("system" , "根据以下上下文回答用户的问题:\n\n{context}" ), MessagesPlaceholder(variable_name="chat_history" ), ("user" , "{input}" ), ]) document_chain = create_stuff_documents_chain(llm, response_prompt) conversational_chain = create_retrieval_chain(history_aware_retriever, document_chain) chat_history = load_history() print (f"已加载 {len (chat_history)//2 } 轮历史对话。" )while True : user_input = input ("你: " ) response = conversational_chain.invoke({ "chat_history" : chat_history, "input" : user_input }) answer = response["answer" ] print ("AI:" , answer) chat_history.append(HumanMessage(content=user_input)) chat_history.append(AIMessage(content=answer)) save_history(chat_history)
使用代理 实时搜索 这里使用的是Tavily平台
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import osfrom langchain_community.tools.tavily_search import TavilySearchResultsfrom langchain_openai import ChatOpenAIfrom langchain.agents import initialize_agent, AgentTypeos.environ["OPENAI_API_KEY" ] = "sk-xx" os.environ["OPENAI_API_BASE" ] = "https://api.gptgod.online/v1/" os.environ["TAVILY_API_KEY" ] = 'tvly-dev-xxxx' search = TavilySearchResults() tools = [search] llm = ChatOpenAI( model="gpt-3.5-turbo" , temperature=0 ) agent_executor = initialize_agent( tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True ) response = agent_executor.invoke({"input" : "猫娘是什么?" }) print (response)