Agent Configuration and Instructions
Purpose and Scope
This page explains how to think about configuring a LangChain agent before it runs: the instruction text that defines the agent’s role, the chat model that performs reasoning, the tools the agent can call, the runtime context that is available while a run is in progress, and middleware that can adjust behavior around model and tool execution. LangChain positions the langchain package as the fastest path to build agents and LLM-powered applications, while still keeping the lower-level LangGraph runtime available for teams that need deeper orchestration control. Sources: libs/langchain_v1/README.md, libs/langchain_v1/langchain/agents/middleware/types.py
An agent configuration is not just a single prompt string. In practical LangChain applications, configuration is the bundle of choices that makes the same agent architecture behave like a product-specific assistant: what task it should perform, which model provider it should use, which integrations it may reach, and which operational policies should be applied around each request. The README describes LangChain as providing pre-built agent architecture and model integrations, and the middleware type module anchors the extension points that let developers modify model calls, tool calls, state, and lifecycle behavior without rewriting the core loop. Sources: libs/langchain_v1/README.md, libs/langchain_v1/langchain/agents/middleware/types.py
Relevant Source Files
libs/langchain_v1/README.md— Describes the current LangChain package, its quick install path, its role in building agents and LLM-powered applications, and the relationship between LangChain agents and LangGraph runtime capabilities such as durable execution, streaming, human-in-the-loop, and persistence.libs/langchain_v1/langchain/agents/middleware/types.py— Defines the agent middleware type surface used by custom and built-in middleware to participate in agent execution, including request/response objects and lifecycle hook shapes for model calls, tool calls, state, and runtime context.
Core Primitives
The first primitive is the agent instruction. An instruction is the highest-level description of what the agent should do and how it should behave. It may include a role, task boundaries, response style, domain rules, safety requirements, and guidance for when tools should or should not be used. In deployment terminology, an assistant is an agent configured for a specific task, so the instruction is part of what turns a reusable agent graph or architecture into a concrete assistant that users can invoke for a particular purpose.
The second primitive is the model. LangChain’s README demonstrates the basic model-first path by installing langchain, initializing a chat model, and invoking it with a simple input. Agent configuration extends that pattern by placing the model inside an agent loop, where each model response can either produce a final answer or request tool execution. The selected model determines provider-specific behavior, latency, cost, context window, tool-calling support, streaming characteristics, and structured-output reliability, so it should be treated as a runtime dependency rather than a hidden implementation detail. Sources: libs/langchain_v1/README.md
The third primitive is the tool set. A tool is an external capability that the model may request during a run, such as searching, calling an API, querying a database, reading a file, or invoking an internal business function. Tools are part of configuration because the same instructions and model can behave very differently depending on which capabilities are available. A narrowly scoped tool list keeps the agent easier to audit; a broad tool list gives the model more autonomy but increases the need for guardrails, approval points, and careful runtime context.
The fourth primitive is runtime context. Runtime context is information supplied for a specific invocation, tenant, user, thread, environment, or deployment rather than hard-coded into the agent definition. Examples include user identity, authorization decisions, session metadata, feature flags, trace identifiers, or per-run policy switches. Middleware types are important here because they provide structured places to read, enrich, or validate request state as the agent moves through lifecycle phases. That separation lets reusable agent code stay stable while per-run behavior remains configurable. Sources: libs/langchain_v1/langchain/agents/middleware/types.py
System-to-Code Mapping
The README provides the outer product contract: LangChain is for building agents and LLM-powered applications quickly, with interoperable components and integrations. It also states that LangChain agents are built on top of LangGraph to provide production-oriented runtime behavior such as durable execution, streaming, human-in-the-loop workflows, and persistence. For configuration work, that means readers should not treat the agent constructor as a toy wrapper around a prompt. It is the top of a runtime stack that can later be deployed, observed, interrupted, resumed, and connected to external systems. Sources: libs/langchain_v1/README.md
The middleware type module provides the inner customization contract. Middleware is the layer for behavior that should wrap or intercept the agent loop rather than live inside the task instruction. That includes modifying model requests, inspecting model responses, controlling tool calls, injecting state, and participating in lifecycle transitions before or after major phases. The practical design rule is simple: put stable task guidance in instructions, put provider and capability choices in model and tool configuration, and put cross-cutting runtime policy in middleware. Sources: libs/langchain_v1/langchain/agents/middleware/types.py
This division matters because configuration is often changed by different owners. Product teams may iterate on instructions. Platform teams may standardize models, tracing, retry behavior, and rate limits. Security teams may require review or filtering around tool calls. Application developers may pass per-run context from web requests, background jobs, or scheduled tasks. LangChain’s agent architecture supports that separation by combining a high-level agent authoring surface with middleware extension points rather than forcing every concern into a single prompt template or a single callback function.
Execution Flow
A configured run typically begins when application code receives a user request and selects the appropriate agent or assistant configuration. The application supplies the current input, any thread or session state, and runtime context such as user metadata or request-scoped settings. The instruction and model configuration define the starting behavior, while the tool list defines the allowed external actions. Before the model is called, middleware can prepare or validate the request, attach additional context, or apply policy checks that should happen consistently across invocations. Sources: libs/langchain_v1/langchain/agents/middleware/types.py
Next, the model receives the current messages and configuration. If the model returns normal content, the agent may continue, stream output, or finish depending on the architecture. If the model requests a tool call, the runtime routes that request through the configured tool layer. Middleware around tool calls is where teams typically implement authorization, argument validation, approval checks, logging, redaction, or custom error handling. This is also the point where human-in-the-loop behavior can become relevant, because the model’s intended action may need review before an external system is changed.
After a tool returns, the result becomes part of the agent’s continuing context, often as a tool message or equivalent state update. The agent can then call the model again with the new information. The loop repeats until the agent reaches a final answer, an interrupt, an error, or another terminal condition. The README’s emphasis on LangGraph-backed durability and persistence is important for this flow: production agents may run longer than a single HTTP request, stream intermediate events, or be paused and resumed. Sources: libs/langchain_v1/README.md
Middleware Configuration Reference
Use middleware for cross-cutting behavior that should be attached to an agent independently of the instruction text. The exact implementation can be built in or custom, but the source module libs/langchain_v1/langchain/agents/middleware/types.py is the reference point for the public type surface. The key idea is that middleware participates through typed request and response objects rather than informal global state. That gives developers a predictable place to inspect the model request, alter behavior, wrap tool execution, and coordinate with runtime context. Sources: libs/langchain_v1/langchain/agents/middleware/types.py
| Configuration concern | Prefer this layer | Why it belongs there |
|---|---|---|
| Task role, behavioral rules, response style | Instructions | These are semantic requirements the model should follow on every reasoning step. |
| Provider, model name, model capabilities | Model configuration | These choices affect execution behavior, cost, latency, tool calling, and streaming. |
| External actions the agent may take | Tools | Tool availability defines the capability boundary for the agent. |
| User, tenant, trace, request, or environment data | Runtime context | These values vary by invocation and should not be baked into the static prompt. |
| Auditing, policy, validation, retries, wrappers | Middleware | These concerns cut across model and tool calls and should remain reusable. |
When writing custom middleware, keep the instruction focused on the agent’s job and keep operational policy in code. For example, an instruction can say that the agent should help with support triage, but middleware should enforce whether the current user may call a ticket-update tool. An instruction can request concise answers, but middleware should attach tracing metadata or redact secrets. This split makes evaluations easier because prompt changes can be tested separately from runtime controls, and platform controls can be reused across multiple agents. Sources: libs/langchain_v1/langchain/agents/middleware/types.py
Practical Configuration Pattern
A useful authoring sequence is to start with the smallest viable agent configuration. First, write a direct instruction that names the task and expected output. Second, choose one chat model that supports the interaction pattern you need. Third, add only the tools required for the first workflow. Fourth, pass runtime context explicitly from the caller instead of relying on ambient process state. Fifth, introduce middleware when you discover a policy, observability, or request-shaping concern that should apply consistently across runs rather than being repeated inside every tool or prompt.
The README’s quick install guidance keeps the package entry point intentionally simple: install langchain and begin with model invocation before adding more architecture. That same staged approach works for agents. Start by proving the model and instruction can solve the task. Then add tools one at a time, checking whether the model uses them as intended. After that, add middleware for production controls such as logging, validation, approval gates, or context injection. Finally, connect the configured agent to deployment infrastructure when persistence, task queues, or managed assistants are needed. Sources: libs/langchain_v1/README.md, libs/langchain_v1/langchain/agents/middleware/types.py
# Conceptual configuration sketch; exact constructor details depend on the agent API in use.
instruction = "You are a support triage agent. Classify the issue, ask for missing details, and use tools only when needed."
runtime_context = {
"tenant_id": "acme",
"user_role": "support_admin",
"trace_id": "req-123",
}
tools = [search_docs, create_ticket]
middleware = [audit_middleware, approval_middleware]In deployed systems, the same configuration ideas map to assistants. The Agent Server documentation describes assistants as agents configured for specific tasks and deployments as one or more graphs plus persistence and a task queue. That means a local configuration should be written with deployment boundaries in mind: keep secrets in environment or platform configuration, keep per-user values in runtime context, and keep reusable policy in middleware. This makes it easier to move from local development to a managed or self-hosted server without redesigning the agent’s conceptual contract.
Testing Signals and Next Steps
A good test plan checks each configuration layer independently before testing the full agent loop. Instruction tests should verify that the model follows the role and output expectations on representative inputs. Model tests should cover provider-specific capabilities such as tool calling and streaming. Tool tests should validate schemas, side effects, and error handling without the agent. Runtime-context tests should confirm that user and tenant data are passed explicitly. Middleware tests should verify that wrappers run at the expected lifecycle points and that they preserve or intentionally transform requests and responses. Sources: libs/langchain_v1/langchain/agents/middleware/types.py
For next steps, read the middleware overview when you need to customize model or tool behavior, the tools page when you are defining external capabilities, and the callbacks and observability page when you need tracing or usage tracking. If your agent must be deployed as a long-running, persistent assistant, continue to the deployment and auth material and the schedules page. If your configuration is becoming a complex workflow with deterministic branches, multiple agents, or strict latency control, the README’s guidance points you toward LangGraph as the lower-level orchestration framework. Sources: libs/langchain_v1/README.md