{ "cells": [ { "cell_type": "markdown", "id": "5a1af5c8-b759-41c8-b813-62b4512f1276", "metadata": {}, "source": [ "# GenAI Career Assistant Agent – Your Ultimate Guide to a Career in Generative AI!🚀\n", "\"Open\n", "## Overview\n", "Meet the GenAI Career Assistant—an AI-powered mentor designed to simplify and support your journey in Generative AI learning, Resume preparation, Interview assistant and job hunting.\n", "#### Tech Stack\n", "I have used all free Open source.
\n", "Langchain,Langgraph, Gemini LLM, DuckDuckGoSearchResult\n", "\n", "## Motivation\n", "As GenAI rapidly evolves, more people are eager to learn it for career advancement or transition. However, navigating the vast resources on the internet and platforms like YouTube can be overwhelming, with long videos and scattered, outdated materials making it hard to know where to begin in this busy life. Even using ChatGPT for coding help often yields deprecated code, as GenAI packages and methods—such as LangChain, LlamaIndex, and Hugging Face—are updated frequently.\n", "\n", "### Key Features\n", "\n", "1. **Learning & Content Creation:**\n", " - Offers tailored learning pathways in GenAI, covering key topics and skills.\n", " - Assists users in creating tutorials, blogs, and posts based on their interests or queries.\n", "2. **Q&A Support:**\n", " - Provides on-demand Q&A sessions for users needing guidance on concepts or coding issues.\n", "3. **Resume Building & Review:**\n", " - One-on-one resume consultations and guidance.\n", " - Crafts personalized, market-relevant resumes optimized for current job trends.\n", "4. **Interview Preparation:**\n", " - Hosts Q&A sessions on common and technical interview questions.\n", " - Simulates real interview scenarios and conducts mock interviews.\n", "5. **Job Search Assistance:**\n", " - Guides users through the job search process, offering tailored insights and support. \n", "With the GenAI Career Assistant, your journey to a career in Generative AI becomes organized, personalized, and efficient!\n", "\n", "\"agent\"\n", "\n", "## Key Components\n", "1. **State Management**: Using TypedDict to define and manage the state of each customer interaction.\n", "2. **Query Categorization**: Classifying users queries into Learning, Resume Preparation, Interview or Job Search.\n", "3. **Sub Categorization**: Learning(Tutorial, Q&A), Interview(Interview prep,Mock interview).\n", "4. **Response Generation**: Creating appropriate responses based on the query category. Create .md files for Tutorial Blogs, Resume, Mock interview etc.\n", "6. **Workflow Graph**: Utilizing LangGraph to create a flexible and extensible workflow.\n", "\n", "## Method Details\n", "1. **Initialization**: Set up the environment and import necessary libraries.\n", "2. **State Definition**: Create a structure to hold query information, category, sub-category, and response.\n", "3. **Node Functions**: Implement separate functions for categorization, and response generation.\n", "4. **Graph Construction**: Use StateGraph to define the workflow, adding nodes and edges to represent the support process.\n", "5. **Conditional Routing**: Implement logic to route queries based on their category and sub- category.\n", "6. **Workflow Compilation**: Compile the graph into an executable application.\n", "7. **Execution**: Process users queries through the workflow and retrieve results." ] }, { "cell_type": "markdown", "id": "f59364b3-4120-473c-8ffd-b2492a3307bd", "metadata": {}, "source": [ "## Conclusion\n", "The GenAI Career Assistant is more than just a tool; it’s a comprehensive, personalized mentor designed to help you thrive in the rapidly evolving field of Generative AI. From mastering key concepts and building a strong resume to preparing for interviews and navigating the job market, this assistant equips you with everything you need to achieve your career goals. With GenAI Career Assistant by your side, your path to a successful Generative AI career becomes clearer, more manageable, and achievable. Embrace the future of AI with confidence and step into your dream role!\n", "## Future Enhancement\n", "- **Knowledge Base**: Incorporate a resource-rich library with curated links to courses, tutorials, and articles for comprehensive learning support.\n", "- **Multi-Domain Customization**: Expand beyond Generative AI, allowing users to tailor the assistant to any career path, creating a versatile \"Dream Job Assistant\"\n", "- **Advanced Job Search Tools**: Include an automated job application tracker, enhanced networking features, and guidance on global job opportunities and visas." ] }, { "cell_type": "markdown", "id": "8c313380-e8dd-4c39-b4e9-a520aa07f1c6", "metadata": {}, "source": [ "### Before starting please install the below packages" ] }, { "cell_type": "code", "execution_count": null, "id": "6e45f49d-cdc2-4b2a-a530-87adc9489e80", "metadata": {}, "outputs": [], "source": [ "pip install langchain==0.3.7 langchain-community==0.3.7 langchain_google_genai==2.0.4 duckduckgo_search==6.3.4 langgraph==0.2.48 python-dotenv" ] }, { "cell_type": "markdown", "id": "dd7fd4d2-e9f2-420b-9ae3-813d6b99142d", "metadata": {}, "source": [ "### Here we will import necessary packages:\n", "`langgraph`, `langchain_core`, `langchain_google_genai` - These are important packages for our project.\n", "\n", "This code imports necessary libraries to create and interact with a generative AI model from Google. It loads environment variables to securely set up an API key, then configures the model `gemini-1.5-flash` with specific parameters like verbosity (for detailed logs) and temperature (for response creativity). The AI model is instantiated with the API key to enable its use in generating responses." ] }, { "cell_type": "code", "execution_count": 2, "id": "553b016a-35eb-435d-bb44-7fc70901f884", "metadata": {}, "outputs": [], "source": [ "from typing import Dict, TypedDict\n", "from langgraph.graph import StateGraph, END, START #Importing StateGraph, END, and START from langgraph.graph to define and manage state transitions within a conversational or generative AI workflow.\n", "from langchain_core.prompts import ChatPromptTemplate\n", "from langchain_google_genai import ChatGoogleGenerativeAI\n", "\n", "from IPython.display import display, Image, Markdown\n", "from langchain_core.runnables.graph import MermaidDrawMethod # to visualize the graph of langgraph node and edges\n", "from dotenv import load_dotenv\n", "import os\n", "\n", "# Load environment variables from a .env file to access sensitive information\n", "load_dotenv()\n", "\n", "# Set the Gemini API key for authentication with Google Generative AI services\n", "os.environ[\"GOOGLE_API_KEY\"] = os.getenv('GOOGLE_API_KEY')\n", "\n", "# Instantiate a chat model using Google's Gemini-1.5-flash with specified configurations\n", "# - verbose=True enables detailed output logs for debugging\n", "# - temperature=0.5 controls the creativity level in responses (lower values make responses more deterministic)\n", "llm = ChatGoogleGenerativeAI(model=\"gemini-1.5-flash\",\n", " verbose=True,\n", " temperature=0.5,\n", " google_api_key=os.getenv(\"GOOGLE_API_KEY\"))\n" ] }, { "cell_type": "markdown", "id": "87dc5e74-70f8-4bda-93e0-a734c223c14b", "metadata": {}, "source": [ "### Defining a State class using TypedDict to specify the structure of state data in the workflow.\n", "- `query`: a string representing the user's input or question.\n", "- `category`: a string indicating the category or type of the query.\n", "- `response`: a string holding the AI model's generated response to the query.\n", "This TypedDict ensures each state has a consistent data format for easier management and readability." ] }, { "cell_type": "code", "execution_count": 4, "id": "99f28752", "metadata": {}, "outputs": [], "source": [ "class State(TypedDict):\n", " query: str\n", " category: str\n", " response: str" ] }, { "cell_type": "markdown", "id": "bebd99d3-4a97-44dd-bb4f-5537f9099f0a", "metadata": {}, "source": [ "### First we are defining utilities we will require further\n", " 👉 trim_messages \n", "\n", "1. **`trim_conversation` Function**: This function limits the conversation history to the latest messages (up to 10), ensuring only recent and relevant messages are retained in the promp\n", " \n", "2. **`save_file` Function**: Saves data into a uniquely timestamped Markdown file in the `Agent_output` folder, creating the folder if it doesn't exst.\n", "\n", "3. **`show_md_file` Function**: Reads and displays the content of a Markdown file within the notebook, rendering it in Markdown form readabilityblity.\n", "lity.\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "2e70488f", "metadata": {}, "outputs": [], "source": [ "# Importing message types and utilities from langchain_core:\n", "# AIMessage, HumanMessage, SystemMessage: Define different types of messages in a conversation.\n", "# trim_messages: Utility to manage and limit the number of messages in a conversation history.\n", "from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, trim_messages\n", "\n", "def trim_conversation(prompt):\n", " \"\"\"Trims conversation history to retain only the latest messages within the limit.\"\"\"\n", " max_messages = 10 # Limit the conversation history to the latest 10 messages\n", " return trim_messages(\n", " prompt,\n", " max_tokens=max_messages, # Specifies the maximum number of messages allowed\n", " strategy=\"last\", # Trimming strategy to keep the last messages\n", " token_counter=len, # Counts tokens/messages using the length of the list\n", " start_on=\"human\", # Start trimming when reaching the first human message\n", " include_system=True, # Include system messages in the trimmed history\n", " allow_partial=False, # Ensures only whole messages are included\n", " )\n", "\n", "import os\n", "from datetime import datetime\n", "\n", "def save_file(data, filename):\n", " \"\"\"Saves data to a markdown file with a timestamped filename.\"\"\"\n", " folder_name = \"Agent_output\" # Folder to store output files\n", " os.makedirs(folder_name, exist_ok=True) # Creates the folder if it doesn't exist\n", " \n", " # Generate a timestamped filename for uniqueness\n", " timestamp = datetime.now().strftime(\"%Y%m%d%H%M%S\") # Format: YYYYMMDDHHMMSS\n", " filename = f\"{filename}_{timestamp}.md\"\n", " \n", " # Define the full file path\n", " file_path = os.path.join(folder_name, filename)\n", " \n", " # Save the data to the file in the specified path\n", " with open(file_path, \"w\", encoding=\"utf-8\") as file:\n", " file.write(data)\n", " print(f\"File '{file_path}' created successfully.\")\n", " \n", " # Return the full path of the saved file\n", " return file_path\n", "\n", "def show_md_file(file_path):\n", " \"\"\"Displays the content of a markdown file as Markdown in the notebook.\"\"\"\n", " with open(file_path, 'r', encoding='utf-8') as file:\n", " content = file.read()\n", " \n", " # Render the content in Markdown format within the notebook\n", " display(Markdown(content))\n" ] }, { "cell_type": "markdown", "id": "e72afb0e-e9e0-435a-8017-b59c79dbc281", "metadata": {}, "source": [ "#### Now We will create class which will be Responsible for Learning(Tutorial and Q&A sessions)\n", "- Checkout here:\n", "👉 create_tool_calling_agent \n", "👉 AgentExecutor \n", "👉 DuckDuckGoSearchResults \n", "\n", "1. **Imports**: \n", " - `ChatPromptTemplate` and `MessagesPlaceholder` from `langchain_core.prompts` help structure prompts.\n", " - `DuckDuckGoSearchResults` from `langchain_community.tools` provides web search capability.\n", " - `create_tool_calling_agent` and `AgentExecutor` manage agent creation and execution.\n", "\n", "2. **`LearningResourceAgent` Class**:\n", " - **`__init__` Method**: Initializes the chat model (`gemini-1.5-pro`), prompt, and tools (like DuckDuckGo search).\n", " - **`TutorialAgent` Method**: Runs a search-based tutorial by invoking the model and saving the output as a timestamped Markdown file for review.\n", " - **`QueryBot` Method**: Conducts a Q&A loop with the user. The conversation is trimmed as it grows, and responses are generated based on updated inputs, with the user able to type 'exit' to end the session.\n" ] }, { "cell_type": "code", "execution_count": 8, "id": "068e34b5-596b-4eb3-b1ae-89281b216284", "metadata": {}, "outputs": [], "source": [ "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", "from langchain_community.tools import DuckDuckGoSearchResults #searching tools\n", "from langchain.agents import create_tool_calling_agent\n", "from langchain.agents import AgentExecutor\n", "\n", "class LearningResourceAgent:\n", " def __init__(self, prompt):\n", " # Initialize the chat model, prompt template, and search tools\n", " self.model = ChatGoogleGenerativeAI(model=\"gemini-1.5-pro\")\n", " self.prompt = prompt\n", " self.tools = [DuckDuckGoSearchResults()]\n", "\n", " def TutorialAgent(self, user_input):\n", " # Set up an agent with tool access and execute a tutorial-style response\n", " agent = create_tool_calling_agent(self.model, self.tools, self.prompt)\n", " agent_executor = AgentExecutor(agent=agent, tools=self.tools, verbose=True)\n", " response = agent_executor.invoke({\"input\": user_input})\n", " \n", " # Save and display the response as a markdown file\n", " path = save_file(str(response.get('output')).replace(\"```markdown\", \"\").strip(), 'Tutorial')\n", " print(f\"Tutorial saved to {path}\")\n", " return path\n", "\n", " def QueryBot(self, user_input):\n", " # Initiates a Q&A loop for continuous interaction with the user\n", " print(\"\\nStarting the Q&A session. Type 'exit' to end the session.\\n\")\n", " record_QA_session = []\n", " record_QA_session.append('User Query: %s \\n' % user_input)\n", " self.prompt.append(HumanMessage(content=user_input))\n", " while True:\n", " # Trim conversation history to maintain prompt size\n", " self.prompt = trim_conversation(self.prompt)\n", " \n", " # Generate a response from the AI model and update conversation history\n", " response = self.model.invoke(self.prompt)\n", " record_QA_session.append('\\nExpert Response: %s \\n' % response.content)\n", " \n", " self.prompt.append(AIMessage(content=response.content))\n", " \n", " # Display the AI's response and prompt for user input\n", " print('*' * 50 + 'AGENT' + '*' * 50)\n", " print(\"\\nEXPERT AGENT RESPONSE:\", response.content)\n", " \n", " print('*' * 50 + 'USER' + '*' * 50)\n", " user_input = input(\"\\nYOUR QUERY: \")\n", " record_QA_session.append('\\nUser Query: %s \\n' % response.content)\n", " self.prompt.append(HumanMessage(content=user_input))\n", " \n", " # Exit the Q&A loop if the user types 'exit'\n", " if user_input.lower() == \"exit\":\n", " print(\"Ending the chat session.\")\n", " path = save_file(''.join(record_QA_session),'Q&A_Doubt_Session')\n", " print(f\"Q&A Session saved to {path}\")\n", " return path\n" ] }, { "cell_type": "markdown", "id": "c580c6d7-3872-4d86-bbff-ddfc2159f382", "metadata": {}, "source": [ "### Here we are creating Class for Interview handling(Interview Question Prep and MockInterview)\n", "\n", "1. **`InterviewAgent` Class**:\n", " - **`__init__` Method**: Initializes the model (`gemini-1.5-flash`), prompt, tools (such as DuckDuckGo search), and creates an agent executor with error handling enabled.\n", "\n", "2. **`Interview_questions` Method**:\n", " - Runs a loop for handling interview questions from the user, generating responses using the agent executor. \n", " - Responses are stored in `questions_bank` for later reference. The conversation ends when the user types \"exit,\" and the chat history is saved as a Markdown file.\n", "\n", "3. **`Mock_Interview` Method**:\n", " - Simulates a mock interview by initiating a conversation loop. Responses from the model are displayed as \"Interviewer\" messages, and user inputs as \"Candidate\" messages.\n", " - The conversation is trimmed as it grows to maintain prompt size. The interview session ends when the user types \"exit,\" returning a record of the entire interview.\n" ] }, { "cell_type": "code", "execution_count": 10, "id": "7e4f3d3c", "metadata": {}, "outputs": [], "source": [ "class InterviewAgent:\n", " def __init__(self, prompt):\n", " # Initialize the chat model, prompt template, and search tool for use in the agent\n", " self.model = ChatGoogleGenerativeAI(model=\"gemini-1.5-flash\")\n", " self.prompt = prompt\n", " self.tools = [DuckDuckGoSearchResults()] # Web search tool for retrieving additional information\n", "\n", " def Interview_questions(self, user_input):\n", " # Holds the conversation history and cumulative questions and answers\n", " chat_history = []\n", " questions_bank = ''\n", " # Create an agent executor with tool access and enable verbose output and error handling\n", " self.agent = create_tool_calling_agent(self.model, self.tools, self.prompt)\n", " self.agent_executor = AgentExecutor(agent=self.agent, tools=self.tools, verbose=True, handle_parsing_errors=True)\n", " while True:\n", " print(\"\\nStarting the Interview question preparation. Type 'exit' to end the session.\\n\")\n", " if user_input.lower() == \"exit\":\n", " print(\"Ending the conversation. Goodbye!\")\n", " break\n", " \n", " # Generate a response to the user input and add it to questions_bank\n", " response = self.agent_executor.invoke({\"input\": user_input, \"chat_history\": chat_history})\n", " questions_bank += str(response.get('output')).replace(\"```markdown\", \"\").strip() + \"\\n\"\n", " \n", " # Update chat history with user input and AI response, limiting history to the last 10 messages\n", " chat_history.extend([HumanMessage(content=user_input), response[\"output\"]])\n", " if len(chat_history) > 10:\n", " chat_history = chat_history[-10:] # Keep only the last 10 messages\n", " \n", " # Get the next input from the user to continue the conversation\n", " user_input = input(\"You: \")\n", " \n", " # Save the entire question-response history to a markdown file and display it\n", " path = save_file(questions_bank, 'Interview_questions')\n", " print(f\"Interviews question saved to {path}\")\n", " return path\n", "\n", " def Mock_Interview(self):\n", " # Start a simulated mock interview session\n", " print(\"\\nStarting the mock interview. Type 'exit' to end the session.\\n\")\n", " \n", " # Initialize with a starting message and store interview records\n", " initial_message = 'I am ready for the interview.\\n'\n", " interview_record = []\n", " interview_record.append('Candidate: %s \\n' % initial_message)\n", " self.prompt.append(HumanMessage(content=initial_message))\n", " \n", " while True:\n", " # Trim conversation history if necessary to maintain prompt size\n", " self.prompt = trim_conversation(self.prompt)\n", " \n", " # Generate a response using the chat model\n", " response = self.model.invoke(self.prompt)\n", " \n", " # Add AI response to the conversation history\n", " self.prompt.append(AIMessage(content=response.content))\n", " \n", " # Output the AI's response as the \"Interviewer\"\n", " print(\"\\nInterviewer:\", response.content)\n", " interview_record.append('\\nInterviewer: %s \\n' % response.content)\n", " \n", " # Get the user's response as \"Candidate\" input\n", " user_input = input(\"\\nCandidate: \")\n", " interview_record.append('\\nCandidate: %s \\n' % user_input)\n", " \n", " # Add user input to the conversation history\n", " self.prompt.append(HumanMessage(content=user_input))\n", " \n", " # End the interview if the user types \"exit\"\n", " if user_input.lower() == \"exit\":\n", " print(\"Ending the interview session.\")\n", " path = save_file(''.join(interview_record),'Mock_Interview')\n", " print(f\"Mock Interview saved to {path}\")\n", " return path\n" ] }, { "cell_type": "markdown", "id": "218d1e00-3b9b-44b0-a740-0f6194dec1cb", "metadata": {}, "source": [ "### Now we will create class for Resume Making which will handle creating resume by chating with user\n", "\n", "1. **`ResumeMaker` Class**:\n", " - **`__init__` Method**: Initializes the chat model (`gemini-1.5-pro`), prompt, and tools (like DuckDuckGo search). Sets up an agent executor with tool access, verbose output, and error handling for generating resume content.\n", "\n", "2. **`Create_Resume` Method**:\n", " - Engages in a conversational loop to gather user input and generate resume content based on responses from the agent.\n", " - The conversation history (`chat_history`) retains only the latest 10 messages to manage context size.\n", " - The conversation loop ends when the user types \"exit,\" at which point the final output is saved as a timestamped Markdown file titled \"Resume,\" and the file path is displayed.\n" ] }, { "cell_type": "code", "execution_count": 15, "id": "8e520d96", "metadata": {}, "outputs": [], "source": [ "class ResumeMaker:\n", " def __init__(self, prompt):\n", " # Initialize the chat model, prompt template, and search tool for resume creation\n", " self.model = ChatGoogleGenerativeAI(model=\"gemini-1.5-pro\")\n", " self.prompt = prompt\n", " self.tools = [DuckDuckGoSearchResults()] # Search tool to gather additional information if needed\n", " # Create an agent executor with tool access, enabling verbose output and error handling\n", " self.agent = create_tool_calling_agent(self.model, self.tools, self.prompt)\n", " self.agent_executor = AgentExecutor(agent=self.agent, tools=self.tools, verbose=True, handle_parsing_errors=True)\n", "\n", " def Create_Resume(self, user_input):\n", " # Maintain chat history for the resume creation conversation\n", " chat_history = []\n", " while True:\n", " print(\"\\nStarting the Resume create session. Type 'exit' to end the session.\\n\")\n", " if user_input.lower() == \"exit\":\n", " print(\"Ending the conversation. Goodbye!\")\n", " break\n", " \n", " # Generate a response to user input using the agent and add it to the chat history\n", " response = self.agent_executor.invoke({\"input\": user_input, \"chat_history\": chat_history})\n", " chat_history.extend([HumanMessage(content=user_input), response[\"output\"]])\n", " \n", " # Limit the chat history to the last 10 messages\n", " if len(chat_history) > 10:\n", " chat_history = chat_history[-10:]\n", " \n", " # Prompt for the next user input to continue the resume creation conversation\n", " user_input = input(\"You: \")\n", " \n", " # Save the final output as a markdown file and return the file path\n", " path = save_file(str(response.get('output')).replace(\"```markdown\", \"\").strip(), 'Resume')\n", " print(f\"Resume saved to {path}\")\n", " return path\n" ] }, { "cell_type": "markdown", "id": "de3f2764-2e61-46c0-ac66-05b278d9ae0d", "metadata": {}, "source": [ "### Code Explanation\n", "\n", "1. **`JobSearch` Class**:\n", " - **`__init__` Method**: Initializes the chat model (`gemini-1.5-pro`), prompt, and search tools for job search assistance. Sets up an agent executor to handle conversation flow with verbose output and error handling.\n", "\n", "2. **`find_jobs` Method**:\n", " - Conducts a conversational loop to assist users with job search queries, using the agent's responses based on user input.\n", " - Retains only the latest 10 messages in `chat_history` to manage the prompt size effectively.\n", " - The loop ends when the user types \"exit,\" after which the final conversation output is saved to a Markdown file titled \"Resume,\" and the file path is displayed to the user.\n" ] }, { "cell_type": "code", "execution_count": 20, "id": "7e402606", "metadata": {}, "outputs": [], "source": [ "class JobSearch:\n", " def __init__(self, prompt):\n", " # Initialize the chat model, prompt template, and search tool for job search assistance\n", " self.model = ChatGoogleGenerativeAI(model=\"gemini-1.5-pro\")\n", " self.prompt = prompt\n", " self.tools = DuckDuckGoSearchResults() # Search tool to find job listings or related information\n", " # Create an agent executor with tool access, enabling verbose output and error handling\n", " # self.agent = create_tool_calling_agent(self.model, self.tools, self.prompt)\n", " # self.agent_executor = AgentExecutor(agent=self.agent, tools=self.tools, verbose=True, handle_parsing_errors=True)\n", "\n", " def find_jobs(self, user_input):\n", " results = self.tools.invoke(user_input)\n", " chain = self.prompt | self.model \n", " jobs = chain.invoke({\"result\": results}).content\n", " \n", " path = save_file(str(jobs).replace(\"```markdown\", \"\").strip(), 'Job_search')\n", " print(f\"Jobs saved to {path}\")\n", " return path\n" ] }, { "cell_type": "markdown", "id": "e328d5c6-e9fb-4f19-a8de-1e740bff2a40", "metadata": {}, "source": [ "### Now we are creating function which will help to categorize our user Input\n", "- We are using 👉 Few Shot prompting (Checkout here) to make our LLM understand the categories.\n", "1. **`categorize` Function**:\n", " - Categorizes a user query into four main areas: Learning Generative AI, Resume Making, Interview Preparation, or Job Search.\n", " - Uses a template prompt with examples to guide the AI in choosing the correct category and returns the category number.\n", "\n", "2. **`handle_learning_resource` Function**:\n", " - Determines if a user query about generative AI is related to creating tutorials or asking general questions.\n", " - Uses a prompt to specify these categories and returns \"Tutorial\" or \"Question\" based on the AI's categorization.\n", "\n", "3. **`handle_interview_preparation` Function**:\n", " - Identifies if a user query in the interview category is about a mock interview or general interview questions.\n", " - Uses examples to instruct the AI on the difference, returning either \"Mock\" or \"Question\" to guide further interaction.\n" ] }, { "cell_type": "code", "execution_count": 23, "id": "d053e39b-f986-4c21-83a3-6b2ea9acbe28", "metadata": {}, "outputs": [], "source": [ "def categorize(state: State) -> State:\n", " \"\"\"Categorizes the user query into one of four main categories: Learn Generative AI Technology, Resume Making, Interview Preparation, or Job Search.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Categorize the following customer query into one of these categories:\\n\"\n", " \"1: Learn Generative AI Technology\\n\"\n", " \"2: Resume Making\\n\"\n", " \"3: Interview Preparation\\n\"\n", " \"4: Job Search\\n\"\n", " \"Give the number only as an output.\\n\\n\"\n", " \"Examples:\\n\"\n", " \"1. Query: 'What are the basics of generative AI, and how can I start learning it?' -> 1\\n\"\n", " \"2. Query: 'Can you help me improve my resume for a tech position?' -> 2\\n\"\n", " \"3. Query: 'What are some common questions asked in AI interviews?' -> 3\\n\"\n", " \"4. Query: 'Are there any job openings for AI engineers?' -> 4\\n\\n\"\n", " \"Now, categorize the following customer query:\\n\"\n", " \"Query: {query}\"\n", " )\n", "\n", " # Creates a categorization chain and invokes it with the user's query to get the category\n", " chain = prompt | llm \n", " print('Categorizing the customer query...')\n", " category = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"category\": category}\n", "\n", "def handle_learning_resource(state: State) -> State:\n", " \"\"\"Determines if the query is related to Tutorial creation or general Questions on generative AI topics.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Categorize the following user query into one of these categories:\\n\\n\"\n", " \"Categories:\\n\"\n", " \"- Tutorial: For queries related to creating tutorials, blogs, or documentation on generative AI.\\n\"\n", " \"- Question: For general queries asking about generative AI topics.\\n\"\n", " \"- Default to Question if the query doesn't fit either of these categories.\\n\\n\"\n", " \"Examples:\\n\"\n", " \"1. User query: 'How to create a blog on prompt engineering for generative AI?' -> Category: Tutorial\\n\"\n", " \"2. User query: 'Can you provide a step-by-step guide on fine-tuning a generative model?' -> Category: Tutorial\\n\"\n", " \"3. User query: 'Provide me the documentation for Langchain?' -> Category: Tutorial\\n\"\n", " \"4. User query: 'What are the main applications of generative AI?' -> Category: Question\\n\"\n", " \"5. User query: 'Is there any generative AI course available?' -> Category: Question\\n\\n\"\n", " \"Now, categorize the following user query:\\n\"\n", " \"The user query is: {query}\\n\"\n", " )\n", "\n", " # Creates a further categorization chain to decide between Tutorial or Question\n", " chain = prompt | llm \n", " print('Categorizing the customer query further...')\n", " response = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"category\": response}\n", "\n", "def handle_interview_preparation(state: State) -> State:\n", " \"\"\"Determines if the query is related to Mock Interviews or general Interview Questions.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Categorize the following user query into one of these categories:\\n\\n\"\n", " \"Categories:\\n\"\n", " \"- Mock: For requests related to mock interviews.\\n\"\n", " \"- Question: For general queries asking about interview topics or preparation.\\n\"\n", " \"- Default to Question if the query doesn't fit either of these categories.\\n\\n\"\n", " \"Examples:\\n\"\n", " \"1. User query: 'Can you conduct a mock interview with me for a Gen AI role?' -> Category: Mock\\n\"\n", " \"2. User query: 'What topics should I prepare for an AI Engineer interview?' -> Category: Question\\n\"\n", " \"3. User query: 'I need to practice interview focused on Gen AI.' -> Category: Mock\\n\"\n", " \"4. User query: 'Can you list important coding topics for AI tech interviews?' -> Category: Question\\n\\n\"\n", " \"Now, categorize the following user query:\\n\"\n", " \"The user query is: {query}\\n\"\n", " )\n", "\n", " # Creates a further categorization chain to decide between Mock or Question\n", " chain = prompt | llm \n", " print('Categorizing the customer query further...')\n", " response = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"category\": response}\n" ] }, { "cell_type": "markdown", "id": "1aca2e35-d37b-45a7-b228-6c04d51f4231", "metadata": {}, "source": [ "### Now we will create function for job search and Resume making\n", "\n", "1. **`job_search` Function**:\n", " - Sets up a job search agent to find Generative AI job listings based on user input, gathering details like company name, job title, and links.\n", " - Generates a Markdown (.md) file with results, displayed to the user.\n", "\n", "2. **`handle_resume_making` Function**:\n", " - Creates a customized resume for AI-focused roles by gathering user details (skills, experience, projects) in a structured format.\n", " - Produces a Markdown (.md) resume template tailored to the Generative AI jobcandidate's performance.\n" ] }, { "cell_type": "code", "execution_count": 26, "id": "34c60b01-a5be-4f71-a356-cb5b6fbaad8c", "metadata": {}, "outputs": [], "source": [ "def job_search(state: State) -> State:\n", " \"\"\"Provide a job search response based on user query requirements.\"\"\"\n", " prompt = ChatPromptTemplate.from_template('''Your task is to refactor and make .md file for the this content which includes\n", " the jobs available in the market. Refactor such that user can refer easily. Content: {result}''')\n", " jobSearch = JobSearch(prompt)\n", " state[\"query\"] = input('Please make sure to mention Job location you want,Job roles\\n')\n", " path = jobSearch.find_jobs(state[\"query\"])\n", " show_md_file(path)\n", " return {\"response\": path}\n", "\n", "def handle_resume_making(state: State) -> State:\n", " \"\"\"Generate a customized resume based on user details for a tech role in AI and Generative AI.\"\"\"\n", " prompt = ChatPromptTemplate.from_messages([\n", " (\"system\", '''You are a skilled resume expert with extensive experience in crafting resumes tailored for tech roles, especially in AI and Generative AI. \n", " Your task is to create a resume template for an AI Engineer specializing in Generative AI, incorporating trending keywords and technologies in the current job market. \n", " Feel free to ask users for any necessary details such as skills, experience, or projects to complete the resume. \n", " Try to ask details step by step and try to ask all details within 4 to 5 steps.\n", " Ensure the final resume is in .md format.'''),\n", " MessagesPlaceholder(\"chat_history\"),\n", " (\"human\", \"{input}\"),\n", " (\"placeholder\", \"{agent_scratchpad}\"),\n", " ])\n", " resumeMaker = ResumeMaker(prompt)\n", " path = resumeMaker.Create_Resume(state[\"query\"])\n", " show_md_file(path)\n", " return {\"response\": path}\n" ] }, { "cell_type": "markdown", "id": "df818050-866e-4c56-aebd-7588e6bddd88", "metadata": {}, "source": [ "### Next we will create a function for Q&A query bot and Tutorial maker\n", "\n", "3. **`ask_query_bot` Function**:\n", " - Engages in a conversational Q&A session, providing detailed answers to user queries related to Generative AI.\n", " - Uses back-and-forth interaction to ensure clarity and completeness in responses.\n", "\n", "4. **`tutorial_agent` Function**:\n", " - Generates comprehensive tutorial blogs on Generative AI topics with explanations, example code, and resources for further learning.\n", " - Saves the tutorial in Markdown (.md) format, designed for clarity and learning support." ] }, { "cell_type": "code", "execution_count": 29, "id": "0c0ed58d-b28d-457f-8111-6d1138803e5b", "metadata": {}, "outputs": [], "source": [ "def ask_query_bot(state: State) -> State:\n", " \"\"\"Provide detailed answers to user queries related to Generative AI.\"\"\"\n", " system_message = '''You are an expert Generative AI Engineer with extensive experience in training and guiding others in AI engineering. \n", " You have a strong track record of solving complex problems and addressing various challenges in AI. \n", " Your role is to assist users by providing insightful solutions and expert advice on their queries.\n", " Engage in a back-and-forth chat session to address user queries.'''\n", " prompt = [SystemMessage(content=system_message)]\n", "\n", " learning_agent = LearningResourceAgent(prompt)\n", "\n", " path = learning_agent.QueryBot(state[\"query\"])\n", " show_md_file(path)\n", " return {\"response\": path}\n", "\n", "def tutorial_agent(state: State) -> State:\n", " \"\"\"Generate a tutorial blog for Generative AI based on user requirements.\"\"\"\n", " system_message = '''You are a knowledgeable assistant specializing as a Senior Generative AI Developer with extensive experience in both development and tutoring. \n", " Additionally, you are an experienced blogger who creates tutorials focused on Generative AI.\n", " Your task is to develop high-quality tutorials blogs in .md file with Coding example based on the user's requirements. \n", " Ensure tutorial includes clear explanations, well-structured python code, comments, and fully functional code examples.\n", " Provide resource reference links at the end of each tutorial for further learning.'''\n", " prompt = ChatPromptTemplate.from_messages([(\"system\", system_message),\n", " (\"placeholder\", \"{chat_history}\"),\n", " (\"human\", \"{input}\"),\n", " (\"placeholder\", \"{agent_scratchpad}\"),])\n", " #agent_scratchpad is a function that formats the intermediate steps of the agent's actions and observations into a string. \n", " #This function is used to keep track of the agent's thoughts or actions during the execution of the program. But its not necessary, we can do without this so we will not include it only define it.\n", " learning_agent = LearningResourceAgent(prompt)\n", " path = learning_agent.TutorialAgent(state[\"query\"])\n", " show_md_file(path)\n", " return {\"response\": path}\n", "\n" ] }, { "cell_type": "markdown", "id": "e2627e11-0dce-4374-8c47-3541125981a4", "metadata": {}, "source": [ "### Finally we will create function Interview Question prep and Mock interview\n", "\n", "5. **`interview_topics_quesions` Function**:\n", " - Provides a list of interview questions tailored to Generative AI roles, along with references where possible.\n", " - Outputs a Markdown (.md) document with curated questions based on user requirements.\n", "\n", "6. **`mock_interview` Function**:\n", " - Conducts a simulated Generative AI job interview, interacting with the user in real-time.\n", " - Provides a post-interview evaluation, summarizing the candidate's performance." ] }, { "cell_type": "code", "execution_count": 32, "id": "cbef12ea-9dde-4408-a7d6-8e2a3e10e6b3", "metadata": {}, "outputs": [], "source": [ "def interview_topics_questions(state: State) -> State:\n", " \"\"\"Provide a curated list of interview questions related to Generative AI based on user input.\"\"\"\n", " system_message = '''You are a good researcher in finding interview questions for Generative AI topics and jobs.\n", " Your task is to provide a list of interview questions for Generative AI topics and job based on user requirements.\n", " Provide top questions with references and links if possible. You may ask for clarification if needed.\n", " Generate a .md document containing the questions.'''\n", " prompt = ChatPromptTemplate.from_messages([\n", " (\"system\", system_message),\n", " MessagesPlaceholder(\"chat_history\"),\n", " (\"human\", \"{input}\"),\n", " (\"placeholder\", \"{agent_scratchpad}\"),])\n", " interview_agent = InterviewAgent(prompt)\n", " path = interview_agent.Interview_questions(state[\"query\"])\n", " show_md_file(path)\n", " return {\"response\": path}\n", "\n", "def mock_interview(state: State) -> State:\n", " \"\"\"Conduct a mock interview for a Generative AI position, including evaluation at the end.\"\"\"\n", " system_message = '''You are a Generative AI Interviewer. You have conducted numerous interviews for Generative AI roles.\n", " Your task is to conduct a mock interview for a Generative AI position, engaging in a back-and-forth interview session.\n", " The conversation should not exceed more than 15 to 20 minutes.\n", " At the end of the interview, provide an evaluation for the candidate.'''\n", " prompt = [SystemMessage(content=system_message)]\n", " interview_agent = InterviewAgent(prompt)\n", " path = interview_agent.Mock_Interview()\n", " show_md_file(path)\n", " return {\"response\": path}" ] }, { "cell_type": "markdown", "id": "ea12e827-16f9-46a5-9a81-ba4edd44ccd7", "metadata": {}, "source": [ "### Here, We are creating routing function which will be responsible for conditional edge to give direction after categorization.\n", "- Checkout Here👉 Conditional Edge\n", "1. **`route_query` Function**:\n", " - Routes the main query based on the assigned category number, directing it to the appropriate handler: Learning Resource, Resume Making, Interview Preparation, or Job Search.\n", " - If the query does not match any predefined categories, prompts the user to ask a more relevant question.\n", "\n", "2. **`route_interview` Function**:\n", " - Routes interview-related queries to specific handlers based on the query's sub-category (either Mock Interview or Interview Topics).\n", " - If the category is unclear, defaults to \"mock_interview.\"\n", "\n", "3. **`route_learning` Function**:\n", " - Routes learning-related queries, directing them to either a general question bot or a tutorial creation agent.\n", " - Returns `False` if the query does not clearly fit either sub-category.\n" ] }, { "cell_type": "code", "execution_count": 35, "id": "10f31dd1-9edc-447c-9cb3-cb4f71c73a29", "metadata": {}, "outputs": [], "source": [ "def route_query(state: State):\n", " \"\"\"Route the query based on its category to the appropriate handler.\"\"\"\n", " if '1' in state[\"category\"]:\n", " print('Category: handle_learning_resource')\n", " return \"handle_learning_resource\" # Directs queries about learning generative AI to the learning resource handler\n", " elif '2' in state[\"category\"]:\n", " print('Category: handle_resume_making')\n", " return \"handle_resume_making\" # Directs queries about resume making to the resume handler\n", " elif '3' in state[\"category\"]:\n", " print('Category: handle_interview_preparation')\n", " return \"handle_interview_preparation\" # Directs queries about interview preparation to the interview handler\n", " elif '4' in state[\"category\"]:\n", " print('Category: job_search')\n", " return \"job_search\" # Directs job search queries to the job search handler\n", " else:\n", " print(\"Please ask your question based on my description.\")\n", " return False # Returns False if the category does not match any predefined options\n", "\n", "def route_interview(state: State) -> str:\n", " \"\"\"Route the query to the appropriate interview-related handler.\"\"\"\n", " if 'Question'.lower() in state[\"category\"].lower():\n", " print('Category: interview_topics_questions')\n", " return \"interview_topics_questions\" # Directs to the handler for interview topic questions\n", " elif 'Mock'.lower() in state[\"category\"].lower():\n", " print('Category: mock_interview')\n", " return \"mock_interview\" # Directs to the mock interview handler\n", " else:\n", " print('Category: mock_interview')\n", " return \"mock_interview\" # Defaults to mock interview if category does not clearly match\n", "\n", "def route_learning(state: State):\n", " \"\"\"Route the query based on the learning path category.\"\"\"\n", " if 'Question'.lower() in state[\"category\"].lower():\n", " print('Category: ask_query_bot')\n", " return \"ask_query_bot\" # Directs queries to the general question bot\n", " elif 'Tutorial'.lower() in state[\"category\"].lower():\n", " print('Category: tutorial_agent')\n", " return \"tutorial_agent\" # Directs queries to the tutorial creation agent\n", " else:\n", " print(\"Please ask your question based on my interview description.\")\n", " return False # Returns False if no clear category match is found\n" ] }, { "cell_type": "markdown", "id": "c2d30406-4f79-4eaf-8d86-cb98c20d764d", "metadata": {}, "source": [ "### Now all set lets create workflow graphs adding edges and nodes.\n", "\n", "1. **Workflow Creation**:\n", " - Initializes a `StateGraph` to define the workflow for query handling, with each node representing a different query handler.\n", "\n", "2. **Nodes and Edges**:\n", " - Adds nodes for each query category and handling function: `categorize`, `handle_learning_resource`, `handle_resume_making`, `handle_interview_preparation`, and `job_search`.\n", " - Adds edges to connect nodes conditionally based on the category (e.g., `route_query` routes from \"categorize\" to the appropriate handler).\n", " - Conditional edges further route within specific categories, such as learning resources (`route_learning`) and interview preparation (`route_interview`).\n", "\n", "3. **Workflow Endpoints**:\n", " - Defines nodes where the workflow terminates (e.g., `handle_resume_making`, `mock_interview`, and `job_search`), connecting them to `END`.\n", "\n", "4. **Compilation**:\n", " - Sets `categorize` as the entry point and compiles the workflow into an executable application, `app`, for handling user queries.\n" ] }, { "cell_type": "code", "execution_count": 38, "id": "e932ca15-983a-4bff-8ed9-51e62323f9ed", "metadata": {}, "outputs": [], "source": [ "# Create the workflow graph\n", "workflow = StateGraph(State)\n", "\n", "# Add nodes for each state in the workflow\n", "workflow.add_node(\"categorize\", categorize) # Initial categorization node\n", "workflow.add_node(\"handle_learning_resource\", handle_learning_resource) # Handles learning-related queries\n", "workflow.add_node(\"handle_resume_making\", handle_resume_making) # Handles resume-making queries\n", "workflow.add_node(\"handle_interview_preparation\", handle_interview_preparation) # Handles interview prep queries\n", "workflow.add_node(\"job_search\", job_search) # Handles job search queries\n", "workflow.add_node(\"mock_interview\", mock_interview) # Handles mock interview sessions\n", "workflow.add_node(\"interview_topics_questions\", interview_topics_questions) # Handles interview topic questions\n", "workflow.add_node(\"tutorial_agent\", tutorial_agent) # Tutorial agent for generative AI learning resources\n", "workflow.add_node(\"ask_query_bot\", ask_query_bot) # General query bot for learning resources\n", "\n", "# Define the starting edge to the categorization node\n", "workflow.add_edge(START, \"categorize\")\n", "\n", "# Add conditional edges based on category routing function\n", "workflow.add_conditional_edges(\n", " \"categorize\",\n", " route_query,\n", " {\n", " \"handle_learning_resource\": \"handle_learning_resource\",\n", " \"handle_resume_making\": \"handle_resume_making\",\n", " \"handle_interview_preparation\": \"handle_interview_preparation\",\n", " \"job_search\": \"job_search\"\n", " }\n", ")\n", "\n", "# Add conditional edges for further routing in interview preparation\n", "workflow.add_conditional_edges(\n", " \"handle_interview_preparation\",\n", " route_interview,\n", " {\n", " \"mock_interview\": \"mock_interview\",\n", " \"interview_topics_questions\": \"interview_topics_questions\",\n", " }\n", ")\n", "\n", "# Add conditional edges for further routing in learning resources\n", "workflow.add_conditional_edges(\n", " \"handle_learning_resource\",\n", " route_learning,\n", " {\n", " \"tutorial_agent\": \"tutorial_agent\",\n", " \"ask_query_bot\": \"ask_query_bot\",\n", " }\n", ")\n", "\n", "# Define edges that lead to the end of the workflow\n", "workflow.add_edge(\"handle_resume_making\", END)\n", "workflow.add_edge(\"job_search\", END)\n", "workflow.add_edge(\"interview_topics_questions\", END)\n", "workflow.add_edge(\"mock_interview\", END)\n", "workflow.add_edge(\"ask_query_bot\", END)\n", "workflow.add_edge(\"tutorial_agent\", END)\n", "\n", "# Set the initial entry point to start the workflow at the categorize node\n", "workflow.set_entry_point(\"categorize\")\n", "\n", "# Compile the workflow graph into an application\n", "app = workflow.compile()\n" ] }, { "cell_type": "markdown", "id": "cc25655d-72d8-44d4-b049-983b168c2429", "metadata": {}, "source": [ "### Lets Visualize our graph\n", "\n", "- **Displaying Workflow Graph**:\n", " - Generates a visual representation of the `app` workflow graph using Mermaid, which is then displayed as a PNG image.\n", " - The `MermaidDrawMethod.API` method is used to create the PNG, ensuring a clear, structured view of the workflow nodes and their connections.\n" ] }, { "cell_type": "code", "execution_count": 41, "id": "0ab9b40e-5ea0-4147-a8fc-c30d7a018dab", "metadata": {}, "outputs": [ { "data": { "image/png": "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8tOnT3inAOA/aWlppqameKcAoMF2794dHBxsYGCAdxCgvCZNmmRoaNi+fXu8g/wqpWgoIoSmTZv28ePHVatW4R0EyKmoqKj169fjnQIoL2tra5igD8iVrKwsd3d3vFMA0DC3bt0qKysbOHAg3kGAkjp79mxYWNioUaMUemiikLI0FBFCixYtatu2bYcOHW7cuIF3FiB3qFTq8uX/a+/Oo9os876BJ4GwhUDIQjZK2AotbSmCFltwqVO12haqY+vouIzbOE5flzn2OMfjsWf08T0zOsfRcab1cVx7nDqvfbQtdNFapQvFQiulG5QlrAkkIQlJSEISsr1/XE9v7wZatSbcgXw/f+Tcudl+UEru731d1+/6v6tXr2a6EIhdHA7nxIkTTFcB8L8aGhpUKhXTVQD8BO+8886RI0eefvpppguBWNTU1PTrX//67NmzH3300SwYSyRiKCiyWKyVK1c2NjaePn163bp1x44dY7ociC5isXjHjh2VlZXYfhMYUVFRgQa8ED2OHz8+a651IBa8+eabaWlpL730EtOFQMxpaGi4//77P/744xdffPHFF19ks9lMVxQ2sRUUWSxWfHz8xo0bX3311f37969fv762tpbpiiCKJCQkfPPNN6+88gp+MWD63Xjjja2trUxXAcBisVg9PT1SqRRrFGFG0Gg099xzj1Qqveeee5iuBWKI1Wp9//33V61adeDAgeeff37z5s3z5s1juqgwY8fyFs89PT3btm07evTo7bffvnr16oKCAqYrgmjx8ssvJyUl/fa3vxUIBEzXAjHk4YcffvrppxcvXsx0IRDrXnvtNZVKdffddzNdCMAPePvtt/fv3//aa68VFhYyXQvEBJ/P9/XXX585c2b//v2//OUv77zzTplMxnRRkRLTQZFwuVyfffbZnj174uPj161bV1VVhW2jgEwk+NOf/vT444+vX7+e6VogVnz55ZddXV1PPfUU04VArHv44Yc3b96cnJzMdCEAl/Tll1++8sorjzzyyEMPPcR0LTD7ORyOEydO7N27t6GhYcWKFbfddltVVRXTRUUcguL3Ojo6Dh06tHPnTplMdtNNNy1fvjw7O5vpooBhW7dufe+995544onZ0b0Kol9NTc3mzZuzsrKYLgRi1wcffOByuTZs2MB0IQBT2759+/vvv19TU/PQQw/hdgZEVEdHR2NjY2Nj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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Display the workflow graph as a PNG image using Mermaid\n", "display(\n", " Image(\n", " app.get_graph().draw_mermaid_png(\n", " draw_method=MermaidDrawMethod.API, # Uses Mermaid's API to generate the PNG image of the workflow graph\n", " )\n", " )\n", ")\n" ] }, { "cell_type": "markdown", "id": "71869f0f-9339-4ef9-8873-5543701a27c3", "metadata": {}, "source": [ "### Final function to Processes a user query using the LangGraph workflow and returns a dictionary containing the query's category and response." ] }, { "cell_type": "code", "execution_count": 43, "id": "40306bbb-b2d7-4964-9b4e-0c2c0daddbeb", "metadata": {}, "outputs": [], "source": [ "def run_user_query(query: str) -> Dict[str, str]:\n", " \"\"\"Process a user query through the LangGraph workflow.\n", " \n", " Args:\n", " query (str): The user's query\n", " \n", " Returns:\n", " Dict[str, str]: A dictionary containing the query's category and response\n", " \"\"\"\n", " results = app.invoke({\"query\": query})\n", " return {\n", " \"category\": results[\"category\"],\n", " \"response\": results[\"response\"]\n", " }\n" ] }, { "cell_type": "code", "execution_count": null, "id": "8892d2a9-f92c-4ba5-82fe-684cbef51c26", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "1625db2e-9bc0-40ef-92f2-d004af4b687e", "metadata": {}, "source": [ "# ---------------------------Testing Different Scenarios------------------------------" ] }, { "cell_type": "markdown", "id": "cb68e7b4-0788-45b9-b6c0-0b86b5620980", "metadata": {}, "source": [ "## TEST CASE 1: Creating Tutorials" ] }, { "cell_type": "code", "execution_count": 47, "id": "58014e0e-7031-47d7-b357-cfe640fb7be9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: handle_learning_resource\n", "Categorizing the customer query further...\n", "Category: tutorial_agent\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m```markdown\n", "# LangChain and LangGraph: A Powerful Combination for Generative AI Applications\n", "\n", "This tutorial introduces LangChain and LangGraph, two powerful libraries that enhance the development of Generative AI applications. We'll explore their core concepts and demonstrate their usage with practical Python code examples.\n", "\n", "## LangChain: Building Complex LLM Workflows\n", "\n", "LangChain simplifies the creation of sophisticated applications using Large Language Models (LLMs). It provides a structured framework for chaining together different components, enabling complex workflows and interactions.\n", "\n", "### Core Concepts:\n", "\n", "* **Chains:** The fundamental building blocks of LangChain. Chains link together various components like LLMs, prompts, and other utilities to perform specific tasks.\n", "* **LLMs:** LangChain supports integration with various LLMs, allowing flexibility in choosing the best model for your needs.\n", "* **Prompts:** Well-crafted prompts are essential for effective LLM interaction. LangChain provides tools for managing and optimizing prompts.\n", "* **Indexes:** Indexes structure your data for efficient retrieval and usage within LangChain workflows.\n", "* **Agents:** Agents empower LLMs to interact with their environment, making decisions and gathering information.\n", "* **Memory:** Memory components maintain context and history across chain interactions.\n", "* **Callbacks:** Callbacks provide insights into chain execution and allow for monitoring and customization.\n", "\n", "### Code Example:\n", "\n", "```python\n", "from langchain_openai import OpenAI\n", "from langchain.prompts import PromptTemplate\n", "from langchain.chains import LLMChain\n", "\n", "# Initialize an LLM\n", "llm = OpenAI(temperature=0.7)\n", "\n", "# Define a prompt template\n", "template = \"\"\"Tell me a {adjective} joke about {topic}.\"\"\"\n", "prompt = PromptTemplate(template=template, input_variables=[\"adjective\", \"topic\"])\n", "\n", "# Create an LLM chain\n", "chain = LLMChain(prompt=prompt, llm=llm)\n", "\n", "# Execute the chain\n", "response = chain.invoke({\"adjective\": \"funny\", \"topic\": \"programming\"})\n", "print(response)\n", "\n", "```\n", "\n", "## LangGraph: Visualizing and Analyzing LLM Workflows\n", "\n", "LangGraph complements LangChain by providing tools to visualize, analyze, and debug LLM workflows. It offers a graphical representation of chains, facilitating understanding and optimization.\n", "\n", "### Core Concepts:\n", "\n", "* **Graph Visualization:** LangGraph creates interactive graphs of LangChain workflows, making it easy to see how components interact.\n", "* **Workflow Analysis:** Analyze chain execution flow, identify bottlenecks, and optimize performance.\n", "* **Debugging:** Visual debugging tools help pinpoint issues in complex chains.\n", "\n", "### Code Example (Conceptual - LangGraph integration is evolving):\n", "\n", "```python\n", "# Hypothetical LangGraph integration - API is subject to change\n", "from langgraph import visualize\n", "\n", "# Visualize the LLM chain\n", "visualize(chain)\n", "\n", "```\n", "\n", "## Resources for Further Learning:\n", "\n", "* **LangChain Documentation:** [https://python.langchain.com/en/latest/index.html](https://python.langchain.com/en/latest/index.html)\n", "* **LangGraph Repository:** [https://github.com/langchain-ai/langchain-langgraph](https://github.com/langchain-ai/langchain-langgraph)\n", "\n", "\n", "This tutorial provided a foundational understanding of LangChain and LangGraph. Experiment with the code examples and explore the provided resources to delve deeper into these powerful libraries and unlock their full potential for your Generative AI projects.\n", "```\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "File 'Agent_output\\Tutorial_20241117172824.md' created successfully.\n", "Tutorial saved to Agent_output\\Tutorial_20241117172824.md\n" ] }, { "data": { "text/markdown": [ "# LangChain and LangGraph: A Powerful Combination for Generative AI Applications\n", "\n", "This tutorial introduces LangChain and LangGraph, two powerful libraries that enhance the development of Generative AI applications. We'll explore their core concepts and demonstrate their usage with practical Python code examples.\n", "\n", "## LangChain: Building Complex LLM Workflows\n", "\n", "LangChain simplifies the creation of sophisticated applications using Large Language Models (LLMs). It provides a structured framework for chaining together different components, enabling complex workflows and interactions.\n", "\n", "### Core Concepts:\n", "\n", "* **Chains:** The fundamental building blocks of LangChain. Chains link together various components like LLMs, prompts, and other utilities to perform specific tasks.\n", "* **LLMs:** LangChain supports integration with various LLMs, allowing flexibility in choosing the best model for your needs.\n", "* **Prompts:** Well-crafted prompts are essential for effective LLM interaction. LangChain provides tools for managing and optimizing prompts.\n", "* **Indexes:** Indexes structure your data for efficient retrieval and usage within LangChain workflows.\n", "* **Agents:** Agents empower LLMs to interact with their environment, making decisions and gathering information.\n", "* **Memory:** Memory components maintain context and history across chain interactions.\n", "* **Callbacks:** Callbacks provide insights into chain execution and allow for monitoring and customization.\n", "\n", "### Code Example:\n", "\n", "```python\n", "from langchain_openai import OpenAI\n", "from langchain.prompts import PromptTemplate\n", "from langchain.chains import LLMChain\n", "\n", "# Initialize an LLM\n", "llm = OpenAI(temperature=0.7)\n", "\n", "# Define a prompt template\n", "template = \"\"\"Tell me a {adjective} joke about {topic}.\"\"\"\n", "prompt = PromptTemplate(template=template, input_variables=[\"adjective\", \"topic\"])\n", "\n", "# Create an LLM chain\n", "chain = LLMChain(prompt=prompt, llm=llm)\n", "\n", "# Execute the chain\n", "response = chain.invoke({\"adjective\": \"funny\", \"topic\": \"programming\"})\n", "print(response)\n", "\n", "```\n", "\n", "## LangGraph: Visualizing and Analyzing LLM Workflows\n", "\n", "LangGraph complements LangChain by providing tools to visualize, analyze, and debug LLM workflows. It offers a graphical representation of chains, facilitating understanding and optimization.\n", "\n", "### Core Concepts:\n", "\n", "* **Graph Visualization:** LangGraph creates interactive graphs of LangChain workflows, making it easy to see how components interact.\n", "* **Workflow Analysis:** Analyze chain execution flow, identify bottlenecks, and optimize performance.\n", "* **Debugging:** Visual debugging tools help pinpoint issues in complex chains.\n", "\n", "### Code Example (Conceptual - LangGraph integration is evolving):\n", "\n", "```python\n", "# Hypothetical LangGraph integration - API is subject to change\n", "from langgraph import visualize\n", "\n", "# Visualize the LLM chain\n", "visualize(chain)\n", "\n", "```\n", "\n", "## Resources for Further Learning:\n", "\n", "* **LangChain Documentation:** [https://python.langchain.com/en/latest/index.html](https://python.langchain.com/en/latest/index.html)\n", "* **LangGraph Repository:** [https://github.com/langchain-ai/langchain-langgraph](https://github.com/langchain-ai/langchain-langgraph)\n", "\n", "\n", "This tutorial provided a foundational understanding of LangChain and LangGraph. Experiment with the code examples and explore the provided resources to delve deeper into these powerful libraries and unlock their full potential for your Generative AI projects.\n", "```" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'category': 'Category: Tutorial\\n',\n", " 'response': 'Agent_output\\\\Tutorial_20241117172824.md'}" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"I want to learn Langchain and langgraph.With usage and concept. Also give coding example implementation for both.Create tutorial for this.\"\n", "result = run_user_query(query)\n", "result" ] }, { "cell_type": "markdown", "id": "e17a3631-1467-4847-9368-dffc5a9ebf91", "metadata": {}, "source": [ "## TEST CASE 2: Q&A session for Doubts" ] }, { "cell_type": "code", "execution_count": 460, "id": "7c780ce3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: handle_learning_resource\n", "Categorizing the customer query further...\n", "Category: ask_query_bot\n", "\n", "Starting the Q&A session. Type 'exit' to end the session.\n", "\n", "**************************************************AGENT**************************************************\n", "\n", "EXPERT AGENT RESPONSE: Let's break down the differences between LangGraph and CrewAI and when you might choose one over the other for agent creation. They target slightly different needs and approaches within the broader field of generative AI-powered agents.\n", "\n", "**LangGraph (LangChain + Graph Databases):**\n", "\n", "* **Focus:** Building agents that interact with and reason over knowledge graphs or other structured data sources. LangChain itself is a framework for developing LLM applications, and incorporating a graph database adds a powerful way to represent and query relationships between entities.\n", "* **Strengths:**\n", " * **Complex Reasoning:** Excels when your agent needs to understand and navigate relationships between different pieces of information. Think about scenarios like knowledge exploration, question answering over a specific dataset, or tasks requiring multi-hop reasoning.\n", " * **Explainability:** The structured nature of a graph database can offer better explainability for the agent's decisions. It can trace back the reasoning path through the graph.\n", " * **Data Grounding:** Prevents hallucinations by anchoring the agent's responses to the facts stored in the graph.\n", "* **Weaknesses:**\n", " * **Setup Complexity:** Requires setting up and managing a graph database, which adds complexity compared to simpler approaches.\n", " * **Data Dependence:** The agent's knowledge is limited to what's in the graph. It might struggle with information not represented in the graph structure.\n", " * **Less Flexible for Free-Form Conversation:** While possible, adapting LangGraph for highly dynamic, open-ended conversations can be more challenging than using tools designed specifically for dialogue.\n", "\n", "\n", "**CrewAI:**\n", "\n", "* **Focus:** Building conversational agents and bots, especially for task-oriented dialogues. It emphasizes the flow of conversation and integrating with various APIs and tools.\n", "* **Strengths:**\n", " * **Ease of Use for Conversational Flows:** Provides a more streamlined experience for designing conversational flows and handling user interactions.\n", " * **Tool Integration:** Facilitates connecting your agent to external services (e.g., booking systems, databases, APIs) to perform actions within the conversation.\n", " * **Multi-Agent Collaboration:** CrewAI supports the development of multiple agents that can collaborate on a task, which can be powerful for complex workflows.\n", "* **Weaknesses:**\n", " * **Less Suitable for Complex Reasoning:** While you can implement some logic, CrewAI is not primarily designed for deep reasoning over complex knowledge structures like a graph database.\n", " * **Potential for Hallucinations:** Relies more heavily on LLMs, which can be prone to generating incorrect or nonsensical information if not carefully managed.\n", " * **Less Emphasis on Explainability:** Tracing the reasoning behind an agent's actions might be more difficult compared to a graph-based approach.\n", "\n", "\n", "**In short:**\n", "\n", "* **Choose LangGraph (LangChain + Graph DB) if:** Your application requires complex reasoning over structured data, explainability is crucial, and you want to minimize hallucinations by grounding responses to a knowledge base.\n", "* **Choose CrewAI if:** You need to build a conversational agent for task-oriented dialogues, integrate with various tools and APIs, and potentially orchestrate multiple agents.\n", "\n", "\n", "Could you tell me more about the specific agent you're trying to build? Knowing the context will allow me to give you more tailored advice. For example, what is the agent's purpose, what kind of data will it interact with, and what are the key functionalities you're aiming for?\n", "\n", "**************************************************USER**************************************************\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "YOUR QUERY: I want to create my Custom AI Agents\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "**************************************************AGENT**************************************************\n", "\n", "EXPERT AGENT RESPONSE: Creating your own custom AI agents is an exciting endeavor! To give you the best advice, let's refine our understanding of your goals. \"Custom AI agents\" is a broad term. Here's a breakdown of key considerations and how they might influence your tool choices:\n", "\n", "**1. Purpose and Functionality:**\n", "\n", "* **What is the agent's primary goal?** Examples: Answering questions, performing tasks, generating creative content, controlling a game character, analyzing data, etc.\n", "* **What specific tasks will it perform?** Be as detailed as possible. For example, if it's a customer service agent, list the types of customer queries it should handle.\n", "* **What level of autonomy are you aiming for?** Will the agent operate completely independently, or will there be human oversight?\n", "\n", "**2. Data and Knowledge:**\n", "\n", "* **What data will the agent need access to?** Examples: A specific knowledge base, a database, real-time data streams, files, APIs, etc.\n", "* **How structured is this data?** Is it neatly organized in a database, or is it unstructured text?\n", "* **Will the agent need to learn and update its knowledge over time?**\n", "\n", "**3. Interaction and Interface:**\n", "\n", "* **How will users interact with the agent?** Through a chat interface, voice commands, a graphical interface, API calls, etc.?\n", "* **What is the desired level of natural language understanding (NLU)?** Does it need to handle complex language, or are simple commands sufficient?\n", "* **Does the agent need to generate natural language responses?**\n", "\n", "**4. Development Platform and Tools:**\n", "\n", "* **What is your level of programming expertise?** Are you comfortable with Python and other relevant libraries?\n", "* **What resources are available to you?** Computational power, cloud services, existing datasets, etc.\n", "\n", "\n", "**Example Scenarios and Tool Recommendations:**\n", "\n", "Let's illustrate with some examples:\n", "\n", "* **Scenario 1: A research assistant that can answer questions based on a collection of scientific papers.**\n", " * **Likely Tools:** LangChain with a vector database (e.g., Pinecone, Weaviate) to store embeddings of the papers. This allows for semantic search and retrieval of relevant information.\n", "* **Scenario 2: A customer service chatbot for a website.**\n", " * **Likely Tools:** Dialogflow, Rasa, or Botpress. These platforms specialize in building conversational agents and provide tools for managing dialogue flows.\n", "* **Scenario 3: An agent that can automate tasks in a software application.**\n", " * **Likely Tools:** LangChain with integrations to the specific software APIs. You might also consider tools like Microsoft's Power Automate or Zapier for simpler automations.\n", "* **Scenario 4: An AI agent that plays a character in a text-based game.**\n", " * **Likely Tools:** LangChain, with a focus on prompt engineering to guide the agent's behavior and personality.\n", "\n", "\n", "Once you provide me with more details about your specific needs, I can give you more targeted advice on the best tools and approaches for building your custom AI agent.\n", "\n", "**************************************************USER**************************************************\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "YOUR QUERY: I think i understand now. Thanks for help\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "**************************************************AGENT**************************************************\n", "\n", "EXPERT AGENT RESPONSE: You're welcome! I'm glad I could help clarify things. Please don't hesitate to reach out if you have any more questions as you progress with your AI agent development. Even a small detail about your project can often lead to more specific and helpful recommendations. Good luck!\n", "\n", "**************************************************USER**************************************************\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "YOUR QUERY: exit\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Ending the chat session.\n", "File 'Agent_output\\Q&A_Doubt_Session_20241117150253.md' created successfully.\n", "Q&A Session saved to Agent_output\\Q&A_Doubt_Session_20241117150253.md\n", "{'category': 'Category: Question\\n', 'response': 'Agent_output\\\\Q&A_Doubt_Session_20241117150253.md'}\n" ] } ], "source": [ "query = \"I am confused between Langgraph and CrewAI when to use what for Agent Creation?\"\n", "result = run_user_query(query)\n", "print(result)" ] }, { "cell_type": "markdown", "id": "3a88c7a5-8e78-4098-9b10-03e2ec550ca6", "metadata": {}, "source": [ "## TEST CASE 3: Interview Question Discussion" ] }, { "cell_type": "code", "execution_count": 519, "id": "ba349db1-fd86-4ea4-89e7-b9ecedbecbda", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: handle_interview_preparation\n", "Categorizing the customer query further...\n", "Category: interview_topics_questions\n", "\n", "Starting the Interview question preparation. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mTo best tailor interview questions for Generative AI job roles, I need some more information. Please tell me:\n", "\n", "1. **What specific role are we targeting?** (e.g., Research Scientist, Machine Learning Engineer, Product Manager, Software Engineer focusing on Generative AI) The questions will differ significantly depending on the role.\n", "\n", "2. **What is the seniority level?** (e.g., Intern, Junior, Mid-level, Senior) The difficulty and depth of the questions should scale with experience.\n", "\n", "3. **What are the key technologies or areas of focus?** (e.g., Large Language Models (LLMs), Diffusion Models, Generative Adversarial Networks (GANs), specific applications like image generation, text generation, code generation)\n", "\n", "Once I have this information, I can generate a more relevant and effective set of interview questions.\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: For Mid-level,LLM and Gen AI other techs.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Interview question preparation. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mOkay, focusing on a **Mid-level** role with expertise in **LLMs** and other **Generative AI technologies**, here's a markdown file containing interview questions. This covers a range of topics, from foundational knowledge to practical application and problem-solving. Remember that the specific questions asked should be adapted based on the candidate's resume and the specific needs of the role.\n", "\n", "\n", "```markdown\n", "# Generative AI Interview Questions - Mid-Level\n", "\n", "This document outlines interview questions for a mid-level Generative AI role, encompassing expertise in LLMs and other generative AI technologies.\n", "\n", "\n", "## I. Foundational Knowledge\n", "\n", "1. **Explain the difference between autoregressive and diffusion models. Give examples of each and discuss their strengths and weaknesses.** (Tests understanding of core model architectures)\n", "\n", "2. **Describe the Transformer architecture. Explain the role of self-attention and positional encoding.** (Tests understanding of the backbone of many LLMs)\n", "\n", "3. **What are some common challenges in training LLMs? Discuss methods for mitigating these challenges (e.g., overfitting, vanishing gradients, computational cost).** (Tests practical experience and problem-solving skills)\n", "\n", "4. **Explain the concept of attention mechanisms. How do they improve upon previous sequence-to-sequence models?** (Tests understanding of a key component of LLMs)\n", "\n", "5. **What are different ways to evaluate the performance of a generative model? Discuss both quantitative and qualitative metrics.** (Tests understanding of evaluation methodologies)\n", "\n", "\n", "## II. LLM Specifics\n", "\n", "1. **Explain the concept of prompt engineering. Provide examples of effective prompting techniques and discuss their impact on model output.** (Tests practical experience with LLMs)\n", "\n", "2. **Describe different methods for fine-tuning LLMs for specific tasks. Discuss the trade-offs between different approaches.** (Tests knowledge of adaptation techniques)\n", "\n", "3. **What are some common biases found in LLMs? How can these biases be mitigated during training or deployment?** (Tests awareness of ethical considerations)\n", "\n", "4. **Discuss different methods for handling long context lengths in LLMs. What are the limitations and potential solutions?** (Tests understanding of scalability challenges)\n", "\n", "5. **Compare and contrast different LLM architectures (e.g., GPT, BERT, LaMDA). What are their strengths and weaknesses for different applications?** (Tests broad knowledge of LLM landscape)\n", "\n", "\n", "## III. Other Generative AI Technologies\n", "\n", "1. **Explain the concept of Generative Adversarial Networks (GANs). Describe the roles of the generator and discriminator.** (Tests understanding of a different generative model architecture)\n", "\n", "2. **Describe the process of generating images using diffusion models. What are the advantages and disadvantages compared to GANs?** (Tests knowledge of another generative model)\n", "\n", "3. **Discuss the ethical implications of generative AI, including potential for misuse and bias amplification.** (Tests awareness of responsible AI development)\n", "\n", "\n", "## IV. Practical Application and Problem Solving\n", "\n", "1. **Describe a project where you used generative AI to solve a real-world problem. What were the challenges, and how did you overcome them?** (Tests practical experience and problem-solving abilities – this should be a detailed discussion)\n", "\n", "2. **Design a system for generating realistic human faces using generative AI. Discuss the technical challenges and potential solutions.** (Tests ability to design a generative AI system)\n", "\n", "3. **You are tasked with improving the efficiency of an existing LLM. Describe your approach, considering factors such as computational resources, model size, and performance metrics.** (Tests practical problem-solving skills)\n", "\n", "4. **How would you approach debugging a generative model that is producing nonsensical or low-quality outputs?** (Tests practical troubleshooting skills)\n", "\n", "\n", "## V. System Design and Deployment\n", "\n", "1. **Design a system for deploying an LLM as an API. Consider aspects such as scalability, latency, and security.** (Tests understanding of deployment considerations)\n", "\n", "2. **Discuss strategies for monitoring and maintaining the performance of a deployed generative AI model.** (Tests understanding of model lifecycle management)\n", "\n", "\n", "This list is not exhaustive, and the specific questions asked should be tailored to the candidate's experience and the requirements of the role. Remember to also assess soft skills such as communication, teamwork, and problem-solving abilities throughout the interview process.\n", "```\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: Can you give me questions for Langchain and Langgraph.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Interview question preparation. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mOkay, let's add some questions specifically targeting Langchain and LangGraph to the existing interview questions. We'll integrate them into the existing markdown structure. Since LangChain and LangGraph are relatively new, the questions will focus on understanding their core concepts and how they relate to broader Generative AI principles.\n", "\n", "\n", "```markdown\n", "# Generative AI Interview Questions - Mid-Level\n", "\n", "This document outlines interview questions for a mid-level Generative AI role, encompassing expertise in LLMs and other generative AI technologies, including LangChain and LangGraph.\n", "\n", "\n", "## I. Foundational Knowledge\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## II. LLM Specifics\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## III. Other Generative AI Technologies\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## IV. LangChain and LangGraph\n", "\n", "1. **What is LangChain, and what are its key components? Describe how it simplifies the development of LLM-powered applications.** (Tests understanding of LangChain's core functionality)\n", "\n", "2. **Explain the concept of chains and agents in LangChain. Provide examples of how they can be used to build complex LLM applications.** (Tests understanding of LangChain's architectural patterns)\n", "\n", "3. **How does LangChain handle memory in LLM applications? Discuss different memory types and their use cases.** (Tests understanding of state management in LangChain)\n", "\n", "4. **Describe how you would use LangChain to build an application that integrates multiple LLMs or other tools (e.g., databases, APIs).** (Tests ability to apply LangChain in a practical scenario)\n", "\n", "5. **What is LangGraph? How does it differ from other knowledge graph approaches, and what are its advantages and disadvantages for building LLM applications?** (Tests understanding of LangGraph's unique features)\n", "\n", "6. **How can LangGraph be used to enhance the capabilities of LLMs? Provide specific examples of how it improves reasoning, knowledge access, or context management.** (Tests understanding of LangGraph's applications)\n", "\n", "7. **Compare and contrast LangChain and LangGraph. Discuss scenarios where one might be preferred over the other.** (Tests ability to compare and contrast different tools)\n", "\n", "8. **Describe a potential project where you would utilize both LangChain and LangGraph to build a sophisticated LLM-powered application. Outline the architecture and key components.** (Tests ability to design a complex system using both tools)\n", "\n", "\n", "## V. Practical Application and Problem Solving\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## VI. System Design and Deployment\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "This list is not exhaustive, and the specific questions asked should be tailored to the candidate's experience and the requirements of the role. Remember to also assess soft skills such as communication, teamwork, and problem-solving abilities throughout the interview process.\n", "```\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: exit\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Interview question preparation. Type 'exit' to end the session.\n", "\n", "Ending the conversation. Goodbye!\n", "File 'Agent_output\\Interview_questions_20241117151913.md' created successfully.\n", "Interviews question saved to Agent_output\\Interview_questions_20241117151913.md\n" ] }, { "data": { "text/markdown": [ "To best tailor interview questions for Generative AI job roles, I need some more information. Please tell me:\n", "\n", "1. **What specific role are we targeting?** (e.g., Research Scientist, Machine Learning Engineer, Product Manager, Software Engineer focusing on Generative AI) The questions will differ significantly depending on the role.\n", "\n", "2. **What is the seniority level?** (e.g., Intern, Junior, Mid-level, Senior) The difficulty and depth of the questions should scale with experience.\n", "\n", "3. **What are the key technologies or areas of focus?** (e.g., Large Language Models (LLMs), Diffusion Models, Generative Adversarial Networks (GANs), specific applications like image generation, text generation, code generation)\n", "\n", "Once I have this information, I can generate a more relevant and effective set of interview questions.\n", "Okay, focusing on a **Mid-level** role with expertise in **LLMs** and other **Generative AI technologies**, here's a markdown file containing interview questions. This covers a range of topics, from foundational knowledge to practical application and problem-solving. Remember that the specific questions asked should be adapted based on the candidate's resume and the specific needs of the role.\n", "\n", "\n", "\n", "# Generative AI Interview Questions - Mid-Level\n", "\n", "This document outlines interview questions for a mid-level Generative AI role, encompassing expertise in LLMs and other generative AI technologies.\n", "\n", "\n", "## I. Foundational Knowledge\n", "\n", "1. **Explain the difference between autoregressive and diffusion models. Give examples of each and discuss their strengths and weaknesses.** (Tests understanding of core model architectures)\n", "\n", "2. **Describe the Transformer architecture. Explain the role of self-attention and positional encoding.** (Tests understanding of the backbone of many LLMs)\n", "\n", "3. **What are some common challenges in training LLMs? Discuss methods for mitigating these challenges (e.g., overfitting, vanishing gradients, computational cost).** (Tests practical experience and problem-solving skills)\n", "\n", "4. **Explain the concept of attention mechanisms. How do they improve upon previous sequence-to-sequence models?** (Tests understanding of a key component of LLMs)\n", "\n", "5. **What are different ways to evaluate the performance of a generative model? Discuss both quantitative and qualitative metrics.** (Tests understanding of evaluation methodologies)\n", "\n", "\n", "## II. LLM Specifics\n", "\n", "1. **Explain the concept of prompt engineering. Provide examples of effective prompting techniques and discuss their impact on model output.** (Tests practical experience with LLMs)\n", "\n", "2. **Describe different methods for fine-tuning LLMs for specific tasks. Discuss the trade-offs between different approaches.** (Tests knowledge of adaptation techniques)\n", "\n", "3. **What are some common biases found in LLMs? How can these biases be mitigated during training or deployment?** (Tests awareness of ethical considerations)\n", "\n", "4. **Discuss different methods for handling long context lengths in LLMs. What are the limitations and potential solutions?** (Tests understanding of scalability challenges)\n", "\n", "5. **Compare and contrast different LLM architectures (e.g., GPT, BERT, LaMDA). What are their strengths and weaknesses for different applications?** (Tests broad knowledge of LLM landscape)\n", "\n", "\n", "## III. Other Generative AI Technologies\n", "\n", "1. **Explain the concept of Generative Adversarial Networks (GANs). Describe the roles of the generator and discriminator.** (Tests understanding of a different generative model architecture)\n", "\n", "2. **Describe the process of generating images using diffusion models. What are the advantages and disadvantages compared to GANs?** (Tests knowledge of another generative model)\n", "\n", "3. **Discuss the ethical implications of generative AI, including potential for misuse and bias amplification.** (Tests awareness of responsible AI development)\n", "\n", "\n", "## IV. Practical Application and Problem Solving\n", "\n", "1. **Describe a project where you used generative AI to solve a real-world problem. What were the challenges, and how did you overcome them?** (Tests practical experience and problem-solving abilities – this should be a detailed discussion)\n", "\n", "2. **Design a system for generating realistic human faces using generative AI. Discuss the technical challenges and potential solutions.** (Tests ability to design a generative AI system)\n", "\n", "3. **You are tasked with improving the efficiency of an existing LLM. Describe your approach, considering factors such as computational resources, model size, and performance metrics.** (Tests practical problem-solving skills)\n", "\n", "4. **How would you approach debugging a generative model that is producing nonsensical or low-quality outputs?** (Tests practical troubleshooting skills)\n", "\n", "\n", "## V. System Design and Deployment\n", "\n", "1. **Design a system for deploying an LLM as an API. Consider aspects such as scalability, latency, and security.** (Tests understanding of deployment considerations)\n", "\n", "2. **Discuss strategies for monitoring and maintaining the performance of a deployed generative AI model.** (Tests understanding of model lifecycle management)\n", "\n", "\n", "This list is not exhaustive, and the specific questions asked should be tailored to the candidate's experience and the requirements of the role. Remember to also assess soft skills such as communication, teamwork, and problem-solving abilities throughout the interview process.\n", "```\n", "Okay, let's add some questions specifically targeting Langchain and LangGraph to the existing interview questions. We'll integrate them into the existing markdown structure. Since LangChain and LangGraph are relatively new, the questions will focus on understanding their core concepts and how they relate to broader Generative AI principles.\n", "\n", "\n", "\n", "# Generative AI Interview Questions - Mid-Level\n", "\n", "This document outlines interview questions for a mid-level Generative AI role, encompassing expertise in LLMs and other generative AI technologies, including LangChain and LangGraph.\n", "\n", "\n", "## I. Foundational Knowledge\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## II. LLM Specifics\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## III. Other Generative AI Technologies\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## IV. LangChain and LangGraph\n", "\n", "1. **What is LangChain, and what are its key components? Describe how it simplifies the development of LLM-powered applications.** (Tests understanding of LangChain's core functionality)\n", "\n", "2. **Explain the concept of chains and agents in LangChain. Provide examples of how they can be used to build complex LLM applications.** (Tests understanding of LangChain's architectural patterns)\n", "\n", "3. **How does LangChain handle memory in LLM applications? Discuss different memory types and their use cases.** (Tests understanding of state management in LangChain)\n", "\n", "4. **Describe how you would use LangChain to build an application that integrates multiple LLMs or other tools (e.g., databases, APIs).** (Tests ability to apply LangChain in a practical scenario)\n", "\n", "5. **What is LangGraph? How does it differ from other knowledge graph approaches, and what are its advantages and disadvantages for building LLM applications?** (Tests understanding of LangGraph's unique features)\n", "\n", "6. **How can LangGraph be used to enhance the capabilities of LLMs? Provide specific examples of how it improves reasoning, knowledge access, or context management.** (Tests understanding of LangGraph's applications)\n", "\n", "7. **Compare and contrast LangChain and LangGraph. Discuss scenarios where one might be preferred over the other.** (Tests ability to compare and contrast different tools)\n", "\n", "8. **Describe a potential project where you would utilize both LangChain and LangGraph to build a sophisticated LLM-powered application. Outline the architecture and key components.** (Tests ability to design a complex system using both tools)\n", "\n", "\n", "## V. Practical Application and Problem Solving\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "## VI. System Design and Deployment\n", "\n", "[Existing questions from previous response]\n", "\n", "\n", "This list is not exhaustive, and the specific questions asked should be tailored to the candidate's experience and the requirements of the role. Remember to also assess soft skills such as communication, teamwork, and problem-solving abilities throughout the interview process.\n", "```\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "{'category': 'Category: Question\\n', 'response': 'Agent_output\\\\Interview_questions_20241117151913.md'}\n" ] } ], "source": [ "query = \"I want to discussion Interview question for Gen AI job roles.\"\n", "result = run_user_query(query)\n", "print(result)" ] }, { "cell_type": "markdown", "id": "debd628e-730b-4627-a8c6-e00a6022a54a", "metadata": {}, "source": [ "## TEST CASE 4: Mock Interview with Evaluation Feedback" ] }, { "cell_type": "code", "execution_count": 61, "id": "728b6877-9383-470f-ad01-2c7e5705593b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: handle_interview_preparation\n", "Categorizing the customer query further...\n", "Category: mock_interview\n", "\n", "Starting the mock interview. Type 'exit' to end the session.\n", "\n", "\n", "Interviewer: Great! Welcome. My name is Alex, and I'll be conducting your interview today for the Generative AI Engineer position. Let's start with a brief introduction from you. Tell me about yourself and your experience relevant to this role. We have your resume, but I'd like to hear it in your own words. Keep it to about 2-3 minutes.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "Candidate: I’m Karan, and I’m currently focused on advancing my skills and contributions in Generative AI. My journey started with a solid foundation in Computer Science, where I developed a strong interest in AI and machine learning. Over the years, I’ve built a range of projects that have helped me gain expertise in several core areas of this role. One of my most impactful experiences was working on an end-to-end Legal Case Identification system for Verinext and Pondlehocky. This project involved integrating Gen-AI to automate case assignments. I led a team to develop a pipeline that included NLP, GPT, prompt engineering, and Litify DB integration, ultimately enabling efficient case handling through an AI-driven model. I’ve also worked on an Automatic Number Plate Recognition project for NPCI. This required designing and deploying a real-time ANPR solution using transfer learning, Deepstream, and OCR. I collaborated closely with my team on model improvement and pipeline optimization to ensure the project could effectively replace existing toll services. Beyond my technical skills, I bring a strategic approach to problem-solving and a knack for diving into the nuances of machine learning models, optimizing them to fit specific business needs. I’m passionate about harnessing AI to address real-world challenges, and I’m excited about the possibility of contributing my skills and learning further with your team.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Interviewer: That's a strong introduction, Karan. Your projects demonstrate a good understanding of the practical applications of Generative AI. Let's delve a bit deeper. You mentioned prompt engineering in your Legal Case Identification project. Can you describe a challenging prompt engineering problem you faced and how you solved it? What metrics did you use to evaluate the success of your prompt engineering efforts?\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "Candidate: Certainly, Alex. In the Legal Case Identification project, a significant challenge in prompt engineering arose when trying to accurately classify complex case types from unstructured legal data. The prompts needed to be crafted carefully to balance specificity with flexibility, as the language in legal documents can vary widely. One particular issue was handling nuanced legal terms and context-specific language that often influenced the interpretation of a case’s category. To address this, I experimented with structured prompt templates that included both contextual keywords and specific qualifiers. For example, rather than just asking the model to classify a \"personal injury\" case, I structured prompts to include additional context like, \"Identify if this case involves physical harm due to an accident or negligence,\" which guided the model to focus on relevant legal scenarios. For evaluation, I used precision, recall, and F1 scores to measure how accurately the prompts identified cases correctly across categories. Additionally, we monitored the model’s consistency by testing it on a set of challenging cases with subtle differences to see if the prompts led to consistent responses. I also tracked user feedback from legal experts who verified if the classifications aligned with practical expectations. This iterative approach, along with close collaboration with subject matter experts, allowed me to refine prompts effectively. It was a great learning experience in balancing prompt detail and adaptability while ensuring reliable, high-quality results for the client.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Interviewer: Excellent. That demonstrates a good understanding of prompt engineering and evaluation metrics. Now, let's shift gears slightly. Generative AI models can sometimes produce biased or inaccurate outputs. How would you address such issues in a production environment?\n", "\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "Candidate: Thank you, Alex; that’s an important consideration. In a production environment, handling bias and inaccuracies in Generative AI outputs requires a proactive, multi-layered approach. Here’s how I’d approach it: Data and Model Auditing: I’d start by auditing the training data to identify and mitigate any inherent biases. This might involve using a diverse dataset or adding counterexamples to balance the perspectives presented in the model’s outputs. Model fine-tuning can help adjust any biases found in pre-trained models by focusing on more representative or neutral datasets. Prompt Design and Constraints: In prompt engineering, I’d craft prompts that guide the model toward neutral and accurate responses. For instance, setting constraints in the prompt to avoid speculative or potentially biased language can help. Additionally, I’d use prompt templates that explicitly frame questions to elicit factual and context-appropriate information. Post-Processing and Filtering: After generating outputs, I’d implement a filtering or post-processing layer that flags any content that seems potentially biased or incorrect. For example, sentiment analysis or bias detection algorithms can help flag outputs, allowing for an additional layer of human review or correction before the final output is published.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Interviewer: Good. You've covered some key aspects. One last question: Describe your preferred approach to staying up-to-date with the rapidly evolving field of Generative AI.\n", "\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "Candidate: To stay current in Generative AI, I rely on a structured approach that combines both learning from established resources and exploring emerging trends: Research Papers and Journals: I regularly read papers from sources like arXiv and conferences such as NeurIPS, ICML, and CVPR. Following key researchers and institutions helps me stay updated on cutting-edge techniques, and I make it a habit to read and analyze at least one new paper each week, focusing on both theoretical advances and practical applications. Community and Open-Source Contributions: I participate in open-source projects on platforms like GitHub, which keeps me connected with the latest tools and libraries. Additionally, contributing to or following repositories in frameworks like Hugging Face or PyTorch gives me hands-on exposure to practical advancements in model development and deployment. Online Courses and Workshops: I engage in online courses or certifications, especially when new architectures or methodologies gain traction, such as diffusion models or prompt engineering techniques. Platforms like Coursera and specialized workshops provide structured, in-depth content that complements hands-on experience. Podcasts and Newsletters: I subscribe to AI-focused newsletters like \"The Batch\" by Andrew Ng and listen to podcasts such as \"Lex Fridman\" and \"Data Skeptic,\" which often feature industry experts discussing the latest trends and breakthroughs. This is a great way to get a broader perspective on AI developments and practical applications.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Interviewer: Excellent. Thank you, Karan. That concludes our interview. I appreciate you taking the time to speak with me today.\n", "\n", "\n", "**Evaluation:**\n", "\n", "Karan demonstrated a strong understanding of Generative AI concepts and their practical application. His project descriptions were detailed and showcased his ability to tackle complex problems and evaluate results effectively. He articulated a well-rounded approach to addressing bias and maintaining accuracy in production environments. His commitment to continuous learning is also commendable. While he could have provided more specific examples in some areas, overall, he presented himself as a strong candidate for the Generative AI Engineer position. I would recommend him for the next stage of the interview process.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "\n", "Candidate: exit\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Ending the interview session.\n", "File 'Agent_output\\Mock_Interview_20241117174111.md' created successfully.\n", "Mock Interview saved to Agent_output\\Mock_Interview_20241117174111.md\n" ] }, { "data": { "text/markdown": [ "Candidate: I am ready for the interview.\n", " \n", "\n", "Interviewer: Great! Welcome. My name is Alex, and I'll be conducting your interview today for the Generative AI Engineer position. Let's start with a brief introduction from you. Tell me about yourself and your experience relevant to this role. We have your resume, but I'd like to hear it in your own words. Keep it to about 2-3 minutes.\n", " \n", "\n", "Candidate: I’m Karan, and I’m currently focused on advancing my skills and contributions in Generative AI. My journey started with a solid foundation in Computer Science, where I developed a strong interest in AI and machine learning. Over the years, I’ve built a range of projects that have helped me gain expertise in several core areas of this role. One of my most impactful experiences was working on an end-to-end Legal Case Identification system for Verinext and Pondlehocky. This project involved integrating Gen-AI to automate case assignments. I led a team to develop a pipeline that included NLP, GPT, prompt engineering, and Litify DB integration, ultimately enabling efficient case handling through an AI-driven model. I’ve also worked on an Automatic Number Plate Recognition project for NPCI. This required designing and deploying a real-time ANPR solution using transfer learning, Deepstream, and OCR. I collaborated closely with my team on model improvement and pipeline optimization to ensure the project could effectively replace existing toll services. Beyond my technical skills, I bring a strategic approach to problem-solving and a knack for diving into the nuances of machine learning models, optimizing them to fit specific business needs. I’m passionate about harnessing AI to address real-world challenges, and I’m excited about the possibility of contributing my skills and learning further with your team. \n", "\n", "Interviewer: That's a strong introduction, Karan. Your projects demonstrate a good understanding of the practical applications of Generative AI. Let's delve a bit deeper. You mentioned prompt engineering in your Legal Case Identification project. Can you describe a challenging prompt engineering problem you faced and how you solved it? What metrics did you use to evaluate the success of your prompt engineering efforts?\n", " \n", "\n", "Candidate: Certainly, Alex. In the Legal Case Identification project, a significant challenge in prompt engineering arose when trying to accurately classify complex case types from unstructured legal data. The prompts needed to be crafted carefully to balance specificity with flexibility, as the language in legal documents can vary widely. One particular issue was handling nuanced legal terms and context-specific language that often influenced the interpretation of a case’s category. To address this, I experimented with structured prompt templates that included both contextual keywords and specific qualifiers. For example, rather than just asking the model to classify a \"personal injury\" case, I structured prompts to include additional context like, \"Identify if this case involves physical harm due to an accident or negligence,\" which guided the model to focus on relevant legal scenarios. For evaluation, I used precision, recall, and F1 scores to measure how accurately the prompts identified cases correctly across categories. Additionally, we monitored the model’s consistency by testing it on a set of challenging cases with subtle differences to see if the prompts led to consistent responses. I also tracked user feedback from legal experts who verified if the classifications aligned with practical expectations. This iterative approach, along with close collaboration with subject matter experts, allowed me to refine prompts effectively. It was a great learning experience in balancing prompt detail and adaptability while ensuring reliable, high-quality results for the client. \n", "\n", "Interviewer: Excellent. That demonstrates a good understanding of prompt engineering and evaluation metrics. Now, let's shift gears slightly. Generative AI models can sometimes produce biased or inaccurate outputs. How would you address such issues in a production environment?\n", "\n", "\n", " \n", "\n", "Candidate: Thank you, Alex; that’s an important consideration. In a production environment, handling bias and inaccuracies in Generative AI outputs requires a proactive, multi-layered approach. Here’s how I’d approach it: Data and Model Auditing: I’d start by auditing the training data to identify and mitigate any inherent biases. This might involve using a diverse dataset or adding counterexamples to balance the perspectives presented in the model’s outputs. Model fine-tuning can help adjust any biases found in pre-trained models by focusing on more representative or neutral datasets. Prompt Design and Constraints: In prompt engineering, I’d craft prompts that guide the model toward neutral and accurate responses. For instance, setting constraints in the prompt to avoid speculative or potentially biased language can help. Additionally, I’d use prompt templates that explicitly frame questions to elicit factual and context-appropriate information. Post-Processing and Filtering: After generating outputs, I’d implement a filtering or post-processing layer that flags any content that seems potentially biased or incorrect. For example, sentiment analysis or bias detection algorithms can help flag outputs, allowing for an additional layer of human review or correction before the final output is published. \n", "\n", "Interviewer: Good. You've covered some key aspects. One last question: Describe your preferred approach to staying up-to-date with the rapidly evolving field of Generative AI.\n", "\n", " \n", "\n", "Candidate: To stay current in Generative AI, I rely on a structured approach that combines both learning from established resources and exploring emerging trends: Research Papers and Journals: I regularly read papers from sources like arXiv and conferences such as NeurIPS, ICML, and CVPR. Following key researchers and institutions helps me stay updated on cutting-edge techniques, and I make it a habit to read and analyze at least one new paper each week, focusing on both theoretical advances and practical applications. Community and Open-Source Contributions: I participate in open-source projects on platforms like GitHub, which keeps me connected with the latest tools and libraries. Additionally, contributing to or following repositories in frameworks like Hugging Face or PyTorch gives me hands-on exposure to practical advancements in model development and deployment. Online Courses and Workshops: I engage in online courses or certifications, especially when new architectures or methodologies gain traction, such as diffusion models or prompt engineering techniques. Platforms like Coursera and specialized workshops provide structured, in-depth content that complements hands-on experience. Podcasts and Newsletters: I subscribe to AI-focused newsletters like \"The Batch\" by Andrew Ng and listen to podcasts such as \"Lex Fridman\" and \"Data Skeptic,\" which often feature industry experts discussing the latest trends and breakthroughs. This is a great way to get a broader perspective on AI developments and practical applications. \n", "\n", "Interviewer: Excellent. Thank you, Karan. That concludes our interview. I appreciate you taking the time to speak with me today.\n", "\n", "\n", "**Evaluation:**\n", "\n", "Karan demonstrated a strong understanding of Generative AI concepts and their practical application. His project descriptions were detailed and showcased his ability to tackle complex problems and evaluate results effectively. He articulated a well-rounded approach to addressing bias and maintaining accuracy in production environments. His commitment to continuous learning is also commendable. While he could have provided more specific examples in some areas, overall, he presented himself as a strong candidate for the Generative AI Engineer position. I would recommend him for the next stage of the interview process.\n", " \n", "\n", "Candidate: exit \n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'category': 'Category: Mock\\n',\n", " 'response': 'Agent_output\\\\Mock_Interview_20241117174111.md'}" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" }, { "name": "stdout", "output_type": "stream", "text": [ "Ending the conversation. Goodbye!\n", "File 'Agent_output\\Interview_questions_20241117005746.md' created successfully.\n" ] }, { "data": { "text/markdown": [ "To best help you prepare for your Generative AI interview, I need some more information. Please tell me:\n", "\n", "1. **What is your target role?** (e.g., Research Scientist, Software Engineer, Product Manager, etc.) The questions will vary significantly depending on the role.\n", "\n", "2. **What is your experience level?** (e.g., Intern, Junior, Mid-level, Senior) This will help tailor the difficulty of the questions.\n", "\n", "3. **Which specific Generative AI areas are you most familiar with?** (e.g., Large Language Models, Diffusion Models, Generative Adversarial Networks, etc.) Focusing on your strengths will maximize your chances of success.\n", "\n", "4. **Are there any specific companies or teams you're interviewing with?** Knowing the company's focus can help me tailor the questions to their specific interests.\n", "\n", "\n", "Once I have this information, I can generate a list of relevant interview questions and potential answers, along with references and links to helpful resources. I will organize this into a markdown (.md) file.\n", "Okay, given that you're a mid-level Generative AI Engineer focusing on LLMs, GANs, NLP, and ML, I can create a tailored set of interview questions. I will categorize them for clarity. Note that some questions may touch upon multiple areas. I won't provide complete answers here, as that would be too extensive, but I'll give you pointers to guide your preparation.\n", "\n", "\n", "# Generative AI Engineer Interview Questions (Mid-Level)\n", "\n", "This document outlines potential interview questions for a mid-level Generative AI Engineer role, focusing on LLMs, GANs, NLP, and ML. Remember to tailor your answers to your specific experiences and projects.\n", "\n", "## I. Large Language Models (LLMs)\n", "\n", "**A. Foundational Understanding:**\n", "\n", "1. **Explain the architecture of a Transformer network. Discuss the role of self-attention and its computational complexity.** *(Focus on encoder-decoder structure, attention mechanisms, positional encoding, and computational challenges like quadratic complexity with naive attention.)*\n", "\n", "2. **Compare and contrast different LLM architectures (e.g., GPT, BERT, T5). Highlight their strengths and weaknesses for different tasks.** *(Consider differences in training objectives, autoregressive vs. masked language modeling, and suitability for various NLP tasks.)*\n", "\n", "3. **What are some common challenges in training LLMs? Discuss methods to mitigate issues like vanishing gradients, overfitting, and catastrophic forgetting.** *(Address gradient clipping, regularization techniques, transfer learning, and continual learning strategies.)*\n", "\n", "\n", "**B. Advanced Topics & Applications:**\n", "\n", "4. **Describe different methods for prompting LLMs to improve performance and control the generated text. Give examples of few-shot, zero-shot, and chain-of-thought prompting.** *(Discuss prompt engineering techniques, including various prompting strategies and their effectiveness.)*\n", "\n", "5. **Explain how reinforcement learning can be used to fine-tune LLMs. Discuss the role of reward models and algorithms like Proximal Policy Optimization (PPO).** *(Focus on RLHF (Reinforcement Learning from Human Feedback) and its application in aligning LLMs with human preferences.)*\n", "\n", "6. **Discuss the ethical considerations surrounding LLMs, such as bias, toxicity, and misinformation. How can these issues be addressed?** *(Consider bias mitigation techniques, safety guidelines, and responsible AI practices.)*\n", "\n", "7. **Describe your experience with specific LLM frameworks (e.g., Hugging Face Transformers, TensorFlow, PyTorch).** *(Highlight your practical experience with these frameworks and any relevant projects.)*\n", "\n", "\n", "## II. Generative Adversarial Networks (GANs)\n", "\n", "**A. Core Concepts:**\n", "\n", "1. **Explain the architecture and training process of a GAN. Describe the roles of the generator and discriminator.** *(Focus on the minimax game, backpropagation, and the adversarial training process.)*\n", "\n", "2. **What are some common problems encountered when training GANs (e.g., mode collapse, vanishing gradients)? How can these be addressed?** *(Discuss techniques like Wasserstein GANs (WGANs), gradient penalty, and spectral normalization.)*\n", "\n", "3. **Compare and contrast different GAN architectures (e.g., DCGAN, StyleGAN, CycleGAN). Discuss their applications and advantages.** *(Highlight architectural differences and their impact on generated output quality and diversity.)*\n", "\n", "\n", "**B. Advanced Topics & Applications:**\n", "\n", "4. **Explain how GANs can be used for image generation, image-to-image translation, and other generative tasks.** *(Provide specific examples and discuss the effectiveness of GANs in these applications.)*\n", "\n", "5. **Describe your experience with GAN training and optimization techniques. Discuss your experience with hyperparameter tuning and model evaluation metrics.** *(Highlight your practical experience and the tools/techniques used.)*\n", "\n", "\n", "## III. Natural Language Processing (NLP) and Machine Learning (ML)\n", "\n", "**A. NLP Techniques:**\n", "\n", "1. **Describe different NLP techniques used in preprocessing text data (e.g., tokenization, stemming, lemmatization).** *(Explain the purpose and impact of each technique.)*\n", "\n", "2. **Explain various word embedding techniques (e.g., Word2Vec, GloVe, FastText). Discuss their strengths and weaknesses.** *(Focus on the underlying algorithms and their representational capabilities.)*\n", "\n", "3. **Discuss different sequence-to-sequence models and their applications in machine translation and text summarization.** *(Explain the encoder-decoder architecture and its use in these tasks.)*\n", "\n", "\n", "**B. ML Fundamentals:**\n", "\n", "1. **Explain different types of machine learning algorithms (e.g., supervised, unsupervised, reinforcement learning).** *(Provide examples and discuss their use cases.)*\n", "\n", "2. **Describe different model evaluation metrics (e.g., precision, recall, F1-score, AUC).** *(Explain the meaning and interpretation of these metrics.)*\n", "\n", "3. **Discuss your experience with model deployment and monitoring.** *(Highlight your practical experience in deploying models to production environments.)*\n", "\n", "\n", "## IV. Project & Experience Based Questions\n", "\n", "1. **Describe a challenging project you worked on involving generative AI. What were the key challenges, and how did you overcome them?** *(Focus on a project that showcases your technical skills and problem-solving abilities.)*\n", "\n", "2. **Discuss your experience with version control (e.g., Git) and collaborative development.** *(Highlight your teamwork skills and experience with collaborative tools.)*\n", "\n", "3. **How do you stay up-to-date with the latest advancements in generative AI?** *(Discuss your approach to continuous learning and staying current in the field.)*\n", "\n", "\n", "This comprehensive list should provide a strong foundation for your interview preparation. Remember to practice explaining your projects and technical concepts clearly and concisely. Good luck!\n", "Let's focus on a few crucial topics and provide more detailed answers, keeping in mind the mid-level Generative AI Engineer role and your expertise in LLMs, GANs, NLP, and ML. Remember that these are examples, and your answers should reflect your own experiences and understanding.\n", "\n", "**I. LLMs: Addressing Bias in LLMs**\n", "\n", "**Question:** \"Large language models are known to exhibit biases present in their training data. Describe several techniques used to mitigate bias in LLMs, and discuss their limitations.\"\n", "\n", "**Answer:** \"Mitigating bias in LLMs is a complex and ongoing challenge. Several strategies exist, each with limitations:\n", "\n", "* **Data Preprocessing:** Carefully curating the training data to remove or rebalance biased content. This is resource-intensive and might not completely eliminate subtle biases. Furthermore, identifying and removing all biased content is very difficult.\n", "\n", "* **Algorithmic Mitigation:** Techniques like adversarial training can be employed. This involves training a separate model to identify and counteract bias during the LLM's training. However, designing effective adversarial training methods is challenging, and it's difficult to ensure complete bias removal.\n", "\n", "* **Post-Processing Techniques:** These methods filter or modify the LLM's output after generation to reduce bias. Examples include re-ranking generated responses based on fairness metrics or using classifiers to identify and flag biased text. The drawback is that these methods might impact the fluency or coherence of the generated text.\n", "\n", "* **Reinforcement Learning from Human Feedback (RLHF):** This approach involves training a reward model that ranks responses based on their fairness and lack of bias. The LLM is then fine-tuned using this reward model via reinforcement learning. While effective, it requires significant human effort to create and evaluate the reward model, and human biases can still creep in.\n", "\n", "* **Fairness-Aware Metrics:** Developing and using metrics that specifically quantify bias in LLM outputs is crucial. This allows for better monitoring and evaluation of bias mitigation techniques. However, designing truly comprehensive and unbiased metrics remains an area of active research.\n", "\n", "In summary, mitigating bias in LLMs is a multifaceted problem requiring a combination of approaches. No single technique is a silver bullet, and continuous research is necessary to develop more effective and robust methods.\"\n", "\n", "\n", "**II. GANs: Mode Collapse and its Solutions**\n", "\n", "**Question:** \"Explain the phenomenon of 'mode collapse' in GAN training. Describe at least three different techniques to mitigate mode collapse.\"\n", "\n", "**Answer:** \"Mode collapse in GANs occurs when the generator learns to produce only a limited set of outputs, failing to capture the full diversity of the data distribution. This results in the generator producing similar samples repeatedly, even when the input noise varies. Several methods address this:\n", "\n", "* **Improved Architectures:** Using architectures like Wasserstein GANs (WGANs) or improved versions like WGAN-GP (WGAN with Gradient Penalty) often helps. These methods use different loss functions that encourage the discriminator to provide more informative gradients, thus preventing the generator from getting stuck in local optima.\n", "\n", "* **Regularization Techniques:** Applying regularization techniques such as spectral normalization to the discriminator or weight clipping in WGANs can stabilize training and reduce mode collapse. These methods constrain the discriminator's behavior, preventing it from becoming too powerful and overwhelming the generator.\n", "\n", "* **Mini-batch Discrimination:** This technique involves feeding mini-batches of generated samples to the discriminator simultaneously. This allows the discriminator to compare generated samples with each other, encouraging the generator to produce more diverse outputs.\n", "\n", "* **Label Smoothing:** Adding noise to the discriminator's labels during training can help improve the stability of training and reduce mode collapse.\n", "\n", "* **Two Timescale Update Rule (TTUR):** This method uses different learning rates for the generator and the discriminator, often leading to more stable training dynamics.\n", "\n", "\n", "The choice of technique often depends on the specific GAN architecture and dataset. A combination of methods is often most effective.\"\n", "\n", "\n", "**III. NLP & ML: Explainable AI (XAI) in NLP**\n", "\n", "**Question:** \"Explain the importance of explainable AI (XAI) in NLP, particularly in the context of LLMs. Describe some techniques used to make NLP models more interpretable.\"\n", "\n", "**Answer:** \"Explainability is crucial in NLP, especially with complex models like LLMs, because it increases trust, facilitates debugging, and allows for better model understanding and improvement. Opaque models make it difficult to identify biases, errors, or unexpected behaviors. Several techniques promote interpretability:\n", "\n", "* **Attention Mechanisms:** Analyzing the attention weights in Transformer networks provides insights into which parts of the input sequence the model focuses on when generating output. This can reveal the model's reasoning process.\n", "\n", "* **Saliency Maps:** These highlight the input features that most influence the model's prediction. In NLP, this could show which words or phrases are most important for a particular classification or generation task.\n", "\n", "* **Feature Importance Analysis:** Techniques like SHAP (SHapley Additive exPlanations) or LIME (Local Interpretable Model-agnostic Explanations) can be used to quantify the contribution of individual features (words, phrases, etc.) to the model's prediction.\n", "\n", "* **Rule Extraction:** For simpler models, rules can be extracted directly from the model's parameters, providing a more explicit representation of the model's decision-making process.\n", "\n", "* **Probing Classifiers:** Training separate classifiers to predict specific aspects of the model's internal representations can reveal what information the model learns and how it uses it.\n", "\n", "\n", "While these methods offer insights, perfect explainability is often challenging to achieve, especially with highly complex models. The choice of technique depends on the specific model and the desired level of interpretability.\"\n", "\n", "\n", "These expanded answers provide a more thorough response to common interview questions. Remember to adapt them to your own experiences and projects. Good luck!\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'category': 'Category: Question\\n',\n", " 'response': 'Agent_output\\\\Interview_questions_20241117005746.md'}" ] }, "execution_count": 276, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"I need mock interview to practice.\"\n", "result = run_user_query(query)\n", "result" ] }, { "cell_type": "markdown", "id": "4bc89a57-2c6e-4cff-a1e5-44a461df813a", "metadata": {}, "source": [ "## TEST CASE 5: Resume Modification Based on Job Description" ] }, { "cell_type": "code", "execution_count": 55, "id": "987566c5-0db8-4033-9fa5-da939dd2f57f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: handle_resume_making\n", "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mI can definitely help you with that! To tailor your resume effectively, I'll need some information from you. First, could you please share:\n", "\n", "1. Your current resume (in any format).\n", "2. The job description of the role you're targeting.\n", "3. Your LinkedIn profile URL (optional).\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: SKILLS: Technical skills: • Demonstrated work experience with natural language processing techniques to drive business value. Experience building user-centric AI products/features is highly valuable. • Knowledge in Hypothesis testing, Statistical Methods, Sampling Theory, Experimental Design • Familiarity with common advanced analysis tools – SQL & Python/R • Demonstrated familiarity (work experience, GitHub account) with OOP concepts. Expertise in Python is a big plus. • Experience with cloud computing (AWS) & MLOps is a plus. • Strong knowledge of Machine Learning & Deep Learning Soft/Leadership skills: • Use business acumen and analytical skills to identify opportunities, estimate potential, layout strategy roadmaps to solve complex business problems. • Be motivated to explore and identify opportunities from scratch by thinking backwards on problem solving by putting users and data at the center of analysis and decision making. • Be responsible for using analytical techniques like Machine learning, Natural Language Processing, and advanced data visualizations to improve Asurion’s customers’ experiences. • Deploy ML solutions in production environment • Design statistical tests for product experiments, measure impact, derive insights and provide recommendations • Work closely with product managers to identify and answer important product questions that help improve outcomes Resume: KARAN SHRESTHA LinkedIn | 747-295-9996 | ks.karanshrestha@gmail.com | GitHub Seasoned Data Scientist skilled in Python, Machine Learning, NLP, and Deep Learning, Generative AI, Prompt Engineering with 4.5 years of experience. Proven ability in data science, excellent communication skills, and analytical skills. Effective team player with strong time management. Keen learner with a proactive attitude. Skills ____________________________________________________________________________________________ • Python | SQL | C# | Tensorflow | Pytorch | Numpy | NLTK | Pandas | Natural Language Processing | Machine Learning| Database query | • Computer Vision | Transformers | MXNet | Deep Learning | Anomaly detection | Scikit-learn | CNN | RNN | LSTM -Neural networks | • AWS | JavaScript | REST API | LLMs-Large Language Models | Keras | Predictive Modeling | Generative AI | Prompt Engineering | Neo4j • Tableau | Power BI | Fine Tuning | Problem solving | Web Development | PySpark | GCP | Azure | Statistics | Statistical modeling | R Experience _______________________________________________________________________________________ Senior Data Scientist FreightMango Gurgaon, India 06/2023 – 12/2023 • Applied data preprocessing techniques, including data collection and cleaning, to prepare datasets for Machine learning models. • Tuned and optimized datasets through advanced data preprocessing techniques for machine learning models. • Engineered an automated customer quotation document scanning pipeline, boosting customer acquisition by 40%. • Drive the vision of the product, ensuring alignment with business goals. Implement networking protocols and ensure robust product security. Conducted research to identify industry trends, applying findings to product innovation. • Applied machine learning (ML) algorithms to optimize finance-related applications, enhancing the accuracy and efficiency of financial forecasting models. • Developed ML models and maintained information systems to manage and process large data sets, ensuring data integrity and availability for machine learning projects. • Demonstrated a high level of attention to detail in data preprocessing, model tuning, and system optimization, ensuring accuracy and reliability in deliverables. • Collaborate with cross-functional teams to develop innovative solutions. Apply analytical skills to solve complex problems and improve basic functionalities. Managed social media campaigns, boosting engagement by 30% with targeted content strategies. Software Engineer DataNova Noida, India 02/2019 - 06/2023 • Conducted image annotation, text data cleaning, text vectorization, manipulation, and data preprocessing for Machine learning projects. • Feature Engineering and created data visualizations to support data-driven decisions. Execute on design, build, analysis and validation of data analytics, modeling, and machine learning techniques • In-depth expertise with a rich repertoire of Regression, Classification, Clustering, and Dimensionality reduction algorithms. • Delivered pre-trained and fine-tuned neural network models using TensorFlow for internal projects, including object detection and automated chatbots using NLP. • Collaborated with cross-functional teams to deploy machine learning solutions, enhancing performance for perception tasks like Object Detection. • Developed predictive models using algorithms such as Kernel-KNN, Decision Trees, Random Forest, Gradient Boosting, SVMs, and XgBoost. • Ensure scalability, security, and performance of the applications. Conduct thorough testing and monitoring to ensure high-quality deliverables. Developed and executed strategic plans, driving growth and improving efficiency. • Engage in code review processes to maintain code quality and best practices. Utilize metrics and analytics to measure and improve product performance. Created and refined project specifications to align with client requirements and industry standards. • Developed innovative machine learning solutions and computer vision models, significantly enhancing system performance and accuracy. • Contribute to the development of ML models and their integration into the product. Provide written and verbal communication on project progress and technical issues. • Regularly monitored the status of machine learning models and data pipelines, ensuring optimal performance and accuracy through continuous evaluation and fine-tuning. Education ________________________________________________________________________________________ Master of Science San Francisco Bay University Fremont, CA, USA 01/2024 - Present • Major in Computer Science (3.93 GPA) Bachelor of Science ITS Engineering College Greater Noida, India 05/2015 - 06/2019 • Major in Computer Science & Engineering (3.62 GPA) Projects __________________________________________________________________________________________ • WAFER SENSOR FAULT CLASSIFICATION: Predict the quality of the wafer whether good or bad based on the different sensor values for each wafer. A wafer is a thin semiconductor used in various electronic devices. Technology: Python, SQL, Machine learning, RandomForest Classifier, Data Validation, Preprocessing, K Means++ Clustering, Classification, Hyperparameter tuning. • HAND DETECTION-Shredder Machine: Detect the hands of the workers working with the shredder machine and stop the machine if hands come near the machine to prevent injury. Technology: Python, SQL, Tensorflow object detection framework-SSDlite • ANPR (Automatic Number Plate Recognition): Worked on end-to-end ANPR for NPCI , installed on Mumbai Marine Lines running on real time. ANPR is Automatic Number Plate Recognition system , Purpose for this Solution is to replace Fastag and convert all toll services with ANPR solution. Technology: Computer vision, Transfer learning, Deepstream, Docker, GCP, Yolo, Tracker, paddel, dbnet, OCR(CRNN, paddel OCR,tensorRT), ML-Flow, Python, OpenCV, Pandas. • VERINEXT(PondLehocky) on Project Legal-Case-Identification (LCI): LCI( Legal-Case-Identification) is a legal domain project , This Solution is for US legal firms to replace their Manual processes to assign case to suitable handling firm with Gen-AI solution with Littify DB. Technology: Gen-AI, NLP, GPT, Prompt engineering, LangChain, Authentication API , Litify, Deep learning Algo, AZURE-API. • FM QUOTATION REQUEST - OCR: A fully automated OCR model that takes input as a pdf or doc file scans it and retrieves information regarding quotation of the user for delivery and pick up details of requests and process it. Technology: Natural Language Processing, Spacy, NER, Data cleaning. • CONCRETE STRENGTH PREDICTION: A regression model to predict the concrete compressive strength based on quantity of different components of mixtures and cement. Technology: Python,SQL, Machine learning, XGboost Regressor, Data Validation, Preprocessing, Clustering, Hyperparameter tuning. • WEBSHOP-CUSTOMER REVIEWS SENTIMENTS: Classifies the reviews of all the customers visited in Web-Shop and gives the different sentiment analysis reports. Technology: NLP, Naive bayes, Support Vector machine, TFIDF, SQL. Mentorship _______________________________________________________________________________________ • Data Science Tutor: Programming | Data Science | Machine Learning | Data Visualization. Certificates ___________________________________________________________________________________________ • Oracle Cloud Infrastructure 2024 Generative AI Certified Professional. Link • Gold Badge (5 Star) for Python on HackerRank. Link • Data Scientist 1 year Master Professional Program. Link • Certificate of Training in MACHINE LEARNING Advance course. Link\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m```markdown\n", "# Karan Shrestha\n", "[LinkedIn](LinkedIn) | 747-295-9996 | ks.karanshrestha@gmail.com | [GitHub](GitHub)\n", "\n", "## Summary\n", "\n", "Highly motivated and results-oriented Data Scientist with 4.5 years of experience specializing in Machine Learning, Natural Language Processing (NLP), Deep Learning, Generative AI, and Prompt Engineering. Proven ability to leverage data-driven insights to solve complex business problems, with a strong focus on building user-centric AI products. Expertise in Python, cloud computing (AWS), and MLOps, along with excellent communication and teamwork skills. Passionate about exploring and identifying opportunities to improve customer experiences through innovative AI solutions.\n", "\n", "## Skills\n", "\n", "**Technical Skills:** Python, SQL, C#, TensorFlow, PyTorch, NumPy, NLTK, Pandas, Scikit-learn, Transformers, MXNet, Keras, Deep Learning, CNN, RNN, LSTM, Computer Vision, Anomaly Detection, AWS, JavaScript, REST API, LLMs (Large Language Models), Generative AI, Prompt Engineering, Fine-tuning, PySpark, GCP, Azure, Statistics, Statistical Modeling, R, Neo4j\n", "\n", "**Soft/Leadership Skills:** Problem-solving, Business Acumen, Analytical Skills, Strategic Planning, Communication (Written & Verbal), Teamwork, Time Management, Product Vision, Cross-functional Collaboration, Data Visualization (Tableau, Power BI)\n", "\n", "\n", "## Experience\n", "\n", "**Senior Data Scientist, FreightMango, Gurgaon, India (06/2023 – 12/2023)**\n", "\n", "* Engineered an automated customer quotation document scanning pipeline using OCR and NLP, resulting in a 40% increase in customer acquisition.\n", "* Applied Machine Learning (ML) algorithms to optimize finance-related applications, improving the accuracy and efficiency of financial forecasting models.\n", "* Developed and maintained information systems for managing and processing large datasets for machine learning projects.\n", "* Conducted research on industry trends and applied findings to product innovation, driving the product vision and ensuring alignment with business goals.\n", "* Implemented networking protocols and ensured robust product security.\n", "* Collaborated with cross-functional teams to develop innovative solutions and improve core functionalities.\n", "* Managed social media campaigns, increasing engagement by 30% through targeted content strategies.\n", "\n", "**Software Engineer, DataNova, Noida, India (02/2019 - 06/2023)**\n", "\n", "* Developed and delivered pre-trained and fine-tuned neural network models using TensorFlow for internal projects, including object detection and automated chatbots using NLP.\n", "* Collaborated with cross-functional teams to deploy machine learning solutions, enhancing performance for perception tasks like object detection.\n", "* Developed predictive models using algorithms such as Kernel-KNN, Decision Trees, Random Forest, Gradient Boosting, SVMs, and XGBoost.\n", "* Conducted image annotation, text data cleaning, text vectorization, and data preprocessing for machine learning projects.\n", "* Created data visualizations to support data-driven decisions.\n", "* Contributed to the development of ML models and their integration into the product.\n", "* Regularly monitored and fine-tuned machine learning models and data pipelines to ensure optimal performance and accuracy.\n", "\n", "\n", "## Education\n", "\n", "**Master of Science in Computer Science (3.93 GPA), San Francisco Bay University, Fremont, CA, USA (01/2024 – Present)**\n", "\n", "**Bachelor of Science in Computer Science & Engineering (3.62 GPA), ITS Engineering College, Greater Noida, India (05/2015 - 06/2019)**\n", "\n", "\n", "## Projects\n", "\n", "* **Wafer Sensor Fault Classification:** Developed a machine learning model using Random Forest Classifier and K-Means++ Clustering to predict wafer quality based on sensor data.\n", "* **Hand Detection - Shredder Machine:** Implemented a real-time hand detection system using TensorFlow Object Detection framework (SSDlite) to prevent workplace injuries.\n", "* **ANPR (Automatic Number Plate Recognition):** Developed an end-to-end ANPR system for NPCI using computer vision, transfer learning, and deep learning techniques.\n", "* **Verinext (PondLehocky) on Project Legal-Case-Identification (LCI):** Developed a Gen-AI solution using NLP, GPT, and Prompt Engineering to automate legal case assignments.\n", "* **FM Quotation Request - OCR:** Built an automated OCR model using NLP and Spacy to extract information from quotation documents and streamline the request process.\n", "* **Concrete Strength Prediction:** Developed a regression model using XGBoost Regressor to predict concrete compressive strength based on mixture components.\n", "* **Webshop - Customer Reviews Sentiments:** Implemented a sentiment analysis model using NLP techniques to classify customer reviews and generate reports.\n", "\n", "## Mentorship\n", "\n", "* **Data Science Tutor:** Provided tutoring in Programming, Data Science, Machine Learning, and Data Visualization.\n", "\n", "## Certifications\n", "\n", "* **Oracle Cloud Infrastructure 2024 Generative AI Certified Professional:** [Link](Link)\n", "* **Gold Badge (5 Star) for Python on HackerRank:** [Link]\n", "* **Data Scientist 1-year Master Professional Program:** [Link]\n", "* **Certificate of Training in Machine Learning Advanced Course:** [Link]\n", "\n", "```\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: exit\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "Ending the conversation. Goodbye!\n", "File 'Agent_output\\Resume_20241117173459.md' created successfully.\n", "Resume saved to Agent_output\\Resume_20241117173459.md\n" ] }, { "data": { "text/markdown": [ "# Karan Shrestha\n", "[LinkedIn](LinkedIn) | 747-295-9996 | ks.karanshrestha@gmail.com | [GitHub](GitHub)\n", "\n", "## Summary\n", "\n", "Highly motivated and results-oriented Data Scientist with 4.5 years of experience specializing in Machine Learning, Natural Language Processing (NLP), Deep Learning, Generative AI, and Prompt Engineering. Proven ability to leverage data-driven insights to solve complex business problems, with a strong focus on building user-centric AI products. Expertise in Python, cloud computing (AWS), and MLOps, along with excellent communication and teamwork skills. Passionate about exploring and identifying opportunities to improve customer experiences through innovative AI solutions.\n", "\n", "## Skills\n", "\n", "**Technical Skills:** Python, SQL, C#, TensorFlow, PyTorch, NumPy, NLTK, Pandas, Scikit-learn, Transformers, MXNet, Keras, Deep Learning, CNN, RNN, LSTM, Computer Vision, Anomaly Detection, AWS, JavaScript, REST API, LLMs (Large Language Models), Generative AI, Prompt Engineering, Fine-tuning, PySpark, GCP, Azure, Statistics, Statistical Modeling, R, Neo4j\n", "\n", "**Soft/Leadership Skills:** Problem-solving, Business Acumen, Analytical Skills, Strategic Planning, Communication (Written & Verbal), Teamwork, Time Management, Product Vision, Cross-functional Collaboration, Data Visualization (Tableau, Power BI)\n", "\n", "\n", "## Experience\n", "\n", "**Senior Data Scientist, FreightMango, Gurgaon, India (06/2023 – 12/2023)**\n", "\n", "* Engineered an automated customer quotation document scanning pipeline using OCR and NLP, resulting in a 40% increase in customer acquisition.\n", "* Applied Machine Learning (ML) algorithms to optimize finance-related applications, improving the accuracy and efficiency of financial forecasting models.\n", "* Developed and maintained information systems for managing and processing large datasets for machine learning projects.\n", "* Conducted research on industry trends and applied findings to product innovation, driving the product vision and ensuring alignment with business goals.\n", "* Implemented networking protocols and ensured robust product security.\n", "* Collaborated with cross-functional teams to develop innovative solutions and improve core functionalities.\n", "* Managed social media campaigns, increasing engagement by 30% through targeted content strategies.\n", "\n", "**Software Engineer, DataNova, Noida, India (02/2019 - 06/2023)**\n", "\n", "* Developed and delivered pre-trained and fine-tuned neural network models using TensorFlow for internal projects, including object detection and automated chatbots using NLP.\n", "* Collaborated with cross-functional teams to deploy machine learning solutions, enhancing performance for perception tasks like object detection.\n", "* Developed predictive models using algorithms such as Kernel-KNN, Decision Trees, Random Forest, Gradient Boosting, SVMs, and XGBoost.\n", "* Conducted image annotation, text data cleaning, text vectorization, and data preprocessing for machine learning projects.\n", "* Created data visualizations to support data-driven decisions.\n", "* Contributed to the development of ML models and their integration into the product.\n", "* Regularly monitored and fine-tuned machine learning models and data pipelines to ensure optimal performance and accuracy.\n", "\n", "\n", "## Education\n", "\n", "**Master of Science in Computer Science (3.93 GPA), San Francisco Bay University, Fremont, CA, USA (01/2024 – Present)**\n", "\n", "**Bachelor of Science in Computer Science & Engineering (3.62 GPA), ITS Engineering College, Greater Noida, India (05/2015 - 06/2019)**\n", "\n", "\n", "## Projects\n", "\n", "* **Wafer Sensor Fault Classification:** Developed a machine learning model using Random Forest Classifier and K-Means++ Clustering to predict wafer quality based on sensor data.\n", "* **Hand Detection - Shredder Machine:** Implemented a real-time hand detection system using TensorFlow Object Detection framework (SSDlite) to prevent workplace injuries.\n", "* **ANPR (Automatic Number Plate Recognition):** Developed an end-to-end ANPR system for NPCI using computer vision, transfer learning, and deep learning techniques.\n", "* **Verinext (PondLehocky) on Project Legal-Case-Identification (LCI):** Developed a Gen-AI solution using NLP, GPT, and Prompt Engineering to automate legal case assignments.\n", "* **FM Quotation Request - OCR:** Built an automated OCR model using NLP and Spacy to extract information from quotation documents and streamline the request process.\n", "* **Concrete Strength Prediction:** Developed a regression model using XGBoost Regressor to predict concrete compressive strength based on mixture components.\n", "* **Webshop - Customer Reviews Sentiments:** Implemented a sentiment analysis model using NLP techniques to classify customer reviews and generate reports.\n", "\n", "## Mentorship\n", "\n", "* **Data Science Tutor:** Provided tutoring in Programming, Data Science, Machine Learning, and Data Visualization.\n", "\n", "## Certifications\n", "\n", "* **Oracle Cloud Infrastructure 2024 Generative AI Certified Professional:** [Link](Link)\n", "* **Gold Badge (5 Star) for Python on HackerRank:** [Link]\n", "* **Data Scientist 1-year Master Professional Program:** [Link]\n", "* **Certificate of Training in Machine Learning Advanced Course:** [Link]\n", "\n", "```" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'category': '2\\n', 'response': 'Agent_output\\\\Resume_20241117173459.md'}" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"Can you help me to modify my resume based on job description\"\n", "result = run_user_query(query)\n", "result" ] }, { "cell_type": "markdown", "id": "1032b1b8-641e-4fff-a816-a0254be1a4c1", "metadata": {}, "source": [ "## TEST CASE 6: Resume Making" ] }, { "cell_type": "code", "execution_count": 50, "id": "2e967ff9-f878-4eb8-ab33-a478ab5f0fcb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: handle_resume_making\n", "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mI can definitely help you with that! To create a tailored resume for Generative AI roles, I need some information from you. Could you please tell me about your technical skills related to AI/ML and Generative AI in particular? For example, list specific programming languages, platforms, libraries, and tools you're proficient in (e.g., Python, TensorFlow, PyTorch, Transformers, LangChain, etc.).\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: Skills ____________________________________________________________________________________________ • Python | SQL | C# | Tensorflow | Pytorch | Numpy | NLTK | Pandas | Natural Language Processing | Machine Learning| Database query | • Computer Vision | Transformers | MXNet | Deep Learning | Anomaly detection | Scikit-learn | CNN | RNN | LSTM -Neural networks | • AWS | JavaScript | REST API | LLMs-Large Language Models | Keras | Predictive Modeling | Generative AI | Prompt Engineering | Neo4j • Tableau | Power BI | Fine Tuning | Problem solving | Web Development | PySpark | GCP | Azure | Statistics | Statistical modeling | R\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mGreat! Now, please tell me about your work experience and projects, focusing on those relevant to Generative AI. For each experience/project, please provide a brief description, highlighting your contributions and the technologies used. If you have any publications or patents, please mention those as well. If you're a fresh graduate or have no direct experience, describe relevant academic projects or coursework.\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: Experience _______________________________________________________________________________________ Senior Data Scientist FreightMango Gurgaon, India 06/2023 – 12/2023 • Applied data preprocessing techniques, including data collection and cleaning, to prepare datasets for Machine learning models. • Tuned and optimized datasets through advanced data preprocessing techniques for machine learning models. • Engineered an automated customer quotation document scanning pipeline, boosting customer acquisition by 40%. • Drive the vision of the product, ensuring alignment with business goals. Implement networking protocols and ensure robust product security. Conducted research to identify industry trends, applying findings to product innovation. • Applied machine learning (ML) algorithms to optimize finance-related applications, enhancing the accuracy and efficiency of financial forecasting models.Software Engineer DataNova Noida, India 02/2019 - 06/2023 • Conducted image annotation, text data cleaning, text vectorization, manipulation, and data preprocessing for Machine learning projects. • Feature Engineering and created data visualizations to support data-driven decisions. Execute on design, build, analysis and validation of data analytics, modeling, and machine learning techniques • In-depth expertise with a rich repertoire of Regression, Classification, Clustering, and Dimensionality reduction algorithms. • Delivered pre-trained and fine-tuned neural network models using TensorFlow for internal projects, including object detection and automated chatbots using NLP. • Collaborated with cross-functional teams to deploy machine learning solutions, enhancing performance for perception tasks like Object Detection. Projects __________________________________________________________________________________________ • WAFER SENSOR FAULT CLASSIFICATION: Predict the quality of the wafer whether good or bad based on the different sensor values for each wafer. A wafer is a thin semiconductor used in various electronic devices. Technology: Python, SQL, Machine learning, RandomForest Classifier, Data Validation, Preprocessing, K Means++ Clustering, Classification, Hyperparameter tuning. • HAND DETECTION-Shredder Machine: Detect the hands of the workers working with the shredder machine and stop the machine if hands come near the machine to prevent injury. Technology: Python, SQL, Tensorflow object detection framework-SSDlite • ANPR (Automatic Number Plate Recognition): Worked on end-to-end ANPR for NPCI , installed on Mumbai Marine Lines running on real time. ANPR is Automatic Number Plate Recognition system , Purpose for this Solution is to replace Fastag and convert all toll services with ANPR solution. Technology: Computer vision, Transfer learning, Deepstream, Docker, GCP, Yolo, Tracker, paddel, dbnet, OCR(CRNN, paddel OCR,tensorRT), ML-Flow, Python, OpenCV, Pandas. • VERINEXT(PondLehocky) on Project Legal-Case-Identification (LCI): LCI( Legal-Case-Identification) is a legal domain project , This Solution is for US legal firms to replace their Manual processes to assign case to suitable handling firm with Gen-AI solution with Littify DB. Technology: Gen-AI, NLP, GPT, Prompt engineering, LangChain, Authentication API , Litify, Deep learning Algo, AZURE-API. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mOkay, that's a good start. Finally, could you please provide your education details (degrees, university, graduation dates), any relevant certifications (e.g., AWS Certified Machine Learning – Specialty), and your contact information (name, phone number, email, LinkedIn profile URL if you have one)? You can replace your actual contact information with placeholders if you prefer not to share it here.\n", "\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: Education ________________________________________________________________________________________ Master of Science San Francisco Bay University Fremont, CA, USA 01/2024 - Present • Major in Computer Science (3.93 GPA) Bachelor of Science ITS Engineering College Greater Noida, India 05/2015 - 06/2019 • Major in Computer Science & Engineering (3.62 GPA)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m```markdown\n", "# [Your Name]\n", "[Phone Number] | [Email Address] | [LinkedIn Profile URL]\n", "\n", "## Summary\n", "\n", "Highly motivated and results-oriented AI Engineer with a proven track record in developing and deploying Generative AI solutions. Expertise in leveraging cutting-edge technologies like LLMs, Transformers, and Deep Learning to solve complex business problems. Passionate about building innovative and impactful AI-driven applications.\n", "\n", "## Skills\n", "\n", "**Programming Languages:** Python, SQL, C#, JavaScript, R\n", "**AI/ML Libraries & Frameworks:** TensorFlow, PyTorch, Keras, Scikit-learn, Transformers, LangChain, NLTK, Pandas, NumPy, MXNet\n", "**Cloud Platforms:** AWS, GCP, Azure\n", "**Databases:** SQL, Neo4j\n", "**Other Tools & Technologies:** Computer Vision, CNN, RNN, LSTM, Natural Language Processing (NLP), Deep Learning, Predictive Modeling, Generative AI, Prompt Engineering, Fine-tuning, REST API, Tableau, Power BI, PySpark, Docker, Deepstream\n", "\n", "## Experience\n", "\n", "**Senior Data Scientist, FreightMango (Gurgaon, India)** 06/2023 – 12/2023\n", "* Engineered an automated customer quotation document scanning pipeline, boosting customer acquisition by 40%.\n", "* Applied data preprocessing techniques, including data collection and cleaning, to prepare datasets for Machine learning models.\n", "* Tuned and optimized datasets through advanced data preprocessing techniques for machine learning models.\n", "* Applied machine learning (ML) algorithms to optimize finance-related applications, enhancing the accuracy and efficiency of financial forecasting models.\n", "* Drove the product vision, ensuring alignment with business goals. Implemented networking protocols and ensured robust product security.\n", "* Conducted research to identify industry trends, applying findings to product innovation.\n", "\n", "\n", "**Software Engineer, DataNova (Noida, India)** 02/2019 - 06/2023\n", "* Conducted image annotation, text data cleaning, text vectorization, manipulation, and data preprocessing for Machine learning projects.\n", "* Feature Engineering and created data visualizations to support data-driven decisions. Executed design, build, analysis and validation of data analytics, modeling, and machine learning techniques.\n", "* In-depth expertise with a rich repertoire of Regression, Classification, Clustering, and Dimensionality reduction algorithms.\n", "* Delivered pre-trained and fine-tuned neural network models using TensorFlow for internal projects, including object detection and automated chatbots using NLP.\n", "* Collaborated with cross-functional teams to deploy machine learning solutions, enhancing performance for perception tasks like Object Detection.\n", "\n", "\n", "## Projects\n", "\n", "* **VERINEXT (PondLehocky) on Project Legal-Case-Identification (LCI):** Developed a Generative AI solution for US legal firms to automate case assignment using the Littify database. Technologies: Gen-AI, NLP, GPT, Prompt engineering, LangChain, Authentication API, Litify, Deep learning algorithms, Azure API.\n", "* **ANPR (Automatic Number Plate Recognition):** Developed an end-to-end ANPR system for NPCI, deployed on Mumbai Marine Lines, running in real-time, to replace Fastag and convert toll services to ANPR. Technologies: Computer vision, Transfer learning, Deepstream, Docker, GCP, Yolo, Tracker, PaddleOCR, DBNet, OCR (CRNN, PaddleOCR, TensorRT), MLflow, Python, OpenCV, Pandas.\n", "* **HAND DETECTION-Shredder Machine:** Developed a hand detection system using TensorFlow Object Detection framework (SSDlite) to prevent injuries by stopping the shredder machine when hands come near. Technologies: Python, SQL, TensorFlow Object Detection framework-SSDlite.\n", "* **WAFER SENSOR FAULT CLASSIFICATION:** Developed a model to predict wafer quality based on sensor values. Technologies: Python, SQL, Machine learning, RandomForest Classifier, Data Validation, Preprocessing, K-Means++ Clustering, Classification, Hyperparameter tuning.\n", "\n", "## Education\n", "\n", "* **Master of Science in Computer Science,** San Francisco Bay University (Fremont, CA, USA) 01/2024 - Present (GPA: 3.93)\n", "* **Bachelor of Science in Computer Science & Engineering,** ITS Engineering College (Greater Noida, India) 05/2015 - 06/2019 (GPA: 3.62)\n", "\n", "\n", "```\n", "\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "You: exit\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Starting the Resume create session. Type 'exit' to end the session.\n", "\n", "Ending the conversation. Goodbye!\n", "File 'Agent_output\\Resume_20241117162047.md' created successfully.\n", "Resume saved to Agent_output\\Resume_20241117162047.md\n" ] }, { "data": { "text/markdown": [ "# [Your Name]\n", "[Phone Number] | [Email Address] | [LinkedIn Profile URL]\n", "\n", "## Summary\n", "\n", "Highly motivated and results-oriented AI Engineer with a proven track record in developing and deploying Generative AI solutions. Expertise in leveraging cutting-edge technologies like LLMs, Transformers, and Deep Learning to solve complex business problems. Passionate about building innovative and impactful AI-driven applications.\n", "\n", "## Skills\n", "\n", "**Programming Languages:** Python, SQL, C#, JavaScript, R\n", "**AI/ML Libraries & Frameworks:** TensorFlow, PyTorch, Keras, Scikit-learn, Transformers, LangChain, NLTK, Pandas, NumPy, MXNet\n", "**Cloud Platforms:** AWS, GCP, Azure\n", "**Databases:** SQL, Neo4j\n", "**Other Tools & Technologies:** Computer Vision, CNN, RNN, LSTM, Natural Language Processing (NLP), Deep Learning, Predictive Modeling, Generative AI, Prompt Engineering, Fine-tuning, REST API, Tableau, Power BI, PySpark, Docker, Deepstream\n", "\n", "## Experience\n", "\n", "**Senior Data Scientist, FreightMango (Gurgaon, India)** 06/2023 – 12/2023\n", "* Engineered an automated customer quotation document scanning pipeline, boosting customer acquisition by 40%.\n", "* Applied data preprocessing techniques, including data collection and cleaning, to prepare datasets for Machine learning models.\n", "* Tuned and optimized datasets through advanced data preprocessing techniques for machine learning models.\n", "* Applied machine learning (ML) algorithms to optimize finance-related applications, enhancing the accuracy and efficiency of financial forecasting models.\n", "* Drove the product vision, ensuring alignment with business goals. Implemented networking protocols and ensured robust product security.\n", "* Conducted research to identify industry trends, applying findings to product innovation.\n", "\n", "\n", "**Software Engineer, DataNova (Noida, India)** 02/2019 - 06/2023\n", "* Conducted image annotation, text data cleaning, text vectorization, manipulation, and data preprocessing for Machine learning projects.\n", "* Feature Engineering and created data visualizations to support data-driven decisions. Executed design, build, analysis and validation of data analytics, modeling, and machine learning techniques.\n", "* In-depth expertise with a rich repertoire of Regression, Classification, Clustering, and Dimensionality reduction algorithms.\n", "* Delivered pre-trained and fine-tuned neural network models using TensorFlow for internal projects, including object detection and automated chatbots using NLP.\n", "* Collaborated with cross-functional teams to deploy machine learning solutions, enhancing performance for perception tasks like Object Detection.\n", "\n", "\n", "## Projects\n", "\n", "* **VERINEXT (PondLehocky) on Project Legal-Case-Identification (LCI):** Developed a Generative AI solution for US legal firms to automate case assignment using the Littify database. Technologies: Gen-AI, NLP, GPT, Prompt engineering, LangChain, Authentication API, Litify, Deep learning algorithms, Azure API.\n", "* **ANPR (Automatic Number Plate Recognition):** Developed an end-to-end ANPR system for NPCI, deployed on Mumbai Marine Lines, running in real-time, to replace Fastag and convert toll services to ANPR. Technologies: Computer vision, Transfer learning, Deepstream, Docker, GCP, Yolo, Tracker, PaddleOCR, DBNet, OCR (CRNN, PaddleOCR, TensorRT), MLflow, Python, OpenCV, Pandas.\n", "* **HAND DETECTION-Shredder Machine:** Developed a hand detection system using TensorFlow Object Detection framework (SSDlite) to prevent injuries by stopping the shredder machine when hands come near. Technologies: Python, SQL, TensorFlow Object Detection framework-SSDlite.\n", "* **WAFER SENSOR FAULT CLASSIFICATION:** Developed a model to predict wafer quality based on sensor values. Technologies: Python, SQL, Machine learning, RandomForest Classifier, Data Validation, Preprocessing, K-Means++ Clustering, Classification, Hyperparameter tuning.\n", "\n", "## Education\n", "\n", "* **Master of Science in Computer Science,** San Francisco Bay University (Fremont, CA, USA) 01/2024 - Present (GPA: 3.93)\n", "* **Bachelor of Science in Computer Science & Engineering,** ITS Engineering College (Greater Noida, India) 05/2015 - 06/2019 (GPA: 3.62)\n", "\n", "\n", "```" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'category': '2\\n', 'response': 'Agent_output\\\\Resume_20241117162047.md'}" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"I want to make resume for Gen AI roles job.\"\n", "result = run_user_query(query)\n", "result" ] }, { "cell_type": "markdown", "id": "eeb9ed5d-b29f-4030-86fc-6dd2d4f7a8c8", "metadata": {}, "source": [ "## TEST CASE 7: Job Search" ] }, { "cell_type": "code", "execution_count": 45, "id": "fbe5815d-19d3-480e-81f8-2e4a97f47494", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Categorizing the customer query...\n", "Category: job_search\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ "Please make sure to mention Job location you want,Job roles\n", " Find jobs in GenAI, AI Engineer roles, Location USA\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "File 'Agent_output\\Job_search_20241117172655.md' created successfully.\n", "Jobs saved to Agent_output\\Job_search_20241117172655.md\n" ] }, { "data": { "text/markdown": [ "# Generative AI Engineer Job Listings\n", "\n", "This document provides a curated list of job opportunities in the field of Generative AI.\n", "\n", "## Job Listings\n", "\n", "| Title | Company | Location | Salary Range | Description | Link |\n", "|---------------------------------------------------------------------------------------------------|---------------|--------------------------|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|\n", "| Generative AI Engineer | Cognizant | Varies | Not specified | Cognizant seeks an innovative Gen AI Engineer to develop cutting-edge, cloud-based software. Ideal candidates enjoy working in diverse, collaborative, geographically distributed teams and are expert engineers. | [Apply Here](https://careers.cognizant.com/global-en/jobs/00061676931/generative-ai-engineer/) |\n", "| Staff Software Engineer, AI/ML GenAI, Gemini | Google | US | $189,000-$284,000 + bonus + equity + benefits | Build a conversational AI tool that enables users to collaborate with generative AI, augmenting their imagination, expanding their curiosity, and enhancing their productivity. | [Apply Here](https://jobs.anitab.org/companies/google-24698/jobs/42530065-staff-software-engineer-ai-ml-genai-gemini) |\n", "| Staff Software Engineer, AI/ML GenAI, Google Cloud AI | Google | Sunnyvale, CA | Not specified | Join the Google Cloud AI team as a Staff Software Engineer, AI/ML GenAI. Salary ranges are determined by role, level, and location. | [Apply Here](https://www.linkedin.com/jobs/view/staff-software-engineer-ai-ml-genai-google-cloud-ai-at-google-4074504841) |\n", "| Staff Software Engineer, AI/ML GenAI, Google Cloud AI | Google | Not specified | Not specified | Another listing for the same role at Google, potentially with different details. Salary ranges are determined by role, level, and location. | [Apply Here](https://www.themuse.com/jobs/google/staff-software-engineer-aiml-genai-google-cloud-ai) |\n", "\n", "\n", "This list is not exhaustive and may be updated periodically. Please check the provided links for the most up-to-date information on each position." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'category': '4\\n', 'response': 'Agent_output\\\\Job_search_20241117172655.md'}" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"I want to search jobs.\"\n", "\n", "result = run_user_query(query)\n", "result" ] }, { "cell_type": "code", "execution_count": null, "id": "540f75df-ebf3-4bc3-b71d-17116524146f", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](https://europe-west1-genai-agents-views-tracker.cloudfunctions.net/genai-agents-tracker?notebook=all-agents-tutorials--agent-hackathon-genai-career-assistant)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.4" } }, "nbformat": 4, "nbformat_minor": 5 }