Upload app.py
Browse files
app.py
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
from langchain.schema import Document
|
3 |
+
from langchain.embeddings.openai import OpenAIEmbeddings
|
4 |
+
from langchain.chat_models import ChatOpenAI
|
5 |
+
from langchain.prompts import PromptTemplate
|
6 |
+
from langchain.chains import LLMChain
|
7 |
+
from langchain.chains.question_answering import load_qa_chain
|
8 |
+
from langchain.vectorstores import Chroma
|
9 |
+
import pandas as pd
|
10 |
+
import json
|
11 |
+
import os
|
12 |
+
from dotenv import load_dotenv
|
13 |
+
|
14 |
+
import streamlit as st
|
15 |
+
from langchain.llms import OpenAI
|
16 |
+
from langchain.retrievers.self_query.base import SelfQueryRetriever
|
17 |
+
from langchain.chains.query_constructor.base import AttributeInfo
|
18 |
+
|
19 |
+
|
20 |
+
load_dotenv()
|
21 |
+
|
22 |
+
os.environ["DASHSCOPE_API_KEY"] = 'sk-38e455061c004036a70f661a768ba779'
|
23 |
+
DASHSCOPE_API_KEY='sk-38e455061c004036a70f661a768ba779'
|
24 |
+
|
25 |
+
|
26 |
+
embeddings = OpenAIEmbeddings()
|
27 |
+
vectorstore = Chroma(persist_directory="./chroma_db_modelY", embedding_function=embeddings)
|
28 |
+
|
29 |
+
# vectorstore.as_retriever(search_kwargs={'k': 1})
|
30 |
+
# vectorstore.as_retriever(search_type="mmr")
|
31 |
+
# vectorstore.as_retriever(search_type="similarity_score_threshold",search_kwargs={'k': 3,'score_threshold': 0.1})
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
# print(len(vectorstore.get(limit=1)))
|
36 |
+
|
37 |
+
metadata_field_info = [
|
38 |
+
AttributeInfo(
|
39 |
+
name="brand",
|
40 |
+
description="汽车品牌",
|
41 |
+
type="string",
|
42 |
+
),
|
43 |
+
AttributeInfo(
|
44 |
+
name="model",
|
45 |
+
description="车型",
|
46 |
+
type="string",
|
47 |
+
),
|
48 |
+
AttributeInfo(
|
49 |
+
name="name",
|
50 |
+
description="具体车型名称",
|
51 |
+
type="string",
|
52 |
+
),
|
53 |
+
AttributeInfo(
|
54 |
+
name="year",
|
55 |
+
description="上市年份",
|
56 |
+
type="integer",
|
57 |
+
),
|
58 |
+
AttributeInfo(
|
59 |
+
name="price",
|
60 |
+
description="售价",
|
61 |
+
type="string"
|
62 |
+
)
|
63 |
+
]
|
64 |
+
document_content_description = "汽车车型的用户评价"
|
65 |
+
llm = OpenAI(temperature=0)
|
66 |
+
|
67 |
+
|
68 |
+
retriever = SelfQueryRetriever.from_llm(
|
69 |
+
llm, vectorstore, document_content_description, metadata_field_info, verbose=True
|
70 |
+
)
|
71 |
+
# ,enable_limit=True
|
72 |
+
|
73 |
+
# retriever=SelfQueryRetriever(search_kwargs={"k":3})
|
74 |
+
# retriever.from_llm(llm=llm,vectorstore=vectorstore,document_content_description=document_content_description,metadata_field_info=metadata_field_info,verbose=True,enable_limit=True)
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
#✔️ 增加name属性
|
79 |
+
# print(retriever.get_relevant_documents(query="李光L9,2.0T自动优点"))
|
80 |
+
|
81 |
+
# filter 2.0T自动 丢失
|
82 |
+
# print(retriever.get_relevant_documents(query="我最近考虑买车,目前关注李光L9这款车,请介绍一下2.0T自动优点和缺点"))
|
83 |
+
|
84 |
+
# 这个可以,三个过滤条件
|
85 |
+
# print(retriever.get_relevant_documents(query="请介绍李光L9纯电动,这款车的缺点"))
|
86 |
+
# 四个过滤条件就不行了,目前最多只能三个过滤条件??????结论不扎实,纯电动这个过滤条件丢失了
|
87 |
+
# print(retriever.get_relevant_documents(query="请介绍李光L9纯电动,这款车的缺点"))
|
88 |
+
|
89 |
+
|
90 |
+
# ✔️ 可以找出缺点
|
91 |
+
# print(retriever.get_relevant_documents(query="李光L9的缺点"))
|
92 |
+
|
93 |
+
|
94 |
+
# ✔️ 全部找出来,把优点排前面,缺点排后面
|
95 |
+
# print(retriever.get_relevant_documents(query="丰田卡罗拉优点,2020年上市"))
|
96 |
+
|
97 |
+
# print(retriever.get_relevant_documents(query="驾驶者之车",metadata={"brand": '理想'}))
|
98 |
+
|
99 |
+
# This example only specifies a relevant query
|
100 |
+
# ✔️
|
101 |
+
# print(retriever.get_relevant_documents("大众高尔夫的优点"))
|
102 |
+
# ✔️
|
103 |
+
# print(retriever.get_relevant_documents("2020年之后上市的宝马"))
|
104 |
+
# print(retriever.get_relevant_documents("2015年之后上市的宝马"))
|
105 |
+
|
106 |
+
# 2.检索生成结果
|
107 |
+
def retrieve_info(query):
|
108 |
+
return retriever.get_relevant_documents(query=query)
|
109 |
+
|
110 |
+
# 3.设置LLMChain和提示
|
111 |
+
llm=ChatOpenAI(temperature=0, model='gpt-3.5-turbo-16k-0613')
|
112 |
+
|
113 |
+
template = """
|
114 |
+
你是一名掌握了全部汽车用户真实使用评价内容的智能回复机器人。
|
115 |
+
我将发送给你一位客户关于汽车使用、购买建议、与其他品牌车型对比等方面的问题。
|
116 |
+
客户希望你在真实车主评价的基础上,归纳总结形成一句结论性的内容,发送给这位客户,并遵循以下所有规则。
|
117 |
+
1/ 在篇幅、语气、逻辑论证和其他细节方面,答复应与尽可能的给人专业的感觉,如实客观的表达问题的答案,不要增加你自己的幻觉。
|
118 |
+
2/ 如果在真实车主评价内容中没有这个问题的相关答案,请回答:“很抱歉,基于真实车主的口碑数据,我暂时不能给出您这个问题的答案。“
|
119 |
+
{message}
|
120 |
+
以下是针对这个问题,真实车主评价内容:
|
121 |
+
{best_practice}
|
122 |
+
请为这个客户返回最符合问题的最佳回复内容:
|
123 |
+
|
124 |
+
所有回复均为中文
|
125 |
+
"""
|
126 |
+
prompt=PromptTemplate(
|
127 |
+
input_variables=["message","best_practice"],
|
128 |
+
template=template
|
129 |
+
)
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
st.set_page_config(page_title="汽车口碑GPT",page_icon="🚗")
|
134 |
+
|
135 |
+
chain=LLMChain(llm=llm,prompt=prompt)
|
136 |
+
# 4.检索生成结果
|
137 |
+
def generate_response(message):
|
138 |
+
best_practice = retrieve_info(message)
|
139 |
+
|
140 |
+
# st.markdown(f'<small style="color: grey;">向量召回内容��{best_practice}</small>', unsafe_allow_html=True)
|
141 |
+
# 获取每个 Document 对象中的 page_content 属性,并将其内容组合为一个字符串
|
142 |
+
best_practice_text = "<br>".join([doc.page_content for doc in best_practice])
|
143 |
+
|
144 |
+
# 在页面上以较小的字体打印 best_practice_text 变量的内容,并设置颜色为淡灰色
|
145 |
+
st.markdown(f'<small style="color: #aaaaaa;">召回内容:<br>{best_practice_text}</small>', unsafe_allow_html=True)
|
146 |
+
|
147 |
+
|
148 |
+
|
149 |
+
|
150 |
+
print('message:',message)
|
151 |
+
print('向量召回内容Len:',len(best_practice))
|
152 |
+
print('向量召回内容:',best_practice)
|
153 |
+
|
154 |
+
print('')
|
155 |
+
print('')
|
156 |
+
print('')
|
157 |
+
print('')
|
158 |
+
print('')
|
159 |
+
print('')
|
160 |
+
print('')
|
161 |
+
|
162 |
+
# chain_qw = load_qa_chain(llm=llm_qwen, chain_type="stuff",prompt=prompt)
|
163 |
+
# chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff", prompt=prompt)
|
164 |
+
# response=chain({"input_documents": best_practice, "question": message}, return_only_outputs=True)
|
165 |
+
|
166 |
+
|
167 |
+
|
168 |
+
# response=chain_qw({"input_documents": best_practice, "question": message}, return_only_outputs=True)
|
169 |
+
# response=chain.run(input_documents=best_practice, question=message)
|
170 |
+
response = chain.run(message=message,best_practice=best_practice)
|
171 |
+
return response
|
172 |
+
|
173 |
+
# message='特斯拉ModelY的后备箱可以放下自行车么?'
|
174 |
+
# message='特斯拉ModelY的后备箱可以放下冰箱么?'
|
175 |
+
|
176 |
+
# 很抱歉,基于真实车主的口碑数据,我暂时不能给出您这个问题的答案。
|
177 |
+
# message='特斯拉ModelY四驱能越野么?'
|
178 |
+
|
179 |
+
|
180 |
+
# message='特斯拉Model Y的后备箱可以放下自行车么?'
|
181 |
+
# print(generate_response(message))
|
182 |
+
|
183 |
+
# 5.创建一个应用使用streamlit框架
|
184 |
+
def main():
|
185 |
+
|
186 |
+
st.header("汽车口碑GPT 🚗")
|
187 |
+
|
188 |
+
message = st.text_area("问问我吧:我知道关于特斯拉ModelY的一切问题:冬天续航衰减多少?后备箱能放下自行车么?")
|
189 |
+
|
190 |
+
if message:
|
191 |
+
|
192 |
+
result_placeholder = st.empty() # 创建一个空位,用于显示临时消息
|
193 |
+
result_placeholder.write("正在生成回复内容,请稍后...")
|
194 |
+
|
195 |
+
result = generate_response("特斯拉ModelY"+message)
|
196 |
+
|
197 |
+
st.info(result)
|
198 |
+
result_placeholder.empty() # 清空临时消息
|
199 |
+
|
200 |
+
|
201 |
+
if __name__ == "__main__":
|
202 |
+
main()
|