Spaces:
No application file
No application file
Upload simple_agent.ipynb
Browse files- simple_agent.ipynb +497 -0
simple_agent.ipynb
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"id": "94c8b42c",
|
| 7 |
+
"metadata": {},
|
| 8 |
+
"outputs": [],
|
| 9 |
+
"source": [
|
| 10 |
+
"import getpass\n",
|
| 11 |
+
"import os\n",
|
| 12 |
+
"from langchain.chat_models import init_chat_model\n",
|
| 13 |
+
"\n",
|
| 14 |
+
"if not os.environ.get(\"GOOGLE_API_KEY\"):\n",
|
| 15 |
+
" os.environ[\"GOOGLE_API_KEY\"] = getpass.getpass(\"Enter API key for Google Gemini: \")\n",
|
| 16 |
+
"llm = init_chat_model(\"gemini-2.5-flash-preview-04-17\", model_provider=\"google_genai\", temperature=0)"
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "code",
|
| 21 |
+
"execution_count": 18,
|
| 22 |
+
"id": "ce83aa2a",
|
| 23 |
+
"metadata": {},
|
| 24 |
+
"outputs": [],
|
| 25 |
+
"source": [
|
| 26 |
+
"import re\n",
|
| 27 |
+
"from langchain.document_loaders import WebBaseLoader\n",
|
| 28 |
+
"from langchain_community.tools import DuckDuckGoSearchResults\n",
|
| 29 |
+
"def download_web_pages(query: str) -> str:\n",
|
| 30 |
+
" \"\"\"\n",
|
| 31 |
+
" Performs a web search using the given query, downloads the content of two relevant web pages,\n",
|
| 32 |
+
" and returns their combined content as a raw string.\n",
|
| 33 |
+
"\n",
|
| 34 |
+
" This is useful when the task requires analysis of web page content, such as retrieving poems, \n",
|
| 35 |
+
" changelogs, or other textual resources.\n",
|
| 36 |
+
"\n",
|
| 37 |
+
" Args:\n",
|
| 38 |
+
" query (str): The search query.\n",
|
| 39 |
+
"\n",
|
| 40 |
+
" Returns:\n",
|
| 41 |
+
" str: The combined raw text content of the two retrieved web pages.\n",
|
| 42 |
+
" \"\"\"\n",
|
| 43 |
+
" search_engine = DuckDuckGoSearchResults(output_format=\"list\", num_results=2)\n",
|
| 44 |
+
" page_urls = [url[\"link\"] for url in search_engine(query)]\n",
|
| 45 |
+
"\n",
|
| 46 |
+
" loader = WebBaseLoader(web_paths=(page_urls))\n",
|
| 47 |
+
" docs = loader.load()\n",
|
| 48 |
+
"\n",
|
| 49 |
+
" combined_text = \"\\n\\n\".join(doc.page_content[:15000] for doc in docs)\n",
|
| 50 |
+
"\n",
|
| 51 |
+
" # Clean up excessive newlines, spaces and strip leading/trailing whitespace\n",
|
| 52 |
+
" cleaned_text = re.sub(r'\\n{3,}', '\\n\\n', combined_text).strip()\n",
|
| 53 |
+
" cleaned_text = re.sub(r'[ \\t]{6,}', ' ', cleaned_text)\n",
|
| 54 |
+
"\n",
|
| 55 |
+
" # Strip leading/trailing whitespace\n",
|
| 56 |
+
" cleaned_text = cleaned_text.strip()\n",
|
| 57 |
+
" return cleaned_text"
|
| 58 |
+
]
|
| 59 |
+
},
|
| 60 |
+
{
|
| 61 |
+
"cell_type": "code",
|
| 62 |
+
"execution_count": 24,
|
| 63 |
+
"id": "586df437",
|
| 64 |
+
"metadata": {},
|
| 65 |
+
"outputs": [],
|
| 66 |
+
"source": [
|
| 67 |
+
"from langchain_community.retrievers import WikipediaRetriever\n",
|
| 68 |
+
"\n",
|
| 69 |
+
"def wikipedia_search(query: str) -> str:\n",
|
| 70 |
+
" \"\"\"\n",
|
| 71 |
+
" Searches for a Wikipedia articles using the provided query and returns the content of the corresponding Wikipedia pages.\n",
|
| 72 |
+
"\n",
|
| 73 |
+
" Args:\n",
|
| 74 |
+
" query (str): The search term to look up on Wikipedia.\n",
|
| 75 |
+
"\n",
|
| 76 |
+
" Returns:\n",
|
| 77 |
+
" str: The text content of the Wikipedia articles related to the query.\n",
|
| 78 |
+
" \"\"\"\n",
|
| 79 |
+
" retriever = WikipediaRetriever()\n",
|
| 80 |
+
" docs = retriever.invoke(query)\n",
|
| 81 |
+
" combined_text = \"\\n\\n\".join(doc.page_content for doc in docs)\n",
|
| 82 |
+
" return combined_text"
|
| 83 |
+
]
|
| 84 |
+
},
|
| 85 |
+
{
|
| 86 |
+
"cell_type": "code",
|
| 87 |
+
"execution_count": 25,
|
| 88 |
+
"id": "fac2cb01",
|
| 89 |
+
"metadata": {},
|
| 90 |
+
"outputs": [],
|
| 91 |
+
"source": [
|
| 92 |
+
"from google import genai\n",
|
| 93 |
+
"from google.genai import types\n",
|
| 94 |
+
"\n",
|
| 95 |
+
"def youtube_viewer(youtube_url: str, question: str) -> str:\n",
|
| 96 |
+
" \"\"\"\n",
|
| 97 |
+
" Analyzes a YouTube video from the provided URL and returns an answer \n",
|
| 98 |
+
" to the given question based on the analysis results.\n",
|
| 99 |
+
"\n",
|
| 100 |
+
" Args:\n",
|
| 101 |
+
" youtube_url (str): The URL of the YouTube video, in the format \n",
|
| 102 |
+
" \"https://www.youtube.com/...\".\n",
|
| 103 |
+
" question (str): A question related to the content of the video.\n",
|
| 104 |
+
"\n",
|
| 105 |
+
" Returns:\n",
|
| 106 |
+
" str: An answer to the question based on the video's content.\n",
|
| 107 |
+
" \"\"\"\n",
|
| 108 |
+
" client = genai.Client()\n",
|
| 109 |
+
" response = client.models.generate_content(\n",
|
| 110 |
+
" model='models/gemini-2.5-flash-preview-04-17',\n",
|
| 111 |
+
" contents=types.Content(\n",
|
| 112 |
+
" parts=[\n",
|
| 113 |
+
" types.Part(\n",
|
| 114 |
+
" file_data=types.FileData(file_uri=youtube_url)\n",
|
| 115 |
+
" ),\n",
|
| 116 |
+
" types.Part(text=question)\n",
|
| 117 |
+
" ]\n",
|
| 118 |
+
" )\n",
|
| 119 |
+
" )\n",
|
| 120 |
+
" return response.text"
|
| 121 |
+
]
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"cell_type": "code",
|
| 125 |
+
"execution_count": 26,
|
| 126 |
+
"id": "4c498a3d",
|
| 127 |
+
"metadata": {},
|
| 128 |
+
"outputs": [
|
| 129 |
+
{
|
| 130 |
+
"name": "stderr",
|
| 131 |
+
"output_type": "stream",
|
| 132 |
+
"text": [
|
| 133 |
+
"Key 'title' is not supported in schema, ignoring\n",
|
| 134 |
+
"Key 'title' is not supported in schema, ignoring\n",
|
| 135 |
+
"Key 'title' is not supported in schema, ignoring\n"
|
| 136 |
+
]
|
| 137 |
+
}
|
| 138 |
+
],
|
| 139 |
+
"source": [
|
| 140 |
+
"tools = [download_web_pages, wikipedia_search, youtube_viewer]\n",
|
| 141 |
+
"\n",
|
| 142 |
+
"# Bind the tools to the agent\n",
|
| 143 |
+
"llm_with_tools = llm.bind_tools(tools)"
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"cell_type": "code",
|
| 148 |
+
"execution_count": 27,
|
| 149 |
+
"id": "10628e0f",
|
| 150 |
+
"metadata": {},
|
| 151 |
+
"outputs": [],
|
| 152 |
+
"source": [
|
| 153 |
+
"from typing import TypedDict, Annotated, Optional\n",
|
| 154 |
+
"from langchain_core.messages import AnyMessage\n",
|
| 155 |
+
"from langgraph.graph.message import add_messages\n",
|
| 156 |
+
"\n",
|
| 157 |
+
"class AgentState(TypedDict):\n",
|
| 158 |
+
" \"\"\"Agent state for the graph.\"\"\"\n",
|
| 159 |
+
" input_file: Optional[str]\n",
|
| 160 |
+
" messages: Annotated[list[AnyMessage], add_messages]"
|
| 161 |
+
]
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
"cell_type": "code",
|
| 165 |
+
"execution_count": 28,
|
| 166 |
+
"id": "f1594fb9",
|
| 167 |
+
"metadata": {},
|
| 168 |
+
"outputs": [],
|
| 169 |
+
"source": [
|
| 170 |
+
"from langchain_core.messages import SystemMessage, HumanMessage\n",
|
| 171 |
+
"\n",
|
| 172 |
+
"def assistant(state: AgentState):\n",
|
| 173 |
+
" sys_msg = SystemMessage(\n",
|
| 174 |
+
" content=\n",
|
| 175 |
+
" \"\"\"\n",
|
| 176 |
+
"You are a helpful assistant tasked with answering questions using a set of tools. When given a question, follow these steps:\n",
|
| 177 |
+
"1. Create a clear, step-by-step plan to solve the question.\n",
|
| 178 |
+
"2. If a tool is necessary, select the most appropriate tool based on its functionality. If one tool isn't working, use another with similar functionality.\n",
|
| 179 |
+
"3. Execute your plan and provide the response in the following format:\n",
|
| 180 |
+
"\n",
|
| 181 |
+
"FINAL ANSWER: [YOUR FINAL ANSWER]\n",
|
| 182 |
+
"\n",
|
| 183 |
+
"Your final answer should be:\n",
|
| 184 |
+
"\n",
|
| 185 |
+
"- A number (without commas or units unless explicitly requested),\n",
|
| 186 |
+
"- A short string (avoid articles, abbreviations, and use plain text for digits unless otherwise specified),\n",
|
| 187 |
+
"- A comma-separated list (apply the formatting rules above for each element, with exactly one space after each comma).\n",
|
| 188 |
+
"\n",
|
| 189 |
+
"Ensure that your answer is concise and follows the task instructions strictly. If the answer is more complex, break it down in a way that follows the format.\n",
|
| 190 |
+
"Begin your response with \"FINAL ANSWER: \" followed by the answer, and nothing else.\n",
|
| 191 |
+
" \"\"\"\n",
|
| 192 |
+
" )\n",
|
| 193 |
+
"\n",
|
| 194 |
+
" return {\n",
|
| 195 |
+
" \"messages\": [llm_with_tools.invoke([sys_msg] + state[\"messages\"])],\n",
|
| 196 |
+
" \"input_file\": state[\"input_file\"]\n",
|
| 197 |
+
" }"
|
| 198 |
+
]
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"cell_type": "code",
|
| 202 |
+
"execution_count": 29,
|
| 203 |
+
"id": "b36bc36c",
|
| 204 |
+
"metadata": {},
|
| 205 |
+
"outputs": [
|
| 206 |
+
{
|
| 207 |
+
"data": {
|
| 208 |
+
"image/png": "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",
|
| 209 |
+
"text/plain": [
|
| 210 |
+
"<IPython.core.display.Image object>"
|
| 211 |
+
]
|
| 212 |
+
},
|
| 213 |
+
"metadata": {},
|
| 214 |
+
"output_type": "display_data"
|
| 215 |
+
}
|
| 216 |
+
],
|
| 217 |
+
"source": [
|
| 218 |
+
"from langgraph.prebuilt import ToolNode, tools_condition\n",
|
| 219 |
+
"from IPython.display import Image, display\n",
|
| 220 |
+
"from langgraph.graph import StateGraph, START\n",
|
| 221 |
+
"\n",
|
| 222 |
+
"# Build the state graph\n",
|
| 223 |
+
"# The graph\n",
|
| 224 |
+
"builder = StateGraph(AgentState)\n",
|
| 225 |
+
"\n",
|
| 226 |
+
"# Define nodes: these do the work\n",
|
| 227 |
+
"builder.add_node(\"assistant\", assistant)\n",
|
| 228 |
+
"builder.add_node(\"tools\", ToolNode(tools))\n",
|
| 229 |
+
"# Define edges: these determine how the control flow moves\n",
|
| 230 |
+
"builder.add_edge(START, \"assistant\")\n",
|
| 231 |
+
"builder.add_conditional_edges(\n",
|
| 232 |
+
" \"assistant\",\n",
|
| 233 |
+
" tools_condition,\n",
|
| 234 |
+
")\n",
|
| 235 |
+
"builder.add_edge(\"tools\", \"assistant\")\n",
|
| 236 |
+
"react_graph = builder.compile()\n",
|
| 237 |
+
"# Show the butler's thought process\n",
|
| 238 |
+
"display(Image(react_graph.get_graph(xray=True).draw_mermaid_png()))"
|
| 239 |
+
]
|
| 240 |
+
},
|
| 241 |
+
{
|
| 242 |
+
"cell_type": "code",
|
| 243 |
+
"execution_count": 13,
|
| 244 |
+
"id": "ead8e45f",
|
| 245 |
+
"metadata": {},
|
| 246 |
+
"outputs": [
|
| 247 |
+
{
|
| 248 |
+
"data": {
|
| 249 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 250 |
+
"model_id": "ed21ed00ada141289cbee25b93029435",
|
| 251 |
+
"version_major": 2,
|
| 252 |
+
"version_minor": 0
|
| 253 |
+
},
|
| 254 |
+
"text/plain": [
|
| 255 |
+
"VBox(children=(HTML(value='<center> <img\\nsrc=https://huggingface.co/front/assets/huggingface_logo-noborder.sv…"
|
| 256 |
+
]
|
| 257 |
+
},
|
| 258 |
+
"metadata": {},
|
| 259 |
+
"output_type": "display_data"
|
| 260 |
+
}
|
| 261 |
+
],
|
| 262 |
+
"source": [
|
| 263 |
+
"from huggingface_hub import login\n",
|
| 264 |
+
"\n",
|
| 265 |
+
"# This will prompt you for your token\n",
|
| 266 |
+
"login()"
|
| 267 |
+
]
|
| 268 |
+
},
|
| 269 |
+
{
|
| 270 |
+
"cell_type": "code",
|
| 271 |
+
"execution_count": 12,
|
| 272 |
+
"id": "b4b1299d",
|
| 273 |
+
"metadata": {},
|
| 274 |
+
"outputs": [
|
| 275 |
+
{
|
| 276 |
+
"name": "stdout",
|
| 277 |
+
"output_type": "stream",
|
| 278 |
+
"text": [
|
| 279 |
+
"Logged in as: SpyFox\n"
|
| 280 |
+
]
|
| 281 |
+
}
|
| 282 |
+
],
|
| 283 |
+
"source": [
|
| 284 |
+
"from huggingface_hub import whoami\n",
|
| 285 |
+
"\n",
|
| 286 |
+
"info = whoami()\n",
|
| 287 |
+
"username = info[\"name\"]\n",
|
| 288 |
+
"\n",
|
| 289 |
+
"print(f\"Logged in as: {username}\")"
|
| 290 |
+
]
|
| 291 |
+
},
|
| 292 |
+
{
|
| 293 |
+
"cell_type": "code",
|
| 294 |
+
"execution_count": 13,
|
| 295 |
+
"id": "45e5f7ca",
|
| 296 |
+
"metadata": {},
|
| 297 |
+
"outputs": [],
|
| 298 |
+
"source": [
|
| 299 |
+
"DEFAULT_API_URL = \"https://agents-course-unit4-scoring.hf.space\" \n",
|
| 300 |
+
"api_url = DEFAULT_API_URL\n",
|
| 301 |
+
"questions_url = f\"{api_url}/questions\"\n",
|
| 302 |
+
"submit_url = f\"{api_url}/submit\"\n",
|
| 303 |
+
"files_url = f\"{api_url}/files\""
|
| 304 |
+
]
|
| 305 |
+
},
|
| 306 |
+
{
|
| 307 |
+
"cell_type": "code",
|
| 308 |
+
"execution_count": 14,
|
| 309 |
+
"id": "af2e50c9",
|
| 310 |
+
"metadata": {},
|
| 311 |
+
"outputs": [
|
| 312 |
+
{
|
| 313 |
+
"name": "stdout",
|
| 314 |
+
"output_type": "stream",
|
| 315 |
+
"text": [
|
| 316 |
+
"Fetching questions from: https://agents-course-unit4-scoring.hf.space/questions\n",
|
| 317 |
+
"Fetched 20 questions.\n",
|
| 318 |
+
"{'task_id': 'cabe07ed-9eca-40ea-8ead-410ef5e83f91', 'question': \"What is the surname of the equine veterinarian mentioned in 1.E Exercises from the chemistry materials licensed by Marisa Alviar-Agnew & Henry Agnew under the CK-12 license in LibreText's Introductory Chemistry materials as compiled 08/21/2023?\", 'Level': '1', 'file_name': ''}\n"
|
| 319 |
+
]
|
| 320 |
+
}
|
| 321 |
+
],
|
| 322 |
+
"source": [
|
| 323 |
+
"import requests\n",
|
| 324 |
+
"print(f\"Fetching questions from: {questions_url}\")\n",
|
| 325 |
+
"try:\n",
|
| 326 |
+
" response = requests.get(questions_url, timeout=15)\n",
|
| 327 |
+
" response.raise_for_status()\n",
|
| 328 |
+
" questions_data = response.json()\n",
|
| 329 |
+
" if not questions_data:\n",
|
| 330 |
+
" print(\"Fetched questions list is empty.\")\n",
|
| 331 |
+
" print(f\"Fetched {len(questions_data)} questions.\")\n",
|
| 332 |
+
"except requests.exceptions.RequestException as e:\n",
|
| 333 |
+
" print(f\"Error fetching questions: {e}\")\n",
|
| 334 |
+
"except requests.exceptions.JSONDecodeError as e:\n",
|
| 335 |
+
" print(f\"Error decoding JSON response from questions endpoint: {e}\")\n",
|
| 336 |
+
" print(f\"Response text: {response.text[:500]}\")\n",
|
| 337 |
+
"except Exception as e:\n",
|
| 338 |
+
" print(f\"An unexpected error occurred fetching questions: {e}\")\n",
|
| 339 |
+
"\n",
|
| 340 |
+
"print(questions_data[7])"
|
| 341 |
+
]
|
| 342 |
+
},
|
| 343 |
+
{
|
| 344 |
+
"cell_type": "code",
|
| 345 |
+
"execution_count": 30,
|
| 346 |
+
"id": "3c6996e6",
|
| 347 |
+
"metadata": {},
|
| 348 |
+
"outputs": [
|
| 349 |
+
{
|
| 350 |
+
"name": "stdout",
|
| 351 |
+
"output_type": "stream",
|
| 352 |
+
"text": [
|
| 353 |
+
"Running agent on 20 questions...\n",
|
| 354 |
+
"Question: How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia.\n"
|
| 355 |
+
]
|
| 356 |
+
},
|
| 357 |
+
{
|
| 358 |
+
"name": "stderr",
|
| 359 |
+
"output_type": "stream",
|
| 360 |
+
"text": [
|
| 361 |
+
"C:\\Users\\wasyl\\AppData\\Local\\Temp\\ipykernel_22488\\81366616.py:19: LangChainDeprecationWarning: The method `BaseTool.__call__` was deprecated in langchain-core 0.1.47 and will be removed in 1.0. Use :meth:`~invoke` instead.\n",
|
| 362 |
+
" page_urls = [url[\"link\"] for url in search_engine(query)]\n"
|
| 363 |
+
]
|
| 364 |
+
},
|
| 365 |
+
{
|
| 366 |
+
"name": "stdout",
|
| 367 |
+
"output_type": "stream",
|
| 368 |
+
"text": [
|
| 369 |
+
"Answer: 3\n",
|
| 370 |
+
"Question: In the video https://www.youtube.com/watch?v=L1vXCYZAYYM, what is the highest number of bird species to be on camera simultaneously?\n",
|
| 371 |
+
"Answer: 3\n"
|
| 372 |
+
]
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"ename": "KeyboardInterrupt",
|
| 376 |
+
"evalue": "",
|
| 377 |
+
"output_type": "error",
|
| 378 |
+
"traceback": [
|
| 379 |
+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
| 380 |
+
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
|
| 381 |
+
"Cell \u001b[1;32mIn[30], line 28\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAnswer: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00msubmitted_answer\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 27\u001b[0m answers_payload\u001b[38;5;241m.\u001b[39mappend({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtask_id\u001b[39m\u001b[38;5;124m\"\u001b[39m: task_id, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msubmitted_answer\u001b[39m\u001b[38;5;124m\"\u001b[39m: submitted_answer})\n\u001b[1;32m---> 28\u001b[0m time\u001b[38;5;241m.\u001b[39msleep(\u001b[38;5;241m10\u001b[39m) \u001b[38;5;66;03m# Sleep for 10 seconds to avoid rate limiting\u001b[39;00m\n\u001b[0;32m 29\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 30\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mError running agent on task \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtask_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
|
| 382 |
+
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
|
| 383 |
+
]
|
| 384 |
+
}
|
| 385 |
+
],
|
| 386 |
+
"source": [
|
| 387 |
+
"import time\n",
|
| 388 |
+
"\n",
|
| 389 |
+
"def extract_after_final_answer(text):\n",
|
| 390 |
+
" keyword = \"FINAL ANSWER: \"\n",
|
| 391 |
+
" index = text.find(keyword)\n",
|
| 392 |
+
" if index != -1:\n",
|
| 393 |
+
" return text[index + len(keyword):]\n",
|
| 394 |
+
" else:\n",
|
| 395 |
+
" return \"\"\n",
|
| 396 |
+
"\n",
|
| 397 |
+
"answers_payload = []\n",
|
| 398 |
+
"\n",
|
| 399 |
+
"print(f\"Running agent on {len(questions_data)} questions...\")\n",
|
| 400 |
+
"for item in questions_data:\n",
|
| 401 |
+
" task_id = item.get(\"task_id\")\n",
|
| 402 |
+
" question_text = item.get(\"question\")\n",
|
| 403 |
+
" print(f\"Question: {question_text}\")\n",
|
| 404 |
+
" messages = [HumanMessage(content=question_text)]\n",
|
| 405 |
+
"\n",
|
| 406 |
+
" if not task_id or question_text is None:\n",
|
| 407 |
+
" print(f\"Skipping item with missing task_id or question: {item}\")\n",
|
| 408 |
+
" continue\n",
|
| 409 |
+
" try:\n",
|
| 410 |
+
" submitted_answer = react_graph.invoke({\"messages\": messages, \"input_file\": None})\n",
|
| 411 |
+
" submitted_answer = extract_after_final_answer(submitted_answer['messages'][-1].content)\n",
|
| 412 |
+
" print(f\"Answer: {submitted_answer}\")\n",
|
| 413 |
+
" answers_payload.append({\"task_id\": task_id, \"submitted_answer\": submitted_answer})\n",
|
| 414 |
+
" time.sleep(10) # Sleep for 10 seconds to avoid rate limiting\n",
|
| 415 |
+
" except Exception as e:\n",
|
| 416 |
+
" print(f\"Error running agent on task {task_id}: {e}\")\n"
|
| 417 |
+
]
|
| 418 |
+
},
|
| 419 |
+
{
|
| 420 |
+
"cell_type": "code",
|
| 421 |
+
"execution_count": 27,
|
| 422 |
+
"id": "8e47414a",
|
| 423 |
+
"metadata": {},
|
| 424 |
+
"outputs": [
|
| 425 |
+
{
|
| 426 |
+
"name": "stdout",
|
| 427 |
+
"output_type": "stream",
|
| 428 |
+
"text": [
|
| 429 |
+
"Agent finished. Submitting 20 answers for user 'SpyFox'...\n"
|
| 430 |
+
]
|
| 431 |
+
}
|
| 432 |
+
],
|
| 433 |
+
"source": [
|
| 434 |
+
"submission_data = {\"username\": username.strip(), \"agent_code\": \"https://huggingface.co/spaces/SpyFox/agents_final_test/tree/main\", \"answers\": answers_payload}\n",
|
| 435 |
+
"status_update = f\"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'...\"\n",
|
| 436 |
+
"print(status_update)"
|
| 437 |
+
]
|
| 438 |
+
},
|
| 439 |
+
{
|
| 440 |
+
"cell_type": "code",
|
| 441 |
+
"execution_count": 28,
|
| 442 |
+
"id": "a086f73f",
|
| 443 |
+
"metadata": {},
|
| 444 |
+
"outputs": [
|
| 445 |
+
{
|
| 446 |
+
"name": "stdout",
|
| 447 |
+
"output_type": "stream",
|
| 448 |
+
"text": [
|
| 449 |
+
"Submitting 20 answers to: https://agents-course-unit4-scoring.hf.space/submit\n",
|
| 450 |
+
"Submission successful.\n",
|
| 451 |
+
"Submission Successful!\n",
|
| 452 |
+
"User: SpyFox\n",
|
| 453 |
+
"Overall Score: 45.0% (9/20 correct)\n",
|
| 454 |
+
"Message: Score calculated successfully: 9/20 total questions answered correctly (20 valid tasks attempted). High score updated on leaderboard.\n"
|
| 455 |
+
]
|
| 456 |
+
}
|
| 457 |
+
],
|
| 458 |
+
"source": [
|
| 459 |
+
"print(f\"Submitting {len(answers_payload)} answers to: {submit_url}\")\n",
|
| 460 |
+
"\n",
|
| 461 |
+
"response = requests.post(submit_url, json=submission_data, timeout=60)\n",
|
| 462 |
+
"response.raise_for_status()\n",
|
| 463 |
+
"result_data = response.json()\n",
|
| 464 |
+
"final_status = (\n",
|
| 465 |
+
" f\"Submission Successful!\\n\"\n",
|
| 466 |
+
" f\"User: {result_data.get('username')}\\n\"\n",
|
| 467 |
+
" f\"Overall Score: {result_data.get('score', 'N/A')}% \"\n",
|
| 468 |
+
" f\"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\\n\"\n",
|
| 469 |
+
" f\"Message: {result_data.get('message', 'No message received.')}\"\n",
|
| 470 |
+
")\n",
|
| 471 |
+
"print(\"Submission successful.\")\n",
|
| 472 |
+
"print(final_status)"
|
| 473 |
+
]
|
| 474 |
+
}
|
| 475 |
+
],
|
| 476 |
+
"metadata": {
|
| 477 |
+
"kernelspec": {
|
| 478 |
+
"display_name": "base",
|
| 479 |
+
"language": "python",
|
| 480 |
+
"name": "python3"
|
| 481 |
+
},
|
| 482 |
+
"language_info": {
|
| 483 |
+
"codemirror_mode": {
|
| 484 |
+
"name": "ipython",
|
| 485 |
+
"version": 3
|
| 486 |
+
},
|
| 487 |
+
"file_extension": ".py",
|
| 488 |
+
"mimetype": "text/x-python",
|
| 489 |
+
"name": "python",
|
| 490 |
+
"nbconvert_exporter": "python",
|
| 491 |
+
"pygments_lexer": "ipython3",
|
| 492 |
+
"version": "3.11.4"
|
| 493 |
+
}
|
| 494 |
+
},
|
| 495 |
+
"nbformat": 4,
|
| 496 |
+
"nbformat_minor": 5
|
| 497 |
+
}
|