
GraphRAG:基于PolarDB+通義千問api+LangChain的知識圖譜定制實踐
LangChain的一個核心價值就是它提供了標準的模型接口;然后我們可以自由的切換不同的模型,當前主要有兩種類型的模型,但是考慮到使用場景,對我們一般用戶來說就是使用一種模型即文本生成模型。
說到模型,大家就理解模型就是ChatGPT就可以。單純的模型只能生成文本內容。
用于文本生成,文字作為輸入,輸出也是文字。
1. 普通LLM:接收文本字符串作為輸入,并返回文本字符串作為輸出。2. 聊天模型:將聊天消息列表作為輸入,并返回一個聊天消息。代碼案例:
from langchain.schema import HumanMessage
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
llm = OpenAI()
chat_model = ChatOpenAI()
print(llm("say hi!"))
print(chat_model.predict("say hi!"))
把文字轉換為浮點數形式的描述:
這些模型接收文本作為輸入并返回一組浮點數。這些浮點數通常用于表示文本的語義信息,以便進行文本相似性計算、聚類分析等任務。文本嵌入模型可以幫助開發(fā)者在文本之間建立更豐富的聯系,提高基于大型語言模型的應用的性能。
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
text = "This is a test document."
query_result = embeddings.embed_query(text)
doc_result = embeddings.embed_documents([text])
print(doc_result)
提示詞是我們與模型交互的方式,或者是模型的輸入,通過提示詞可以讓模型返回我們期望的內容,比如讓模型按照一定的格式返回數據給我們。LangChain提供了一些工具,可以方便我們更容易的構建出我們想要的提示詞,主要工具如下:了解這些工具都是更方便的讓我們構造提示詞就行了。
語言模型提示詞模板PromptTemplates,提示模板可以讓我們重復的生成提示,復用我們的提示。它包含一個文本字符串(“模板”),從用戶那里獲取一組參數并生成提示,包含:
1. 對語言模型的說明,應該扮演什么角色。
2. 一組少量示例,以幫助LLM生成更好的響應。3. 具體的問題。代碼案例:
from langchain import PromptTemplate
template = """
I want you to act as a naming consultant for new companies.
What is a good name for a company that makes {product}?
"""
prompt = PromptTemplate(
input_variables=["product"],
template=template,
)
prompt.format(product="colorful socks")
# -> I want you to act as a naming consultant for new companies.
# -> What is a good name for a company that makes colorful socks?
聊天模型提示詞模板ChatPrompt Templates,ChatModels接受聊天消息列表作為輸入。列表一般是不同的提示,并且每個列表消息一般都會有一個角色。
from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
# get a chat completion from the formatted messages
print(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
示例選擇器Example Selectors,如果有多個案例的時候,使用ExampleSelectors選擇一個案例讓提示詞使用:1. 自定義的案例選擇器。2. 基于長度的案例選擇器,輸入長的時候按理會少一點,輸入多的時候,案例會多一些。3. 相關性選擇器,選擇一個和輸入最相關的案例。
from langchain.prompts.example_selector.base import BaseExampleSelector
from typing import Dict, List
import numpy as np
class CustomExampleSelector(BaseExampleSelector):
def __init__(self, examples: List[Dict[str, str]]):
self.examples = examples
def add_example(self, example: Dict[str, str]) -> None:
"""Add new example to store for a key."""
self.examples.append(example)
def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
"""Select which examples to use based on the inputs."""
return np.random.choice(self.examples, size=2, replace=False)
examples = [
{"foo": "1"},
{"foo": "2"},
{"foo": "3"}
]
# Initialize example selector.
example_selector = CustomExampleSelector(examples)
# Select examples
print(example_selector.select_examples({"foo": "foo"}))
# -> array([{'foo': '2'}, {'foo': '3'}], dtype=object)
# Add new example to the set of examples
example_selector.add_example({"foo": "4"})
print(example_selector.examples)
# -> [{'foo': '1'}, {'foo': '2'}, {'foo': '3'}, {'foo': '4'}]
# Select examples
print(example_selector.select_examples({"foo": "foo"}))
# -> array([{'foo': '1'}, {'foo': '4'}], dtype=object)
輸出解析器OutputParsers,可以讓LLM輸出更加結構化的信息:
1. 指示模型如何格式化輸出:get_format_instructions2. 輸出解析為所需的格式:parse(str)主要的Parsers:1. CommaSeparatedListOutputParser,讓LLM按照逗號分隔的形式返回。[‘Vanilla’, ‘Chocolate’, ‘Strawberry’, ‘Mint Chocolate Chip’, ‘Cookies and Cream’]2. StructuredOutputParser 無需定義對象,直接生成結構化的內容。和PydanticOutputParser比較像,但是不用定義對象。
3. PydanticOutputParser定義一個對象模型,讓LLM按照這個模型返回數據。
可以看到我們定義了Joke類,然后PydanticOutputParser可以讓LLM按照我們定義對象的格式返回數據給我們。
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field, validator
from typing import List
model_name = 'text-davinci-003'
temperature = 0.0
model = OpenAI(model_name=model_name, temperature=temperature)
# Define your desired data structure.
class Joke(BaseModel):
setup: str = Field(description="question to set up a joke")
punchline: str = Field(description="answer to resolve the joke")
# You can add custom validation logic easily with Pydantic.
@validator('setup')
def question_ends_with_question_mark(cls, field):
if field[-1] != '?':
raise ValueError("Badly formed question!")
return field
parser = PydanticOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
joke_query = "Tell me a joke."
_input = prompt.format_prompt(query=joke_query)
output = model(_input.to_string())
print(parser.get_format_instructions())
print(output)
print(parser.parse(output))
索引可以讓文檔結構化,從而LLM可以直接更好的和文檔交互;比如用于答疑,知識庫等,LLM先從文檔中獲取答案。LangChain在索引這塊也提供了許多有用的函數和工具,方便我們從外部加載與檢索不同的文檔數據。
在數據索引這塊,LangChain提供的主要工具:1. Document Loaders:從不同的數據源加載文檔,當使用loader加載器讀取到數據源后,數據源需要轉換成 Document 對象后,后續(xù)才能進行使用。2. Text Splitters:實現文本分割,我們每次不管是做把文本當作 prompt 發(fā)給 openai api ,還是還是使用 openai api embedding 功能都是有字符限制的。比如我們將一份300頁的 pdf 發(fā)給 openai api,讓他進行總結,他肯定會報超過最大 Token 錯。所以這里就需要使用文本分割器去分割我們 loader 進來的 Document。3. VectorStores:把文檔存儲為向量結構,因為數據相關性搜索其實是向量運算。所以,不管我們是使用 openai api embedding 功能還是直接通過向量數據庫直接查詢,都需要將我們的加載進來的數據 Document 進行向量化,才能進行向量運算搜索。轉換成向量也很簡單,只需要我們把數據存儲到對應的向量數據庫中即可完成向量的轉換。4. Retrievers:用于檢索文檔的數據。
圖中的FAISS是一種向量存儲的服務;
給一個案例,了解下不同工具的用法:1. 首先加載文檔;2. 然后分隔文檔為不同區(qū)塊;3. 然后轉換為向量存儲;4. 將向量存儲轉換為檢索器,交給LangChain,用于問答;
import os
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
# 設置代理
os.environ['HTTP_PROXY'] = 'socks5h://127.0.0.1:13659'
os.environ['HTTPS_PROXY'] = 'socks5h://127.0.0.1:13659'
# 創(chuàng)建文本加載器
loader = TextLoader('/Users/aihe/Downloads/demo.txt', encoding='utf8')
# 加載文檔
documents = loader.load()
# 文本分塊
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 計算嵌入向量
embeddings = OpenAIEmbeddings()
# 創(chuàng)建向量庫
db = Chroma.from_documents(texts, embeddings)
# 將向量庫轉換為檢索器
retriever = db.as_retriever()
# 創(chuàng)建檢索問答系統
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)
# 運行問題答案檢索
query = "如何申請租戶?"
print(qa.run(query))
print(qa.run("能否說明下你可以提供的功能?"))
默認情況下Agent和Chain都是無狀態(tài)的,也就是用完之后不知道上次的對話內容是什么。每次的query都是獨立的。
但是在有些應用中,記住上一次的會話內容是比較重要的,比如聊天,LangChain對于也提供了一些相關的工具類。
from langchain import ConversationChain, OpenAI
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.chat_memory.add_user_message("你好!")
memory.chat_memory.add_ai_message("你好嗎?")
llm = OpenAI(temperature=0)
chain = ConversationChain(llm=llm,
verbose=True,
memory=memory)
chain.predict(input="最近怎么樣!")
print(chain.predict(input="感覺很不錯,剛和AI做了場對話."))
鏈可以讓我們把多個組件組合成一個應用,比如我們創(chuàng)建一個鏈,這個鏈可以接受用戶的輸入,然后通過PromptTemplate格式化用戶的輸入為提示詞,然后把這個提示詞輸入給LLM。我們也可以把一些鏈組合在一起,構建更復雜的鏈。
一個簡單的案例:
# 引入所需模塊和類
from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
from langchain import PromptTemplate
from langchain.prompts.chat import (
ChatPromptTemplate, # 引入對話模板類
HumanMessagePromptTemplate, # 引入人類消息模板類
)
# 創(chuàng)建人類消息模板類
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template="給我一個制作{product}的好公司名字?", # 輸入模板,其中product為占位符
input_variables=["product"], # 指定輸入變量為product
)
)
# 創(chuàng)建對話模板類
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])
# 創(chuàng)建OpenAI聊天模型對象
chat = ChatOpenAI(temperature=0.9)
# 創(chuàng)建LLMChain對象,將聊天模型和對話模板傳入
chain = LLMChain(llm=chat, prompt=chat_prompt_template)
# 運行LLMChain對象,并輸出結果
print(chain.run("襪子"))
代理是使用LLM作為思考工具,決定當前要做什么。我們會給代理一系列的工具,代理根據我們的輸入判斷用哪些工具可以完成這個目標,然后不斷的運行工具,來完成目標。代理可以看做是增強版的Chain,不僅綁定模板、LLM,還可以給代理添加一些工具。
Agent是一個智能代理,它負責根據用戶輸入和應用場景,在一系列可用工具中選擇合適的工具進行操作。Agent可以根據任務的復雜性,采用不同的策略來決定如何執(zhí)行操作。
有兩種類型的Agent:1. 動作代理(Action Agents):這種代理一次執(zhí)行一個動作,然后根據結果決定下一步的操作。
2. 計劃-執(zhí)行代理(Plan-and-Execute Agents):這種代理首先決定一系列要執(zhí)行的操作,然后根據上面判斷的列表逐個執(zhí)行這些操作。對于簡單的任務,動作代理更為常見且易于實現。對于更復雜或長期運行的任務,計劃-執(zhí)行代理的初始規(guī)劃步驟有助于維持長期目標并保持關注。但這會以更多調用和較高延遲為代價。這兩種代理并非互斥,可以讓動作代理負責執(zhí)行計劃-執(zhí)行代理的計劃。
Agent內部涉及的核心概念如下:
1. 代理(Agent):這是應用程序主要邏輯。代理暴露一個接口,接受用戶輸入和代理已執(zhí)行的操作列表,并返回AgentAction或AgentFinish。
2. 工具(Tools):這是代理可以采取的動作。比如發(fā)起HTTP請求,發(fā)郵件,執(zhí)行命令。
3. 工具包(Toolkits):這些是為特定用例設計的一組工具。例如,為了讓代理以最佳方式與SQL數據庫交互,它可能需要一個執(zhí)行查詢的工具和另一個查看表格的工具。可以看做是工具的集合。
4. 代理執(zhí)行器(Agent Executor):這將代理與一系列工具包裝在一起。它負責迭代運行代理,直到滿足停止條件。
代理的執(zhí)行流程:
一個案例:
# 引入所需模塊和類
from langchain.agents import load_tools # 引入加載工具函數
from langchain.agents import initialize_agent # 引入初始化代理函數
from langchain.agents import AgentType # 引入代理類型類
from langchain.llms import OpenAI # 引入OpenAI語言模型類
import os # 引入os模塊
# 創(chuàng)建OpenAI語言模型對象,設定temperature為0,即關閉隨機性
llm = OpenAI(temperature=0)
# 加載所需工具,包括serpapi和llm-math
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 初始化代理對象,設定代理類型為ZERO_SHOT_REACT_DESCRIPTION,輸出詳細信息
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 運行代理對象,向其提問特朗普的年齡和年齡除以2的結果
agent.run("特朗普今年多少歲? 他的年齡除以2是多少?")
上述代碼中關于Agent有個初始化的階段,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,代理類型決定了代理如何使用工具、處理輸入以及與用戶進行交互。從而為用戶提供有針對性的服務。其中可以選擇的類型如下:
initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
1. zero-shot-react-description:該代理使用ReAct框架僅根據工具的描述來確定要使用哪個工具,可以提供任意數量的工具。要求為每個工具提供一個描述。
2. react-docstore:該代理使用ReAct框架與文檔存儲(docstore)進行交互。必須提供兩個工具:一個搜索工具和一個查找工具(它們必須確切地命名為Search和Lookup)。搜索工具應該用于搜索文檔,而查找工具應該在最近找到的文檔中查找術語。該代理等同于原始的ReAct論文,特別是維基百科的示例。
3. self-ask-with-search:該代理使用一個名為Intermediate Answer的單一工具。這個工具應該能夠查找問題的事實性答案。這個代理等同于原始的自問自答(self-ask)與搜索論文,其中提供了作為工具的谷歌搜索API。
4. conversational-react-description:該代理旨在用于對話設置中。提示讓代理在對話中變得有幫助。它使用ReAct框架來決定使用哪個工具,并使用內存來記住之前的對話互動。5. structured-chat-zero-shot-react-description: 在對話中可以使用任意的工具,并且能夠記住對話的上下文。
官方已經默認提供了一系列的工具箱,發(fā)Gmail郵件,數據庫查詢,JSON處理等;還有一些單個的工具列表,都可以在文檔中看到:
https://python.langchain.com/en/latest/modules/agents/tools/getting_started.html
我們通過一個自定義的工具,了解下工具怎么用,因為后面再使用LangChain的時候我們做的也就是不斷的自定義工具。編寫工具的時候,要準備:
1. 名稱。
2. 工具描述:說明你的工具是做什么的?
3. 參數結構:當前工具需要的入參是什么結構?
假設我們需要構建一個基于LLM的問答系統,該系統需要從指定的數據源中提取信息以回答用戶的問題。我們可以使用LangChain中的數據增強生成功能與外部數據源進行交互,獲取所需的數據。然后,將數據輸入到LLM中,生成回答。記憶功能可以幫助我們在多次調用之間保持相關狀態(tài),從而提高問答系統的性能。此外,我們還可以使用智能代理功能實現系統的自動優(yōu)化。最后,通過LangChain提供的評估提示和鏈實現,我們可以對問答系統的性能進行評估和優(yōu)化。
實現了一個基于語言模型的文本生成圖片工具,調用不同的工具函數來最終生成圖片。主要提供了以下幾個工具:
1. random_poem:隨機返回中文的詩詞。
2. prompt_generate:根據中文提示詞生成對應的英文提示詞。3. generate_image:根據英文提示詞生成對應的圖片。
import base64
import json
import os
from io import BytesIO
import requests
from PIL import Image
from pydantic import BaseModel, Field
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
from langchain.tools import BaseTool, StructuredTool, Tool, tool
from langchain import LLMMathChain, SerpAPIWrapper
def generate_image(prompt: str) -> str:
"""
根據提示詞生成對應的圖片
Args:
prompt (str): 英文提示詞
Returns:
str: 圖片的路徑
"""
url = "http://127.0.0.1:7860/sdapi/v1/txt2img"
headers = {
"accept": "application/json",
"Content-Type": "application/json"
}
data = {
"prompt": prompt,
"negative_prompt": "(worst quality:2), (low quality:2),disfigured, ugly, old, wrong finger",
"steps": 20,
"sampler_index": "Euler a",
"sd_model_checkpoint": "cheeseDaddys_35.safetensors [98084dd1db]",
# "sd_model_checkpoint": "anything-v3-fp16-pruned.safetensors [d1facd9a2b]",
"batch_size": 1,
"restore_faces": True
}
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
response_data = response.json()
images = response_data['images']
for index, image_data in enumerate(images):
img_data = base64.b64decode(image_data)
img = Image.open(BytesIO(img_data))
file_name = f"image_{index}.png"
file_path = os.path.join(os.getcwd(), file_name)
img.save(file_path)
print(f"Generated image saved at {file_path}")
return file_path
else:
print(f"Request failed with status code {response.status_code}")
def random_poem(arg: str) -> str:
"""
隨機返回中文的詩詞
Returns:
str: 隨機的中文詩詞
"""
llm = OpenAI(temperature=0.9)
text = """
能否幫我從中國的詩詞數據庫中隨機挑選一首詩給我,希望是有風景,有畫面的詩:
比如:山重水復疑無路,柳暗花明又一村。
"""
return llm(text)
def prompt_generate(idea: str) -> str:
"""
生成圖片需要對應的英文提示詞
Args:
idea (str): 中文提示詞
Returns:
str: 英文提示詞
"""
llm = OpenAI(temperature=0, max_tokens=2048)
res = llm(f"""
Stable Diffusion is an AI art generation model similar to DALLE-2.
Below is a list of prompts that can be used to generate images with Stable Diffusion:
- portait of a homer simpson archer shooting arrow at forest monster, front game card, drark, marvel comics, dark, intricate, highly detailed, smooth, artstation, digital illustration by ruan jia and mandy jurgens and artgerm and wayne barlowe and greg rutkowski and zdislav beksinski
- pirate, concept art, deep focus, fantasy, intricate, highly detailed, digital painting, artstation, matte, sharp focus, illustration, art by magali villeneuve, chippy, ryan yee, rk post, clint cearley, daniel ljunggren, zoltan boros, gabor szikszai, howard lyon, steve argyle, winona nelson
- ghost inside a hunted room, art by lois van baarle and loish and ross tran and rossdraws and sam yang and samdoesarts and artgerm, digital art, highly detailed, intricate, sharp focus, Trending on Artstation HQ, deviantart, unreal engine 5, 4K UHD image
- red dead redemption 2, cinematic view, epic sky, detailed, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski
- a fantasy style portrait painting of rachel lane / alison brie hybrid in the style of francois boucher oil painting unreal 5 daz. rpg portrait, extremely detailed artgerm greg rutkowski alphonse mucha greg hildebrandt tim hildebrandt
- athena, greek goddess, claudia black, art by artgerm and greg rutkowski and magali villeneuve, bronze greek armor, owl crown, d & d, fantasy, intricate, portrait, highly detailed, headshot, digital painting, trending on artstation, concept art, sharp focus, illustration
- closeup portrait shot of a large strong female biomechanic woman in a scenic scifi environment, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, warframe, illustration, thomas kinkade, tomasz alen kopera, peter mohrbacher, donato giancola, leyendecker, boris vallejo
- ultra realistic illustration of steve urkle as the hulk, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha
I want you to write me a list of detailed prompts exactly about the idea written after IDEA. Follow the structure of the example prompts. This means a very short description of the scene, followed by modifiers divided by commas to alter the mood, style, lighting, and more.
IDEA: {idea}""")
return res
class PromptGenerateInput(BaseModel):
"""
生成英文提示詞所需的輸入模型類
"""
idea: str = Field()
class GenerateImageInput(BaseModel):
"""
生成圖片所需的輸入模型類
"""
prompt: str = Field(description="英文提示詞")
tools = [
Tool.from_function(
func=random_poem,
name="詩歌獲取",
description="隨機返回中文的詩詞"
),
Tool.from_function(
func=prompt_generate,
name="提示詞生成",
description="生成圖片需要對應的英文提示詞,當前工具可以將輸入轉換為英文提示詞,以便方便生成",
args_schema=PromptGenerateInput
),
Tool.from_function(
func=generate_image,
name="圖片生成",
description="根據提示詞生成對應的圖片,提示詞需要是英文的,返回是圖片的路徑",
args_schema=GenerateImageInput
),
]
def main():
"""
主函數,初始化代理并執(zhí)行對話
"""
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("幫我生成一張詩詞的圖片?")
if __name__ == '__main__':
main()
參考上面的索引部分:
import os
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
# 設置代理
os.environ['HTTP_PROXY'] = 'socks5h://127.0.0.1:13659'
os.environ['HTTPS_PROXY'] = 'socks5h://127.0.0.1:13659'
# 創(chuàng)建文本加載器
loader = TextLoader('/Users/aihe/Downloads/demo.txt', encoding='utf8')
# 加載文檔
documents = loader.load()
# 文本分塊
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 計算嵌入向量
embeddings = OpenAIEmbeddings()
# 創(chuàng)建向量庫
db = Chroma.from_documents(texts, embeddings)
# 將向量庫轉換為檢索器
retriever = db.as_retriever()
# 創(chuàng)建檢索問答系統
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)
# 運行問題答案檢索
query = "如何申請租戶?"
print(qa.run(query))
print(qa.run("能否說明下你可以提供的功能?"))
參考上述概念,提示詞工具中提供了OutputParser可以把我們的對象轉換為提示詞,告訴LLM要返回什么結構的內容。
import requests
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field
def post_message(type: str, param: dict) -> str:
"""
當需要生成人群、分析畫像、咨詢問題時,使用如下的指示:url 固定為:http://localhost:3001/
如果請求是生成人群,請求的type為crowd; 如果請求是分析畫像,請求的type為analyze; 如果是其他或者答疑,請求的type為question;
請求body的param把用戶指定的條件傳進來即可
"""
result = requests.post("http://localhost:3001/", json={"type": type, "param": param})
return f"Status: {result.status_code} - {result.text}"
class PostInput(BaseModel):
# body: dict = Field(description="""格式:{"type":"","param":{}}""")
type: str = Field(description="請求的類型,人群為crowd,畫像為analyze")
param: dict = Field(description="請求的具體描述")
llm = ChatOpenAI(temperature=0)
tools = [
StructuredTool.from_function(post_message)
]
agent = initialize_agent(tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("我想生成一個性別為男并且在180天訪問過淘特的人群?")
原本做聊天機器人,需要一些前端代碼,但是已經有相應的開源工具,幫我們把LangChian的各種組件做了可視化,直接拖拽即可,我們直接使用LangFlow;
pip install langflow
然后運行命令:
langfow
如果和本地的LangChain有沖突,可以使用Docker運行l(wèi)angfow:
FROM python:3.10-slim
RUN apt-get update && apt-get install gcc g++ git make -y
RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
WORKDIR $HOME/app
COPY --chown=user . $HOME/app
RUN pip install langflow>==0.0.71 -U --user
CMD ["langflow", "--host", "0.0.0.0", "--port", "7860"]
在界面上配置LangChain的三個組件:在最右下角是對應的聊天窗口,輸入下openai的key。
開始聊天驗證下我們的配置:
全程基本上不用怎么寫代碼,只需要了解LangChain的組件是做什么的,基本上就可以搭出一款簡單的聊天機器人。
其它的LangChain組件代理、內存、數據索引也是都可以使用的。
LangChain為構建基于大型語言模型的應用提供了一個強大的框架,將逐步的運用到各個領域中,如:智能客服、文本生成、知識圖譜構建等。隨著更多的工具和資源與LangChain進行集成,大語言模型對人的生產力將會有更大的提升。
應用場景構思:
現在有個平臺已經實現了大部分:https://zapier.com/l/natural-language-actions。底層為OpenAI模型,使用 zapier 來實現將萬種工具連接起來。可以在這個平臺上配置各種工具,模型會根據你的目標選擇相應的動作。工作內容自動化在不遠處很快就會實現。
本文介紹了LangChain框架,它能夠將大型語言模型與其他計算或知識來源相結合,從而實現功能更加強大的應用。接著,對LangChain的關鍵概念進行了詳細說明,并基于該框架進行了一些案例嘗試,旨在幫助讀者更輕松地理解LangChain的工作原理。展望未來,LangChain有望在各個領域發(fā)揮巨大作用,促進我們工作效率的變革。我們正處于AI爆發(fā)的前夜,積極擁抱新技術將會帶來完全不同的感覺。
參考資料:
1. Langchain中文入門:https://github.com/liaokongVFX/LangChain-Chinese-Getting-Started-Guide
2. LangChain官方文檔:https://python.langchain.com/en/latest/modules/indexes/getting_started.html
3. LangFlow,LangChain的可視化編排工具:https://github.com/logspace-ai/langflow
文章轉自微信公眾號@阿里云開發(fā)者