Labsco
langchain-ai logo

langchain-fundamentals

846

by langchain-ai · part of langchain-ai/langchain-skills

Build production LangChain agents with create_agent(), tools, and middleware patterns. Use create_agent() with model, tools list, and system prompt; configure state persistence with checkpointer and thread_id for conversation memory across invocations Define tools via @tool decorator (Python) or tool() function (TypeScript) with clear descriptions so agents know when to call them Add middleware like HumanInTheLoopMiddleware for approval workflows, custom error handling, and human-in-the-loop...

🔥🔥🔥🔥✓ VerifiedFreeQuick setup
🧩 One of 7 skills in the langchain-ai/langchain-skills package — works on its own, and pairs well with its siblings.

Build production LangChain agents with create_agent(), tools, and middleware patterns. Use create_agent() with model, tools list, and system prompt; configure state persistence with checkpointer and thread_id for conversation memory across invocations Define tools via @tool decorator (Python) or tool() function (TypeScript) with clear descriptions so agents know when to call them Add middleware like HumanInTheLoopMiddleware for approval workflows, custom error handling, and human-in-the-loop...

Inspect the full instructions your agent will receiveExpand

This is the exact playbook injected into your agent when the skill activates — shown here so you can audit it before installing. You don't need to read it to use the skill.

by langchain-ai

Build production LangChain agents with create_agent(), tools, and middleware patterns. Use create_agent() with model, tools list, and system prompt; configure state persistence with checkpointer and thread_id for conversation memory across invocations Define tools via @tool decorator (Python) or tool() function (TypeScript) with clear descriptions so agents know when to call them Add middleware like HumanInTheLoopMiddleware for approval workflows, custom error handling, and human-in-the-loop... npx skills add https://github.com/langchain-ai/langchain-skills --skill langchain-fundamentals Download ZIPGitHub846

Build production agents using create_agent(), middleware patterns, and the @tool decorator / tool() function. When creating LangChain agents, you MUST use create_agent(), with middleware for custom flows. All other alternatives are outdated.

<create_agent>

Creating Agents with create_agent

create_agent() is the recommended way to build agents. It handles the agent loop, tool execution, and state management.

Agent Configuration Options

Parameter Purpose Example model LLM to use "anthropic:claude-sonnet-4-5" or model instance tools List of tools [search, calculator] system_prompt / systemPrompt Agent instructions "You are a helpful assistant" checkpointer State persistence MemorySaver() middleware Processing hooks [HumanInTheLoopMiddleware] (Python) / [humanInTheLoopMiddleware({...})] (TypeScript) </create_agent>

Copy & paste — that's it
from langchain.agents import create_agent
from langchain_core.tools import tool

@tool
def get_weather(location: str) -> str:
 """Get current weather for a location.

 Args:
 location: City name
 """
 return f"Weather in {location}: Sunny, 72F"

agent = create_agent(
 model="anthropic:claude-sonnet-4-5",
 tools=[get_weather],
 system_prompt="You are a helpful assistant."
)

result = agent.invoke({
 "messages": [{"role": "user", "content": "What's the weather in Paris?"}]
})
print(result["messages"][-1].content)
Copy & paste — that's it
import { createAgent } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const getWeather = tool(
 async ({ location }) => `Weather in ${location}: Sunny, 72F`,
 {
 name: "get_weather",
 description: "Get current weather for a location.",
 schema: z.object({ location: z.string().describe("City name") }),
 }
);

const agent = createAgent({
 model: "anthropic:claude-sonnet-4-5",
 tools: [getWeather],
 systemPrompt: "You are a helpful assistant.",
});

const result = await agent.invoke({
 messages: [{ role: "user", content: "What's the weather in Paris?" }],
});
console.log(result.messages[result.messages.length - 1].content);

Add MemorySaver checkpointer to maintain conversation state across invocations.

Copy & paste — that's it
from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver

checkpointer = MemorySaver()

