主要学习了代理,以及RAG应用的更高级应用,以及实现了一个新的数据库应用开发范式
代理
- 思维链无法主动更新自己知识,解决大模型“事实幻觉”:先本地知识库找否则外部搜索
- 代理根据输入决定调用哪些外部工具(数据清洗、搜索引擎、应用程序)
ReAct
- 基于推理reasoning与行动Acting之间协同作用生成任务轨迹:观察-思考-行动
- 利用SERPAPI_API_KEY作为Google搜索工具
# 老版本
os.environ["SERPAPI_API_KEY"] = ("xx")
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.invoke("xxx")
# thought > action > action input > observation > thought > final answer
# 新版本
tools = load_tools(["serpapi", "llm-math"], llm=llm)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
agent_executor.invoke({"input": "xx"})
Structured Tool Chat
- Playwright工具包,模拟真实用户操作网页
# 使用playwright访问网页
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.lauch()
page = browser.new_page()
page.goto("https://xx.com/")
title = page.title()
browser.close()
- 结构化工具对话代理——浏览器自动化工具链
async_browser = create_async_playwright_browser()
toolkit = PlayWrightBrowserToolkit.from_browser(async_browser=async_browser)
tools = toolkit.get_tools()
llm = xxx
agent_chain = initialize_agent(
tools,
llm,
# 基于输入的自然语言指令,智能选择适当的工具执行任务
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCIPTION,
verbose=True,
)
async def main():
response = await agent_chain.ainvoke("xxx")
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Self-Ask with Search:
- 自主询问搜索代理, Follow-up Question追问+Intermediate Answer中间答案,来辅助llm寻找事实性问题的过渡性答案
- 多跳问题(Multi-hop question)引出最终答案
search = SerpAPIWrapper()
tools = [
Tool(
name="Intermediate Answer",
func=search.run,
description="useful for when you need to ask with search",
)
]
self_ask_with_search = initialize_agent(
tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True
)
self_ask_with_search.run("xxx?")
Plan and execute
- 计划与执行代理,计划由一个大语言模型代理(负责推理)完成,执行由另一个大语言模型代理(负责调用工具)完成
search = SerpAPIWrapper()
llm = ChatOpenAI(model=os.environ["LLM_MODELEND"], temperature=0)
llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)
tools = [
Tool(
name="Search",
func=search.run,
description="useful for when you need to answer questions about current events",
),
Tool(
name="Calculator",
func=llm_math_chain.run,
description="useful for when you need to answer questions about math",
),
]
model = ChatOpenAI(model=os.environ["LLM_MODELEND"], temperature=0)
planner = load_chat_planner(model)
executor = load_agent_executor(model, tools, verbose=True)
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
agent.invoke("xx?")
工具
tools = load_tools(["arxiv"],) # 论文研究
RAG
Retrieval-Augmented Generation,检索增强生成
- 检索:对于给定的输入从大型文档集合中查找文档,基于密集向量搜索
- 上下文编码:将文档与原始输入一起编码
- 生成:模型生成输出
文档加载
# TextLoader
loader = TextLoader("./x.txt", encoding="utf8")
# CSVLoader
# HTMLLoader
# JSONLoader
# MarkdownLoader
# PDFLoader
文本转换
长文档分割成小的块,适合模型的上下文窗口
文本分割器
- 将文本分成小的、有语义意义的块(句子),将小块组合成更大的块直到达到一定大小形成块
- 创建新的文本块与块有重叠来保持块之间上下文
文本嵌入
LLM来对文本块做嵌入(Embeddings),创建一段文本的向量表示,使可以在向量空间中思考文本并执行语义搜索操作,在向量空间查找最相似的文本片段
Langchain中Embeddings类设计用于与文本嵌入模型交互
from langchain_community.embeddings import OpenAIEmbeddings
embeddings_model = OpenAIEmbeddings()
embed_documents方法:为文档创建嵌入,接收多个文本输入,一次性将文档转换为向量表示-
embeddings = embeddings_model.embed_documents( [ "a", "b", "c", ] ) # return [1,2,3,4] embed_query方法:为查询创建嵌入,接收一个文本作为输入,为用户的搜索查询-
embedded_query = embeddings_model.embed_query("a?")
存储嵌入
缓存存储:CacheBackedEmbeddings是一个支持缓存的嵌入式包装器,嵌入缓存在键值存储中:对文本进行哈希处理作为键
缓存策略
- InMemoryStore:内存中缓存,用于单元测试
- LocalFileStore:本地文件系统存储
- RedisStore:在Redis数据库中缓存嵌入,高速可扩展
store = InMemoryStore()
embedder = CacheBackedEmbeddings.from_bytes_store(
underlying_embeddings, # 实际生成文本嵌入的工具
store, # 嵌入的缓存位置
namespace=underlying_embeddings.model # 嵌入缓存的命名空间
)
embeddings = embdder.embed_documents(["first", "second"]) # embbeder为文本生成嵌入,结果向量存储在内存存储中
向量存储:通过向量数据库(Vector Store)保存
数据检索
通过非结构化查询返回相关文档,向量存储检索器支持向量检索
index = VectorstoreIndexCreator(embedding=embeddings).from_loaders([loader])
# 创建索引来查询检索
query = "xxx是什么?"
result = index.query(llm=llm, question=query)
数据库应用
Chain 查询
db = SQLDatabase.from_uri("sqlite:///test.db") # 连接数据库
# 温度0: 模型输出更具确定性
llm = ChatOpenAI(model=os.environ["LLM_MODELEND"], temperature=0, verbose=True)
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)
response = db_chain.run("xxx?")
Agent 查询数据库
具有纠错能力
db = SQLDatabase.from_uri("sqlite:///test.db")
llm = ...
# 创建SQL Agent
agent_executor = create_sql_agent(
llm=llm,
toolkit=SQLDatabaseToolkit(db=db, llm=llm),
verbose=True,
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)
questions = ["q1?","q2?",]
for question in questions:
response = agent_executor.invoke(question)