ChatOllama y paquete langchain-ollama
LangChain es un framework para orquestar llamadas a modelos de lenguaje, recuperación de documentos y lógica de aplicación en un mismo flujo. La integración con Ollama se hace a través del paquete langchain-ollama (PyPI). Dicho paquete proporciona la clase ChatOllama: un modelo de chat compatible con la API de mensajes de LangChain que usa por defecto tu instancia local de Ollama en http://localhost:11434.
Instala el paquete con
pip install langchain-ollama. El servidor de Ollama debe estar en marcha (por ejemplo con la aplicación de escritorio oollama serve) para que las peticiones funcionen.
Tras instalar, puedes crear una instancia del modelo e invocarla con una lista de mensajes (system, human, AI). El formato de mensajes sigue el estándar de LangChain: tuplas (role, content) o clases como HumanMessage y AIMessage.
Ejemplo básico de chat:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.2", temperature=0)
messages = [
("system", "Traduce al francés la frase del usuario."),
("human", "Me encanta programar en Python."),
]
response = llm.invoke(messages)
print(response.content)
Puedes usar modelos en la nube indicando el nombre con el sufijo :cloud (por ejemplo qwen3.5:cloud). En ese caso necesitas tener configurada la autenticación con Ollama Cloud (API key en cabeceras o ollama signin) para que LangChain envíe las peticiones al backend correcto.
Embeddings y uso en RAG
Además del chat, langchain-ollama ofrece integración con embeddings. Así puedes usar el mismo modelo de embeddings que ya utilizas con la API REST (por ejemplo nomic-embed-text) dentro de un flujo LangChain para indexar documentos y realizar búsqueda semántica antes de llamar al LLM.
En un flujo RAG típico:
- Indexar: dividir documentos en fragmentos y generar embeddings con Ollama. Guardar vectores en un almacén (en memoria, Chroma, etc.).
- Consultar: generar el embedding de la pregunta del usuario.
- Recuperar: obtener los fragmentos más similares al vector de la pregunta.
- Generar: construir un prompt con esos fragmentos como contexto y llamar a
ChatOllamapara obtener la respuesta.
flowchart LR
subgraph Indexación
D[Documentos] --> S[Splitter]
S --> E[Ollama Embeddings]
E --> V[(Vector Store)]
end
subgraph Consulta
Q[Pregunta] --> E2[Ollama Embeddings]
E2 --> R[Retriever]
V --> R
R --> C[Contexto]
C --> L[ChatOllama]
L --> A[Respuesta]
end
Usa el mismo modelo de embeddings para indexar y para la consulta. Así los vectores viven en el mismo espacio y la similitud (por ejemplo coseno) tiene sentido.
Ejemplo mínimo usando embeddings de Ollama y un retriever en memoria (en la práctica sustituirías el vector store por uno persistente según tu proyecto):
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_text_splitters import RecursiveCharacterTextSplitter
embedding = OllamaEmbeddings(model="nomic-embed-text")
llm = ChatOllama(model="llama3.2", temperature=0)
# Documentos de ejemplo (en un caso real, cargarías desde disco o base de datos)
docs = [
"Ollama expone una API REST en localhost:11434.",
"El endpoint /api/chat permite conversaciones con historial.",
"Los embeddings se obtienen con POST /api/embed.",
]
splits = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=50).split_text("\n".join(docs))
vectorstore = DocArrayInMemorySearch.from_texts(splits, embedding)
retriever = vectorstore.as_retriever(k=2)
template = """Responde solo con lo que digan los fragmentos. Contexto: {context}. Pregunta: {question}"""
prompt = ChatPromptTemplate.from_messages([("human", template)])
def format_docs(chunks):
return "\n".join(d.page_content for d in chunks)
chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
print(chain.invoke("¿En qué puerto escucha la API de Ollama?"))
La cadena combina recuperación (retriever), plantilla de prompt, ChatOllama y un parser de salida. El flujo es reutilizable para otras preguntas sobre los mismos documentos.
Cadenas, streaming y tool calling
Puedes componer ChatOllama con otros componentes de LangChain usando LCEL (LangChain Expression Language). Por ejemplo, encadenar un prompt fijo, el modelo y un parser para obtener texto plano. Con stream=True en la invocación (o usando el método de streaming del modelo) puedes consumir la respuesta por fragmentos.
ChatOllama soporta también tool calling: si tu modelo en Ollama soporta herramientas (por ejemplo gpt-oss o modelos con capacidad de tools), puedes usar bind_tools en LangChain y pasar definiciones de herramientas. El modelo devolverá llamadas a herramientas que tu código puede ejecutar y volver a inyectar en la conversación. Esto permite construir asistentes que consultan APIs, bases de datos o búsqueda web desde un único flujo LangChain.
Con langchain-ollama tienes ChatOllama para chat, OllamaEmbeddings para vectores y la posibilidad de montar cadenas RAG, con o sin tools, usando siempre tu instancia de Ollama en local o en la nube.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Ollama es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Ollama
Explora más contenido relacionado con Ollama y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Integrar Ollama en proyectos Python con LangChain usando ChatOllama, embeddings y cadenas, y aplicar patrones RAG con modelos locales o en la nube.
Cursos que incluyen esta lección
Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje