Ollama con LangChain en Python

Intermedio
Ollama
Ollama
Actualizado: 27/03/2026

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 o ollama 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:

  1. Indexar: dividir documentos en fragmentos y generar embeddings con Ollama. Guardar vectores en un almacén (en memoria, Chroma, etc.).
  2. Consultar: generar el embedding de la pregunta del usuario.
  3. Recuperar: obtener los fragmentos más similares al vector de la pregunta.
  4. Generar: construir un prompt con esos fragmentos como contexto y llamar a ChatOllama para 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 - Autor del tutorial

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