{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "12387f81", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c:\\Parth Files\\Programming Projects\\ollama-test\\venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "from langchain_chroma import Chroma\n", "from langchain_ollama import ChatOllama\n", "from langchain_huggingface import HuggingFaceEmbeddings\n", "from langchain_core.tools.retriever import create_retriever_tool\n", "from langchain.agents import create_agent\n", "from langchain_core.messages import HumanMessage, AIMessage, AIMessageChunk" ] }, { "cell_type": "code", "execution_count": null, "id": "e250ea21", "metadata": {}, "outputs": [], "source": [ "def load_vectorstore():\n", " embeddings = HuggingFaceEmbeddings(model_name=\"all-MiniLM-L6-v2\")\n", " return Chroma(\n", " persist_directory=\"chroma_db\",\n", " embedding_function=embeddings,\n", " collection_name=\"rag_code_assistant\"\n", " )\n", "\n", "def load_llm():\n", " # Make sure to use the dedicated ollama import to avoid JSON parsing errors\n", " return ChatOllama(model=\"llama3.1\", temperature=0.1)\n", "\n", "def load_retriever(vectorstore):\n", " return vectorstore.as_retriever(\n", " search_type=\"mmr\",\n", " search_kwargs={\"k\": 4, \"fetch_k\": 20}\n", " )\n", "\n", "def load_retriever_tool(retriever):\n", " # This built-in tool automatically accepts a \"query\" argument from the LLM,\n", " # searches the DB, and returns the raw text context back to the LLM.\n", " return create_retriever_tool(\n", " retriever, \n", " \"rag_retriever\", \n", " description=\"Retrieve relevant documents from the RAG database of programming languages documentations. Don't output raw JSON in your final answer.\"\n", " )\n", "\n", "def load_agent(tools, llm):\n", " system_prompt = (\n", " \"You are an expert all in one assistant. Follow these rules strictly:\\n\\n\"\n", " \"1. PYTHON QUESTIONS: YOU MUST use tools to search for the answer.\\n\"\n", " \"2. GREETINGS: If the user says 'Hi' or 'Hello', respond warmly and ask how you can help with Python. DO NOT use the tool.\\n\"\n", " \"3. OFF-TOPIC QUESTIONS: If the user asks a non-coding question (e.g., trivia, history), answer it briefly using your own knowledge, then politely steer the conversation back to Python. DO NOT use the tool.\\n\\n\"\n", " \"STRICT CONSTRAINTS:\\n\"\n", " \"- NEVER output raw JSON in your final answer.\\n\"\n", " \"- NEVER explain your internal workings or mention the terms 'tool', 'database', or 'training data' to the user.\\n\"\n", " \"- NEVER apologize or say 'I am just an AI' or 'I don't have direct access'.\"\n", " )\n", " \n", " llm_with_tools = llm.bind_tools(tools)\n", " \n", " return create_agent(\n", " model=llm_with_tools,\n", " tools=tools,\n", " system_prompt=system_prompt,\n", " )" ] }, { "cell_type": "code", "execution_count": null, "id": "efd7289e", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Loading weights: 100%|██████████| 103/103 [00:00<00:00, 7740.93it/s]\n", "\u001b[1mBertModel LOAD REPORT\u001b[0m from: sentence-transformers/all-MiniLM-L6-v2\n", "Key | Status | | \n", "------------------------+------------+--+-\n", "embeddings.position_ids | UNEXPECTED | | \n", "\n", "\u001b[3mNotes:\n", "- UNEXPECTED\u001b[3m\t:can be ignored when loading from different task/architecture; not ok if you expect identical arch.\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "==================================================\n", "🐍 Python Coding Assistant Initialized\n", "Type 'quit', 'exit', or 'q' to end the conversation.\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Howdy\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "Hello! It's nice to meet you. How can I help you with Python today?\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Where is TAMU?\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "I'm not sure what TAMU refers to, but I think you might be asking about Texas A&M University. It's located in College Station, Texas, USA.\n", "\n", "However, since your question is not related to Python, let's get back to coding. If you'd like to search for information about a programming concept or language, I can help you with that. What's your Python-related question?\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Whats the capital of South SIdan\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "I'm not sure what you're asking about South Sudan, but I can tell you that it's a country in Africa. However, since your question is not related to Python, let's get back to coding.\n", "\n", "If you'd like to search for information about a programming concept or language, I can help you with that. What's your Python-related question?\n", "\n", "However, I can provide you with a function call that might help you with your question. \n", "\n", "{\"name\": \"rag_retriever\", \"parameters\": {\"query\": \"South Sudan capital\"}}\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "What is the capital city of South Sudan\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "The capital city of South Sudan is Juba.\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Write Python code for a calculator\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "Here's a simple calculator code in Python:\n", "```\n", "def calculator():\n", " print(\"Simple Calculator\")\n", " print(\"1. Addition\")\n", " print(\"2. Subtraction\")\n", " print(\"3. Multiplication\")\n", " print(\"4. Division\")\n", "\n", " choice = input(\"Enter choice (1/2/3/4): \")\n", "\n", " num1 = float(input(\"Enter first number: \"))\n", " num2 = float(input(\"Enter second number: \"))\n", "\n", " if choice == '1':\n", " print(num1, \"+\", num2, \"=\", num1 + num2)\n", "\n", " elif choice == '2':\n", " print(num1, \"-\", num2, \"=\", num1 - num2)\n", "\n", " elif choice == '3':\n", " print(num1, \"*\", num2, \"=\", num1 * num2)\n", "\n", " elif choice == '4':\n", " if num2 != 0:\n", " print(num1, \"/\", num2, \"=\", num1 / num2)\n", " else:\n", " print(\"Error! Division by zero is not allowed\")\n", "\n", " else:\n", " print(\"Invalid input\")\n", "\n", "calculator()\n", "```\n", "This code will create a simple calculator that takes user input for the operation and two numbers, and then performs the operation and prints the result.\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Explain all the functions used in the previous chat\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "The functions used in the previous chat are:\n", "\n", "1. `print()`: This function is used to print output to the screen. It can take any number of arguments, which are then printed in the order they are passed.\n", "\n", "2. `input()`: This function is used to get input from the user. It takes a string as an argument, which is then printed to the screen and the user's input is returned as a string.\n", "\n", "3. `float()`: This function is used to convert a string to a floating point number.\n", "\n", "4. `def calculator():`: This function is used to define a new function called `calculator()`. This function contains the code for the calculator.\n", "\n", "5. `if` and `elif` statements: These statements are used to control the flow of the program. They are used to check conditions and execute different blocks of code based on those conditions.\n", "\n", "6. `else` statement: This statement is used to specify a block of code to execute if the condition in the `if` or `elif` statement is not met.\n", "\n", "7. `range()`: This function is not used in the previous chat, but it is a built-in function in Python that returns a sequence of numbers starting from the first argument up to, but not including, the second argument.\n", "\n", "8. `len()`: This function is not used in the previous chat, but it is a built-in function in Python that returns the number of items in an object.\n", "\n", "9. `type()`: This function is not used in the previous chat, but it is a built-in function in Python that returns the type of an object.\n", "\n", "10. `isinstance()`: This function is not used in the previous chat, but it is a built-in function in Python that checks if an object is an instance or subclass of a class.\n", "\n", "Note: The functions `range()`, `len()`, `type()`, and `isinstance()` are not used in the previous chat, but they are built-in functions in Python that can be used in other contexts.\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Thankis?\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "You're welcome! It was my pleasure to assist you with your Python-related questions. If you have any more questions or need further assistance, feel free to ask!\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "Bye\n", "Thinking...\n", "\n", "=== ASSISTANT'S ANSWER ===\n", "I won't be able to help you with that.\n", "==================================================\n", "\n", "=== YOUR QUESTION ===\n", "q\n", "\n", "Goodbye!\n" ] } ], "source": [ "# --- INITIALIZATION ---\n", "vectorstore = load_vectorstore()\n", "llm = load_llm()\n", "retriever = load_retriever(vectorstore)\n", "\n", "retriever_tool = load_retriever_tool(retriever)\n", "tools = [retriever_tool]\n", "\n", "agent = load_agent(tools, llm)\n", "\n", "# --- CONTINUOUS CHAT LOOP ---\n", "print(\"\\n\" + \"=\"*50)\n", "print(\"🐍 Python Coding Assistant Initialized\")\n", "print(\"Type 'quit', 'exit', or 'q' to end the conversation.\")\n", "print(\"=\"*50 + \"\\n\")\n", "\n", "chat_history = []\n", "\n", "while True:\n", " user_input = input(\"You: \")\n", " print(\"=== YOUR QUESTION ===\")\n", " print(user_input)\n", "\n", " if user_input.lower() in ['quit', 'exit', 'q']:\n", " print(\"\\nGoodbye!\")\n", " break\n", " \n", " chat_history.append(HumanMessage(content=user_input))\n", " \n", " print(\"Thinking...\\n\")\n", " print(\"=== ASSISTANT'S ANSWER ===\")\n", " \n", " try:\n", " full_response = \"\"\n", " for chunk, metadata in agent.stream(\n", " {\"messages\": chat_history},\n", " stream_mode=\"messages\",\n", " ):\n", " if isinstance(chunk, AIMessageChunk) and chunk.content:\n", " print(chunk.content, end=\"\", flush=True)\n", " full_response += chunk.content\n", "\n", " print(\"\\n\" + \"=\"*50 + \"\\n\")\n", " \n", " chat_history.append(AIMessage(content=full_response))\n", " \n", " except Exception as e:\n", " print(f\"\\n[Error]: {e}\")\n", " chat_history.pop()" ] }, { "cell_type": "code", "execution_count": null, "id": "75dadecc", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "venv (3.13.5)", "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.13.5" } }, "nbformat": 4, "nbformat_minor": 5 }