TrafficLens / app.py
KatGaw's picture
adding files
fbac160
raw
history blame
6.94 kB
from openai import OpenAI
import streamlit as st
from langchain_openai import ChatOpenAI
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
import markdown
from operator import itemgetter
from langchain.schema.runnable import RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate
from langchain.schema import Document
from dotenv import load_dotenv
from langchain_community.vectorstores import Qdrant
#from langchain_qdrant import Qdrant
import os
load_dotenv()
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
base_llm = ChatOpenAI(model="gpt-4o")
embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
#========= DATA ================
# UPLOAD DOC
with open(f'./data/sentiment_index_traffic_index_final.md', "r", encoding="utf-8") as file_content:
docs=file_content.read()
docs = [Document(page_content=markdown.markdown(docs))]
#docs = [Document(page_content=doc) for doc in docs]
print(docs)
split_documents = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size = 1000,
chunk_overlap = 20
).split_documents(docs)
max_chunk_length = 0
vectorstore = Qdrant.from_documents(
split_documents,
embedding_model,
location=":memory:",
collection_name="langchainblogs")
retriever = vectorstore.as_retriever()
print("Loaded Vectorstore")
# Ste up ur retriever using LangChain
retriever = vectorstore.as_retriever()
#========== APP
st.set_page_config(page_title="LangChain Agent", layout="wide")
st.title("Narrativ 📰")
st.image('./data/Sentiment_index_traffic.png')
st.write('Start by entering topic into the sidebar.')
sideb=st.sidebar
with st.sidebar:
prompt=st.text_input("Insert topic: ")
check1=sideb.button(f"Submit")
if 'messages' not in st.session_state:
st.session_state.messages = []
if check1:
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
#Generate summarized message rationalize dominant sentiment
RAG_PROMPT = """# Traffic Analyst - Transurban Prompt
You are a Transurban traffic consultant focusing on the I-495 and I-95 express lanes in the Greater Washington area (GWA). Your task is to analyze news articles provided by a client on a specific topic. You will receive the full text of the relevant articles for the assigned topic, along with key data points.
## Your Tasks:
### 1. Summarize Opinions:
- Extract the key opinions and perspectives from the provided news articles.
- The news articles will include: title, URL, date, text, article source, sentiment index created by Transurban, sentiment index using HF (Hugging Face) model, and confidence for the HF index.
- Highlight any significant patterns, agreements, or disagreements across the sources.
### 2. Analyze Sentiment:
- Determine the overall sentiment (positive, negative, neutral) about the topic based on the extracted opinions.
- Provide a clear explanation of your sentiment conclusion, referencing specific points or trends from the articles.
### 3. Provide Chain-of-Thought Reasoning:
- Detail your reasoning process step by step. Explain how you interpreted the articles, derived insights, and reached your sentiment conclusion.
- Ensure the reasoning is logical, transparent, and grounded in the content provided.
### 4. Collect URL Sources:
- From the provided context, select 5 critical and recent URL sources related to the topic.
## Output Format:
- **Summary of Opinions:** [Concise summary of key opinions]
- **Sentiment Analysis:**
- Sentiment: [Positive/Negative/Neutral]
- Reasoning: [Detailed explanation here]
- **Chain-of-Thought Reasoning:** [Step-by-step explanation]
- **Sources:** [URLs for 5 most critical and recent articles on this topic]
## Guidelines:
- Maintain objectivity and precision in your analysis.
- Focus on the context specific to the Greater Washington Area.
- Use professional and analytical language suitable for client reports.
- Respond in the language of the article (mostly English).
CONTEXT:
{context}
QUERY:
{question}
Use the provide context to answer the provided user question. Only use the provided context to answer the question. If you do not know the answer, response with "I don't know"
"""
rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)
# RAG CHAIN
lcel_rag_chain = (
# INVOKE CHAIN WITH: {"question" : "<<SOME USER QUESTION>>"}
# "question" : populated by getting the value of the "question" key
# "context" : populated by getting the value of the "question" key and chaining it into the base_retriever
{"context": itemgetter("question") | retriever, "question": itemgetter("question")}
# "context" : is assigned to a RunnablePassthrough object (will not be called or considered in the next step)
# by getting the value of the "context" key from the previous step
| RunnablePassthrough.assign(context=itemgetter("context"))
# "response" : the "context" and "question" values are used to format our prompt object and then piped
# into the LLM and stored in a key called "response"
# "context" : populated by getting the value of the "context" key from the previous step
| {"response": rag_prompt | base_llm, "context": itemgetter("context")}
)
summary = lcel_rag_chain.invoke({"question" : prompt})
print(summary)
st.chat_message("assistant").write((summary['response'].content))
st.session_state.messages.append({"role": "assistant", "content": summary['response'].content})
#answers=np.append(res["messages"][-1].content,summary)
client = OpenAI(api_key=OPENAI_API_KEY)
if "openai_model" not in st.session_state:
st.session_state["openai_model"] = "gpt-4o"
if prompt := st.chat_input("Nějaké další otázky? "):
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
# Display assistant response in chat message container
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[
{"role": m["role"], "content": m["content"]}
for m in st.session_state.messages
],
stream=True,
)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})