Context Engineering
Purpose and Scope
Context engineering is the practice of deciding what information an LLM-powered agent can see, when it can see it, and how that information is shaped before the next model call. In LangChain terms, context includes messages, instructions, tool definitions, tool results, retrieved documents, runtime metadata, and tracing or observability state that follows execution. The repository sources for this page focus on concrete mechanisms that edit message history, reorder long-context documents, preserve compatibility with older context callbacks, and attach tracing context to execution scopes.
Sources: libs/core/langchain_core/tracers/context.py, libs/langchain_v1/langchain/agents/middleware/context_editing.py
The official LangChain documentation frames context engineering as providing the right information and tools in the right format so an agent can accomplish tasks reliably. That framing is important because context is not just prompt text. Startup context can include the system prompt, persistent agent instructions, skills, memory, and tool guidance. Runtime context can include per-run metadata, user-specific configuration, credentials, and connections. The source code shown here covers lower-level Python building blocks that support those higher-level patterns, especially message editing and execution-local tracing.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py, libs/core/langchain_core/tracers/context.py
Relevant Source Files
libs/core/langchain_core/tracers/context.py- Defines execution-scoped tracing context usingContextVar, includingtracing_v2_enabled,collect_runs, and helper functions that attach LangSmith tracers or run collectors to callback managers.libs/langchain_v1/langchain/agents/middleware/context_editing.py- Implements context editing middleware for agents, including theContextEditprotocol andClearToolUsesEditstrategy for clearing older tool outputs after a token threshold is exceeded.libs/langchain/langchain_classic/callbacks/context_callback.py- Provides a deprecated-import shim forContextCallbackHandler, routing legacy imports tolangchain_community.callbacks.context_callbackthroughcreate_importer.libs/langchain/langchain_classic/document_loaders/parsers/language/javascript.py- Provides a deprecated-import shim forJavaScriptSegmenter, preserving the classic import path while delegating tolangchain_community.document_loaders.parsers.language.javascript.libs/langchain/langchain_classic/document_transformers/long_context_reorder.py- Provides a deprecated-import shim forLongContextReorder, keeping the classic document transformer import available while delegating tolangchain_community.document_transformers.
Core Primitives
The most direct context-management primitive in the supplied agent source is ContextEdit. It is a protocol with an apply method that receives a mutable list of messages and a token-counting callable. This contract is intentionally small: a strategy does not need to know how the agent loop works, which model is being used, or how tools are implemented. It only needs to inspect and mutate the message list according to a policy. That design keeps context editing model-agnostic while still allowing it to participate directly in agent middleware.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py
ClearToolUsesEdit is the concrete strategy shown in the repository evidence. It clears older ToolMessage outputs once the conversation exceeds a configured token threshold. The default threshold is high, the default placeholder is [cleared], and the strategy preserves a configurable number of the most recent tool results. The strategy can also reclaim a minimum number of tokens, exclude named tools from clearing, and optionally remove tool input parameters from the originating AIMessage. This is a context compression pattern: the agent keeps the conversational structure while replacing bulky historical artifacts with a compact marker.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py
Tracing context is a separate primitive. tracing_v2_enabled creates a LangChainTracer, stores it in a ContextVar, and yields it as a context manager so code executed inside the block can be traced to LangSmith. collect_runs similarly installs a RunCollectorCallbackHandler in a context variable and yields the collector. These APIs do not edit the model prompt, but they engineer execution context for observability: downstream callback resolution can discover the active tracer or run collector without requiring every function call to manually pass those objects around.
Sources: libs/core/langchain_core/tracers/context.py
System-to-Code Mapping
At the application level, context engineering usually starts with a policy decision: what should stay in the prompt, what should be loaded only when relevant, what should be summarized or cleared, and what should be isolated in a subagent or separate workflow. The agent middleware source maps to the compression part of that decision. When tool outputs grow large, ClearToolUsesEdit targets older tool messages rather than blindly truncating the whole conversation. This preserves recent evidence and keeps message roles intact, which is safer than deleting arbitrary turns from the transcript.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py
Document context is represented in the supplied sources through compatibility entry points rather than full implementations. LongContextReorder is exposed from the classic package through a deprecated-import shim, indicating that long-context document ordering remains a named concept for retrieval and prompt assembly workflows. Likewise, JavaScriptSegmenter is preserved as a classic import for language-aware JavaScript parsing. Together, these paths point to a retrieval-side context engineering pattern: parse source material into useful units, then transform or reorder documents before they become prompt context.
Sources: libs/langchain/langchain_classic/document_loaders/parsers/language/javascript.py, libs/langchain/langchain_classic/document_transformers/long_context_reorder.py
Legacy callback context is also part of the mapping. context_callback.py keeps ContextCallbackHandler available from langchain_classic.callbacks.context_callback, but resolves it dynamically from langchain_community.callbacks.context_callback. For developers maintaining older applications, this means context-related callback imports may still work while emitting deprecation behavior through the shared importer machinery. For new code, the more explicit source-backed pattern is to use tracing context managers from langchain_core.tracers.context when the goal is LangSmith tracing or run collection.
Sources: libs/langchain/langchain_classic/callbacks/context_callback.py, libs/core/langchain_core/tracers/context.py
Execution Flow
A typical agent-side context editing flow begins after the conversation has accumulated messages from user input, model responses, and tool calls. The strategy counts approximate tokens across the message list. If the count is at or below the configured trigger, no edit is applied. If the count is above the threshold, the strategy scans for ToolMessage instances, preserves the configured number of most recent candidates, and considers older tool outputs for clearing. This makes the edit responsive to actual context pressure instead of running on every turn.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py
When a candidate tool message is considered, the strategy looks backward for the corresponding AIMessage, finds the matching tool call by tool_call_id, and skips the message if no matching tool call exists. It also skips tools listed in exclude_tools, which is useful when a particular tool result must remain auditable or semantically necessary. When the edit proceeds, the replacement message removes the artifact, replaces content with the placeholder, and records response_metadata.context_editing with cleared and strategy values. That metadata gives downstream code a way to recognize that the context has already been edited.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py
A tracing flow has a different shape. Code enters with tracing_v2_enabled(...) as cb, runs LangChain operations, and can then inspect the tracer for a LangSmith run URL. Internally, the context manager converts a string example_id to a UUID, creates the LangChainTracer, sets it on the tracing context variable, and resets the variable in a finally block. _get_trace_callbacks checks whether tracing is enabled and adds a tracer to an existing callback manager only when one is not already present, avoiding duplicate tracer insertion that could distort trace hierarchy.
Sources: libs/core/langchain_core/tracers/context.py
API Components and Configuration Reference
| Component | Kind | Key inputs or fields | Behavior |
|---|---|---|---|
ContextEdit | Protocol | messages, count_tokens | Defines the in-place editing contract for context strategies. |
ClearToolUsesEdit | Dataclass strategy | trigger, clear_at_least, keep, clear_tool_inputs, exclude_tools, placeholder | Clears older tool outputs when token count exceeds the trigger. |
DEFAULT_TOOL_PLACEHOLDER | Constant | [cleared] | Default replacement text for cleared tool outputs. |
tracing_v2_enabled | Context manager | project_name, example_id, tags, client | Enables LangSmith tracing for runs executed inside the context. |
collect_runs | Context manager | none | Collects traced runs in a RunCollectorCallbackHandler. |
_get_trace_callbacks | Internal helper | project_name, example_id, callback_manager | Resolves tracer callbacks when tracing is active. |
ContextCallbackHandler | Deprecated classic export | dynamic attribute lookup | Delegates legacy imports to langchain_community. |
JavaScriptSegmenter | Deprecated classic export | dynamic attribute lookup | Delegates language parser imports to langchain_community. |
LongContextReorder | Deprecated classic export | dynamic attribute lookup | Delegates long-context document transformer imports to langchain_community. |
The public-facing takeaway is that LangChain separates prompt-facing context controls from execution-facing context controls. Message editing changes what the model sees. Document parsing and long-context reordering change which retrieved materials are likely to be presented usefully. Tracing context changes what the developer can observe about a run without changing the prompt. These controls can be combined: an application may reorder retrieved documents, invoke an agent with context-editing middleware, and wrap the execution in tracing_v2_enabled to evaluate whether the edited context improves behavior.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py, libs/core/langchain_core/tracers/context.py, libs/langchain/langchain_classic/document_transformers/long_context_reorder.py
Implementation Details and Constraints
The context editing implementation uses message types from langchain_core.messages, including AIMessage, BaseMessage, ToolMessage, and AnyMessage. It also uses count_tokens_approximately as the default style of token accounting exposed in the module evidence. Because the edit mutates a message list in place, callers should treat the edited list as the source of truth for the next model call. If application code needs an unedited audit copy, capture it before middleware edits are applied or rely on tracing and persisted run data.
Sources: libs/langchain_v1/langchain/agents/middleware/context_editing.py
The classic import shims are intentionally narrow. Each file defines DEPRECATED_LOOKUP, creates an importer with create_importer, implements __getattr__, and exposes a small __all__ list. That pattern is useful for migration because it preserves names without embedding the moved implementation in langchain_classic. For context engineering work, read these files as compatibility surfaces rather than the full behavior of JavaScript segmentation, callback context handling, or long-context reordering. The operative implementations live in the community package named by each lookup.
Sources: libs/langchain/langchain_classic/callbacks/context_callback.py, libs/langchain/langchain_classic/document_loaders/parsers/language/javascript.py, libs/langchain/langchain_classic/document_transformers/long_context_reorder.py
Next Steps
Use the primitives on this page to choose the right context control for the problem you are solving. If the model is overloaded by old tool results, start with ClearToolUsesEdit and tune trigger, keep, and exclude_tools around real traces. If retrieved material is poorly positioned in long prompts, review the long-context document transformer surface and retrieval pages. If you need to understand whether context edits improved behavior, wrap representative runs in tracing_v2_enabled or collect_runs and compare the resulting traces in LangSmith.
Sources: libs/core/langchain_core/tracers/context.py, libs/langchain_v1/langchain/agents/middleware/context_editing.py
Related pages: agent-configuration-instructions, middleware-overview, middleware-customization, event-streaming, callbacks-observability, documents-and-loaders, retrievers