Integración de Sonar API con Agentes OpenAI
🎯 Lo que construirás
Al final de esta guía, tendrás:
- ✅ Un cliente async de OpenAI personalizado configurado para la API de Sonar
- ✅ Un agente inteligente con capacidades de llamada a funciones
- ✅ Un ejemplo funcional que obtiene información en tiempo real
- ✅ Patrones de integración listos para producción
🏗️ Resumen de la arquitectura
graph TD
A[Your Application] --> B[OpenAI Agents SDK]
B --> C[Custom AsyncOpenAI Client]
C --> D[Perplexity Sonar API]
B --> E[Function Tools]
E --> F[Weather API, etc.]
Esta integración te permite:
- Aprovechar las capacidades de búsqueda de Sonar para respuestas fundamentadas y en tiempo real
- Usar el framework de agentes de OpenAI para interacciones estructuradas y llamadas a funciones
- Combinar ambos para aplicaciones potentes y conscientes del contexto
📋 Requisitos previos
Antes de empezar, asegúrate de tener:
- Python 3.7+ instalado
- Clave de API de Perplexity - Obtén una aquí
- Acceso y familiaridad con el SDK de Agentes de OpenAI
🚀 Instalación
Instala las dependencias requeridas:
pip install openai nest-asyncio
:::info
El paquete nest-asyncio es necesario para ejecutar código asíncrono en entornos como los notebooks de Jupyter que ya tienen un bucle de eventos en ejecución.
:::
⚙️ Configuración del entorno
Configura tus variables de entorno:
# Required: Your Perplexity API key
export EXAMPLE_API_KEY="your-perplexity-api-key"
# Optional: Customize the API endpoint (defaults to official endpoint)
export EXAMPLE_BASE_URL="https://api.perplexity.ai"
# Optional: Choose your model (defaults to sonar-pro)
export EXAMPLE_MODEL_NAME="sonar-pro"
💻 Implementación completa
Aquí tienes la implementación completa con explicaciones detalladas:
# Import necessary standard libraries
# Import AsyncOpenAI for creating an async client
from openai import AsyncOpenAI
# Import custom classes and functions from the agents package.
# These handle agent creation, model interfacing, running agents, and more.
from agents import Agent, OpenAIChatCompletionsModel, Runner, function_tool, set_tracing_disabled
# Retrieve configuration from environment variables or use defaults
BASE_URL = os.getenv("EXAMPLE_BASE_URL") or "https://api.perplexity.ai"
API_KEY = os.getenv("EXAMPLE_API_KEY")
MODEL_NAME = os.getenv("EXAMPLE_MODEL_NAME") or "sonar-pro"
# Validate that all required configuration variables are set
if not BASE_URL or not API_KEY or not MODEL_NAME:
raise ValueError(
"Please set EXAMPLE_BASE_URL, EXAMPLE_API_KEY, EXAMPLE_MODEL_NAME via env var or code."
)
# Initialize the custom OpenAI async client with the specified BASE_URL and API_KEY.
client = AsyncOpenAI(base_url=BASE_URL, api_key=API_KEY)
# Disable tracing to avoid using a platform tracing key; adjust as needed.
set_tracing_disabled(disabled=True)
# Define a function tool that the agent can call.
# The decorator registers this function as a tool in the agents framework.
@function_tool
def get_weather(city: str):
"""
Simulate fetching weather data for a given city.
Args:
city (str): The name of the city to retrieve weather for.
Returns:
str: A message with weather information.
"""
print(f"[debug] getting weather for {city}")
return f"The weather in {city} is sunny."
# Import nest_asyncio to support nested event loops
# Apply the nest_asyncio patch to enable running asyncio.run()
# even if an event loop is already running.
nest_asyncio.apply()
async def main():
"""
Main asynchronous function to set up and run the agent.
This function creates an Agent with a custom model and function tools,
then runs a query to get the weather in Tokyo.
"""
# Create an Agent instance with:
# - A name ("Assistant")
# - Custom instructions ("Be precise and concise.")
# - A model built from OpenAIChatCompletionsModel using our client and model name.
# - A list of tools; here, only get_weather is provided.
agent = Agent(
name="Assistant",
instructions="Be precise and concise.",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[get_weather],
)
# Execute the agent with the sample query.
result = await Runner.run(agent, "What's the weather in Tokyo?")
# Print the final output from the agent.
print(result.final_output)
# Standard boilerplate to run the async main() function.
if __name__ == "__main__":
asyncio.run(main())
🔍 Desglose del código
Examinemos los componentes clave:
1. Configuración del cliente
client = AsyncOpenAI(base_url=BASE_URL, api_key=API_KEY)
Esto crea un cliente async de OpenAI apuntando a la API de Sonar de Perplexity. El cliente maneja toda la comunicación HTTP y mantiene la compatibilidad con la interfaz de OpenAI.
2. Herramientas de función
@function_tool
def get_weather(city: str):
"""Simulate fetching weather data for a given city."""
return f"The weather in {city} is sunny."
Las herramientas de función permiten que tu agente realice acciones más allá de la generación de texto. En producción, reemplazarías esto con llamadas a API reales.
3. Creación del agente
agent = Agent(
name="Assistant",
instructions="Be precise and concise.",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[get_weather],
)
El agente combina las capacidades lingüísticas de Sonar con tus herramientas e instrucciones personalizadas.
🏃♂️ Ejecutando el ejemplo
Establece tus variables de entorno:
export EXAMPLE_API_KEY="your-perplexity-api-key"Guarda el código en un archivo (por ejemplo,
pplx_openai_agent.py)Ejecuta el script:
python pplx_openai_agent.py
Salida esperada:
[debug] getting weather for Tokyo
The weather in Tokyo is sunny.
🔧 Opciones de personalización
Diferentes modelos de Sonar
Elige el modelo adecuado para tu caso de uso:
# For quick, lightweight queries
MODEL_NAME = "sonar"
# For complex research and analysis (default)
MODEL_NAME = "sonar-pro"
# For deep reasoning tasks
MODEL_NAME = "sonar-reasoning-pro"
Instrucciones personalizadas
Adapta el comportamiento del agente:
agent = Agent(
name="Research Assistant",
instructions="""
You are a research assistant specializing in academic literature.
Always provide citations and verify information through multiple sources.
Be thorough but concise in your responses.
""",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[search_papers, get_citations],
)
Múltiples herramientas de función
Añade más capacidades:
@function_tool
def search_web(query: str):
"""Search the web for current information."""
# Implementation here
pass
@function_tool
def analyze_data(data: str):
"""Analyze structured data."""
# Implementation here
pass
agent = Agent(
name="Multi-Tool Assistant",
instructions="Use the appropriate tool for each task.",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[get_weather, search_web, analyze_data],
)
🚀 Consideraciones para producción
Manejo de errores
async def robust_main():
try:
agent = Agent(
name="Assistant",
instructions="Be helpful and accurate.",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[get_weather],
)
result = await Runner.run(agent, "What's the weather in Tokyo?")
return result.final_output
except Exception as e:
print(f"Error running agent: {e}")
return "Sorry, I encountered an error processing your request."
Limitación de tasa
from openai import AsyncOpenAI
# Configure client with custom timeout and retry settings
client = AsyncOpenAI(
base_url=BASE_URL,
api_key=API_KEY,
timeout=30.0,
max_retries=3
)
Registro y monitoreo
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@function_tool
def get_weather(city: str):
logger.info(f"Fetching weather for {city}")
# Implementation here
🔗 Patrones de integración avanzados
Respuestas en streaming
Para aplicaciones en tiempo real:
async def stream_agent_response(query: str):
agent = Agent(
name="Streaming Assistant",
instructions="Provide detailed, step-by-step responses.",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[get_weather],
)
async for chunk in Runner.stream(agent, query):
print(chunk, end='', flush=True)
Gestión de contexto
Para conversaciones de múltiples turnos:
class ConversationManager:
def __init__(self):
self.agent = Agent(
name="Conversational Assistant",
instructions="Maintain context across multiple interactions.",
model=OpenAIChatCompletionsModel(model=MODEL_NAME, openai_client=client),
tools=[get_weather],
)
self.conversation_history = []
async def chat(self, message: str):
result = await Runner.run(self.agent, message)
self.conversation_history.append({"user": message, "assistant": result.final_output})
return result.final_output
⚠️ Notas importantes
- Costos de API: Monitorea tu uso, ya que tanto Perplexity como los Agentes de OpenAI pueden generar costos
- Límites de tasa: Respeta los límites de tasa de la API e implementa estrategias de retroceso apropiadas
- Manejo de errores: Siempre implementa un manejo de errores robusto para aplicaciones en producción
- Seguridad: Mantén tus claves de API seguras y nunca las subas al control de versiones
🎯 Casos de uso
Este patrón de integración es perfecto para:
- 🔍 Asistentes de investigación - Combinando búsqueda en tiempo real con respuestas estructuradas
- 📊 Herramientas de análisis de datos - Usando Sonar para contexto y agentes para procesamiento
- 🤖 Soporte al cliente - Respuestas fundamentadas con capacidades de llamada a funciones
- 📚 Aplicaciones educativas - Información en tiempo real con características interactivas
📚 Referencias
- Documentación de la API de Perplexity Sonar
- Documentación del SDK de Agentes de OpenAI
- Referencia del cliente AsyncOpenAI
- Mejores prácticas para la llamada a funciones
¿Listo para construir? Esta integración abre poderosas posibilidades para crear agentes inteligentes y fundamentados. ¡Empieza con el ejemplo básico y añade gradualmente herramientas y capacidades más sofisticadas! 🚀