agent = create_agent(
 model="anthropic:claude-sonnet-4-5",
 tools=[search],
 checkpointer=checkpointer,
)

config = {"configurable": {"thread_id": "user-123"}}
agent.invoke({"messages": [{"role": "user", "content": "My name is Alice"}]}, config=config)
result = agent.invoke({"messages": [{"role": "user", "content": "What's my name?"}]}, config=config)
# Agent remembers: "Your name is Alice"

Add MemorySaver checkpointer to maintain conversation state across invocations.

Copy & paste — that's it
import { createAgent } from "langchain";
import { MemorySaver } from "@langchain/langgraph";

const checkpointer = new MemorySaver();

const agent = createAgent({
 model: "anthropic:claude-sonnet-4-5",
 tools: [search],
 checkpointer,
});

const config = { configurable: { thread_id: "user-123" } };
await agent.invoke({ messages: [{ role: "user", content: "My name is Alice" }] }, config);
const result = await agent.invoke({ messages: [{ role: "user", content: "What's my name?" }] }, config);
// Agent remembers: "Your name is Alice"

Defining Tools

Tools are functions that agents can call. Use the @tool decorator (Python) or tool() function (TypeScript).

Copy & paste — that's it
from langchain_core.tools import tool

@tool
def add(a: float, b: float) -> float:
 """Add two numbers.

 Args:
 a: First number
 b: Second number
 """
 return a + b
Copy & paste — that's it
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const add = tool(
 async ({ a, b }) => a + b,
 {
 name: "add",
 description: "Add two numbers.",
 schema: z.object({
 a: z.number().describe("First number"),
 b: z.number().describe("Second number"),
 }),
 }
);

Middleware for Agent Control

Middleware intercepts the agent loop to add human approval, error handling, logging, and more. A deep understanding of middleware is essential for production agents — use HumanInTheLoopMiddleware (Python) / humanInTheLoopMiddleware (TypeScript) for approval workflows, and @wrap_tool_call (Python) / createMiddleware (TypeScript) for custom hooks.

Key imports:

Copy & paste — that's it
from langchain.agents.middleware import HumanInTheLoopMiddleware, wrap_tool_call
Copy & paste — that's it
import { humanInTheLoopMiddleware, createMiddleware } from "langchain";

Key patterns:

  • HITL: middleware=[HumanInTheLoopMiddleware(interrupt_on={"dangerous_tool": True})] — requires checkpointer + thread_id

  • Resume after interrupt: agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config=config)

  • Custom middleware: @wrap_tool_call decorator (Python) or createMiddleware({ wrapToolCall: ... }) (TypeScript)

<structured_output>

Structured Output

Get typed, validated responses from agents using response_format or with_structured_output().

Copy & paste — that's it
from langchain.agents import create_agent
from pydantic import BaseModel, Field

class ContactInfo(BaseModel):
 name: str
 email: str
 phone: str = Field(description="Phone number with area code")

# Option 1: Agent with structured output
agent = create_agent(model="gpt-4.1", tools=[search], response_format=ContactInfo)
result = agent.invoke({"messages": [{"role": "user", "content": "Find contact for John"}]})
print(result["structured_response"]) # ContactInfo(name='John', ...)

# Option 2: Model-level structured output (no agent needed)
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4.1")
structured_model = model.with_structured_output(ContactInfo)
response = structured_model.invoke("Extract: John, [email protected], 555-1234")
# ContactInfo(name='John', email='[email protected]', phone='555-1234')
Copy & paste — that's it
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";

const ContactInfo = z.object({
 name: z.string(),
 email: z.string().email(),
 phone: z.string().describe("Phone number with area code"),
});

// Model-level structured output
const model = new ChatOpenAI({ model: "gpt-4.1" });
const structuredModel = model.withStructuredOutput(ContactInfo);
const response = await structuredModel.invoke("Extract: John, [email protected], 555-1234");
// { name: 'John', email: '[email protected]', phone: '555-1234' }

<model_config>