作者:CSDN博客
Langchain基础例子
这里写目录标题
Langchain基础例子一、模型调用
1.网络API调用2.本地调用ollama
3.本地调用Xinference
二、应用Demo
1.实现一个朴素RAG2.实现一个带界面的RAG3.与Neo4j结合
三、其它
官方文档:
https://python.langchain.com/v0.2/docs/introduction/
langchain的更新非常快,变化也非常大。
0.1:2024.1
0.2:2024.5
0.3:2024.9,不再支持python3.8
下面代码是基于 0.2.16的
一、模型调用
1.网络API调用
方式一:- from langchain_community.chat_models import ChatTongyi
- import os
- os.environ["DASHSCOPE_API_KEY"]='用你自己的api—key'
- chat = ChatTongyi(model='qwen-long',top_p=0.8,temperature=0.1)print(chat.invoke("你是谁?1+1等于多少?"))
复制代码 方式二:- from langchain_core.prompts import PromptTemplate
- import os
- from langchain_community.llms import Tongyi
- DASHSCOPE_API_KEY ='用你自己的api_key'
- os.environ["DASHSCOPE_API_KEY"]= DASHSCOPE_API_KEY
- # llm = Tongyi()# 指定模型
- llm = Tongyi(model_name="qwen-plus")# 默认qwen-plus, 为什么qwen-long不能用
- template ="""Question: {question}
- Answer: Let's think step by step."""
- prompt = PromptTemplate.from_template(template)
- chain = prompt | llm
- question ="What NFL team won the Super Bowl in the year Justin Bieber was born?"print(chain.invoke({"question": question}))
复制代码 方式三:针对qwen- '''
- 依赖dashscope
- 需要安装pip install dashscope
- '''import os
- from langchain_community.llms import Tongyi
- os.environ["DASHSCOPE_API_KEY"]='用你自己的api_key'
- text ="今天天气怎么样?"print(Tongyi().invoke(text))
复制代码 2.本地调用ollama
方式一:基于ollama库- import ollama
- back = ollama.chat(model="qwen2.5",messages=[{"role":"user","content":"简单介绍一下你自己"}],
- options ={"temperature":1145141919810,# 模型温度"num_ctx":4096# 返回的最大token数},# ...
- stream =False)# 是否流式输出)print(back.message['content'])
复制代码 方式二:基于langchain
LLM问答
方式1:chat方式- # from langchain.chat_models import ChatOpenAIfrom langchain_community.chat_models import ChatOllama
- from langchain_core.messages import HumanMessage
- llm = ChatOllama(model="qwen2:7b")
- messages =[
- HumanMessage(
- content="你好,请你介绍一下你自己",)]
- response = llm.invoke(messages)print(response)
复制代码 方式2:指令方式- # from langchain_community.llms import OpenAIfrom langchain_community.llms.ollama import Ollama
- llm = Ollama(base_url='http://localhost:11434', model='qwen2:7b')print(llm('你是谁'))
复制代码 Embedding
- # from langchain_community.embeddings.openai import OpenAIEmbeddingsfrom langchain_community.embeddings import OllamaEmbeddings
- ollama_emb = OllamaEmbeddings(base_url="http://127.0.0.1:11434", model="twwch/m3e-base:latest")
- r1 = ollama_emb.embed_documents(["发动机点不着或","汽车停放一晚后亏电",])
- r2 = ollama_emb.embed_query("我爱北京天安门")print(r1)print(r2)
复制代码 单独Post接口调用
- # -*- coding: utf-8 -*-import requests
- import json
- defsend_message_to_ollama(message, port=11434):
- url =f"http://127.0.0.1:{port}/api/chat"
- payload ={"model":"qwen2.5:7b","messages":[{"role":"user","content": message}]}
- response = requests.post(url, json=payload)if response.status_code ==200:
- response_content =""for line in response.iter_lines():if line:
- response_content += json.loads(line)["message"]["content"]return response_content
- else:returnf"Error: {response.status_code} - {response.text}"if __name__ =="__main__":
- user_input ="介绍一下北京的旅游景点?"
- response = send_message_to_ollama(user_input)print("Ollama's response:")print(response)
复制代码 3.本地调用Xinference
LLM问答
- from langchain.llms import Xinference
- from langchain.prompts import PromptTemplate
- llm = Xinference(server_url="http://localhost:9997", model_uid="qwen2:7b")
- response = llm("你是谁")print(response)
复制代码 Embedding
- from langchain_community.embeddings import XinferenceEmbeddings
- from langchain_community.document_loaders import TextLoader
- from langchain.text_splitter import RecursiveCharacterTextSplitter
- from langchain_community.vectorstores import Chroma
- # 1.文件加载
- loader = TextLoader("三体.txt", encoding="UTF-8")
- docs = loader.load()# 2.文本切割# text_splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=0)
- text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=0)
- texts = text_splitter.split_documents(docs)print(texts[0].page_content)# 3.向量化及存储
- embeddings = XinferenceEmbeddings(server_url="http://127.0.0.1:9997", model_uid="bge-large-zh-v1.5")
- embeded_texts = embeddings.embed_documents([t.page_content for t in texts])print(len(embeded_texts),len(embeded_texts[0]))
- db = Chroma.from_documents(texts, embeddings)# 文本向量存储# 4.文本检索
- query ="章北海是谁?"
- query_vector = embeddings.embed_query(query)print(query_vector[:4])
- docs = db.similarity_search_by_vector(query_vector, k=1)print(docs[0].page_content)
复制代码 从长长的睡眠中醒来,章北海一看时间,居然睡了十五个小时,这可能是他除了长达两个世纪的冬眠外睡得最长的一觉了。此时,他有一种新生的感觉,仔细审视自己的内心后,他发现了这种感觉的来源。
他现在是一个人了。
以前,即使独自悬浮在无际的太空中,他也没有一人独处的感觉,父亲的眼睛在冥冥之中看着他,这种目光每时每刻都存在,像白昼的太阳和夜里的星光,已成为他的世界的一部分,而现在父亲的目光消失了。
二、应用Demo
1.实现一个朴素RAG
LLM:通过ollama调用
Embedding:通过Xfinference调用
向量数据库:使用Chroma- # -*- coding: utf-8 -*-from langchain_community.document_loaders import DirectoryLoader,TextLoader
- from langchain.text_splitter import CharacterTextSplitter,RecursiveCharacterTextSplitter
- from langchain_community.vectorstores import Chroma
- from langchain.chains import ConversationalRetrievalChain, ChatVectorDBChain
- from langchain.prompts import SystemMessagePromptTemplate,HumanMessagePromptTemplate,ChatPromptTemplate
- from langchain_community.chat_models import ChatOllama
- from langchain_community.embeddings import XinferenceEmbeddings
- # 加载pdf文件# loader = DirectoryLoader(# './pdf/', glob="*.pdf", show_progress=True# )# 加载txt文件
- loader = TextLoader('./txt/三体.txt')
- docs = loader.load()# text_splitter = CharacterTextSplitter(chunk_size=1000,chunk_overlap=0)
- text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
- docs_splitted = text_splitter.split_documents(docs)# embeddings = OpenAIEmbeddings()
- embeddings = XinferenceEmbeddings(server_url="http://127.0.0.1:9997", model_uid="m3e-base")
- db = Chroma.from_documents(
- docs_splitted,
- embeddings,
- persist_directory="./chroma_db",)
- retriever = db.as_retriever()
- system_template ="""
- 使用下面的上下文来回答问题。如果你不知道答案,就说你不知道,不要编造答案。用中文回答这些问题。
- -------------
- {question}
- -------------
- {chat_history}
- """
- messages =[
- SystemMessagePromptTemplate.from_template(system_template),
- HumanMessagePromptTemplate.from_template("{question}"),]
- prompt = ChatPromptTemplate.from_messages(messages)# llm = ChatOpenAI(temperature=0.1, max_tokens=2048)
- llm = ChatOllama(temperature=0.1, max_tokens=2048, model="qwen2.5")
- qa = ConversationalRetrievalChain.from_llm(llm, retriever=retriever, condense_question_prompt=prompt)
- chat_history =[]whileTrue:
- question =input("请输入问题:")
- result = qa({"question": question,"chat_history": chat_history})print(result["answer"])
- chat_history.append((question, result["answer"]))
复制代码 2.实现一个带界面的RAG
未实际跑- # -*- coding: utf-8 -*-'''
- llm和嵌入模型均调用Xinference接口
- '''import streamlit as st
- from langchain.llms import Xinference
- from langchain.embeddings import XinferenceEmbeddings
- from langchain.prompts import PromptTemplate
- from langchain.chains import LLMChain
- from langchain.document_loaders import TextLoader
- from langchain.text_splitter import CharacterTextSplitter
- from langchain.vectorstores import Chroma
- # Customize the layout
- st.set_page_config(page_title="Local AI Chat Powered by Xinference", page_icon=" ", layout="wide")# Write uploaded file in temp dirdefwrite_text_file(content, file_path):try:withopen(file_path,'w')asfile:file.write(content)returnTrueexcept Exception as e:print(f"Error occurred while writing the file: {e}")returnFalse# Prepare prompt template
- prompt_template ="""
- 使用下面的上下文来回答问题。
- 如果你不知道答案,就说你不知道,不要编造答案。
- {context}
- 问题: {question}
- 回答:"""
- prompt = PromptTemplate(template=prompt_template, input_variables=["context","question"])# Initialize the Xinference LLM & Embeddings
- xinference_server_url ="http://localhost:9997"
- llm = Xinference(server_url=xinference_server_url, model_uid="my_llm")
- embeddings = XinferenceEmbeddings(server_url=xinference_server_url, model_uid="my_embedding")
- llm_chain = LLMChain(llm=llm, prompt=prompt)
- st.title(" 文档对话")
- uploaded_file = st.file_uploader("上传文件",type="txt")if uploaded_file isnotNone:
- content = uploaded_file.read().decode('utf-8')
- file_path ="/tmp/file.txt"
- write_text_file(content, file_path)
- loader = TextLoader(file_path)
- docs = loader.load()
- text_splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=0)
- texts = text_splitter.split_documents(docs)
- db = Chroma.from_documents(texts, embeddings)
- st.success("上传文档成功")# Query through LLM
- question = st.text_input("提问", placeholder="请问我任何关于文章的问题", disabled=not uploaded_file)if question:
- similar_doc = db.similarity_search(question, k=1)
- st.write("相关上下文:")
- st.write(similar_doc)
- context = similar_doc[0].page_content
- query_llm = LLMChain(llm=llm, prompt=prompt)
- response = query_llm.run({"context": context,"question": question})
- st.write(f"回答:{response}")
复制代码 3.与Neo4j结合
Neo4j官方例子
图谱RAG
- # -*- coding: utf-8 -*-'''
- 基于Neo4j的电影情节向量检索器
- 1.Create the Neo4jVector from the moviePlots vector index.
- 2.Create the RetrievalQA chain using the Neo4jVector as the retriever.
- 3.Update the tools to use the RetrievalQA chain.
- '''from langchain.chains import RetrievalQA
- from langchain_openai import ChatOpenAI, OpenAIEmbeddings
- from langchain_community.graphs import Neo4jGraph
- from langchain_community.vectorstores import Neo4jVector
- OPENAI_API_KEY ="sk-..."
- llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY)
- embedding_provider = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY)
- graph = Neo4jGraph(
- url="bolt://localhost:7687",
- username="neo4j",
- password="pleaseletmein")
- movie_plot_vector = Neo4jVector.from_existing_index(
- embedding_provider,
- graph=graph,
- index_name="moviePlots",
- embedding_node_property="plotEmbedding",
- text_node_property="plot",)
- plot_retriever = RetrievalQA.from_llm(
- llm=llm,
- retriever=movie_plot_vector.as_retriever())
- response = plot_retriever.invoke({"query":"A movie where a mission to the moon goes wrong"})print(response)
复制代码 图谱Agent
- # -*- coding: utf-8 -*-'''
- 电影预告片agent
- '''from langchain_openai import ChatOpenAI
- from langchain.agents import AgentExecutor, create_react_agent
- from langchain.tools import Tool
- from langchain import hub
- from langchain_core.prompts import ChatPromptTemplate
- from langchain_core.runnables.history import RunnableWithMessageHistory
- from langchain.schema import StrOutputParser
- from langchain_community.tools import YouTubeSearchTool
- from langchain_community.chat_message_histories import Neo4jChatMessageHistory
- from langchain_community.graphs import Neo4jGraph
- from uuid import uuid4
- SESSION_ID =str(uuid4())print(f"Session ID: {SESSION_ID}")
- llm = ChatOpenAI(openai_api_key="sk-...")
- graph = Neo4jGraph(
- url="bolt://localhost:7687",
- username="neo4j",
- password="pleaseletmein")
- prompt = ChatPromptTemplate.from_messages([("system","You are a movie expert. You find movies from a genre or plot.",),("human","{input}"),])
- movie_chat = prompt | llm | StrOutputParser()
- youtube = YouTubeSearchTool()defget_memory(session_id):return Neo4jChatMessageHistory(session_id=session_id, graph=graph)defcall_trailer_search(input):input=input.replace(","," ")return youtube.run(input)
- tools =[
- Tool.from_function(
- name="Movie Chat",
- description="For when you need to chat about movies. The question will be a string. Return a string.",
- func=movie_chat.invoke,),
- Tool.from_function(
- name="Movie Trailer Search",
- description="Use when needing to find a movie trailer. The question will include the word trailer. Return a link to a YouTube video.",
- func=call_trailer_search,),]
- agent_prompt = hub.pull("hwchase17/react-chat")
- agent = create_react_agent(llm, tools, agent_prompt)
- agent_executor = AgentExecutor(agent=agent, tools=tools)
- chat_agent = RunnableWithMessageHistory(
- agent_executor,
- get_memory,
- input_messages_key="input",
- history_messages_key="chat_history",)whileTrue:
- q =input("> ")
- response = chat_agent.invoke({"input": q
- },{"configurable":{"session_id": SESSION_ID}},)print(response["output"])
复制代码 图谱chatBot
- # -*- coding: utf-8 -*-from langchain_openai import ChatOpenAI
- from langchain.agents import AgentExecutor, create_react_agent
- from langchain.tools import Tool
- from langchain import hub
- from langchain_core.prompts import ChatPromptTemplate
- from langchain_core.runnables.history import RunnableWithMessageHistory
- from langchain.schema import StrOutputParser
- from langchain_community.chat_message_histories import Neo4jChatMessageHistory
- from langchain_community.graphs import Neo4jGraph
- from uuid import uuid4
- SESSION_ID =str(uuid4())print(f"Session ID: {SESSION_ID}")
- llm = ChatOpenAI(openai_api_key="sk-...")
- graph = Neo4jGraph(
- url="bolt://localhost:7687",
- username="neo4j",
- password="pleaseletmein")
- prompt = ChatPromptTemplate.from_messages([("system","You are a Neo4j expert having a conversation about how to create Cypher queries",),("human","{input}"),])
- cypher_chat = prompt | llm | StrOutputParser()defget_memory(session_id):return Neo4jChatMessageHistory(session_id=session_id, graph=graph)
- tools =[
- Tool.from_function(
- name="Cypher Support",
- description="For when you need to talk about Cypher queries.",
- func=cypher_chat.invoke,)]
- agent_prompt = hub.pull("hwchase17/react-chat")
- agent = create_react_agent(llm, tools, agent_prompt)
- agent_executor = AgentExecutor(agent=agent, tools=tools)
- cypher_agent = RunnableWithMessageHistory(
- agent_executor,
- get_memory,
- input_messages_key="input",
- history_messages_key="chat_history",)whileTrue:
- q =input("> ")
- response = cypher_agent.invoke({"input": q
- },{"configurable":{"session_id": SESSION_ID}},)print(response["output"])
复制代码 三、其它
1.获取langchain-hub的Prompt
- from langchain import hub
- prompt = hub.pull("ezhil/text2cypher")print(prompt)
复制代码 input_variables=[‘question’, ‘samples’, ‘schema’] metadata={‘lc_hub_owner’: ‘ezhil’, ‘lc_hub_repo’: ‘text2cypher’, ‘lc_hub_commit_hash’: ‘0e15cdc2394c21084ae5e44d2632753bf4f83f2afa8427dec12c31e58f469449’} template="You are an expert Neo4j Cypher translator who understands the question in english and convert to Cypher strictly based on the Neo4j Schema provided and following the instructions below:\n1. Generate Cypher query compatible ONLY with Neo4j Version 5\n2. Do not use EXISTS, SIZE keywords in the cypher. Use alias when using the WITH keyword\n3. Please do not use same variable names for different nodes and relationships in the query.\n4. Use only Nodes and relationships mentioned in the schema\n5. Always enclose the Cypher output inside 3 backticks\n6. Always do a case-insensitive and fuzzy search for any properties related search. Eg: to search for a Company name use toLower(c.name) contains 'neo4j'\n8. Always use aliases to refer the node in the query\n9. ‘Answer’ is NOT a Cypher keyword. Answer should never be used in a query.\n10. Please generate only one Cypher query per question. \n11. Cypher is NOT SQL. So, do not mix and match the syntaxes.\n12. Every Cypher query always starts with a MATCH keyword.\n\nSchema:\n{schema}\nSamples:\n{samples}\n\nQuestion: {question}\nAnswer: "
原文地址:https://blog.csdn.net/xiangxiang613/article/details/143189378 |