> For the complete documentation index, see [llms.txt](https://saptiva.gitbook.io/saptiva-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://saptiva.gitbook.io/saptiva-docs/saptiva-agents/guia-de-componentes/cliente-de-modelo.md).

# Cliente De Modelo

**Saptiva-Agents** proporciona un cliente de modelo integrado para usar la API de ChatCompletion. Todos los clientes de modelo implementan la clase protocolo `ChatCompletionClient`.

Actualmente soportamos los siguientes clientes de modelo integrados:

* **SaptivaAIChatCompletionClient**: para modelos de Saptiva alojados en Ollama y modelos compatibles con la API de OpenAI.

***

### Llamar a un Registro de Modelo

**Saptiva-Agents** usa el módulo estándar de logging de Python para registrar eventos como llamadas y respuestas del modelo. El nombre del logger es `autogen_core.EVENT_LOGGER_NAME`, y el tipo de evento es `LLMCall`.

```python
import logging

from saptiva_agents.core import EVENT_LOGGER_NAME

logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(EVENT_LOGGER_NAME)
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.INFO)
```

***

### Llamar a un Cliente de Modelo

Para llamar a un cliente de modelo, puedes usar el método `create()`. Este ejemplo utiliza `SaptivaAIChatCompletionClient` para llamar a un modelo de OpenAI.

```python
from saptiva_agents.models import UserMessage
from saptiva_agents.base import SaptivaAIChatCompletionClient

model_client = SaptivaAIChatCompletionClient(
    model="Saptiva Legacy", temperature=0.3, apy_key="TU_SAPTIVA_API_KEY"
)

result = await model_client.create([UserMessage(content="What is the capital of France?", source="user")])
print(result)
```

```
finish_reason='stop' content='The capital of France is Paris.' usage=RequestUsage(prompt_tokens=15, completion_tokens=8) cached=False logprobs=None thought=None
```

***

### Transmisión de Tokens

Puedes usar el método `create_stream()` para crear una solicitud de chat con transmisión de tokens.

```python
from saptiva_agents.models import CreateResult, UserMessage
from saptiva_agents.base import SaptivaAIChatCompletionClient

model_client = SaptivaAIChatCompletionClient(
    model="Saptiva Legacy", temperature=0.3, apy_key="TU_SAPTIVA_API_KEY"
)

messages = [
    UserMessage(content="Write a very short story about a dragon.", source="user"),
]

# Crear un stream.
stream = model_client.create_stream(messages=messages)

# Iterar sobre el stream e imprimir las respuestas.
print("Streamed responses:")
async for chunk in stream:  # type: ignore
    if isinstance(chunk, str):
        # El fragmento es una cadena.
        print(chunk, flush=True, end="")
    else:
        # El fragmento final es un objeto CreateResult.
        assert isinstance(chunk, CreateResult) and isinstance(chunk.content, str)
        # La última respuesta es un CreateResult con el mensaje completo.
        print("\n\n------------\n")
        print("The complete response:", flush=True)
        print(chunk.content, flush=True)
```

```
Streamed responses:
In the heart of an ancient forest, beneath the shadow of snow-capped peaks, a dragon named Elara lived secretly for centuries. Elara was unlike any dragon from the old tales; her scales shimmered with a deep emerald hue, each scale engraved with symbols of lost wisdom. The villagers in the nearby valley spoke of mysterious lights dancing across the night sky, but none dared venture close enough to solve the enigma.

One cold winter's eve, a young girl named Lira, brimming with curiosity and armed with the innocence of youth, wandered into Elara’s domain. Instead of fire and fury, she found warmth and a gentle gaze. The dragon shared stories of a world long forgotten and in return, Lira gifted her simple stories of human life, rich in laughter and scent of earth.

From that night on, the villagers noticed subtle changes—the crops grew taller, and the air seemed sweeter. Elara had infused the valley with ancient magic, a guardian of balance, watching quietly as her new friend thrived under the stars. And so, Lira and Elara’s bond marked the beginning of a timeless friendship that spun tales of hope whispered through the leaves of the ever-verdant forest.

------------

The complete response:
In the heart of an ancient forest, beneath the shadow of snow-capped peaks, a dragon named Elara lived secretly for centuries. Elara was unlike any dragon from the old tales; her scales shimmered with a deep emerald hue, each scale engraved with symbols of lost wisdom. The villagers in the nearby valley spoke of mysterious lights dancing across the night sky, but none dared venture close enough to solve the enigma.

One cold winter's eve, a young girl named Lira, brimming with curiosity and armed with the innocence of youth, wandered into Elara’s domain. Instead of fire and fury, she found warmth and a gentle gaze. The dragon shared stories of a world long forgotten and in return, Lira gifted her simple stories of human life, rich in laughter and scent of earth.

From that night on, the villagers noticed subtle changes—the crops grew taller, and the air seemed sweeter. Elara had infused the valley with ancient magic, a guardian of balance, watching quietly as her new friend thrived under the stars. And so, Lira and Elara’s bond marked the beginning of a timeless friendship that spun tales of hope whispered through the leaves of the ever-verdant forest.


------------

The token usage was:
RequestUsage(prompt_tokens=0, completion_tokens=0)
```

{% hint style="info" %}
Nota

La última respuesta en la transmisión siempre es de tipo `CreateResult`.
{% endhint %}

***

### Salida Estructurada

La salida estructurada puede habilitarse estableciendo el campo `response_format` en `OpenAIChatCompletionClient` o `AzureOpenAIChatCompletionClient` como una clase `BaseModel` de Pydantic.

{% hint style="info" %}
Nota

La salida estructurada solo está disponible para modelos que la soporten y también requiere que el cliente de modelo la soporte.
{% endhint %}

```python
from typing import Literal
from pydantic import BaseModel

# El formato de respuesta como un modelo base de Pydantic.
class AgentResponse(BaseModel):
    thoughts: str
    response: Literal["happy", "sad", "neutral"]

model_client = SaptivaAIChatCompletionClient(
    model="Saptiva Legacy", 
    response_format=AgentResponse,  # type: ignore
)

messages = [
    UserMessage(content="I am happy.", source="user"),
]
response = await model_client.create(messages=messages)
parsed_response = AgentResponse.model_validate_json(response.content)
print(parsed_response.thoughts)
print(parsed_response.response)
await model_client.close()
```

También puedes usar el parámetro `extra_create_args` en `create()` para establecer `response_format` por solicitud.

***

### Construir un Agente con un Cliente de Modelo

Creamos un agente simple de IA que responde usando la API `ChatCompletion`.

```python
from dataclasses import dataclass
from saptiva_agents.core import MessageContext, RoutedAgent, SingleThreadedAgentRuntime, message_handler
from saptiva_agents.models import ChatCompletionClient, SystemMessage, UserMessage
from saptiva_agents.base import SaptivaAIChatCompletionClient


@dataclass
class Message:
    content: str


class SimpleAgent(RoutedAgent):
    def __init__(self, model_client: ChatCompletionClient) -> None:
        super().__init__("A simple agent")
        self._system_messages = [SystemMessage(content="You are a helpful AI assistant.")]
        self._model_client = model_client

    @message_handler
    async def handle_user_message(self, message: Message, ctx: MessageContext) -> Message:
        # Preparar entrada para el modelo de chat.
        user_message = UserMessage(content=message.content, source="user")
        response = await self._model_client.create(
            self._system_messages + [user_message], cancellation_token=ctx.cancellation_token
        )
        # Retornar la respuesta del modelo.
        assert isinstance(response.content, str)
        return Message(content=response.content)
```

La clase `SimpleAgent` es una subclase de `saptiva_agents.core.RoutedAgent`, lo que proporciona la conveniencia de enrutar automáticamente los mensajes a los controladores correspondientes. Tiene un único controlador, `handle_user_message`, que maneja mensajes del usuario. Utiliza el `ChatCompletionClient` para generar una respuesta al mensaje y luego devuelve dicha respuesta al usuario, siguiendo el modelo de comunicación directa.

{% hint style="info" %}
Nota

El `cancellation_token` del tipo `saptiva_agents.core.CancellationToken` se utiliza para cancelar operaciones asíncronas. Está vinculado a llamadas async dentro de los controladores de mensajes y puede ser utilizado por quien llama para cancelar dichos controladores.
{% endhint %}

***

### Crear y Probar el Agente:

```python
from saptiva_agents.core import AgentId

model_client = SaptivaAIChatCompletionClient(
    model="Saptiva Legacy",
    api_key="TU_SAPTIVA_API_KEY",
)

runtime = SingleThreadedAgentRuntime()
await SimpleAgent.register(
    runtime,
    "simple_agent",
    lambda: SimpleAgent(model_client=model_client),
)

runtime.start()
message = Message("Hello, what are some fun things to do in Seattle?")
response = await runtime.send_message(message, AgentId("simple_agent", "default"))
print(response.content)
await runtime.stop()
await model_client.close()
```

```
Seattle is a vibrant city with a wide range of activities and attractions. Here are some fun things to do in Seattle:

1. **Space Needle**: Visit this iconic observation tower for stunning views of the city and surrounding mountains.

2. **Pike Place Market**: Explore this historic market where you can see the famous fish toss, buy local produce, and find unique crafts and eateries.

3. **Museum of Pop Culture (MoPOP)**: Dive into the world of contemporary culture, music, and science fiction at this interactive museum.

4. **Chihuly Garden and Glass**: Marvel at the beautiful glass art installations by artist Dale Chihuly, located right next to the Space Needle.

5. **Seattle Aquarium**: Discover the diverse marine life of the Pacific Northwest at this engaging aquarium.

6. **Seattle Art Museum**: Explore a vast collection of art from around the world, including contemporary and indigenous art.

7. **Kerry Park**: For one of the best views of the Seattle skyline, head to this small park on Queen Anne Hill.

8. **Ballard Locks**: Watch boats pass through the locks and observe the salmon ladder to see salmon migrating.

9. **Ferry to Bainbridge Island**: Take a scenic ferry ride across Puget Sound to enjoy charming shops, restaurants, and beautiful natural scenery.

10. **Olympic Sculpture Park**: Stroll through this outdoor park with large-scale sculptures and stunning views of the waterfront and mountains.

11. **Underground Tour**: Discover Seattle's history on this quirky tour of the city's underground passageways in Pioneer Square.

12. **Seattle Waterfront**: Enjoy the shops, restaurants, and attractions along the waterfront, including the Seattle Great Wheel and the aquarium.

13. **Discovery Park**: Explore the largest green space in Seattle, featuring trails, beaches, and views of Puget Sound.

14. **Food Tours**: Try out Seattle’s diverse culinary scene, including fresh seafood, international cuisines, and coffee culture (don’t miss the original Starbucks!).

15. **Attend a Sports Game**: Catch a Seahawks (NFL), Mariners (MLB), or Sounders (MLS) game for a lively local experience.

Whether you're interested in culture, nature, food, or history, Seattle has something for everyone to enjoy!
```

El `SimpleAgent` anterior siempre responde con un contexto nuevo que contiene solo el mensaje del sistema y el mensaje más reciente del usuario. <br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://saptiva.gitbook.io/saptiva-docs/saptiva-agents/guia-de-componentes/cliente-de-modelo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
