nmurugesh's picture
Update app.py
96dbb53 verified
# !pip install langchain langchain-groq sentence-transformers langchainhub faiss-cpu gradio gradio_client
# !pip install crewai==0.28.8 crewai_tools==0.1.6 langchain_community==0.0.29
# !pip install gpt4all
from crewai import Agent, Task, Crew
import os
import json
import uuid
# import langchain libraries
# !pip install langchain langchain-groq langchainhub duckduckgo-search
from langchain.agents import AgentExecutor
from langchain.agents import create_react_agent
from langchain.agents import create_structured_chat_agent
from langchain import hub
from langchain_groq import ChatGroq
from langchain_core.prompts import ChatPromptTemplate
from langchain.agents import Tool
from langchain_community.tools import DuckDuckGoSearchResults
from langchain.schema.output_parser import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_community.tools import DuckDuckGoSearchRun
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
from langchain import hub
from langchain.chains import RetrievalQA
from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings
from langchain_community.document_loaders.csv_loader import CSVLoader
from langchain.tools import DuckDuckGoSearchRun
from langchain_core.output_parsers import JsonOutputParser
# from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
#import gradio libraries
# !pip install gradio gradio_client
import gradio as gr
#import vectorstore libraries
# !pip install faiss-cpu
from langchain_community.vectorstores import FAISS
embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
groq_api_key = os.getenv('groq')
# Define the LLM - We shall use ChatGroq of Groq Platform and LLama70B
# This llm definition is redundant as now models will be chosen by user
llm = ChatGroq(
api_key=groq_api_key,
model="llama3-70b-8192",
# model = 'gemma-7b-it',
temperature = 0
# model = 'mixtral-8x7B-32768'
)
import os
from langchain.document_loaders import TextLoader
# folder_path = "https://huggingface.co/spaces/nmurugesh/My-Interview-Chatbot/blob/main/" # Replace with the actual path to your folder
file_names = ['banking.txt', 'certifications.txt','deeplearning.txt','domain-banking.txt',
'education.txt','imple.txt','personal.txt','presales.txt','publications.txt',
'summary.txt', 'requirements-eng.txt','testing.txt','work experience.txt',
'linkedin-articles.txt','kaggle-comp.txt','analytics-vidhya-articles.txt']
documents = []
for filename in file_names:
if filename.endswith(".txt"):
loader = TextLoader(filename)
doc = loader.load()[0] # Load the single Document object for the file
documents.append(doc)
vectorstore1 = FAISS.from_documents(documents, embedding_function)
vectorstore1.save_local("vectorstore1")
retriever2 = vectorstore1.as_retriever(search_type='mmr',search_kwargs={"k": 10})
import os
os.environ["OPENAI_API_KEY"] = groq_api_key
# Agent 1: Interview candidate
Interview_candidate = Agent(
llm = llm,
role="Interview candidate who gives final answers",
goal='''You are currently attending an interview. \
The name of the company that is interviewing is {company}. The position for which interview is conducted is {position}. \
Your objective is to ace the interview and get the job based on your qualifications and expertise''',
verbose=True,
memory = True,
backstory=(''' You are currently attending an interview. \
For all the questions asked, you should NOT ONLY answer from the context provided - \
BUT ALSO from the conversational history available to you. You can also use any conversational memory history stored as embeddings as part of the crew. \
Your answer should be confidently articulated, using professional tone and style, and concise and clear.'''),
)
# Task for Researcher Agent: Extract Job Requirements
Interview_answer_task = Task(
description=('''You are being interviewed by a company. The name of the company that is interviewing is {company}. The position for which interview is conducted is {position}. \
Note that you might have been asked questions before this one. \
You should answer based on NOT ONLY the current information context provided \
BUT ALSO based on previous questions, answers and context as part of the conversation. \
The current question is {question}. The current context is {context}. You should use any memory information you have already stored based on conversational history)'''
),
expected_output=("You are currently attending an interview.For all the questions asked, you SHOULD answer only from the context provided - \
that is data provided for this purpose. Your answer should be confidently articulated, using professional tone and style, and concise and clear."
),
agent=Interview_candidate )
interview_crew = Crew(
agents=[ Interview_candidate],
tasks=[ Interview_answer_task],
memory = True,
embedder={
"provider": "gpt4all"
},
verbose=True
)
from langchain.chains import create_history_aware_retriever, create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
### Contextualize question ###
contextualize_q_system_prompt = (
"Given a chat history and the latest user question "
"which might reference context in the chat history, "
"formulate a standalone question which can be understood "
"without the chat history. Do NOT answer the question, "
"just reformulate it if needed and otherwise return it as is."
)
contextualize_q_prompt = ChatPromptTemplate.from_messages(
[
("system", contextualize_q_system_prompt),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
]
)
history_aware_retriever = create_history_aware_retriever(
llm, retriever2, contextualize_q_prompt
)
### Answer question ###
system_prompt = (
"You are an assistant for question-answering tasks. "
"Use the following pieces of retrieved context to answer "
"the question. If you don't know the answer, say that you "
"don't know. Use three sentences maximum and keep the "
"answer concise."
"\n\n"
"{context}"
)
qa_prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
]
)
question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)
### Statefully manage chat history ###
store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
conversational_rag_chain = RunnableWithMessageHistory(
rag_chain,
get_session_history,
input_messages_key="input",
history_messages_key="chat_history",
output_messages_key="answer",
)
from langchain_core.messages import AIMessage, HumanMessage
# def get_conversation(sessionid):
# conv = []
# for message in store[sessionid].messages:
# if isinstance(message, AIMessage):
# prefix = "AI"
# else:
# prefix = "User"
# conv.append(f"{prefix}: {message.content}\n")
# return "\n".join(conv)
def generate_session_id():
return str(uuid.uuid4())
def answer(input1,input2,input3,input4,session_id):
question = input4
company = input1
position = input2
recruiter = input3
session_id1 = input3 + str(session_id)
context = conversational_rag_chain.invoke(
{"input": question},
config={
"configurable": {"session_id": session_id1}
}, # constructs a key "abc123" in `store`.
)["answer"]
result =interview_crew.kickoff(inputs={"question":question,'context':context,'company':company,'position':position})
return result,session_id
def get_conversation1(input3,sess):
conv = []
sess1 = input3 + str(sess)
if sess1 not in store:
return "No conversation history available",sess
for message in store[sess1].messages:
if isinstance(message, AIMessage):
prefix = "AI"
else:
prefix = "User"
conv.append(f"{prefix}: {message.content}\n")
return "\n".join(conv), sess
def reset_store(sessionid):
if sessionid in store:
store[sessionid].clear()
return sessionid
from gradio import Image
with gr.Blocks() as demo:
# Add a Markdown block for the description
gr.Markdown("""<h1 style='color: blue;'>Interview Chatbot for N Murugesan</h1>""")
gr.Markdown("""Powered by CrewAI,Gradio, Groq, Llama3, FAISS, Langchain""")
gr.Markdown(
"""
<h2 style = 'color: blue;'>
This chatbot will answer interview questions on behalf of Murugesan Narayanaswamy! </h2>
"""
)
gr.Image("photo-recent.jpg", width=250)
gr.Markdown("""<h2 style='color: blue;'>Ask any HR Round Interview Questions - Factual Answers based on Resume!</h2>""")
# Use a Column to structure the inputs and outputs
with gr.Column():
# First text input and button
text_input1 = gr.Textbox(
label="Enter the Company Name!",
placeholder='''Enter the company name e.g. Cognizant Technologies ''',
value = 'ABC Technologies'
)
text_input2 = gr.Textbox(
label="Enter the Position you are interviewing for!",
placeholder='''Enter the position you are interviewing for e.g. Generative AI - Consultant''',
value = 'Generative AI - Consultant'
)
text_input3 = gr.Textbox(
label="Enter Interviewer Name!",
placeholder='''Enter Interviewer Name ''',
value = 'Recruiter-ABC',
)
text_input4 = gr.Textbox(
label="Enter your question here!",
placeholder='''Ask your question; e.g., Tell something about yourself; Your career path has been diverse; \
Could you walk us through the key transitions and the motivations behind those changes?''',
value = 'List the competitions you have participated in kaggle'
)
outputs1 = gr.Textbox(label="Output")
# def getsession(sessionid):
# return sessionid,sessionid
sessionid = gr.State(value=generate_session_id())
button1 = gr.Button("Answer!")
button1.click(answer, inputs=[text_input1, text_input2, text_input3, text_input4, sessionid], outputs=[outputs1, sessionid])
# button1.click(getsession,inputs=[sessionid],outputs=[outputs1,sessionid])
gr.Markdown("""<h2 style='color: blue;'>Get Interview Transcript!</h2>""")
outputs2 = gr.Textbox(label="Interview Transcript!",show_copy_button=True)
button2 = gr.Button("Get Interview Transcript!")
# button2.click(lambda sessionid: get_conversation1,inputs=[sessionid],outputs=[outputs2,sessionid])
button2.click(lambda text_input3,sessionid: get_conversation1(text_input3,sessionid), inputs=[text_input3,sessionid], outputs=[outputs2, sessionid])
# Launch the Gradio app
demo.launch()