Antler by Autoflux

Examples

End-to-end walkthroughs: chat, RAG, agents with tools, streaming, and structured output.

Path: examples

Third-party documentation. This is independently authored analysis of the public LangChain codebase — not the official docs, and not reviewed or endorsed by the LangChain team.

Examples

The examples in this module's manifest cover the four shapes that cover ~90% of real LangChain applications: a chat pipeline, retrieval-augmented generation, an agent with tool-calling, and structured (JSON) output. All use the same LCEL composition and the same constructor pattern for the model.

From example to production

Each example is deliberately minimal. The production version of each adds the same four things:

  • Tracing — a LangSmith project so every prompt/call is inspectable.
  • Error handling — retry parsers, fallback models, and timeouts around invoke.
  • Persistence — a real vector store (pgvector, Pinecone, Weaviate) instead of an in-memory FAISS index for RAG.
  • Concurrencybatch/abatch where throughput matters.

The example code is what you'd run in a notebook first; the production hardening is mechanical on top of the same shapes.

Examples

A minimal chat pipeline

A minimal chat pipeline
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
 
prompt = ChatPromptTemplate.from_messages([
("system", "You are a concise assistant."),
("human", "{question}"),
])
model = ChatOpenAI(model="gpt-4o-mini")
parser = StrOutputParser()
 
chain = prompt | model | parser
 
print(chain.invoke({"question": "What is LCEL?"}))
STATUSexample

Three runnables composed with |. invoke() runs them in sequence; stream()/ainvoke() work on the same object with no rewiring.

Retrieval-augmented generation

Retrieval-augmented generation
python
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
 
# 1. Load + split
loader = TextLoader("notes.txt")
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(docs)
 
# 2. Embed + index
vectorstore = FAISS.from_documents(chunks, OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
 
# 3. Prompt + generation chain
prompt = ChatPromptTemplate.from_template("""Answer using only this context:\n{context}\n\nQuestion: {input}""")
llm = ChatOpenAI(model="gpt-4o-mini")
combine = create_stuff_documents_chain(llm, prompt)
 
# 4. Retrieval chain
rag = create_retrieval_chain(retriever, combine)
 
result = rag.invoke({"input": "What is the refund policy?"})
print(result["answer"])
STATUSexample

The classic RAG flow: split → embed → index → retrieve → stuff-into-prompt → generate. create_retrieval_chain wires retrieval into the answer step.

An agent with tool-calling

An agent with tool-calling
python
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
 
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
# ... call a weather API ...
return f"Sunny, 22C in {city}"
 
tools = [get_weather]
model = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
 
agent = create_tool_calling_agent(model, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)
 
print(executor.invoke({"input": "What's the weather in Lisbon?"}))
STATUSexample

The agent loop: the model decides to call a tool, the tool result feeds back in, until the model returns a final answer.

Structured output (JSON) from the model

Structured output (JSON) from the model
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel
 
class Article(BaseModel):
title: str
summary: str
tags: list[str]
 
parser = JsonOutputParser(pydantic_object=Article)
prompt = ChatPromptTemplate.from_template(
"Summarize the article into JSON.\n{format_instructions}\n\n{input}"
)
 
chain = prompt | ChatOpenAI(model="gpt-4o-mini") | parser
 
result = chain.invoke({
"input": "LangChain is a framework for LLM apps.",
"format_instructions": parser.get_format_instructions(),
})
print(result) # -> {"title": ..., "summary": ..., "tags": [...]}
STATUSexample

JsonOutputParser drives the model toward a validated Pydantic shape — no manual JSON parsing, and failures surface as parser errors.

Edge Cases

  • Empty retrieval results produce a context-free answer rather than an error — check whether the retriever actually returned documents before trusting the answer.
  • Tool-calling agents can loop if a tool keeps returning empty/ambiguous output — set max_iterations and add a stop condition to AgentExecutor.
  • Structured output parsers fail loudly on malformed model output; wrap them with retry logic or fall back to plain-text generation for critical paths.