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" : "<>"} # "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})