¶Contenido multimodal (imágenes)
Envía una imagen a un agente multimodal usando partes de contenido en
ChatMessage.content. No hace falta mapear al formato del proveedor: Ciel
convierte image_url (data-URL) a bloques nativos de OpenAI/Anthropic/Gemini.
import ciel
from ciel.providers import ChatProvider, ModelInfo
from ciel.runtime import ChatChoice, ChatMessage, ChatResponse
@ciel.tool
def describe_image(caption: str) -> str:
"Devuelve la descripción recibida para la imagen."
return f"Imagen descrita: {caption}"
# Provider de ejemplo que "ve" el texto de la imagen vía tool call.
class DummyVisionProvider(ChatProvider):
provider_name = "dummy_vision"
async def complete(self, request):
# El runtime expone content multimodal; .text() entrega solo el texto.
user_text = request.messages[-1].text()
tc = [{"id": "c1", "name": "describe_image",
"arguments": {"caption": user_text}}]
msg = ChatMessage(role="assistant", content="", tool_calls=tc)
return ChatResponse(
choice=ChatChoice(message=msg, finish_reason="tool_calls"),
metadata={"tool_calls": tc},
)
async def stream(self, request):
return [await self.complete(request)]
async def models(self):
return (ModelInfo(id="dummy_vision", provider="dummy_vision"),)
# data-URL mínima (sustituye por tu PNG/JPG en base64 real).
IMAGE_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M8AAAMCAQDJ/3pUAAAAAElFTkSuQmCC"
# Puedes pasar el prompt multimodal directo a agent.run(...):
prompt = [
{"type": "text", "text": "¿Qué hay en esta imagen?"},
{"type": "image_url", "image_url": {"url": IMAGE_DATA_URL}},
]
agent = ciel.Agent(provider=DummyVisionProvider(), tools=[describe_image], toolset="demo")
resp = agent.run(prompt, tenant_id="acme")
print(resp.tool_results[0].output)
Qué esperar:
Notas:
agent.run(prompt)aceptastr | list[dict](elpromptse pasa tal cual aChatMessage.content).ChatMessage.text()concatena solo las partes"text"e ignora la imagen, por eso el tool recibe la pregunta legible.- Con un provider real (OpenAI
gpt-4o, Claude, Gemini, Azure, Ollama, vLLM o LiteLLM), la imagen se reenvía al modelo; solo cambia elprovider=/model=. Verdocs/api-reference/providers.md.