diff --git a/llm_tracing.ipynb b/llm_tracing.ipynb index abd6a4f..53dddc7 100644 --- a/llm_tracing.ipynb +++ b/llm_tracing.ipynb @@ -4,7 +4,9 @@ "metadata": { "colab": { "provenance": [], - "authorship_tag": "ABX9TyPUhTA5YLOC5sFoz0nC/16T", + "toc_visible": true, + "mount_file_id": "1WTu1l4pvKP5xLxo7RAo91NgtXgw08WNV", + "authorship_tag": "ABX9TyPV3wZLKWoXpMeND+K8OBBV", "include_colab_link": true }, "kernelspec": { @@ -26,32 +28,47 @@ "\"Open" ] }, + { + "cell_type": "markdown", + "source": [ + "## LLM using Gemini (langchain)" + ], + "metadata": { + "id": "eh7lH12bGbCE" + } + }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "NFsmQ1KlioR0", - "outputId": "bb3fe022-a329-4feb-e6f3-d8f2577ffa2a" + "outputId": "c4e57725-4f27-4100-da51-588bfd8e44ed" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/1.3 MB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.3/1.3 MB\u001b[0m \u001b[31m18.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "langchain-google-genai 2.1.5 requires google-ai-generativelanguage<0.7.0,>=0.6.18, but you have google-ai-generativelanguage 0.6.15 which is incompatible.\u001b[0m\u001b[31m\n", + "Requirement already satisfied: langchain in /usr/local/lib/python3.11/dist-packages (0.3.25)\n", + "Requirement already satisfied: google-generativeai in /usr/local/lib/python3.11/dist-packages (0.8.5)\n", + "Requirement already satisfied: torch in /usr/local/lib/python3.11/dist-packages (2.6.0+cu124)\n", + "Requirement already satisfied: torchvision in /usr/local/lib/python3.11/dist-packages (0.21.0+cu124)\n", + "Requirement already satisfied: transformers in /usr/local/lib/python3.11/dist-packages (4.52.2)\n", + "Requirement already satisfied: datasets in /usr/local/lib/python3.11/dist-packages (2.14.4)\n", + "Requirement already satisfied: langchain_community in /usr/local/lib/python3.11/dist-packages (0.3.24)\n", + "\u001b[31mERROR: Could not find a version that satisfies the requirement langchain_google_genai--quiet (from versions: none)\u001b[0m\u001b[31m\n", + "\u001b[0m\u001b[31mERROR: No matching distribution found for langchain_google_genai--quiet\u001b[0m\u001b[31m\n", "\u001b[0m" ] } ], "source": [ "# Install dependencies\n", - "!pip install --upgrade pip --q\n", - "!pip install langchain google-generativeai torch torchvision transformers datasets langchain_community --q" + "!pip install --upgrade pip --quiet\n", + "!pip install langchain google-generativeai torch torchvision transformers datasets langchain_community langchain_google_genai--quiet" ] }, { @@ -59,8 +76,6 @@ "source": [ "# Imports & Authentication\n", "import os\n", - "from langchain import OpenAI, LLMChain, PromptTemplate\n", - "from langchain.agents import initialize_agent, Tool, AgentType\n", "from datasets import load_dataset\n", "import re\n", "import pandas as pd\n", @@ -80,9 +95,9 @@ "base_uri": "https://localhost:8080/" }, "id": "c1bumpHjls2s", - "outputId": "0f17bceb-64a6-4ca2-a4c4-8b22b6dc8234" + "outputId": "867b5eec-6ad9-4f44-c913-3449bd52743c" }, - "execution_count": 9, + "execution_count": 1, "outputs": [ { "output_type": "stream", @@ -109,22 +124,25 @@ "\n", "print(\"\\nSending a test prompt to the LLM...\")\n", "print(type(llm))\n", - "print(llm.invoke(\"Write me a ballad about LangChain\").content)" + "print(llm.invoke(\"Write me a ballad about LangChain\").content[:90])" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "-USI0cHo26zz", - "outputId": "d8066617-9f53-4f18-87c7-bae224024957" + "outputId": "03750bea-74a5-425a-f68a-beed257127e5" }, - "execution_count": 10, + "execution_count": 2, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/44.8 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m44.8/44.8 kB\u001b[0m \u001b[31m2.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m34.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m438.5/438.5 kB\u001b[0m \u001b[31m25.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", "google-generativeai 0.8.5 requires google-ai-generativelanguage==0.6.15, but you have google-ai-generativelanguage 0.6.18 which is incompatible.\u001b[0m\u001b[31m\n", "\u001b[0mLLM Initialized successfully.\n", "\n", @@ -133,52 +151,7 @@ "(Verse 1)\n", "The data streams, a raging flood,\n", "A chaos vast, misunderstood.\n", - "To tame its power, find its core,\n", - "A programmer sought, and something more.\n", - "He heard a whisper, on the breeze,\n", - "Of LangChain's promise, meant to please.\n", - "A framework new, a shining light,\n", - "To bring the darkness into sight.\n", - "\n", - "(Verse 2)\n", - "With LLMs vast, and prompts so keen,\n", - "He built a chain, a wondrous scene.\n", - "From prompt engineering's subtle art,\n", - "He crafted queries, played his part.\n", - "The chains he forged, both long and deep,\n", - "Where memories slept, and secrets keep.\n", - "He linked the models, one by one,\n", - "Until the task was nearly done.\n", - "\n", - "(Verse 3)\n", - "The agents danced, a graceful sway,\n", - "Through complex tasks, they found their way.\n", - "They searched the web, with tireless might,\n", - "And brought forth knowledge, pure and bright.\n", - "From simple questions, answers flowed,\n", - "A tapestry of facts bestowed.\n", - "The chatbot spoke, with human grace,\n", - "And wore a smile upon its face.\n", - "\n", - "(Verse 4)\n", - "But challenges arose, a thorny plight,\n", - "The chains would break, in darkest night.\n", - "The models faltered, lost their way,\n", - "And truth was buried, far away.\n", - "He toiled and struggled, day and night,\n", - "To mend the breaks, and set things right.\n", - "With careful tuning, fine-tuned art,\n", - "He strengthened chains, and played his part.\n", - "\n", - "(Verse 5)\n", - "At last, success, a joyful sound,\n", - "The data tamed, on solid ground.\n", - "The LangChain hummed, a gentle song,\n", - "Where knowledge flowed, both right and strong.\n", - "A testament to skill and grace,\n", - "A framework built, to find its place.\n", - "So raise a glass, to this new age,\n", - "Where LangChain guides, upon life's stage.\n" + "To find the gems,\n" ] } ] @@ -193,50 +166,142 @@ } }, { - "cell_type": "code", + "cell_type": "markdown", "source": [ - "!pip install crewai crewai_tools --quiet\n", - "\n", - "from crewai import Agent, Task, Crew, LLM\n", - "\n", - "# 1) Define a simple search tool (or replace with your real search API)\n", - "def search_tool(query: str) -> str:\n", - " # Right now it’s a stub. In production you might call Wikipedia, SerpAPI, etc.\n", - " return \"Ottawa (capital of Canada), population ~1 million\"\n", - "\n", - "# 2) Instantiate your CrewAI Agent with the Search tool registered\n", - "agent_react = Agent(\n", - " role=\"Factual Researcher\",\n", - " goal=\"Retrieve factual snippets for user queries\",\n", - " backstory=\"Always think step-by-step and use external tools when needed.\",\n", - " verbose=True, # prints Thought/Action/Observation logs\n", - " allow_delegation=False,\n", - " llm=llm\n", - " #, tools=[\n", - " # {\"name\": \"Search\", \"func\": search_tool, \"description\": \"Lookup facts online\"}\n", - " # ]\n", - ")\n" + "## Define Serper Tool" ], + "metadata": { + "id": "d7xKOQoXFUO1" + } + }, + { + "source": [ + "!pip install browserbase 'crewai[tools]' --quiet\n", + "from crewai_tools import SerperDevTool\n", + "import os\n", + "from google.colab import userdata\n", + "\n", + "# Load the Serper API key from Colab Secrets\n", + "serper_api_key = userdata.get('SERPER_API_KEY') # Use the name you gave your Serper secret\n", + "\n", + "if serper_api_key:\n", + " # Set the SERPER_API_KEY environment variable\n", + " os.environ[\"SERPER_API_KEY\"] = serper_api_key\n", + " print(\"SERPER_API_KEY loaded and set successfully from Colab Secrets.\")\n", + "else:\n", + " print(\"SERPER_API_KEY not found in Colab Secrets.\")\n", + "\n", + "\n", + "# Initialize the tool for internet searching capabilities\n", + "# Now the tool will find the SERPER_API_KEY in the environment variables\n", + "Serpertool = SerperDevTool(\n", + " search_url=\"https://google.serper.dev/scholar\",\n", + " n_results=10,\n", + ")\n", + "\n", + "# You can now run the tool\n", + "#print(Serpertool.run(search_query=\"ChatGPT\"))" + ], + "cell_type": "code", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, - "id": "_wzMmyp-c1Ih", - "outputId": "b32174d0-182f-4543-bc25-caca26747154" + "id": "Ao3MfCtbFE2k", + "outputId": "90449637-367c-4ba0-af57-762e38995bbd" }, - "execution_count": 13, + "execution_count": 3, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "\n", - "\n", - "\n" + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m42.8/42.8 kB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", + " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", + " Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m48.2/48.2 kB\u001b[0m \u001b[31m2.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m98.0/98.0 kB\u001b[0m \u001b[31m6.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m7.7/7.7 MB\u001b[0m \u001b[31m86.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m135.3/135.3 kB\u001b[0m \u001b[31m7.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.9/94.9 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m602.7/602.7 kB\u001b[0m \u001b[31m29.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m320.2/320.2 kB\u001b[0m \u001b[31m17.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.6/94.6 kB\u001b[0m \u001b[31m5.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m647.0/647.0 kB\u001b[0m \u001b[31m27.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m65.8/65.8 kB\u001b[0m \u001b[31m4.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m55.9/55.9 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m119.0/119.0 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m194.9/194.9 kB\u001b[0m \u001b[31m13.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m60.2/60.2 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.6/5.6 MB\u001b[0m \u001b[31m90.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m756.0/756.0 kB\u001b[0m \u001b[31m42.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m236.0/236.0 kB\u001b[0m \u001b[31m16.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m17.4/17.4 MB\u001b[0m \u001b[31m91.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m284.2/284.2 kB\u001b[0m \u001b[31m16.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m147.8/147.8 kB\u001b[0m \u001b[31m9.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m211.3/211.3 kB\u001b[0m \u001b[31m15.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m628.3/628.3 kB\u001b[0m \u001b[31m33.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m59.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m345.6/345.6 kB\u001b[0m \u001b[31m19.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.0/2.0 MB\u001b[0m \u001b[31m68.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m31.8/31.8 MB\u001b[0m \u001b[31m23.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m101.6/101.6 kB\u001b[0m \u001b[31m7.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m16.4/16.4 MB\u001b[0m \u001b[31m91.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m89.1/89.1 kB\u001b[0m \u001b[31m6.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.9/2.9 MB\u001b[0m \u001b[31m77.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.6/5.6 MB\u001b[0m \u001b[31m96.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.6/57.6 kB\u001b[0m \u001b[31m3.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.0/3.0 MB\u001b[0m \u001b[31m75.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.4/62.4 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m242.5/242.5 kB\u001b[0m \u001b[31m16.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m131.6/131.6 kB\u001b[0m \u001b[31m9.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m459.8/459.8 kB\u001b[0m \u001b[31m27.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m60.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m45.1/45.1 kB\u001b[0m \u001b[31m2.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.5/2.5 MB\u001b[0m \u001b[31m51.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.9/50.9 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m156.0/156.0 kB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m304.2/304.2 kB\u001b[0m \u001b[31m21.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m71.1/71.1 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m71.5/71.5 kB\u001b[0m \u001b[31m5.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.0/4.0 MB\u001b[0m \u001b[31m80.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m454.8/454.8 kB\u001b[0m \u001b[31m28.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m2.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m259.5/259.5 kB\u001b[0m \u001b[31m16.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m5.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m209.2/209.2 kB\u001b[0m \u001b[31m15.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m44.4/44.4 kB\u001b[0m \u001b[31m2.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m327.7/327.7 kB\u001b[0m \u001b[31m21.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.3/3.3 MB\u001b[0m \u001b[31m55.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.9/50.9 kB\u001b[0m \u001b[31m3.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "transformers 4.52.2 requires tokenizers<0.22,>=0.21, but you have tokenizers 0.20.3 which is incompatible.\u001b[0m\u001b[31m\n", + "\u001b[0mSERPER_API_KEY loaded and set successfully from Colab Secrets.\n" ] } ] }, + { + "cell_type": "markdown", + "source": [ + "## Create a CrewAI agent" + ], + "metadata": { + "id": "X77aBYbAFw2Y" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Create prompt templates for agent switching" + ], + "metadata": { + "id": "nWCHs86DF9lL" + } + }, { "cell_type": "code", "source": [ @@ -302,10 +367,10 @@ " return COT_TEMPLATE.format(query=query)\n", " elif mode == \"cot_sc\":\n", " return COT_SC_TEMPLATE.format(query=query)\n", - " elif mode == \"react\":\n", - " return REACT_TEMPLATE.format(query=query)\n", - " elif mode == \"rag\":\n", - " return RAG_TEMPLATE.format(retrieved_docs=kwargs.get(\"retrieved_docs\", \"\"), query=query)\n", + " # elif mode == \"react\":\n", + " # return REACT_TEMPLATE.format(query=query)\n", + " # elif mode == \"rag\":\n", + " # return RAG_TEMPLATE.format(retrieved_docs=kwargs.get(\"retrieved_docs\", \"\"), query=query)\n", " elif mode == \"chain_step1\":\n", " return CHAIN_STEP1.format(query=query)\n", " elif mode == \"chain_step2\":\n", @@ -317,46 +382,438 @@ " else:\n", " raise ValueError(f\"Unknown mode: {mode}\")\n", "\n", - "# # 5. Helper to call either the Agent (for ReAct) or bare LLM\n", - "# def call_with_mode(query: str, mode: str, **kwargs) -> str:\n", - "# prompt = build_prompt(query, mode, **kwargs)\n", - "# if mode == \"react\":\n", - "# response = agent_react.llm.invoke(prompt)\n", - "# return response.content.strip()\n", - "# else:\n", - "# response = llm.invoke(prompt)\n", - "# return response.content.strip()\n", + "# from langchain_core.messages import BaseMessage # for the isinstance check\n", "\n", - "# # 5. Helper to call either the Agent (for ReAct) or bare LLM\n", - "# def call_with_mode(query: str, mode: str, **kwargs) -> str:\n", - "# prompt = build_prompt(query, mode, **kwargs)\n", - "\n", - "# if mode == \"react\":\n", - "# # “Call” the agent’s LLM so that Search[…] actually invokes your registered tool\n", - "# ai_msg = agent_react.llm(prompt)\n", - "# return ai_msg.content.strip()\n", - "# else:\n", - "# # “Call” the bare LLM for all other modes\n", - "# ai_msg = llm(prompt)\n", - "# return ai_msg.content.strip()\n", - "# Solution 2\n", - "# # ------- helper that always extracts text -------\n", - "# def _to_text(resp):\n", - "# \"\"\"\n", - "# CrewAI/Gemini may return either:\n", - "# • a plain str (newer versions)\n", - "# • an AIMessage (older LangChain chat models)\n", - "# This helper normalises both to a clean string.\n", - "# \"\"\"\n", - "# from langchain_core.messages import BaseMessage # only used for isinstance check\n", + "# def _to_text(resp) -> str:\n", + "# \"\"\"Normalise CrewAI responses to a clean string.\"\"\"\n", "# if isinstance(resp, str):\n", "# return resp\n", - "# elif isinstance(resp, BaseMessage): # covers AIMessage, HumanMessage, etc.\n", + "# if isinstance(resp, BaseMessage):\n", "# return resp.content\n", - "# else:\n", - "# # Fallback: best-effort string conversion\n", - "# return str(resp)\n", + "# return str(resp) # fallback\n", "\n", + "# def smart_llm_call(model, prompt):\n", + "# \"\"\"\n", + "# Call the LLM using whichever entry-point the installed\n", + "# CrewAI / LangChain version supports.\n", + "# \"\"\"\n", + "# for m in (\"invoke\", \"predict\", \"__call__\"):\n", + "# if hasattr(model, m):\n", + "# resp = getattr(model, m)(prompt) # call the method\n", + "# return _to_text(resp)\n", + "# raise AttributeError(\"LLM exposes no invoke/predict/__call__\")\n", + "\n", + "# # ------------------ MAIN DISPATCHER ------------------\n", + "# def call_with_mode(query: str, mode: str, **kwargs) -> str:\n", + "# prompt = build_prompt(query, mode, **kwargs)\n", + "# if mode == \"react\": # needs the Search tool\n", + "# return smart_llm_call(agent_react.llm, prompt).strip()\n", + "# else: # every other prompting style\n", + "# return smart_llm_call(llm, prompt).strip()" + ], + "metadata": { + "id": "9GOl2_KBHrBf" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# # Repeating observations and not showing observations etc.\n", + "# # ── 1. make a universal \"stringify\" helper ─────────────────────────\n", + "# def stringify_step(obj, max_obs_chars: int = 600) -> str:\n", + "# \"\"\"\n", + "# Convert whatever CrewAI passes to step_callback into readable text.\n", + "# • AgentAction –> Thought / Action / Action Input\n", + "# • ToolResult –> Observation\n", + "# • AgentFinish –> Final Answer\n", + "# • str –> Final Answer (some builds)\n", + "# Everything else falls back to repr(obj).\n", + "# \"\"\"\n", + "\n", + "# # -------- Final answer sometimes arrives as a bare string --------\n", + "# if isinstance(obj, str):\n", + "# return f\"Final Answer: {obj.strip()}\"\n", + "\n", + "# # -------- AgentAction -------------------------------------------\n", + "# if hasattr(obj, \"action\") and hasattr(obj, \"action_input\"):\n", + "# thought = getattr(obj, \"log\", \"\").strip()\n", + "# return (\n", + "# f\"Thought: {thought}\\n\"\n", + "# f\"Action: {obj.action}\\n\"\n", + "# f\"Action Input: {obj.action_input}\"\n", + "# )\n", + "\n", + "# # -------- ToolResult (Observation) -----------------------------\n", + "# if hasattr(obj, \"result\") or hasattr(obj, \"output\"):\n", + "# observation = getattr(obj, \"result\", getattr(obj, \"output\", \"\"))\n", + "# # shorten very long JSON blobs so your log stays readable\n", + "# obs_text = (\n", + "# observation if len(str(observation)) <= max_obs_chars\n", + "# else str(observation)[:max_obs_chars] + \" …[truncated]…\"\n", + "# )\n", + "# return f\"Observation: {obs_text}\"\n", + "\n", + "# # -------- AgentFinish -------------------------------------------\n", + "# if hasattr(obj, \"return_values\"):\n", + "# final_answer = obj.return_values.get(\"output\", \"\").strip()\n", + "# return f\"Final Answer: {final_answer}\"\n", + "\n", + "# # -------- Fallback ----------------------------------------------\n", + "# return repr(obj)\n", + "\n", + "# def stringify_step(obj, max_obs_chars: int = 600) -> str:\n", + "# # Final answer sometimes arrives as bare str\n", + "# if isinstance(obj, str):\n", + "# return f\"Final Answer: {obj.strip()}\"\n", + "\n", + "# # AgentAction (Thought / Action / Action Input)\n", + "# if hasattr(obj, \"action\") and hasattr(obj, \"action_input\"):\n", + "# return (\n", + "# f\"Thought: {getattr(obj, 'log', '').strip()}\\n\"\n", + "# f\"Action: {obj.action}\\n\"\n", + "# f\"Action Input: {obj.action_input}\"\n", + "# )\n", + "\n", + "# # ToolResult – prepend the *previous* Thought/Action in .log\n", + "# if hasattr(obj, \"result\") or hasattr(obj, \"output\"):\n", + "# prior_log = getattr(obj, \"log\", \"\").strip() # ← new!\n", + "# obs = getattr(obj, \"result\", getattr(obj, \"output\", \"\"))\n", + "# if len(str(obs)) > max_obs_chars:\n", + "# obs = str(obs)[:max_obs_chars] + \" …[truncated]…\"\n", + "# return f\"{prior_log}\\nObservation: {obs}\"\n", + "\n", + "# # AgentFinish\n", + "# if hasattr(obj, \"return_values\"):\n", + "# return f\"Final Answer: {obj.return_values.get('output', '').strip()}\"\n", + "\n", + "# return repr(obj)\n", + "\n", + "# 0. a list to hold them\n", + "raw_steps: list = []\n", + "\n", + "def collect_raw(obj, **_):\n", + " \"\"\"\n", + " CrewAI passes AgentAction / ToolResult / AgentFinish\n", + " (or sometimes a plain str). Keep each object intact.\n", + " \"\"\"\n", + " import copy # avoid later mutation\n", + " raw_steps.append(copy.deepcopy(obj))\n" + ], + "metadata": { + "id": "m03zplzyGR2o" + }, + "execution_count": 41, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "import inspect, crewai, importlib.metadata\n", + "print(importlib.metadata.version(\"crewai\"))\n", + "print(\"Has AgentAction?\", 'AgentAction' in dir(__import__('crewai.agents.parser').agents.parser))\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6EQw_irWb1oM", + "outputId": "e210fff1-9897-46bc-a6c4-6774e880087b" + }, + "execution_count": 30, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "0.121.1\n", + "Has AgentAction? True\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "!pip install crewai crewai_tools --quiet\n", + "from crewai import LLM, Agent, Task, Crew\n", + "import os\n", + "import io, sys, contextlib\n", + "\n", + "# ---- 1. LLM wrapper -------------------------------------------------\n", + "llm_crew = LLM(\n", + " model=\"gemini/gemini-1.5-flash-latest\", # provider prefix\n", + " api_key=api_key # set GOOGLE_API_KEY env var\n", + ")\n", + "\n", + "\n", + "# ---- 3. ReAct agent --------------------------------------------------\n", + "agent_react = Agent(\n", + " role=\"Factual Researcher\",\n", + " goal=\"Find accurate facts quickly\",\n", + " backstory=(\n", + " \"You are a detail-oriented research analyst who uses web search \"\n", + " \"to answer geography and demographic questions with concise, up-to-date data.\"\n", + " ),\n", + " llm=llm_crew,\n", + " tools=[Serpertool],\n", + " step_callback= collect_raw, # collect_step, # register our function to receive every step\n", + " verbose=True # prints Thought / Action / Observation\n", + ")\n", + "\n", + "# ---- 4. One-off task runner -----------------------------------------\n", + "!pip install rich\n", + "from crewai import Task, Crew # already imported Agent earlier\n", + "from rich import get_console\n", + "\n", + "def run_single_agent(query: str) -> str:\n", + " #step_trace.clear() # reset collector\n", + " task = Task(\n", + " description=query,\n", + " expected_output=\"Concise answer\",\n", + " agent=agent_react\n", + " )\n", + " crew = Crew(agents=[agent_react], tasks=[task])\n", + " #result = crew.kickoff() #working\n", + " #result = crew.kickoff_for_each(inputs=[{\"input\": query}])#[0]\n", + "\n", + " # 1. Rich logging didn't work\n", + " # console = get_console() # the console Rich already uses\n", + " # with console.capture() as cap: # start recording *before* kickoff\n", + " # result = crew.kickoff_for_each(inputs=[{\"input\": query}])[0].raw\n", + " # rich_log = cap.get() # full coloured (→ plain) transcript\n", + "\n", + " # 2. This didn't work\n", + " buf = io.StringIO()\n", + " with contextlib.redirect_stdout(buf), contextlib.redirect_stderr(buf):\n", + " # Everything CrewAI prints (via Rich or plain prints) goes into buf\n", + " result = crew.kickoff_for_each(inputs=[{\"input\": query}])[0].raw\n", + "\n", + " # 4) Grab the full transcript\n", + " rich_log = buf.getvalue()\n", + "\n", + " # Normalise return type\n", + " if isinstance(result, str):\n", + " return result.strip(), rich_log\n", + " if isinstance(result, dict):\n", + " return result, rich_log\n", + " return str(result).strip(), rich_log" + ], + "metadata": { + "id": "IVaUrOIykmII", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "826d8b9d-2fd9-4ddc-ad25-ba909e3b7075" + }, + "execution_count": 43, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: rich in /usr/local/lib/python3.11/dist-packages (13.9.4)\n", + "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.11/dist-packages (from rich) (3.0.0)\n", + "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.11/dist-packages (from rich) (2.19.1)\n", + "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.11/dist-packages (from markdown-it-py>=2.2.0->rich) (0.1.2)\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Make LLM calls" + ], + "metadata": { + "id": "9WM1BC50GKS2" + } + }, + { + "cell_type": "code", + "source": [ + "step_trace" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "d5JfWa5oY_J9", + "outputId": "91ee809c-e9d5-4469-e068-d6a0371cf80d" + }, + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['\\nObservation: {\\'searchParameters\\': {\\'q\\': \\'capital of Canada and population\\', \\'type\\': \\'search\\', \\'num\\': 10, \\'engine\\': \\'google\\'}, \\'organic\\': [{\\'title\\': \\'Canada - Wikipedia\\', \\'link\\': \\'https://en.wikipedia.org/wiki/Canada\\', \\'snippet\\': \"Canada\\'s capital is Ottawa and its three largest metropolitan areas are Toronto, Montreal, and Vancouver.\", \\'position\\': 1, \\'sitelinks\\': [{\\'title\\': \\'Largest population centres\\', \\'link\\': \\'https://en.wikipedia.org/wiki/List_of_the_largest_population_centres_in_Canada\\'}, {\\'title\\': \\'Otta …[truncated]…',\n", + " '\\nObservation: {\\'searchParameters\\': {\\'q\\': \\'capital of Canada and population\\', \\'type\\': \\'search\\', \\'num\\': 10, \\'engine\\': \\'google\\'}, \\'organic\\': [{\\'title\\': \\'Canada - Wikipedia\\', \\'link\\': \\'https://en.wikipedia.org/wiki/Canada\\', \\'snippet\\': \"Canada\\'s capital is Ottawa and its three largest metropolitan areas are Toronto, Montreal, and Vancouver.\", \\'position\\': 1, \\'sitelinks\\': [{\\'title\\': \\'Largest population centres\\', \\'link\\': \\'https://en.wikipedia.org/wiki/List_of_the_largest_population_centres_in_Canada\\'}, {\\'title\\': \\'Otta …[truncated]…',\n", + " '\\nObservation: The capital of Canada is Ottawa. The population of Ottawa varies depending on the source and year, but is around 1,017,449 as of a recent estimate.']" + ] + }, + "metadata": {}, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "source": [ + "raw_steps" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-W6FYUUK3BaF", + "outputId": "022830be-8f4b-4862-9c01-45dbd08f24eb" + }, + "execution_count": 45, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[ToolResult(result=\"{'searchParameters': {'q': 'population of Ottawa Canada', 'type': 'search', 'num': 10, 'engine': 'google'}, 'organic': [{'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest ...', 'position': 1, 'sitelinks': [{'title': 'Demographics', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}, {'title': 'History', 'link': 'https://en.wikipedia.org/wiki/History_of_Ottawa'}, {'title': 'List of neighbourhoods in...', 'link': 'https://en.wikipedia.org/wiki/List_of_neighbourhoods_in_Ottawa'}, {'title': 'Timeline of Ottawa history', 'link': 'https://en.wikipedia.org/wiki/Timeline_of_Ottawa_history'}]}, {'title': 'Demographics of Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa', 'snippet': 'In 2021, the population of the city of Ottawa was 1,017,449. The population of the census metropolitan area, Ottawa-Gatineau, was 1,488,307.', 'position': 2}, {'title': 'Ottawa Population 2025', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa', 'snippet': 'Ottawa is a city located in Ontario, Canada with a current estimated population of 1,089,319. The population was recorded at 1,017,449 in the 2021 Canadian ...', 'position': 3, 'sitelinks': [{'title': 'Population of Ottawa', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#population-of-ottawa--ca'}, {'title': 'Demographics', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#demographics'}, {'title': 'Economic and Income Statistics', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#economic-and-income-statistics'}]}, {'title': 'Profile table, Census Profile, 2021 Census of Population - Ottawa ...', 'link': 'https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/prof/details/page.cfm?Lang=E&GENDERlist=1&STATISTIClist=1&HEADERlist=0&DGUIDlist=2021A00053506008&SearchText=ottawa', 'snippet': 'Add or remove data ; 711,900.', 'position': 4}, {'title': 'Ottawa - Data Commons', 'link': 'https://datacommons.org/place/wikidataId/Q1930', 'snippet': 'Ottawa is a city in Canada. The population in Ottawa was 1071868 in 2022.', 'position': 5}, {'title': 'Statistics and demographics | City of Ottawa', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics', 'snippet': 'As the capital of Canada, the City of Ottawa is home to over one million people and is the fourth largest municipality in the country. With a vibrant ...', 'position': 6, 'sitelinks': [{'title': 'Current population and...', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/current-population-and-household-estimates'}, {'title': '2021 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2021-census'}, {'title': '2016 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2016-census'}, {'title': '2011 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2011-census'}]}, {'title': 'Ottawa-Gatineau, Canada Metro Area Population 1950-2025', 'link': 'https://www.macrotrends.net/global-metrics/cities/20387/ottawa-gatineau/population', 'snippet': 'The current metro area population of Ottawa-Gatineau in 2025 is 1,466,000, a 0.96% increase from 2024. The metro area population of Ottawa-Gatineau in 2024 ...', 'position': 7}, {'title': 'Ottawa Canada Population Growth And Demographics', 'link': 'https://www3.nnu.edu/population-of-ottawa-canada_63211.html', 'snippet': 'According to data from Statistics Canada, the population of Ottawa has grown from approximately 883,000 in 2011 to over 983,000 in 2021. This represents a ...', 'position': 8}, {'title': 'Profile table, Census Profile, 2021 Census of Population - Ottawa ...', 'link': 'https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/prof/details/page.cfm?Lang=E&SearchText=Ottawa&GENDERlist=1,2,3&STATISTIClist=1&DGUIDlist=2021A00053506008&HEADERlist=0', 'snippet': 'Add or remove data ; 135,365 ;...', 'position': 9}, {'title': 'Ottawa Population 2025 - Key Figures and Stats - Canada Crime Index', 'link': 'https://canadacrimeindex.com/ottawa-population/', 'snippet': 'As of 2025, the estimated population of Ottawa is 1,070,889, reflecting steady growth from 1,017,449 in the 2021 Canadian Census and 934,243 in ...', 'position': 10}], 'peopleAlsoAsk': [{'question': 'Is Ottawa mostly English or French?', 'snippet': 'The proportion of population whose first official language spoken is English was 81.9% while the proportion of the population whose first official language spoken is French was 14.1%. 21.8%, or 1 in 5 of Ottawa residents speak more than one language at home.', 'title': 'Languages - 2021 Census Highlights for Ottawa and Region', 'link': 'https://2021-census-highlights-for-ottawa-and-region-spc-ottawa.hub.arcgis.com/pages/languages'}, {'question': 'What percentage of Ottawa is white?', 'snippet': 'White: 74.2% (28.4% Canadian, 24.3% English, 22.5% Irish, 21.5% French, 19.8% Scottish, 8.4% German, 4.9% Italian) Black: 5.7% Chinese: 4.0% South Asian: 3.9%', 'title': 'Ottawa Population 2025', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa'}, {'question': 'Is Ottawa Canada a big city?', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest metropolitan area in Canada.', 'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa'}, {'question': 'What percentage of Ottawa is Chinese?', 'snippet': 'These include Arabic (4.33%), Chinese (3.32%), Spanish (1.4%), Italian (0.79%), and many others.', 'title': 'Demographics of Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}], 'relatedSearches': [{'query': 'British Columbia'}, {'query': 'Population of Ottawa 2023'}, {'query': 'Population of ottawa canada by race'}, {'query': 'Population of ottawa canada by age'}, {'query': 'Population of ottawa canada 2022'}, {'query': 'Population of ottawa canada 2020'}, {'query': 'Population of ottawa canada 2021'}, {'query': 'Population of Ottawa 2025'}, {'query': 'Ottawa population 2024'}], 'credits': 1}\", result_as_answer=False),\n", + " ,\n", + " ]" + ] + }, + "metadata": {}, + "execution_count": 45 + } + ] + }, + { + "cell_type": "code", + "source": [ + "triple = raw_steps # the list you showed\n", + "print(raw_steps)\n", + "\n", + "tool_res = triple[0] # ToolResult\n", + "action_obj = triple[1] # AgentAction\n", + "finish_obj = triple[2] # AgentFinish\n", + "\n", + "print(dir(action_obj)) # or: pprint(vars(action_obj))\n", + "\n", + "# 1) Print the LLM’s “thought” string:\n", + "print(\"Thought:\\n\", action_obj.thought)\n", + "\n", + "# 2) Print which tool was invoked (e.g. \"Search\"):\n", + "print(\"Action :\", action_obj.tool)\n", + "\n", + "# 3) Print the payload sent to that tool:\n", + "print(\"Input :\", action_obj.tool_input)\n", + "\n", + "print(\"Action via tool use:\", tool_res)\n", + "\n", + "print(\"Final Answer:\\n\", finish_obj.text)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "QyN-dn2H3U7w", + "outputId": "fc57d082-096d-425b-e3fe-43e725c2edee" + }, + "execution_count": 53, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[ToolResult(result=\"{'searchParameters': {'q': 'population of Ottawa Canada', 'type': 'search', 'num': 10, 'engine': 'google'}, 'organic': [{'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest ...', 'position': 1, 'sitelinks': [{'title': 'Demographics', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}, {'title': 'History', 'link': 'https://en.wikipedia.org/wiki/History_of_Ottawa'}, {'title': 'List of neighbourhoods in...', 'link': 'https://en.wikipedia.org/wiki/List_of_neighbourhoods_in_Ottawa'}, {'title': 'Timeline of Ottawa history', 'link': 'https://en.wikipedia.org/wiki/Timeline_of_Ottawa_history'}]}, {'title': 'Demographics of Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa', 'snippet': 'In 2021, the population of the city of Ottawa was 1,017,449. The population of the census metropolitan area, Ottawa-Gatineau, was 1,488,307.', 'position': 2}, {'title': 'Ottawa Population 2025', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa', 'snippet': 'Ottawa is a city located in Ontario, Canada with a current estimated population of 1,089,319. The population was recorded at 1,017,449 in the 2021 Canadian ...', 'position': 3, 'sitelinks': [{'title': 'Population of Ottawa', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#population-of-ottawa--ca'}, {'title': 'Demographics', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#demographics'}, {'title': 'Economic and Income Statistics', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#economic-and-income-statistics'}]}, {'title': 'Profile table, Census Profile, 2021 Census of Population - Ottawa ...', 'link': 'https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/prof/details/page.cfm?Lang=E&GENDERlist=1&STATISTIClist=1&HEADERlist=0&DGUIDlist=2021A00053506008&SearchText=ottawa', 'snippet': 'Add or remove data ; 711,900.', 'position': 4}, {'title': 'Ottawa - Data Commons', 'link': 'https://datacommons.org/place/wikidataId/Q1930', 'snippet': 'Ottawa is a city in Canada. The population in Ottawa was 1071868 in 2022.', 'position': 5}, {'title': 'Statistics and demographics | City of Ottawa', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics', 'snippet': 'As the capital of Canada, the City of Ottawa is home to over one million people and is the fourth largest municipality in the country. With a vibrant ...', 'position': 6, 'sitelinks': [{'title': 'Current population and...', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/current-population-and-household-estimates'}, {'title': '2021 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2021-census'}, {'title': '2016 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2016-census'}, {'title': '2011 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2011-census'}]}, {'title': 'Ottawa-Gatineau, Canada Metro Area Population 1950-2025', 'link': 'https://www.macrotrends.net/global-metrics/cities/20387/ottawa-gatineau/population', 'snippet': 'The current metro area population of Ottawa-Gatineau in 2025 is 1,466,000, a 0.96% increase from 2024. The metro area population of Ottawa-Gatineau in 2024 ...', 'position': 7}, {'title': 'Ottawa Canada Population Growth And Demographics', 'link': 'https://www3.nnu.edu/population-of-ottawa-canada_63211.html', 'snippet': 'According to data from Statistics Canada, the population of Ottawa has grown from approximately 883,000 in 2011 to over 983,000 in 2021. This represents a ...', 'position': 8}, {'title': 'Profile table, Census Profile, 2021 Census of Population - Ottawa ...', 'link': 'https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/prof/details/page.cfm?Lang=E&SearchText=Ottawa&GENDERlist=1,2,3&STATISTIClist=1&DGUIDlist=2021A00053506008&HEADERlist=0', 'snippet': 'Add or remove data ; 135,365 ;...', 'position': 9}, {'title': 'Ottawa Population 2025 - Key Figures and Stats - Canada Crime Index', 'link': 'https://canadacrimeindex.com/ottawa-population/', 'snippet': 'As of 2025, the estimated population of Ottawa is 1,070,889, reflecting steady growth from 1,017,449 in the 2021 Canadian Census and 934,243 in ...', 'position': 10}], 'peopleAlsoAsk': [{'question': 'Is Ottawa mostly English or French?', 'snippet': 'The proportion of population whose first official language spoken is English was 81.9% while the proportion of the population whose first official language spoken is French was 14.1%. 21.8%, or 1 in 5 of Ottawa residents speak more than one language at home.', 'title': 'Languages - 2021 Census Highlights for Ottawa and Region', 'link': 'https://2021-census-highlights-for-ottawa-and-region-spc-ottawa.hub.arcgis.com/pages/languages'}, {'question': 'What percentage of Ottawa is white?', 'snippet': 'White: 74.2% (28.4% Canadian, 24.3% English, 22.5% Irish, 21.5% French, 19.8% Scottish, 8.4% German, 4.9% Italian) Black: 5.7% Chinese: 4.0% South Asian: 3.9%', 'title': 'Ottawa Population 2025', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa'}, {'question': 'Is Ottawa Canada a big city?', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest metropolitan area in Canada.', 'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa'}, {'question': 'What percentage of Ottawa is Chinese?', 'snippet': 'These include Arabic (4.33%), Chinese (3.32%), Spanish (1.4%), Italian (0.79%), and many others.', 'title': 'Demographics of Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}], 'relatedSearches': [{'query': 'British Columbia'}, {'query': 'Population of Ottawa 2023'}, {'query': 'Population of ottawa canada by race'}, {'query': 'Population of ottawa canada by age'}, {'query': 'Population of ottawa canada 2022'}, {'query': 'Population of ottawa canada 2020'}, {'query': 'Population of ottawa canada 2021'}, {'query': 'Population of Ottawa 2025'}, {'query': 'Ottawa population 2024'}], 'credits': 1}\", result_as_answer=False), , ]\n", + "['__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__str__', '__subclasshook__', '__weakref__', 'result', 'text', 'thought', 'tool', 'tool_input']\n", + "Thought:\n", + " tool_code\n", + "Thought: I need to find the capital city of Canada and its population. I will use a search engine to find this information.\n", + "Action : Search the internet with Serper\n", + "Input : {\"search_query\": \"population of Ottawa Canada\"}\n", + "Action via tool use: ToolResult(result=\"{'searchParameters': {'q': 'population of Ottawa Canada', 'type': 'search', 'num': 10, 'engine': 'google'}, 'organic': [{'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest ...', 'position': 1, 'sitelinks': [{'title': 'Demographics', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}, {'title': 'History', 'link': 'https://en.wikipedia.org/wiki/History_of_Ottawa'}, {'title': 'List of neighbourhoods in...', 'link': 'https://en.wikipedia.org/wiki/List_of_neighbourhoods_in_Ottawa'}, {'title': 'Timeline of Ottawa history', 'link': 'https://en.wikipedia.org/wiki/Timeline_of_Ottawa_history'}]}, {'title': 'Demographics of Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa', 'snippet': 'In 2021, the population of the city of Ottawa was 1,017,449. The population of the census metropolitan area, Ottawa-Gatineau, was 1,488,307.', 'position': 2}, {'title': 'Ottawa Population 2025', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa', 'snippet': 'Ottawa is a city located in Ontario, Canada with a current estimated population of 1,089,319. The population was recorded at 1,017,449 in the 2021 Canadian ...', 'position': 3, 'sitelinks': [{'title': 'Population of Ottawa', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#population-of-ottawa--ca'}, {'title': 'Demographics', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#demographics'}, {'title': 'Economic and Income Statistics', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa#economic-and-income-statistics'}]}, {'title': 'Profile table, Census Profile, 2021 Census of Population - Ottawa ...', 'link': 'https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/prof/details/page.cfm?Lang=E&GENDERlist=1&STATISTIClist=1&HEADERlist=0&DGUIDlist=2021A00053506008&SearchText=ottawa', 'snippet': 'Add or remove data ; 711,900.', 'position': 4}, {'title': 'Ottawa - Data Commons', 'link': 'https://datacommons.org/place/wikidataId/Q1930', 'snippet': 'Ottawa is a city in Canada. The population in Ottawa was 1071868 in 2022.', 'position': 5}, {'title': 'Statistics and demographics | City of Ottawa', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics', 'snippet': 'As the capital of Canada, the City of Ottawa is home to over one million people and is the fourth largest municipality in the country. With a vibrant ...', 'position': 6, 'sitelinks': [{'title': 'Current population and...', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/current-population-and-household-estimates'}, {'title': '2021 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2021-census'}, {'title': '2016 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2016-census'}, {'title': '2011 Census', 'link': 'https://ottawa.ca/en/living-ottawa/statistics-and-demographics/2011-census'}]}, {'title': 'Ottawa-Gatineau, Canada Metro Area Population 1950-2025', 'link': 'https://www.macrotrends.net/global-metrics/cities/20387/ottawa-gatineau/population', 'snippet': 'The current metro area population of Ottawa-Gatineau in 2025 is 1,466,000, a 0.96% increase from 2024. The metro area population of Ottawa-Gatineau in 2024 ...', 'position': 7}, {'title': 'Ottawa Canada Population Growth And Demographics', 'link': 'https://www3.nnu.edu/population-of-ottawa-canada_63211.html', 'snippet': 'According to data from Statistics Canada, the population of Ottawa has grown from approximately 883,000 in 2011 to over 983,000 in 2021. This represents a ...', 'position': 8}, {'title': 'Profile table, Census Profile, 2021 Census of Population - Ottawa ...', 'link': 'https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/prof/details/page.cfm?Lang=E&SearchText=Ottawa&GENDERlist=1,2,3&STATISTIClist=1&DGUIDlist=2021A00053506008&HEADERlist=0', 'snippet': 'Add or remove data ; 135,365 ;...', 'position': 9}, {'title': 'Ottawa Population 2025 - Key Figures and Stats - Canada Crime Index', 'link': 'https://canadacrimeindex.com/ottawa-population/', 'snippet': 'As of 2025, the estimated population of Ottawa is 1,070,889, reflecting steady growth from 1,017,449 in the 2021 Canadian Census and 934,243 in ...', 'position': 10}], 'peopleAlsoAsk': [{'question': 'Is Ottawa mostly English or French?', 'snippet': 'The proportion of population whose first official language spoken is English was 81.9% while the proportion of the population whose first official language spoken is French was 14.1%. 21.8%, or 1 in 5 of Ottawa residents speak more than one language at home.', 'title': 'Languages - 2021 Census Highlights for Ottawa and Region', 'link': 'https://2021-census-highlights-for-ottawa-and-region-spc-ottawa.hub.arcgis.com/pages/languages'}, {'question': 'What percentage of Ottawa is white?', 'snippet': 'White: 74.2% (28.4% Canadian, 24.3% English, 22.5% Irish, 21.5% French, 19.8% Scottish, 8.4% German, 4.9% Italian) Black: 5.7% Chinese: 4.0% South Asian: 3.9%', 'title': 'Ottawa Population 2025', 'link': 'https://worldpopulationreview.com/canadian-cities/ottawa'}, {'question': 'Is Ottawa Canada a big city?', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest metropolitan area in Canada.', 'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa'}, {'question': 'What percentage of Ottawa is Chinese?', 'snippet': 'These include Arabic (4.33%), Chinese (3.32%), Spanish (1.4%), Italian (0.79%), and many others.', 'title': 'Demographics of Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}], 'relatedSearches': [{'query': 'British Columbia'}, {'query': 'Population of Ottawa 2023'}, {'query': 'Population of ottawa canada by race'}, {'query': 'Population of ottawa canada by age'}, {'query': 'Population of ottawa canada 2022'}, {'query': 'Population of ottawa canada 2020'}, {'query': 'Population of ottawa canada 2021'}, {'query': 'Population of Ottawa 2025'}, {'query': 'Ottawa population 2024'}], 'credits': 1}\", result_as_answer=False)\n", + "Final Answer:\n", + " Thought: I now know the final answer\n", + "Final Answer: The capital of Canada is Ottawa. As of 2021, Ottawa had a city population of 1,017,449.\n", + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# 1) Re‐use a “stringify” helper that knows how to format each step\n", + "def stringify_step(obj, max_obs_chars: int = 600) -> str:\n", + " # If it arrives as a bare string, that’s the final answer\n", + " if isinstance(obj, str):\n", + " return f\"Final Answer: {obj.strip()}\"\n", + " # If it’s an AgentAction, print thought / tool name / tool_input\n", + " if hasattr(obj, \"thought\") and hasattr(obj, \"tool_input\"):\n", + " return (\n", + " f\"Thought: {obj.thought.strip()}\\n\"\n", + " f\"Action: {obj.tool}\\n\"\n", + " f\"Action Input: {obj.tool_input}\"\n", + " )\n", + " # If it’s a ToolResult, include the preceding thought (in .text or .log) and the result\n", + " # (some versions store the prior thought in .text or .log, adjust accordingly)\n", + " if hasattr(obj, \"result\"):\n", + " # many builds put the prior “thought” text into obj.text\n", + " prior = getattr(obj, \"text\", \"\").strip() or \"\"\n", + " obs = obj.result\n", + " if len(str(obs)) > max_obs_chars:\n", + " obs = str(obs)[:max_obs_chars] + \" …[truncated]…\"\n", + " if prior:\n", + " return f\"{prior}\\nObservation: {obs}\"\n", + " else:\n", + " return f\"Observation: {obs}\"\n", + " # If it’s an AgentFinish, the final answer lives in obj.text\n", + " if hasattr(obj, \"text\"):\n", + " return f\"Final Answer: {obj.text.strip()}\"\n", + " # Fallback to repr()\n", + " return repr(obj)\n", + "\n", + "# 2) Convert every raw step into a string\n", + "text_lines = [stringify_step(o) for o in raw_steps]\n", + "\n", + "# 3) Now either print them or write to disk. For example:\n", + "with open(\"trace_log.txt\", \"w\", encoding=\"utf-8\") as f:\n", + " for line in text_lines:\n", + " f.write(line.replace(\"\\n\", \"\\n \") + \"\\n\\n\") # indent continuations\n", + "\n", + "# 4) If you just want a single big string:\n", + "full_text = \"\\n\\n\".join(text_lines)\n", + "print(full_text)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "5XcViePa5VXa", + "outputId": "95e21dc7-bbc8-41dd-fd69-df7ea2d64870" + }, + "execution_count": 54, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Observation: {'searchParameters': {'q': 'population of Ottawa Canada', 'type': 'search', 'num': 10, 'engine': 'google'}, 'organic': [{'title': 'Ottawa - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Ottawa', 'snippet': 'As of 2021, Ottawa had a city population of 1,017,449 and a metropolitan population of 1,488,307, making it the fourth-largest city and fourth-largest ...', 'position': 1, 'sitelinks': [{'title': 'Demographics', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Ottawa'}, {'title': 'History', 'link': 'https://en.wikipedia.org/wiki/History_of_Ottawa'}, {'title': 'List of neighbourho …[truncated]…\n", + "\n", + "Thought: tool_code\n", + "Thought: I need to find the capital city of Canada and its population. I will use a search engine to find this information.\n", + "Action: Search the internet with Serper\n", + "Action Input: {\"search_query\": \"population of Ottawa Canada\"}\n", + "\n", + "Final Answer: Thought: I now know the final answer\n", + "Final Answer: The capital of Canada is Ottawa. As of 2021, Ottawa had a city population of 1,017,449.\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ "from langchain_core.messages import BaseMessage # for the isinstance check\n", "\n", "def _to_text(resp) -> str:\n", @@ -376,31 +833,23 @@ " if hasattr(model, m):\n", " resp = getattr(model, m)(prompt) # call the method\n", " return _to_text(resp)\n", - " raise AttributeError(\"LLM exposes no invoke/predict/__call__\")\n", "\n", "# ------------------ MAIN DISPATCHER ------------------\n", "def call_with_mode(query: str, mode: str, **kwargs) -> str:\n", - " prompt = build_prompt(query, mode, **kwargs)\n", - " if mode == \"react\": # needs the Search tool\n", - " return smart_llm_call(agent_react.llm, prompt).strip()\n", + "\n", + " # if mode == \"react\": # needs the Search tool\n", + " # return smart_llm_call(agent_react.llm, prompt).strip()\n", + " if mode == \"react\":\n", + " return run_single_agent(query)\n", " else: # every other prompting style\n", - " return smart_llm_call(llm, prompt).strip()\n", - "\n", - "\n", - "# # ------- ONE call-site for every prompting mode -------\n", - "# def call_with_mode(query: str, mode: str, **kwargs) -> str:\n", - "# prompt = build_prompt(query, mode, **kwargs)\n", - "\n", - "# if mode == \"react\":\n", - "# # ReAct needs the agent so the Search tool can fire\n", - "# resp = agent_react.llm.invoke(prompt) # ✅ modern, no deprecation warning\n", - "# else:\n", - "# resp = llm.invoke(prompt) # ✅ modern, no deprecation warning\n", - "\n", - "# return _to_text(resp).strip()\n", + " prompt = build_prompt(query, mode, **kwargs)\n", + " return smart_llm_call(llm, prompt).strip()\n", "\n", "# 6. Example Calls\n", "query_example = \"What is the capital of Canada and its population?\"\n", + "react_answer, react_log = call_with_mode(query_example, \"react\")\n", + "print(\"react →\", react_answer)\n", + "print(\"react log →\", react_log)\n", "\n", "# 6A. Zero-Shot\n", "res_zero = call_with_mode(query_example, mode=\"zero_shot\")\n", @@ -460,95 +909,35 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "9GOl2_KBHrBf", - "outputId": "9c677341-22c6-4b2b-b455-d8cefa219b17" + "id": "hpK3s7sJwvH5", + "outputId": "d0ee4f9c-79af-4d92-84d1-47b31970d6c9" }, - "execution_count": 25, + "execution_count": 44, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "Zero-Shot: Ottawa; approximately 1 million.\n", - "...................\n", - "Few-Shot: The capital of Canada is Ottawa. Its population is approximately 1 million.\n", - "...................\n", - "CoT: Let’s think step by step.\n", - "\n", - "Step 1: Identify the question. The question asks for two pieces of information: the capital city of Canada and its population.\n", - "\n", - "Step 2: Determine the capital city. The capital city of Canada is Ottawa.\n", - "\n", - "Step 3: Determine the population. The population of Ottawa is not a fixed number as it changes constantly. To answer accurately, we need to specify a time frame (e.g., the population as of a specific year or a recent estimate). A quick online search would provide the most up-to-date information.\n", - "\n", - "Step 4: Combine the information. Once a reliable population figure for Ottawa is found (e.g., from Statistics Canada or a reputable news source), the complete answer can be formulated as: \"The capital of Canada is Ottawa. [Insert population figure here] is its approximate population as of [Insert date here].\"\n", - "...................\n", - "CoT-SC Vote: Answer: The capital of Canada is Ottawa. Its population is approximately 1 million people (this is an approximation and requires a source and year for accuracy).\n", - "...................\n", - "Chained Facts: To answer the question, you need these facts:\n", - "\n", - "* **Capital of Canada:** [Insert City Name Here]\n", - "* **Population of the capital city:** [Insert Population Number Here]\n", - "Chained Final: To answer the question, please provide the missing information: the capital city of Canada and its population.\n", - "...................\n", - "Meta Optimized Prompt: What is the capital city of Canada and what is its current population?\n", - "...................\n", - "PAL: I can't access real-time information, including databases or the internet, to get the current population of Ottawa. Therefore, I'll provide code that would work if I *had* access to such data, and then give a reasonable approximation based on my knowledge.\n", - "\n", - "```python\n", - "import requests # This would be needed for real-world data fetching\n", - "\n", - "def get_capital_and_population(country):\n", - " \"\"\"\n", - " Fetches the capital and population of a given country. This is a simplified example and \n", - " would require a robust error handling mechanism in a real-world application.\n", - " \"\"\"\n", - " try:\n", - " # In a real application, you'd use a reliable API like REST Countries API\n", - " # This is a placeholder. Replace with actual API call.\n", - " response = requests.get(f\"https://example.com/api/country/{country}\") # Placeholder API\n", - " data = response.json()\n", - " capital = data[\"capital\"]\n", - " population = data[\"population\"]\n", - " return capital, population\n", - " except requests.exceptions.RequestException as e:\n", - " return None, f\"Error fetching data: {e}\"\n", - " except KeyError as e:\n", - " return None, f\"Data format error: {e}\"\n", - "\n", - "\n", - "country = \"Canada\"\n", - "capital, population = get_capital_and_population(country)\n", - "\n", - "if capital:\n", - " print(f\"The capital of {country} is {capital}.\")\n", - " print(f\"Its population is approximately {population}.\") # Note: approximation\n", - "else:\n", - " print(population) # Print the error message\n", - "\n", - "```\n", - "\n", - "**Mental Execution and Result (Approximation):**\n", - "\n", - "The code above uses a placeholder API call. In a real execution, it would make a network request to an API providing country information. Since I cannot do that, I'll provide a result based on my knowledge:\n", - "\n", - "\n", - "```\n", - "The capital of Canada is Ottawa.\n", - "Its population is approximately 1000000. (Note: This is a rough estimate. The actual population fluctuates.)\n", - "```\n", - "\n", - "The actual population of Ottawa would need to be looked up from a reliable source like Statistics Canada. My estimate is significantly less precise than what a real API call would provide.\n", - "...................\n" + "react → The capital of Canada is Ottawa. As of 2021, Ottawa had a city population of 1,017,449.\n", + "react log → \n" ] } ] }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "Z0uyeQx72-uU" + }, + "execution_count": null, + "outputs": [] + }, { "cell_type": "code", "source": [ - "query = \"What is the capital of Australia and its population?\"\n", - "for mode in [\"zero_shot\", \"few_shot\", \"cot\", \"cot_sc\"]:\n", + "query = \"What is the capital of Ottawa and its population?\"\n", + "for mode in [\"zero_shot\", \"few_shot\", \"cot\", \"cot_sc\"]:r\n", " print(f\"{mode:<8} →\", call_with_mode(query, mode))" ], "metadata": { @@ -556,9 +945,9 @@ "base_uri": "https://localhost:8080/" }, "id": "KNx1KBs-ieev", - "outputId": "7ea0ac6a-f892-48b6-901c-b46bf0aa0fab" + "outputId": "aefd1bc7-b8a5-493a-b0fe-153496a0e5e0" }, - "execution_count": 28, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -575,15 +964,80 @@ "Step 3: Find the population of the capital city. A quick online search reveals that the population of Canberra is approximately 430,000 (this number fluctuates and depends on the source and year).\n", "\n", "Step 4: Combine the findings. Therefore, the capital of Australia is Canberra, and its population is approximately 430,000.\n", - "cot_sc → Step 1: Identify the question. The question asks for two pieces of information: the capital city of Australia and its population.\n", + "cot_sc → Step 1: Identify the question. The question asks for the capital city of Australia and its population.\n", "\n", "Step 2: Determine the capital city. The capital city of Australia is Canberra.\n", "\n", - "Step 3: Find the population. A quick online search reveals that the population of Canberra fluctuates, but a reasonable approximation is around 450,000 people. (Note: This number is approximate and changes constantly).\n", + "Step 3: Find the population of Canberra. This requires looking up the population data from a reliable source (like the Australian Bureau of Statistics or a reputable encyclopedia). The population fluctuates, so a specific number will depend on the date of the source. I cannot access real-time information, including live population data.\n", "\n", - "Step 4: Combine the information.\n", + "Step 4: Combine the information. Therefore, the answer is: The capital of Australia is Canberra. Its population is [insert population figure from a reliable, up-to-date source].\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Model Switching Demo" + ], + "metadata": { + "id": "h7wiKLZigRw9" + } + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4DTpGe7wHQjz", + "outputId": "55c9de3e-1a9a-4250-f73a-68b44d2b66ed" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m\u001b[95m# Agent:\u001b[00m \u001b[1m\u001b[92mFactual Researcher\u001b[00m\n", + "\u001b[95m## Task:\u001b[00m \u001b[92mWhat is the capital of Australia and its population?\u001b[00m\n", "\n", - "Answer: The capital of Australia is Canberra, with a population of approximately 450,000.\n" + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\u001b[1m\u001b[95m# Agent:\u001b[00m \u001b[1m\u001b[92mFactual Researcher\u001b[00m\n", + "\u001b[95m## Thought:\u001b[00m \u001b[92mtool_code\n", + "Thought: I need to find the capital of Australia and its population using a web search.\u001b[00m\n", + "\u001b[95m## Using tool:\u001b[00m \u001b[92mSearch the internet with Serper\u001b[00m\n", + "\u001b[95m## Tool Input:\u001b[00m \u001b[92m\n", + "\"{\\\"search_query\\\": \\\"capital of Australia and population\\\"}\"\u001b[00m\n", + "\u001b[95m## Tool Output:\u001b[00m \u001b[92m\n", + "{'searchParameters': {'q': 'capital of Australia and population', 'type': 'search', 'num': 10, 'engine': 'google'}, 'organic': [{'title': 'Canberra - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Canberra', 'snippet': \"As of June 2024, Canberra's estimated population was 473,855. Canberra. Kanbarra (Ngunawal). Australian Capital ...\", 'position': 1, 'sitelinks': [{'title': 'History of Canberra', 'link': 'https://en.wikipedia.org/wiki/History_of_Canberra'}, {'title': 'Demographics of Canberra', 'link': 'https://en.wikipedia.org/wiki/Demographics_of_Canberra'}, {'title': 'Canberra (disambiguation)', 'link': 'https://en.wikipedia.org/wiki/Canberra_(disambiguation)'}]}, {'title': 'Australia | History, Cities, Population, Capital, Map, & Facts | Britannica', 'link': 'https://www.britannica.com/place/Australia', 'snippet': \"Australia's capital is Canberra, located in the southeast between the larger and more important economic and cultural centres of Sydney and Melbourne.\", 'position': 2}, {'title': 'Australian Capital Territory - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Australian_Capital_Territory', 'snippet': 'With 453,324 residents, the territory is the second smallest mainland state or territory by population. At the 2016 census, the median weekly income for people ...', 'position': 3}, {'title': 'Canberra | History, Map, Population, Climate, & Facts | Britannica', 'link': 'https://www.britannica.com/place/Canberra', 'snippet': 'Canberra, federal capital of the Commonwealth of Australia. It occupies part ... Population (2021) 454,499. Quick Facts. Australian Capital Territory ...', 'position': 4}, {'title': 'Capital city growth the highest on record', 'link': 'https://www.abs.gov.au/media-centre/media-releases/capital-city-growth-highest-record', 'snippet': 'Melbourne (up 167,500) and Sydney (up 146,700) had the biggest increase in 2022-23, with Perth and Brisbane each also adding over 80,000 people.', 'position': 5}, {'title': 'Australia Cities by Population 2025', 'link': 'https://worldpopulationreview.com/cities/australia', 'snippet': 'Australia Cities by Population 2025 ; Sydney. 4,627,345 ; Melbourne. 4,246,375 ; Brisbane. 2,189,878 ; Perth. 1,896,548 ; Adelaide. 1,225,235.', 'position': 6}, {'title': 'About the profile areas | Australia', 'link': 'https://profile.id.com.au/australia/about?WebID=330', 'snippet': 'The 2024 Estimated Resident Population for Greater Capital Cities is 17,948,954, with a population density of 314.0 persons per square km. Location and ...', 'position': 7}, {'title': \"Australia population: Nation's capitals squeeze in extra 430,000 ...\", 'link': 'https://www.smh.com.au/politics/federal/nation-s-capitals-squeeze-in-an-extra-430-000-people-20250327-p5ln00.html', 'snippet': \"The nation's capital cities squeezed in an extra 430,000 residents over the past 12 months as four in 10 Australians call Sydney and Melbourne ...\", 'position': 8}, {'title': 'Projections of population changes in our capital cities and rest-of ...', 'link': 'https://population.gov.au/data-and-forecasts/dashboards/projections-population-changes-our-capital-cities-and-rest-state', 'snippet': 'Explore the projected population and components of change for state and territory capital cities and the rest-of-state areas.', 'position': 9}], 'peopleAlsoAsk': [{'question': 'What language do they speak in Canberra?', 'snippet': 'Overall, 86.4% of the population used English only, and 7.3% used a non-English language, compared with 86.8% and 6.6% respectively for Regional NSW. The dominant language used at home, other than English, in Canberra Region was Nepali, with 0.4% of the population, or 1,505 people using this language at home.', 'title': 'Language used at home | Canberra Region Joint Organisation area', 'link': 'https://profile.id.com.au/crjo/language'}, {'question': 'Why is Sydney no longer the capital of Australia?', 'snippet': 'Following a long dispute over whether Sydney or Melbourne should be the national capital, a compromise was reached: the new capital would be built in New South Wales, so long as it was at least 100 mi (160 km) from Sydney. The capital city was founded and formally named as Canberra in 1913.', 'title': 'Canberra - Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Canberra'}, {'question': \"Where does 85% of Australia's population live?\", 'snippet': 'Beach paradise\\\\n\\\\n More than 85 per cent of Australians live within 50 kilometres of the coast, making it an integral part of our laid-back lifestyle.', 'title': 'Australia Facts - Travellers Contact Point', 'link': 'https://www.travellers.com.au/plan-your-trip/australia-facts/'}], 'relatedSearches': [{'query': 'United States'}, {'query': 'Capital of Australia before Canberra'}, {'query': 'Capital of australia and population by race'}, {'query': 'Why is Sydney not the capital of Australia'}, {'query': 'Australia population'}, {'query': 'Why is Canberra the capital of Australia'}, {'query': 'Nsw capital of australia and population'}, {'query': 'Capital of australia and population 2021'}, {'query': 'Was Sydney ever the capital of Australia'}], 'credits': 1}\u001b[00m\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\u001b[1m\u001b[95m# Agent:\u001b[00m \u001b[1m\u001b[92mFactual Researcher\u001b[00m\n", + "\n", + "\n", + "\n", + "\u001b[95m## Final Answer:\u001b[00m \u001b[92m\n", + "Canberra, with an estimated population of 473,855 as of June 2024.\u001b[00m\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "react → Canberra, with an estimated population of 473,855 as of June 2024.\n" ] } ]