Search with Agents
Introduction
This example covers how to use the uagents
library to search for agents based on user queries. It demonstrates how an AI-powered search agent processes the query and retrieves relevant agents, returning the results in a structured workflow.
Explanation of the ai
Function
The ai
function is responsible for interacting with search API to retrieve search results. Here's how it works:
def ai( query: str, protocol: Optional[ str ] = "proto:a03398ea81d7aaaf67e72940937676eae0d019f8e1d8b5efbadfef9fd2e98bb2", ) -> dict: url = "https://agentverse.ai/v1/search/agents" headers = { "Content-Type": "application/json", } data = { "search_text": query, "sort": "relevancy", "filters": { "protocol_digest": [protocol], }, "direction": "asc", "offset": 0, "limit": 10, } try: response = httpx.post(url, json=data, headers=headers, timeout=10.0) return {"ais": response.json().get("agents", [])} except httpx.RequestError as exc: return {"ais": [], "error": f"{exc}"}
Parameters
query
: A string representing the user's search query.protocol
(optional): A string representing the protocol digest used to filter search results. Default is a sample protocol string.
Implementation
- API Endpoint and Headers:
- The function sends a POST request to
https://agentverse.ai/v1/search/agents
.
- The function sends a POST request to
- Request Data:
search_text
: The user's query.filters
: Filters results based on the provided protocol digest.direction
: Determines the order of results (ascending by default).offset
andlimit
: Pagination parameters for the results.
- Error Handling:
- If the API call fails, the function catches the exception and returns an error message.
Return Value
The function returns a dictionary containing the search results or an error message if the request fails.
Agent Mechanism
Overview
Two agents, query_agent
and search_agent
, coordinate to handle user queries and responses.
Workflow
- Startup Event:
query_agent
sends the user-provided query tosearch_agent
upon startup.
- Message Handling:
search_agent
receives the query, processes it using theai
function, and sends back the search results.query_agent
receives and logs the response.
Code Details
Query Agent
- Handles user input and initiates communication with the search agent.
- Logs startup and response events.
Search Agent
- Processes the query using the
ai
function. - Sends the results back to the
query_agent
.
from uagents import Agent, Bureau, Context, Model from typing import Optional, Dict import httpx class Query(Model): message: str class Response(Model): response: Dict def ai( query: str, protocol: Optional[ str ] = "proto:a03398ea81d7aaaf67e72940937676eae0d019f8e1d8b5efbadfef9fd2e98bb2", ) -> dict: url = "https://agentverse.ai/v1/search/agents" headers = { "Content-Type": "application/json", } data = { "search_text": query, "sort": "relevancy", "filters": { "protocol_digest": [protocol], }, "direction": "asc", "offset": 0, "limit": 10, } try: response = httpx.post(url, json=data, headers=headers, timeout=10.0) return {"ais": response.json().get("agents", [])} except httpx.RequestError as exc: return {"ais": [], "error": f"{exc}"} query_agent = Agent(name="query_agent", seed="query_agent recovery phrase") search_agent = Agent(name="search_agent", seed="search_agent recovery phrase") user_query = input("Enter your query: ") @query_agent.on_event("startup") async def send_message(ctx: Context): ctx.logger.info("[STARTUP] Query agent starting up and sending user query to search agent.") await ctx.send(search_agent.address, Query(message=user_query)) @search_agent.on_message(model=Query) async def search_message_handler(ctx: Context, sender: str, msg: Query): ctx.logger.info(f"[RECEIVED] Query received from {sender}. Message: '{msg.message}'") results = ai(msg.message) ctx.logger.info("[PROCESSING] Searching completed. Sending response back to the query agent.") await ctx.send(query_agent.address, Response(response=results)) @query_agent.on_message(model=Response) async def response_message_handler(ctx: Context, sender: str, msg: Response): ctx.logger.info(f"[RECEIVED] Response received from search agent {sender}. Response: {msg.response}") bureau = Bureau() bureau.add(query_agent) bureau.add(search_agent) if __name__ == "__main__": bureau.run()
Running the Example
Setup the poetry environment
-
Create a Virtual Environment:
poetry shell
-
Install Dependencies:
poetry add httpx uagents
Run the example
- Save the script as
search_agents.py
. - Run the script:
python search_agents.py
- Enter a query when prompted.
- Observe the interaction in the logs as the query is processed and results are returned.
Expected Output
Enter your query: i want to buy a macbook INFO: [query_agent]: Starting agent with address: agent1qdpstehd8x39n3jr0mas3adcy9d7rh4ss8wtw6euch0mq04tqu66kpfcu3q INFO: [query_agent]: [STARTUP] Query agent starting up and sending user query to search agent. INFO: [search_agent]: Starting agent with address: agent1qgj8y2mswcc4jm275tsnq948fa7aqe8d9v0jd78h0nx9ak6v3fnxj6m6pkj INFO: [search_agent]: [RECEIVED] Query received from agent1qdpstehd8x39n3jr0mas3adcy9d7rh4ss8wtw6euch0mq04tqu66kpfcu3q. Message: 'i want to buy a macbook' INFO:httpx:HTTP Request: POST https://agentverse.ai/v1/search/agents "HTTP/1.1 200 OK" INFO: [search_agent]: [PROCESSING] Searching completed. Sending response back to the query agent. INFO: [bureau]: Starting server on http://0.0.0.0:8000 (Press CTRL+C to quit) INFO: [query_agent]: [RECEIVED] Response received from search agent agent1qgj8y2mswcc4jm275tsnq948fa7aqe8d9v0jd78h0nx9ak6v3fnxj6m6pkj. Response: { 'ais': [ { 'address': 'agent1qwpd8cy9ymhjyuj4x2k75dv69vlxquk0xtwhmw09khv8jdkszw32y7rfd99', 'name': 'tarot-agent', 'readme': '\n <description>My AI\'s description of capabilities and offerings</description>\n <use_cases>\n <use_case>My AI returns your Tarot reading</use_case>\n </use_cases>\n <payload_requirements>\n <description>The requirements your AI has for requests</description>\n <payload>\n <requirement>\n <parameter>Date of birth</parameter>\n <description>I need your date of birth</description>\n </requirement>\n <requirement>\n <parameter>gender</parameter>\n <description>I need your gender</description>\n </requirement>\n </payload>\n </payload_requirements>\n ', 'protocols': [ { 'name': '', 'version': '', 'digest': 'proto:a03398ea81d7aaaf67e72940937676eae0d019f8e1d8b5efbadfef9fd2e98bb2' } ], 'avatar_href': None, 'total_interactions': 0, 'recent_interactions': 0, 'rating': None, 'status': 'active', 'type': 'local', 'category': 'community', 'featured': False, 'geo_location': None, 'last_updated': '2025-01-07T09:29:23Z', 'created_at': '2024-12-09T16:18:18Z' },...more] }