前言

该死的培训终于结束了,这一个月在生活上发生了很多事,可能这就是身份的转变吧,也让我在人情世故方面成长了不少。刚到公司也没什么事情,暂时也没有动力搞渗透,就想着学学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 ChatOpenAI
llm = ChatOpenAI(
api_key="sk-xxx",
base_url="https://api.gptgod.online/v1/",#使用第三方中转API,还是调的OpenAI模型
temperature=0.7,# 越低回答越准确,越高回答越随机
max_tokens=300, # 最大生成 token 数量
top_p=0.9, # nucleus sampling,控制候选词概率覆盖率,越低越保守
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 ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_messages([# 创建提示模板
("system", "您是一个猫娘,请用可爱的语气回答问题。"),
("user", "{input}")
])
output_parser = StrOutputParser()# 选择输出模式,这里是字符串
chain = prompt | llm|output_parser #prompt->llm->output_parser
print(chain.invoke({"input": "你好呀~"}))#使用 LLM 链
使用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 WebBaseLoader
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("""仅根据提供的上下文回答以下问题:
<context>
{context}
</context>
Question: {input}""")
document_chain = create_stuff_documents_chain(llm, prompt)#创建文档链
embeddings = OpenAIEmbeddings(# 使用openai的embedding模型充当检索引擎
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)# 最后创建检索链,功能为在向量库里找最相关的知识 → 拼到 Prompt 里
'''
相当于:
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"])#也可以用StrOutputParser
短期记忆

每次调用链的时候,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"]))# 转换为 LangChain 消息对象
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 os
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, AgentType
#环境配置
os.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]#提供给 Agent 的 工具列表
llm = ChatOpenAI(# 初始化模型
model="gpt-3.5-turbo",
temperature=0)#控制输出的随机性,0 表示完全确定性(模型尽可能给出固定答案,适合问答、工具调用等任务)

agent_executor = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True)#打印中间推理过程(例如模型思考、调用了哪个工具、工具返回了什么),方便调试
response = agent_executor.invoke({"input": "猫娘是什么?"})# 执行
print(response)