Back to blog
    LangChain + Modelo Local Ajustado: Construye Pipelines Sin Costos de API
    langchainlocal-modelollamapipelinefine-tuningsegment:vibecoder

    LangChain + Modelo Local Ajustado: Construye Pipelines Sin Costos de API

    LangChain funciona con cualquier API compatible con OpenAI — incluyendo Ollama. Reemplaza las llamadas API en tus pipelines de LangChain con un modelo local ajustado. Misma estructura de cadena, cero costos por token.

    EErtas Team·

    LangChain es el framework más ampliamente usado para construir pipelines de IA: procesamiento de documentos, RAG, agentes, cadenas. La mayoría de los tutoriales de LangChain apuntan a la API de OpenAI. Tus facturas de producción lo reflejan.

    LangChain soporta modelos locales vía Ollama — y la interfaz compatible con OpenAI de Ollama significa que puedes intercambiar el backend de IA en un pipeline de LangChain con cambios mínimos de código. Combina esto con un modelo ajustado, y obtienes pipelines que son más rápidos para tareas de dominio, más baratos a escala, y privados por defecto.

    Opciones de Integración LangChain + Ollama

    LangChain tiene dos rutas de integración para Ollama:

    Opción 1: ChatOllama (nativo de LangChain)

    from langchain_ollama import ChatOllama
    
    llm = ChatOllama(
        model="your-fine-tuned-model",
        base_url="http://localhost:11434",
        temperature=0.3
    )
    
    # Use exactly like ChatOpenAI
    response = llm.invoke("Generate a listing for this property: ...")
    print(response.content)
    

    Opción 2: ChatOpenAI con URL base de Ollama (preferida para reemplazo directo)

    from langchain_openai import ChatOpenAI
    
    llm = ChatOpenAI(
        model="your-fine-tuned-model",
        base_url="http://localhost:11434/v1",
        api_key="ollama",  # Required field, not validated
        temperature=0.3
    )
    
    # Identical interface to cloud ChatOpenAI
    

    La Opción 2 es la migración más limpia: si ya tienes código de LangChain usando ChatOpenAI, los únicos cambios son base_url y model.

    Patrones Comunes de Pipeline

    Patrón 1: Cadena de Procesamiento de Documentos

    Antes (API de GPT-4):

    from langchain_openai import ChatOpenAI
    from langchain.chains import LLMChain
    from langchain.prompts import PromptTemplate
    
    llm = ChatOpenAI(model="gpt-4o")  # $0.005/1K input tokens
    
    template = PromptTemplate.from_template(
        "Classify this support ticket:\n{ticket}\nOutput: category, priority, suggested_response"
    )
    chain = LLMChain(llm=llm, prompt=template)
    
    result = chain.invoke({"ticket": ticket_text})
    

    Después (Modelo local ajustado):

    from langchain_openai import ChatOpenAI
    from langchain.chains import LLMChain
    from langchain.prompts import PromptTemplate
    
    # One line change
    llm = ChatOpenAI(
        model="support-classifier-v3",  # Your fine-tuned classifier
        base_url="http://localhost:11434/v1",
        api_key="ollama"
    )
    
    # Chain definition is UNCHANGED
    template = PromptTemplate.from_template(
        "Classify this support ticket:\n{ticket}\nOutput: category, priority, suggested_response"
    )
    chain = LLMChain(llm=llm, prompt=template)
    
    result = chain.invoke({"ticket": ticket_text})
    

    Procesando 10,000 tickets de soporte:

    • Antes: 10,000 x $0.005 = $50 en costos de API
    • Después: $50 en VPS mensual, amortizado a través de todo el procesamiento

    Patrón 2: Pipeline RAG Con Lector Ajustado

    Para Generación Aumentada por Recuperación (RAG), frecuentemente quieres que tanto el modelo de recuperación (embeddings) como el modelo lector (generación de respuestas) estén calibrados a tu dominio.

    from langchain_openai import ChatOpenAI, OpenAIEmbeddings
    from langchain.chains import RetrievalQA
    from langchain_chroma import Chroma
    
    # Local embeddings via Ollama (nomic-embed-text works well)
    embeddings = OpenAIEmbeddings(
        model="nomic-embed-text",
        base_url="http://localhost:11434/v1",
        api_key="ollama"
    )
    
    # Fine-tuned reader model
    reader_llm = ChatOpenAI(
        model="your-domain-reader-model",
        base_url="http://localhost:11434/v1",
        api_key="ollama"
    )
    
    # Build vector store from your documents
    vectorstore = Chroma.from_documents(
        documents=your_docs,
        embedding=embeddings,
        persist_directory="./chroma_db"
    )
    
    # RAG chain — zero cloud API calls at inference time
    qa_chain = RetrievalQA.from_chain_type(
        llm=reader_llm,
        retriever=vectorstore.as_retriever(search_kwargs={"k": 5})
    )
    
    answer = qa_chain.invoke({"query": "What is our return policy for sale items?"})
    

    Tanto los embeddings como la generación ocurren localmente. El modelo de recuperación entiende la terminología de tu dominio. El modelo lector está ajustado en el Q&A de tu dominio. Cero llamadas API.

    Patrón 3: Agente LangGraph Con Ejecutor de Herramientas Local

    LangGraph (el framework de agentes de LangChain) funciona con cualquier LLM compatible con LangChain:

    from langgraph.graph import StateGraph, END
    from langchain_openai import ChatOpenAI
    from langchain_core.messages import HumanMessage
    
    # Agent uses local model for orchestration
    orchestrator = ChatOpenAI(
        model="your-orchestrator-model",  # Or use Claude/GPT-4 for orchestration
        base_url="http://localhost:11434/v1",
        api_key="ollama"
    )
    
    # Tool executor uses specialized fine-tuned model
    domain_executor = ChatOpenAI(
        model="your-domain-model",
        base_url="http://localhost:11434/v1",
        api_key="ollama"
    )
    
    def run_domain_task(state):
        task = state["current_task"]
        result = domain_executor.invoke(task)
        return {"result": result.content}
    
    # Build graph
    graph = StateGraph(dict)
    graph.add_node("domain_executor", run_domain_task)
    # ... add orchestration logic
    
    app = graph.compile()
    

    Ajuste de Rendimiento para LangChain + Ollama

    Procesamiento por lotes: Para procesamiento masivo (clasificar 5,000 tickets), usa el método batch de LangChain que paraleliza llamadas:

    # Process 100 tickets concurrently
    results = await chain.abatch(
        [{"ticket": t} for t in tickets],
        config={"max_concurrency": 10}  # 10 concurrent Ollama calls
    )
    

    Caché: Habilita el caché semántico de LangChain para evitar llamadas redundantes al modelo:

    from langchain.globals import set_llm_cache
    from langchain_community.cache import SQLiteCache
    
    set_llm_cache(SQLiteCache(database_path=".langchain.db"))
    # Identical prompts return cached results — no Ollama call needed
    

    Longitud de contexto: Los modelos 7B típicamente soportan 4K-8K de contexto. Para procesamiento de documentos largos, usa los text splitters de LangChain para fragmentar antes de pasar al modelo.

    Cuándo Usar Local Ajustado vs Nube en Pipelines de LangChain

    TareaLocal AjustadoNube (GPT-4)
    Clasificación de dominioMejor + más baratoExcesivo
    Generación de dominioMejor + más baratoExcesivo
    Cadenas de razonamiento complejoConsiderarMejor
    Eventos actuales / webNo aplicaRequerido
    Lotes de alto volumenMucho más baratoCostoso
    Único / bajo volumenCualquieraCualquiera

    Ship AI that runs on your users' devices.

    Ertas early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Lectura Adicional

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading