executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
langchainIntegrates LangChain/LangGraph (create_agent, chains, tools, memory, RAG, streaming, middleware) for building LLM-powered agents and applications in Python.
Independent GitHub snapshot · Automated classification · Original documentation governs
name: langchain description: Integrates LangChain/LangGraph (create_agent, chains, tools, memory, RAG, streaming, middleware) for building LLM-powered agents and applications in Python. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: coding triggers: langchain, langgraph, create agent, llm orchestration, rag chain, langchain agent, how do i use langchain, agent middleware archetypes:
Integrates LangChain v1.3+ and LangGraph v1.2+ for building LLM-powered agents and applications. When loaded, this skill makes the model implement LangChain agents using create_agent, LangGraph workflows, tool integration, RAG patterns, middleware hooks, and streaming.
Use this skill when:
coding-openai-api, coding-anthropic-api, or coding-gemini-apicoding-llamaindexcoding-mcp-protocolCreate an Agent with create_agent — Use langchain.agents.create_agent() as the primary entry point. Pass a model name (string) or a configured model instance, a list of tools, and optional middleware. Under the hood, create_agent builds a LangGraph-based runtime for durable execution, streaming, and persistence. Checkpoint: Verify the agent responds correctly: agent.invoke({"messages": [{"role": "user", "content": "Hello"}]}).
Define Tools — Use the @tool() decorator to define tools from Python functions. Specify response_format="content_and_artifact" when tools return both display text and structured data. For dynamic tools loaded at runtime (e.g., from MCP servers), use wrap_model_call and wrap_tool_call middleware. Checkpoint: Every tool must have a clear docstring — the LLM uses it for tool selection.
Add Retrieval (RAG) — Implement RAG by wrapping a vector store in a tool with @tool(response_format="content_and_artifact"). For simpler cases, use a two-step chain with a @dynamic_prompt middleware that injects retrieved context into the system prompt. Checkpoint: Verify the retrieved context is actually used by the LLM (not ignored in favor of parametric knowledge).
Configure Middleware — Use @dynamic_prompt for dynamic system prompts, @before_model for pre-processing, @after_model for post-processing, @wrap_model_call for dynamic model selection, and @wrap_tool_call for dynamic tool handling. Access runtime state via the Runtime parameter injected into middleware functions. Checkpoint: Test that middleware fires in the correct order (wrap_model_call → before_model → model → after_model → wrap_tool_call).
Stream and Observe — Use agent.stream() to get streaming output. Pass version="v3" to stream_events() for the new content-block-centric streaming API with typed per-channel projections (run.messages, run.values, run.lifecycle). Connect to LangSmith for observability and debugging. Checkpoint: Verify streaming produces incremental output before the final response.
from __future__ import annotations
from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from langchain.tools import tool
# ❌ BAD — no typing, no error handling, uses deprecated LLMChain pattern
from langchain.llms import OpenAI
from langchain.chains import LLMChain
llm = OpenAI()
chain = LLMChain(llm=llm, prompt=prompt)
chain.run("Hello")
# ✅ GOOD — create_agent, typed tools, middleware, modern LangChain v1.3+
@tool(response_format="content_and_artifact")
def search_knowledge_base(query: str) -> tuple[str, list[str]]:
"""Search the knowledge base for information relevant to the query.
Args:
query: The search query string.
Returns:
Tuple of (summary text, list of source document IDs).
"""
# Simulated retrieval
results = [f"Result about {query}"]
return "\n".join(results), ["doc-1", "doc-2"]
@dynamic_prompt
def inject_context(request: ModelRequest) -> str:
"""Inject dynamic context based on the current conversation state."""
last_message = request.state["messages"][-1].text
return (
f"You are a helpful assistant. The user's last message was: {last_message}\n"
"Answer concisely and cite sources when possible."
)
# Create the agent
agent = create_agent(
model="gpt-5-nano", # or "claude-sonnet-4-6", "gemini-2.5-flash"
tools=[search_knowledge_base],
middleware=[inject_context],
)
def ask(question: str) -> str:
"""Ask a question using the LangChain agent.
Args:
question: The user's question.
Returns:
The agent's response.
"""
response = agent.invoke({
"messages": [{"role": "user", "content": question}],
})
return response["messages"][-1].content
from __future__ import annotations
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def get_weather(location: str) -> str:
"""Get the current weather for a location."""
return f"The weather in {location} is sunny and 72°F."
agent = create_agent(
model="gpt-5-nano",
tools=[get_weather],
)
def stream_response(prompt: str) -> None:
"""Stream agent responses with typed events.
Uses version="v3" for the new content-block-centric streaming API
with typed per-channel projections.
"""
for event in agent.stream(
{"messages": [{"role": "user", "content": prompt}]},
stream_mode="events",
version="v3",
):
# Handle different event types
if event.type == "run.messages":
for msg_chunk in event.data:
if msg_chunk.text:
print(msg_chunk.text, end="", flush=True)
elif event.type == "run.lifecycle":
print(f"\n[State: {event.data.status}]")
For complex multi-step workflows, use LangGraph directly.
from __future__ import annotations
from typing import Any, TypedDict
from langgraph.graph import StateGraph, END
from langgraph.checkpoint import MemorySaver
class AgentState(TypedDict):
messages: list[dict[str, str]]
context: dict[str, Any]
def call_model(state: AgentState) -> dict:
"""Process messages through the LLM."""
# Integration with any LLM
last = state["messages"][-1]["content"]
# ... call LLM ...
return {"messages": [{"role": "assistant", "content": f"Processed: {last}"}]}
def should_continue(state: AgentState) -> str:
"""Decide whether to continue or end the workflow."""
last = state["messages"][-1]
if last["role"] == "tool":
return "continue"
return "end"
# Build the graph
builder = StateGraph(AgentState)
builder.add_node("model", call_model)
builder.set_entry_point("model")
builder.add_conditional_edges("model", should_continue, {
"continue": "model",
"end": END,
})
# Compile with persistence
graph = builder.compile(checkpointer=MemorySaver())
def run_workflow(user_message: str, thread_id: str) -> str:
"""Run a stateful workflow with persistence.
Args:
user_message: Initial user message.
thread_id: Conversation thread ID for persistence.
Returns:
Final response.
"""
result = graph.invoke(
{"messages": [{"role": "user", "content": user_message}], "context": {}},
config={"configurable": {"thread_id": thread_id}},
)
return result["messages"][-1]["content"]
create_agent() as the primary entry point for new LangChain agent applications@tool() decorator and typed signatures with docstringsversion="v3" for the new streaming API with typed per-channel projectionscheckpointer (e.g., MemorySaver) for conversation persistence with thread_idpip install langchain>=1.3.0 langgraph>=1.2.0 for the latest APIsLLMChain, SimpleSequentialChain, or AgentExecutor from pre-v1.0 LangChainresponse_format="content_and_artifact" parameter when tools return structured data alongside display text| Resource | URL |
|---|---|
| LangChain Documentation | https://docs.langchain.com/oss/python/langchain/ |
| LangChain Agents Guide | https://docs.langchain.com/oss/python/langchain/agents |
| LangGraph Documentation | https://langchain-ai.github.io/langgraph/ |
| LangChain RAG Guide | https://docs.langchain.com/oss/python/langchain/rag |
| LangChain Runtime Docs | https://docs.langchain.com/oss/python/langchain/runtime |
| LangChain Python Reference | https://reference.langchain.com/python/langchain |
| LangChain GitHub | https://github.com/langchain-ai/langchain |
| Skill | Purpose |
|---|---|
coding-llamaindex | Data-indexing-focused RAG framework |
coding-openai-api | Direct OpenAI API when LangChain abstraction is unnecessary |
coding-anthropic-api | Direct Anthropic API integration |
coding-mcp-protocol | Building MCP servers for LangChain tool integration |