
Context Engineering: Getting the Right Information to Your .NET Coding Agent
An AI coding agent is only as good as the context it sees. Context engineering, the discipline of deliberately curating what your agent reads, is the difference between an assistant that rewrites your service layer correctly and one that confidently breaks it.
This is Part 2 of the "Agentic Engineering for .NET Teams" series. Part 1 covers setting up a coding agent for a .NET solution. Part 3 covers sharing state across sessions and agents.
The Bottleneck Is Not the Model
Context windows are large now. In Claude Code, the Fable models, Sonnet 5 and later, Haiku 5.5, Opus 4.6 and later, and Sonnet 4.6 all support a 1 million token window. That number tempts you into a "just paste everything" approach. Resist it.
Chroma's Context Rot study (July 2025) tested 18 models, including GPT-4.1, Claude 4 and Gemini 2.5, and found that every one of them got worse as the input grew, even on simple tasks and well before the window was full. The older "Lost in the Middle" paper (Liu et al., 2023) showed where it hurts most: with 20 documents in the prompt, GPT-3.5 answered correctly about 76% of the time when the relevant document came first, and about 54% when it sat in the middle.
So there are two numbers to keep apart. The context window is how many tokens you can send. Effective context is how many of those tokens the model uses reliably, and it is always the smaller one.
Anthropic describes context engineering, in its September 2025 post "Effective context engineering for AI agents", as "the set of strategies for curating and maintaining the optimal set of tokens (information) during LLM inference". It treats it as the natural next step after prompt engineering, and that is the discipline this article is about.
Anatomy of an Agent's Context
When your agent processes a request, its context is assembled from several distinct layers:
- System and project instructions. CLAUDE.md, AGENTS.md or
.github/copilot-instructions.md, depending on your toolchain. Loaded at session start. - Files in scope. What the agent has read, been given, or retrieved from your repo.
- Tool results. Output from shell commands, test runners, linters, search tools and MCP connectors.
- Conversation history. Every earlier turn in the session, which keeps growing.
Each layer competes for the same finite budget. A bloated conversation history crowds out your project instructions, and a large file dump crowds out the tool output that contains the actual error. In Claude Code, /context shows the live breakdown by category, so you can see which layer is taking the space instead of guessing.
Techniques That Actually Work
Project Instruction Files: CLAUDE.md and AGENTS.md
CLAUDE.md is a plain Markdown file that Claude Code loads at session start. AGENTS.md is the cross-tool format that started in OpenAI's Codex and that OpenAI contributed to the Linux Foundation's Agentic AI Foundation in December 2025. Since v2.1.277, Claude Code reads AGENTS.md as well, but by default only when there is no CLAUDE.md in the working directory or above it. If you have both, either import AGENTS.md from a one-line CLAUDE.md (@AGENTS.md) or set the Project instructions option to load both.
Anthropic's own guidance is to keep each CLAUDE.md under about 200 lines, because longer files cost more context and reduce adherence. You will not see an error when a file gets too long, you will just see the agent following some conventions and ignoring others. Two features help keep the file short:
- Path-scoped rules. A Markdown file in
.claude/rules/withpaths:frontmatter loads only when Claude works with matching files, so the EF Core migration rules stay out of the context while it edits a Razor page. - Imports.
@pathlines pull other files in, up to four hops deep. They help you organise a long file, but they do not save context, because imported files load together with the file that imports them.
A practical CLAUDE.md for a .NET solution looks like this:
# Project: Payments Platform
## Build & Test
- Build: `dotnet build src/Payments.sln`
- Test: `dotnet test src/Payments.sln --no-build --logger trx`
- Lint: `dotnet format --verify-no-changes`
- Always run tests before considering a task complete.
## Architecture
- Clean Architecture: Domain → Application → Infrastructure → API
- Domain layer has zero external dependencies. Do not add NuGet refs to Domain.
- Use MediatR for CQRS. Commands in Application/Commands/, Queries in Application/Queries/.
- EF Core DbContext lives in Infrastructure only. Never inject it into Application directly.
## Conventions
- Result<T> pattern (no exceptions for flow control). See src/SharedKernel/Result.cs.
- Nullable reference types enabled globally. Do not suppress NRT warnings.
- Integration tests use TestContainers; unit tests use xUnit + NSubstitute.
## Do Not
- Do not modify migration files directly, run `dotnet ef migrations add <Name>`.
- Do not add business logic to API controllers.Every line here is something the agent would otherwise have to guess. A new team member, human or model, reading this knows the rules without opening a single source file.
Scoping the Task and Curating Files
The habit with the most leverage is giving the agent the minimum relevant file set for each task. If you are adding a new query handler, the agent needs the query contract, the relevant entity, the DbContext registration and one existing handler as a reference pattern. It does not need the whole solution.
In Claude Code you control this with @ file references in your prompt. In GitHub Copilot's agent mode, workspace indexing handles much of this, but you can still attach files explicitly.
For large codebases, retrieving the relevant snippets through search or an MCP connector works better than stuffing everything in. A search tool can return the three files that matter for a query instead of giving the agent all 400.
Summarization and Compaction
Long sessions accumulate context rot. Three techniques help, and they work best together:
- Compaction. Summarise the conversation, keeping architectural decisions and dropping resolved back-and-forth. Claude Code compacts automatically as the window fills, and
/autocompactwith a token count, for example/autocompact 500k, sets how full it gets first. You can also run/compactwith a focus, like/compact focus on the payment retry bug, so the summary keeps what you choose. After compaction the project-root CLAUDE.md and auto memory are re-read from disk, which is one more reason to put lasting rules there and not only in the chat. - Structured external memory. Write progress notes, checkpoint files or a
PROGRESS.mdthat the agent reads at the start of each new session. Claude Code's auto memory does a version of this on its own: it loads the first 200 lines or 25KB of itsMEMORY.mdinto every session. Either way, the notes survive a context reset. - Subagent delegation. Break a large task into bounded subtasks handled by separate agents. In Claude Code a subagent works in its own context window, so its file reads stay out of yours, and it returns a compact summary instead of its full transcript.
Repo Hygiene That Pays Off
Context engineering is not only a prompt problem, it is a repo design problem. A well-structured .NET solution is easier for an agent to reason about.
Clear module boundaries matter more than ever. A solution where Infrastructure has no circular references to Application, and where each project has a single clear purpose, lets the agent reason about a change without reading half the repo.
READMEs at every module boundary are not just for humans. A two-paragraph README in src/Payments.Infrastructure/ explaining what lives there and what doesn't gives the agent structural context it cannot reliably infer from code.
Machine-readable build and test commands in CLAUDE.md or AGENTS.md let the agent verify its own output. The loop of write, build, test and fix catches most regressions before they reach review.
// Example: Result<T> pattern referenced in CLAUDE.md
// The agent knows this pattern exists and where to find it.
public sealed class Result<T>
{
public T? Value { get; }
public string? Error { get; }
public bool IsSuccess { get; }
private Result(T value) { Value = value; IsSuccess = true; }
private Result(string error) { Error = error; IsSuccess = false; }
public static Result<T> Ok(T value) => new(value);
public static Result<T> Fail(string error) => new(error);
public Result<TOut> Map<TOut>(Func<T, TOut> map) =>
IsSuccess ? Result<TOut>.Ok(map(Value!)) : Result<TOut>.Fail(Error!);
}When the agent sees Result<T> in a contract and your CLAUDE.md says "Result<T> pattern, see src/SharedKernel/Result.cs", it reads the implementation instead of inventing a different error-handling pattern.
Context Anti-Patterns
Stale instruction files. A CLAUDE.md that describes last year's architecture is worse than no file at all. If it says "use Dapper for data access" but the codebase moved to EF Core six months ago, you will spend your time correcting the agent's choices instead of reviewing correct output. Treat the file as living documentation. Since v2.1.283, /doctor prompt-audit checks your CLAUDE.md, CLAUDE.local.md, AGENTS.md and the rules and skills under .claude/ for instructions written for older models, references to files or commands that no longer exist, and files that contradict each other, and proposes edits without changing anything until you ask.
Contradictory docs. The .cursorrules file says one thing, the CLAUDE.md says another, and the README says a third. The model picks one and you don't know which. Make AGENTS.md the single source, and have the tool-specific files import or point to it instead of repeating it.
Dumping huge files. Giving the agent an entire 3,000-line service class when it only needs one method puts the important part in the middle of a long input, which is exactly where the studies above found the losses. Give it the method, its direct dependencies and the relevant interface.
Losing the thread over long sessions. After 30 or more turns, early instructions are buried deep in history. The agent starts producing output that contradicts decisions made at the start of the session. That is not a model failure, it is a session management failure.
Measuring and Resetting
The signs that an agent has lost context are recognisable once you know to look for them: it ignores conventions it followed earlier in the session, it asks questions it already answered, it brings back a pattern you explicitly ruled out, or it is confident about something that is plainly wrong.
When you see those signals, stop prompting and reset. Run /clear or start a fresh session, let the CLAUDE.md load, give it the minimal relevant file set, and write a one-paragraph summary of the decisions made so far. That paragraph is denser and more reliable than 40 turns of accumulated history.
Better models narrow the problem but do not remove it. When Anthropic released Opus 4.6, it reported 76% on the MRCR v2 benchmark, which hides eight facts across 1 million tokens, against 18.5% for Sonnet 4.5. That is a large improvement, and it still means a quarter of the facts were missed. The answer to context rot is architectural: structure your sessions and keep memory outside the conversation, instead of hoping the next model solves it.
Iterating on your CLAUDE.md based on observed failures is usually the best return on time in context engineering. If an agent keeps misapplying the same pattern, that pattern needs a clearer description in the instruction file, or a reference example. Note which additions removed which kinds of errors, so the file grows from evidence and not from guesses.
Part 3 of this series covers sharing state across sessions and agents: memory, MCP and handoffs in .NET.
Sources
- Context Engineering: A Practical Guide for AI Agents (2026) | Sourcegraph
- Agent Context Engineering 2026: Sliding Windows, Hierarchical Summarization, and Memory Offloading for Long-Running Production Tasks | AgentMarketCap
- Context Engineering: The 2026 Playbook for AI Agents
- Mise en Place for Agentic Coding: Deliberate Preparation as Context Engineering Methodology
- Context Engineering for AI Coding Agents: 9 Techniques for 2026
- Context Window Management and Session Lifecycle for Long-Running AI Agents | Zylos Research
- Claude Code Context Window: How It Works (2026) - Unblocked
- Claude Context Window Size (2026): 1M Tokens on Opus 4.8 & Sonnet 5 | Morph
Keep reading

October 29, 2026 · 7 min
Sharing State Across Sessions and Agents: Memory, MCP, and Handoffs in .NET
Agents forget everything between sessions and cannot see each other's work by default. This third part of Agentic Engineering for .NET Teams covers the practical patterns: persistent memory, MCP servers, multi agent coordination, and the C# wiring that makes them work together.
Read
October 29, 2026 · 8 min
Claude Code for .NET Developers: A Practical Agentic Workflow
Claude Code is a terminal first AI agent that reads, edits and runs your .NET codebase on its own. Here is how to set it up, drive it well, and keep it safe in a team.
Read
October 23, 2026 · 8 min
Function Calling in C#: Building Tools Your AI Agent Can Call
Function calling turns a chatbot into an agent. A working C# agent loop with the official Anthropic SDK 13: tool definitions, parallel tool calls, structured errors, an EF Core dispatcher and the production concerns, all compiled and run.
Read