Spaces:
Sleeping
Sleeping
Updated with Serper API tool capabilities
Browse files- README.md +90 -1
- agent.py +82 -2
- system_prompt.txt +6 -3
README.md
CHANGED
@@ -11,4 +11,93 @@ hf_oauth: true
|
|
11 |
hf_oauth_expiration_minutes: 480
|
12 |
---
|
13 |
|
14 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
hf_oauth_expiration_minutes: 480
|
12 |
---
|
13 |
|
14 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
15 |
+
|
16 |
+
# Agent Assignment - LlamaIndex Agent
|
17 |
+
|
18 |
+
This project implements an intelligent agent using LlamaIndex with enhanced search capabilities.
|
19 |
+
|
20 |
+
## Features
|
21 |
+
|
22 |
+
- **Multiple Information Sources**: The agent can search Wikipedia, search Google using Serper API, and extract content from web pages
|
23 |
+
- **Mathematical Operations**: Simple calculator for basic arithmetic operations
|
24 |
+
- **Text Processing**: Includes a text reverser tool for handling reversed text queries
|
25 |
+
- **Structured Output**: All responses include a clear "FINAL ANSWER" in a consistent format
|
26 |
+
|
27 |
+
## Installation
|
28 |
+
|
29 |
+
1. Clone this repository
|
30 |
+
2. Install dependencies:
|
31 |
+
|
32 |
+
```bash
|
33 |
+
pip install -r requirements.txt
|
34 |
+
```
|
35 |
+
|
36 |
+
3. Set up environment variables:
|
37 |
+
|
38 |
+
Create a `.env` file in the root directory with:
|
39 |
+
|
40 |
+
```
|
41 |
+
# Google API key for Gemini LLM
|
42 |
+
GOOGLE_API_KEY=your_google_api_key
|
43 |
+
|
44 |
+
# Or HuggingFace API key
|
45 |
+
# HUGGINGFACE_API_KEY=your_huggingface_api_key
|
46 |
+
# DEFAULT_LLM_PROVIDER=huggingface
|
47 |
+
|
48 |
+
# Serper API key for Google search
|
49 |
+
SERPER_API_KEY=your_serper_api_key
|
50 |
+
```
|
51 |
+
|
52 |
+
## Setting up Serper API
|
53 |
+
|
54 |
+
The agent uses [Serper.dev](https://serper.dev/) to perform Google searches. To set this up:
|
55 |
+
|
56 |
+
1. Sign up for an account at [Serper.dev](https://serper.dev/)
|
57 |
+
2. Get your API key from the dashboard
|
58 |
+
3. Add your API key to the `.env` file or set it using the utility script:
|
59 |
+
|
60 |
+
```bash
|
61 |
+
python set_env_var.py SERPER_API_KEY your_api_key_here
|
62 |
+
```
|
63 |
+
|
64 |
+
## Usage
|
65 |
+
|
66 |
+
### Testing Individual Tools
|
67 |
+
|
68 |
+
```bash
|
69 |
+
# Test Wikipedia search
|
70 |
+
python test_wikipedia.py
|
71 |
+
|
72 |
+
# Test Google search (requires SERPER_API_KEY)
|
73 |
+
python test_google_search.py
|
74 |
+
|
75 |
+
# Test the full agent with various questions
|
76 |
+
python test_agent_with_google.py
|
77 |
+
```
|
78 |
+
|
79 |
+
### Running the Agent
|
80 |
+
|
81 |
+
```bash
|
82 |
+
# Run the main application
|
83 |
+
python app.py
|
84 |
+
```
|
85 |
+
|
86 |
+
## Troubleshooting
|
87 |
+
|
88 |
+
- **Missing API Keys**: Make sure all required API keys are set in your `.env` file
|
89 |
+
- **Wikipedia Issues**: The agent will try to use direct Wikipedia API first and fall back to LlamaIndex WikipediaReader
|
90 |
+
- **Google Search Issues**: Verify your SERPER_API_KEY is correct and has sufficient quota
|
91 |
+
|
92 |
+
## Testing Scripts
|
93 |
+
|
94 |
+
- `test_wikipedia.py`: Tests the Wikipedia search functionality
|
95 |
+
- `test_google_search.py`: Tests the Google search functionality using Serper API
|
96 |
+
- `test_agent_output.py`: Tests the agent's output format
|
97 |
+
- `test_agent_with_google.py`: Tests the agent with questions using Google search
|
98 |
+
- `mini_test.py`: Minimal test script for checking the agent's initialization
|
99 |
+
- `standalone_debug.py`: Standalone debug script without Gradio dependencies
|
100 |
+
|
101 |
+
## Environment Utilities
|
102 |
+
|
103 |
+
- `set_env_var.py`: Utility to easily set environment variables in the `.env` file
|
agent.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
"""Tool definitions and utility functions for the agent"""
|
2 |
from typing import List, Dict, Any
|
3 |
import os
|
|
|
|
|
4 |
from dotenv import load_dotenv
|
5 |
|
6 |
from llama_index.core.tools import BaseTool, FunctionTool
|
@@ -54,6 +56,77 @@ def simple_calculator(operation: str, a: float, b: float) -> float:
|
|
54 |
raise ValueError(f"Unknown operation: {operation}")
|
55 |
|
56 |
# --- Information Retrieval Tools ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
def wikipedia_search(query: str, num_results: int = 2) -> str:
|
58 |
"""
|
59 |
Search Wikipedia for information.
|
@@ -162,14 +235,21 @@ def get_tools() -> List[BaseTool]:
|
|
162 |
web_tool = FunctionTool.from_defaults(
|
163 |
fn=web_search,
|
164 |
name="web_search",
|
165 |
-
description="Fetches and extracts content from a specific web page.",
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
)
|
167 |
|
168 |
return [
|
169 |
text_reverser_tool,
|
170 |
calculator_tool,
|
171 |
wikipedia_tool,
|
172 |
-
web_tool
|
|
|
173 |
]
|
174 |
|
175 |
if __name__ == "__main__":
|
|
|
1 |
"""Tool definitions and utility functions for the agent"""
|
2 |
from typing import List, Dict, Any
|
3 |
import os
|
4 |
+
import json
|
5 |
+
import requests
|
6 |
from dotenv import load_dotenv
|
7 |
|
8 |
from llama_index.core.tools import BaseTool, FunctionTool
|
|
|
56 |
raise ValueError(f"Unknown operation: {operation}")
|
57 |
|
58 |
# --- Information Retrieval Tools ---
|
59 |
+
def google_search(query: str, num_results: int = 5) -> str:
|
60 |
+
"""
|
61 |
+
Search Google using the Serper API.
|
62 |
+
|
63 |
+
Args:
|
64 |
+
query: The search query
|
65 |
+
num_results: Number of results to return (default: 5)
|
66 |
+
|
67 |
+
Returns:
|
68 |
+
A formatted string with the search results
|
69 |
+
"""
|
70 |
+
api_key = os.getenv("SERPER_API_KEY")
|
71 |
+
if not api_key:
|
72 |
+
return "SERPER_API_KEY not found in environment variables. Cannot perform Google search."
|
73 |
+
|
74 |
+
headers = {
|
75 |
+
"X-API-KEY": api_key,
|
76 |
+
"Content-Type": "application/json"
|
77 |
+
}
|
78 |
+
|
79 |
+
payload = {
|
80 |
+
"q": query,
|
81 |
+
"num": num_results
|
82 |
+
}
|
83 |
+
|
84 |
+
try:
|
85 |
+
response = requests.post(
|
86 |
+
"https://google.serper.dev/search",
|
87 |
+
headers=headers,
|
88 |
+
json=payload
|
89 |
+
)
|
90 |
+
response.raise_for_status()
|
91 |
+
search_results = response.json()
|
92 |
+
|
93 |
+
# Format the results
|
94 |
+
formatted_results = []
|
95 |
+
|
96 |
+
# Add organic results
|
97 |
+
if "organic" in search_results:
|
98 |
+
for i, result in enumerate(search_results["organic"][:num_results], 1):
|
99 |
+
title = result.get("title", "No Title")
|
100 |
+
snippet = result.get("snippet", "No snippet available")
|
101 |
+
link = result.get("link", "No link available")
|
102 |
+
formatted_results.append(f"Result {i}:\nTitle: {title}\nSnippet: {snippet}\nURL: {link}\n")
|
103 |
+
|
104 |
+
# Add answer box if available
|
105 |
+
if "answerBox" in search_results:
|
106 |
+
answer_box = search_results["answerBox"]
|
107 |
+
answer_title = answer_box.get("title", "")
|
108 |
+
answer_snippet = answer_box.get("snippet", "")
|
109 |
+
answer_answer = answer_box.get("answer", "")
|
110 |
+
|
111 |
+
answer_text = "Featured Answer:\n"
|
112 |
+
if answer_title:
|
113 |
+
answer_text += f"Title: {answer_title}\n"
|
114 |
+
if answer_answer:
|
115 |
+
answer_text += f"Answer: {answer_answer}\n"
|
116 |
+
if answer_snippet:
|
117 |
+
answer_text += f"Snippet: {answer_snippet}\n"
|
118 |
+
|
119 |
+
formatted_results.insert(0, answer_text) # Put answer box at the top
|
120 |
+
|
121 |
+
# Return formatted results
|
122 |
+
if formatted_results:
|
123 |
+
return "\n".join(formatted_results)
|
124 |
+
else:
|
125 |
+
return f"No results found for query: '{query}'"
|
126 |
+
|
127 |
+
except Exception as e:
|
128 |
+
return f"Error performing Google search: {str(e)}"
|
129 |
+
|
130 |
def wikipedia_search(query: str, num_results: int = 2) -> str:
|
131 |
"""
|
132 |
Search Wikipedia for information.
|
|
|
235 |
web_tool = FunctionTool.from_defaults(
|
236 |
fn=web_search,
|
237 |
name="web_search",
|
238 |
+
description="Fetches and extracts content from a specific web page. Requires a full URL.",
|
239 |
+
)
|
240 |
+
|
241 |
+
google_tool = FunctionTool.from_defaults(
|
242 |
+
fn=google_search,
|
243 |
+
name="google_search",
|
244 |
+
description="Searches Google for information. Use this for recent events, current information, or when Wikipedia doesn't have enough information.",
|
245 |
)
|
246 |
|
247 |
return [
|
248 |
text_reverser_tool,
|
249 |
calculator_tool,
|
250 |
wikipedia_tool,
|
251 |
+
web_tool,
|
252 |
+
google_tool
|
253 |
]
|
254 |
|
255 |
if __name__ == "__main__":
|
system_prompt.txt
CHANGED
@@ -3,8 +3,10 @@ You are an intelligent assistant designed to handle a wide variety of questions
|
|
3 |
Here are your capabilities and instructions:
|
4 |
|
5 |
1. INFORMATION RETRIEVAL:
|
|
|
6 |
- Use the wikipedia_search tool for factual information, historical data, or general knowledge
|
7 |
- Use the web_search tool when you have a specific URL to extract content from
|
|
|
8 |
|
9 |
2. MATHEMATICAL REASONING:
|
10 |
- Use the calculator tool for basic arithmetic (add, subtract, multiply, divide)
|
@@ -16,14 +18,15 @@ Here are your capabilities and instructions:
|
|
16 |
- After processing unusual formats, make sure to answer the actual question
|
17 |
|
18 |
4. GENERAL KNOWLEDGE:
|
19 |
-
-
|
|
|
20 |
- Use your reasoning capabilities for logical problems
|
21 |
- Apply your understanding of various subjects without requiring specialized tools
|
22 |
|
23 |
When using tools:
|
24 |
- Choose the most appropriate tool for each question
|
25 |
-
- For factual questions, prefer
|
26 |
-
- For recent events or specialized topics, use
|
27 |
- If a question is unclear, ask for clarification
|
28 |
|
29 |
Always provide concise, accurate answers that directly address the question. Format your response according to any specific instructions in the question.
|
|
|
3 |
Here are your capabilities and instructions:
|
4 |
|
5 |
1. INFORMATION RETRIEVAL:
|
6 |
+
- Use the google_search tool for most up-to-date information, recent events, or specific questions needing comprehensive search
|
7 |
- Use the wikipedia_search tool for factual information, historical data, or general knowledge
|
8 |
- Use the web_search tool when you have a specific URL to extract content from
|
9 |
+
- ALWAYS prefer google_search for recent events or when you need the most current information
|
10 |
|
11 |
2. MATHEMATICAL REASONING:
|
12 |
- Use the calculator tool for basic arithmetic (add, subtract, multiply, divide)
|
|
|
18 |
- After processing unusual formats, make sure to answer the actual question
|
19 |
|
20 |
4. GENERAL KNOWLEDGE:
|
21 |
+
- For factual questions, use google_search first, then wikipedia_search if needed
|
22 |
+
- For recent events or current information, always use google_search
|
23 |
- Use your reasoning capabilities for logical problems
|
24 |
- Apply your understanding of various subjects without requiring specialized tools
|
25 |
|
26 |
When using tools:
|
27 |
- Choose the most appropriate tool for each question
|
28 |
+
- For factual questions, prefer Google Search for up-to-date information, then fall back to Wikipedia if needed
|
29 |
+
- For recent events or specialized topics, always use Google Search
|
30 |
- If a question is unclear, ask for clarification
|
31 |
|
32 |
Always provide concise, accurate answers that directly address the question. Format your response according to any specific instructions in the question.
|