Receptury .NET i C#
Receptury .NET i C# dla agentów AI to konfiguracja i prompty, dzięki którym Claude Code, Codex i Cursor dostarczają godne zaufania zmiany w ASP.NET Core i EF Core: jeden AGENTS.md z dokładnymi komendami dotnet, testy xUnit v3 pisane przed kodem i uruchamiane na prawdziwym PostgreSQL oraz analizatory Roslyn ustawione tak, że zły wzorzec wywraca build.
Ta strona jest dla programistów C#, za których większość kodu usługi pisze już agent. Sytuacja, którą rozwiązuje: pull request od agenta się kompiluje, a testy są zielone, tyle że testy używają dostawcy in-memory z EF Core, nowa migracja usuwa kolumnę, którą miała tylko przemianować, .Result blokuje wątek w środku żądania, a świeże #pragma warning disable ukrywa jedyne ostrzeżenie analizatora, które by to wyłapało. C# daje ci kompilator i potok analizatorów, jakich większość języków nie ma. Poniższe receptury sprawiają, że agent zderza się z nimi w każdej turze, więc przeglądasz dowody, a nie diffy. Jeśli repozytorium nie ma jeszcze AGENTS.md ani bramki w CI, zacznij od strony Repozytorium gotowe na agentów.
Co zyskujesz dzięki tym recepturom .NET
Dział zatytułowany „Co zyskujesz dzięki tym recepturom .NET”Directory.Build.propsiglobal.json, które zamieniają ostrzeżenia nullable, reguły jakości kodu i styl kodu w błędy builda oraz przypinają SDK i runner testów używany przez agenta.AGENTS.mddla solucji .NET, podpięty do Claude Code, Codex i Cursora.- Pętlę test-first dla endpointu ASP.NET Core: kryteria akceptacji, padające testy xUnit v3 na bazie PostgreSQL z Testcontainers, a dopiero potem implementacja.
- Hook
Stopw Claude Code, który nie pozwala ogłosić „gotowe”, dopókidotnet buildidotnet testnie przejdą, oraz rozwiązania zastępcze dla Codex i Cursora: hookStopw Codex albo skryptowy przebiegcodex execoraz bramka w CI. - Recepturę na migracje EF Core z kontrolą rozjazdu modelu i ludzką akceptacją zmian niszczących dane.
- Listę zakazanych API, test architektury i testy mutacyjne, które łapią to, co agenci psują w C#.
- Typowe awarie przy pracy agentów w .NET, każda z promptem naprawczym.
Jakie wersje .NET, EF Core i xUnit zakładają te receptury?
Dział zatytułowany „Jakie wersje .NET, EF Core i xUnit zakładają te receptury?”Agenci uczyli się na latach przykładów .NET, więc mieszają API z różnych wersji głównych. Podaj agentowi wersje i przypnij je w repozytorium, żeby nie mógł się od nich odchylać. Te były aktualne 2026-09-26:
| Komponent | Wersja | Źródło (sprawdzone 2026-09-26) |
|---|---|---|
| .NET (LTS) | .NET 10, runtime 10.0.12, SDK 10.0.401; wsparcie do 2028-11-14 | indeks wydań dotnet/core |
| .NET 11 | Release candidate 1 (2026-09-08), wsparcie standardowe (STS) | indeks wydań dotnet/core |
| .NET 8 i .NET 9 | Oba tracą wsparcie 2026-11-10 | indeks wydań dotnet/core |
EF Core, dotnet-ef, Microsoft.AspNetCore.Mvc.Testing | 10.0.12 | NuGet |
Npgsql.EntityFrameworkCore.PostgreSQL | 10.0.3 | NuGet |
xUnit.net v3 (rdzeń, xunit.v3) | 4.0.1 (opublikowane 2026-09-12) | NuGet |
Testcontainers.PostgreSql | 4.15.0 | NuGet |
Receptury zakładają .NET 10. Jeśli nadal jesteś na .NET 8 lub 9, aktualizacja to pierwsze zadanie warte zlecenia agentowi, bo obie wersje tracą wsparcie w listopadzie.
Jak przygotować solucję .NET do pracy z agentem?
Dział zatytułowany „Jak przygotować solucję .NET do pracy z agentem?”Umieść bramki w MSBuild, a nie w prompcie. Polecenie „pisz czysty kod” następna sesja zapomni. Właściwość w Directory.Build.props działa w każdym projekcie, każdej sesji i każdym przebiegu CI. Większość pracy robią trzy pliki w katalogu głównym solucji.
Directory.Build.props zamienia ostrzeżenia w błędy i podnosi poprzeczkę analizatorom:
<!-- Directory.Build.props: applies to every project under this folder --><Project> <PropertyGroup> <TargetFramework>net10.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <AnalysisLevel>latest-recommended</AnalysisLevel> <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile> </PropertyGroup></Project>AnalysisLevel ustawione na latest-recommended włącza zalecany zestaw reguł jakości CA. EnforceCodeStyleInBuild sprawia, że reguły stylu IDE, którym .editorconfig nadaje poziom warning lub error, działają przy dotnet build, więc trafiają do terminala agenta, a nie tylko do IDE. RestorePackagesWithLockFile zapisuje packages.lock.json, dzięki czemu CI przywraca pakiety z --locked-mode i pada, gdy agent zmieni zależność bez zacommitowania pliku blokady.
global.json przypina SDK i przełącza dotnet test na Microsoft Testing Platform (MTP), czyli tryb, który dokumentacja xUnit v3 opisuje dla SDK .NET 10 i nowszych:
{ "sdk": { "version": "10.0.401", "rollForward": "latestFeature" }, "test": { "runner": "Microsoft.Testing.Platform" }}Lokalny manifest narzędzi daje agentowi tę samą wersję dotnet ef co w CI, a nie tę, która akurat jest zainstalowana globalnie:
# terminal, at the solution rootdotnet new tool-manifestdotnet tool install dotnet-efdotnet new install xunit.v3.templates # adds the xunit3 project templateW trybie MTP dotnet test przyjmuje projekt przez --project, a solucję przez --solution, zamiast samej ścieżki, a filtry xUnit v3 stają się opcjami w rodzaju --filter-class. Agenci uczeni na przykładach z epoki VSTest piszą dotnet test MyProject.csproj --filter …, więc wpisz nową składnię do AGENTS.md.
Co wpisać do AGENTS.md w repozytorium .NET?
Dział zatytułowany „Co wpisać do AGENTS.md w repozytorium .NET?”Wpisz komendy, które agent musi uruchomić, w kolejności, w jakiej ma je uruchomić, oraz kilka reguł, które ogólny model C# myli w twoim kodzie. Trzymaj plik krótki; wszystko, co już wymusza MSBuild, zostaje poza nim.
# Orders service (.NET 10, ASP.NET Core minimal APIs, EF Core 10, PostgreSQL)
## Commands (run from the repo root)- Restore: `dotnet restore --locked-mode` (commit packages.lock.json if you add a package)- Build: `dotnet build --no-restore` (warnings are errors; fix the code, never add NoWarn or #pragma)- Test all: `dotnet test --no-build` (needs Docker: integration tests start PostgreSQL with Testcontainers)- Test one class: `dotnet test --project tests/Orders.Api.Tests --filter-class Orders.Api.Tests.CreateOrderTests`- Format: `dotnet format --verify-no-changes`- Migration drift: `dotnet ef migrations has-pending-model-changes --project src/Orders.Infrastructure --startup-project src/Orders.Api`
## Definition of doneBuild, tests, format and the drift check all pass. Report the commands you ran and their result.
## Rules- Tests are the specification. If a test fails, fix src/, not tests/. Ask before changing an assertion.- Integration tests use the ApiFactory fixture (real PostgreSQL). Never use the EF Core in-memory provider.- Package versions live in Directory.Packages.props. Never put Version= on a PackageReference.- Time comes from TimeProvider, never DateTime.Now or DateTime.UtcNow.- async all the way down: no .Result, .Wait() or GetAwaiter().GetResult().- Read-only queries use AsNoTracking(). Queries that Include two or more collections use AsSplitQuery().- Never edit an existing migration. Add a new one.Każde narzędzie wczytuje ten sam plik inaczej:
Utwórz CLAUDE.md, którego pierwsza linia importuje wspólny plik, a pod nią dopisz ewentualne linie tylko dla Claude:
@AGENTS.mdClaude Code w wersji 2.1.277 i nowszych czyta też AGENTS.md bezpośrednio, gdy projekt nie ma CLAUDE.md (w Bedrock, Google Cloud, Foundry i bramach LLM od v2.1.281; obie wersje na kanale wydań latest w dniu 2026-09-26). Import działa w każdej wersji i na każdym kanale. Do nawigacji po kodzie dodaj wtyczkę z serwerem języka C# opisaną w sekcji Jak dać agentowi aktualną dokumentację .NET i nawigację po kodzie?.
Codex czyta AGENTS.md, zanim zacznie pracę. Uruchom /init w TUI, żeby dostać szkic, a potem zastąp go plikiem powyżej. Od codex-cli 0.150.0 projekt, któremu Codex nie ufa, nie dostarcza swojego AGENTS.md, więc zaufaj repozytorium, gdy Codex o to zapyta.
Dodaj regułę projektu (funkcja Rules w Cursorze, pliki w .cursor/rules/), która obowiązuje przy każdym zapytaniu do agenta i każe mu trzymać się AGENTS.md, albo wklej do niej sekcje Commands i Rules. Zacommituj regułę razem z repozytorium. Format pliku i sposób, by reguła obowiązywała zawsze, opisuje strona reguły projektu w Cursorze.
Wspólne reguły agentów wyjaśniają, jak utrzymać jedno źródło prawdy, gdy zespół używa wszystkich trzech narzędzi.
Jak prowadzić pętlę test-first dla endpointu ASP.NET Core?
Dział zatytułowany „Jak prowadzić pętlę test-first dla endpointu ASP.NET Core?”Opisz zachowanie, każ agentowi napisać padające testy, sprawdź, że padają z właściwego powodu, i dopiero wtedy pozwól mu napisać implementację. Testy stają się wyrocznią, której ufasz, więc muszą trafiać w ten sam silnik bazy co produkcja. Dostawca in-memory z EF Core nie wymusza unikalnych indeksów, kluczy obcych ani transakcji, więc test na nim nie dowodzi niczego o zachowaniu, na którym zależy ci najbardziej.
-
Spisz kryteria akceptacji. Od trzech do sześciu obserwowalnych zachowań, każde jako zdanie, które test może sprawdzić. Format pokazuje strona kryteria akceptacji, które agent potrafi zweryfikować.
-
Poproś wyłącznie o padające testy. Użyj pierwszego promptu poniżej. Zatrzymaj agenta, gdy testy się kompilują i padają.
-
Czytaj porażki, nie kod. Każdy test powinien paść na asercji (na przykład
404zamiast201), a nie na brakującej klasie czy błędzie kontenera. Test, który pada z niewłaściwego powodu, przejdzie też z niewłaściwego powodu. -
Poproś o implementację. Użyj drugiego promptu. Pętla kończy się, gdy przechodzi cała bramka, a nie gdy agent ogłosi, że skończył.
-
Sprawdź siłę testów. Uruchom testy mutacyjne na zmienionym kodzie (zobacz Które analizatory i testy zamieniają komentarze z review w błędy builda?).
Porównaj fixture napisany przez agenta z tym kształtem. xUnit v3 przestawił IAsyncLifetime na ValueTask, a Testcontainers 4.x oznacza bezparametrowy konstruktor buildera jako przestarzały, więc starsze wzorce wywracają tu build. Ustaw tag obrazu na główną wersję PostgreSQL, której używasz na produkcji; postgres:17-alpine to tylko przykład:
public sealed class ApiFactory : WebApplicationFactory<Program>, IAsyncLifetime{ private readonly PostgreSqlContainer _db = new PostgreSqlBuilder("postgres:17-alpine").Build();
public async ValueTask InitializeAsync() { await _db.StartAsync(); using var scope = Services.CreateScope(); await scope.ServiceProvider.GetRequiredService<OrdersDbContext>().Database.MigrateAsync(); }
protected override void ConfigureWebHost(IWebHostBuilder builder) => builder.UseSetting("ConnectionStrings:Orders", _db.GetConnectionString());
public override async ValueTask DisposeAsync() { await _db.DisposeAsync(); await base.DisposeAsync(); }}Fixture stosuje twoje prawdziwe migracje, więc każdy przebieg testów integracyjnych dowodzi też, że migracje dają się nałożyć na pustą bazę. Jeśli projekt testowy nie widzi klasy Program, agent może dopisać public partial class Program; na końcu Program.cs; to jedyna zmiana w src/, jaką wolno zrobić na etapie testów.
Ochrona wyroczni wyjaśnia, dlaczego polecenie „nie zmieniaj testów” potrzebuje też mechanicznego zabezpieczenia. Dodaje je następna sekcja.
Jak powstrzymać agenta przed ogłoszeniem „gotowe”, zanim build jest zielony?
Dział zatytułowany „Jak powstrzymać agenta przed ogłoszeniem „gotowe”, zanim build jest zielony?”Polecenie w AGENTS.md to rada. Hook albo kontrola w CI to bramka. Każde narzędzie daje inny sposób, żeby bramka uruchamiała się w każdej turze.
Hook Stop uruchamia się, gdy Claude kończy odpowiedź. Kod wyjścia 2 blokuje zakończenie i pokazuje Claude’owi stderr hooka, więc Claude pracuje dalej. Po ośmiu kolejnych kontynuacjach Claude Code nadpisuje blokadę, więc pętla nie może trwać w nieskończoność; zmienna środowiskowa CLAUDE_CODE_STOP_HOOK_BLOCK_CAP ustawia ten limit (domyślnie 8; sprawdzone w Claude Code 2.1.283, nadal obecne w 2.1.286).
#!/usr/bin/env bash# Refuse "done" until the solution builds without warnings and the tests pass.cd "$CLAUDE_PROJECT_DIR" || exit 0# Skip turns that changed no C#, project or gate files (a question, a plan).[ -z "$(git status --porcelain -- '*.cs' '*.csproj' '*.props' '*.targets' '*.sln' '*.slnx' '.editorconfig' 'BannedSymbols.txt' 'global.json' 'packages.lock.json')" ] && exit 0if ! out=$(dotnet build --no-restore 2>&1); then echo "dotnet build failed. Fix the code; do not add NoWarn or #pragma." >&2 echo "If the error is NETSDK1004 or NU1xxx, run 'dotnet restore --locked-mode' (or update packages.lock.json) first." >&2 echo "$out" | grep -E ": (error|warning) " | sort -u | head -30 >&2 exit 2fiif ! out=$(dotnet test --no-build 2>&1); then echo "dotnet test failed. Fix src/, never tests/:" >&2 echo "$out" | tail -40 >&2 exit 2fiexit 0Warunek pomijania (linia z git status) sprawdza tylko niezatwierdzone zmiany: jeśli agent zrobi commit w trakcie tury, bramka się nie uruchomi, więc każ mu nie commitować (albo porównuj z HEAD z początku sesji). Drzewo, które już wcześniej miało zmiany, uruchamia pełną bramkę w każdej turze, także przy samych pytaniach.
Zarejestruj go w ustawieniach projektu i nadaj skryptowi prawo wykonania (chmod +x):
{ "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/dotnet-gate.sh", "timeout": 600 } ] } ] }}Skrypt celowo ignoruje stop_hook_active, pole, które Claude Code ustawia w danych wejściowych hooka, gdy zakończenie zostało już raz zablokowane. Wyjście z kodem 0 przy wartości true przepuściłoby drugą próbę mimo czerwonego builda; zamiast tego pętlę ogranicza limit ośmiu blokad, więc uporczywy błąd może kosztować około dziewięciu przebiegów builda i testów, zanim Claude Code i tak zakończy pracę.
Hook kosztuje pełny build i przebieg testów, razem z Testcontainers, w każdej turze, która zmieniła pliki C# lub projektu, więc trzymaj Dockera włączonego w trakcie sesji. Jeśli lokalnie to za wolno, uruchamiaj tylko testy, które nie potrzebują Dockera, a pełny zestaw zostaw CI. W trybie MTP składnia --filter z VSTest nie działa; użyj filtra cech (trait) z xUnit v3. Oznacz każdą klasę testów integracyjnych atrybutem [Trait("Category", "Integration")], a potem zmień linię z testami w dotnet-gate.sh:
if ! out=$(dotnet test --no-build --filter-not-trait "Category=Integration" 2>&1); thenPozostałe zdarzenia opisuje strona automatyzacja hookami.
Przywracanie pakietów NuGet wymaga sieci, a sandbox workspace-write nie ma dostępu do sieci, dopóki go nie włączysz. Przywróć pakiety najpierw, poza agentem, a potem uruchom pętlę bez sieci:
dotnet restore --locked-modecodex exec --sandbox workspace-write "Implement POST /orders so every test in CreateOrderTests passes. Do not modify tests/. Finish only when 'dotnet build --no-restore' and 'dotnet test --no-build' both pass; print the last lines of each."Jeśli agent musi dodać pakiet, włącz sieć tylko na ten jeden przebieg: -c sandbox_workspace_write.network_access=true. To starszy system --sandbox; jeśli twoja konfiguracja ustawia default_permissions, oba mechanizmy się nie łączą, więc wybierz jeden (sprawdzone w codex-cli 0.157.1). Testcontainers potrzebuje też dostępu do gniazda Dockera; jeśli sandbox go blokuje, uruchamiaj testy integracyjne w CI, a lokalnej pętli daj tylko testy jednostkowe.
W sesji interaktywnej Codex 0.157.1 ma też zdarzenie hooka Stop; rejestrację hooków i zaufanie do nich opisuje strona automatyzacja Codex.
Wklej prompt implementacyjny do agenta, najpierw w Plan Mode, jeśli zmiana obejmuje kilka projektów. Wpisz Definition of done do reguły projektu, żeby agent uruchamiał komendy, zanim zgłosi wynik. Cursor ma też Hooks, czyli skrypty wymieniające z agentem JSON przez stdio, więc hook może lokalnie uruchamiać te same komendy dotnet build i dotnet test; strona Używaj hooków jako deterministycznych zabezpieczeń pokazuje, jak zaadaptować skrypt z Claude Code i traktować go jako doradczy, dopóki nie przejdzie testu w prawdziwej sesji Cursora. Właściwa bramka dla Cursora działa po otwarciu pull requesta: zadanie CI poniżej oraz Bugbot, jeśli twój zespół używa go do review.
Niezależnie od tego, co działa lokalnie, rozstrzyga CI. Uruchom tam te same komendy z tokenem tylko do odczytu:
name: dotnet-gateson: [pull_request]permissions: contents: readjobs: gates: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-dotnet@v6 with: global-json-file: global.json - run: dotnet restore --locked-mode - run: dotnet tool restore - run: dotnet format --verify-no-changes --no-restore - run: dotnet build --no-restore - run: dotnet test --no-build - run: dotnet ef migrations has-pending-model-changes --project src/Orders.Infrastructure --startup-project src/Orders.ApiJak obsługiwać migracje EF Core z agentem?
Dział zatytułowany „Jak obsługiwać migracje EF Core z agentem?”Migracje to jedyne miejsce, w którym zielone testy nie są wystarczającym dowodem. Agent może wygenerować migrację, która czysto nakłada się na pustą bazę testową, a mimo to niszczy dane na produkcji. Klasyczny przypadek: agent zmienia nazwę właściwości, EF Core generuje DropColumn i AddColumn, testy przechodzą na świeżej bazie, a dane z kolumny znikają przy pierwszym wdrożeniu.
Podziel pracę między bramki i człowieka:
| Kontrola | Jak | Kto decyduje |
|---|---|---|
| Model i migracje są zgodne | dotnet ef migrations has-pending-model-changes (EF Core 8 i nowsze) pada, gdy model zmienił się bez migracji | CI |
| Migracje nakładają się od zera | Fixture ApiFactory uruchamia MigrateAsync() na pustym PostgreSQL | CI |
| SQL jest taki, jakiego oczekujesz | Wynik dotnet ef migrations script --idempotent dołączony do pull requesta | Człowiek czyta SQL, a nie C# |
| Operacje niszczące | DropColumn, DropTable, AlterColumn zawężające typ | Człowiek, przez CODEOWNERS na **/Migrations/ |
Szersze zasady zmian typu expand-and-contract i wycofywania opisują wzorce migracji baz danych. EF Core 11 dodaje plik .config/dotnet-ef.json z domyślnymi wartościami --project i --startup-project; w EF Core 10 trzymaj te flagi w AGENTS.md.
Które analizatory i testy zamieniają komentarze z review w błędy builda?
Dział zatytułowany „Które analizatory i testy zamieniają komentarze z review w błędy builda?”Każdy komentarz, który piszesz drugi raz pod pull requestem agenta, to reguła, której jeszcze nie zautomatyzowałeś. W C# większość z nich może stać się diagnostyką kompilatora albo testem. Każda bramka poniżej robi się czerwona z konkretnego powodu:
| Bramka | Konfiguracja | Robi się czerwona, gdy |
|---|---|---|
| Typy referencyjne nullable | <Nullable>enable</Nullable> plus TreatWarningsAsErrors | Agent dereferuje wartość, która może być null |
| Reguły jakości CA | <AnalysisLevel>latest-recommended</AnalysisLevel> | Kod łamie regułę z zalecanego zestawu CA (projekt, niezawodność, wydajność, bezpieczeństwo, użycie) |
| Styl kodu | Poziomy w .editorconfig plus EnforceCodeStyleInBuild | Agent ignoruje konwencje nazewnictwa albo użycia var w zespole |
| Zakazane API | Microsoft.CodeAnalysis.BannedApiAnalyzers (5.6.0) i BannedSymbols.txt | Kod wywołuje DateTime.Now, Task.Result albo cokolwiek innego z listy (diagnostyka RS0030) |
| Architektura | NetArchTest.Rules (1.3.2, ostatnie wydanie w maju 2021; aktywnie rozwijaną alternatywą jest TngTech.ArchUnitNET 0.13.4) w teście | Projekt domeny odwołuje się do infrastruktury albo ASP.NET Core |
| Siła testów | dotnet-stryker (5.0.0) | Testy nadal przechodzą po tym, jak Stryker zmutuje testowany kod |
Lista zakazanych API to najprostszy sposób na zapisanie zasady „tak tu nie robimy”. Dodaj pakiet do projektów w src/, dodaj <AdditionalFiles Include="BannedSymbols.txt" /> i wypisz identyfikatory dokumentacji z komunikatem, który agent przeczyta:
P:System.DateTime.Now;Inject TimeProvider and call GetUtcNow()P:System.DateTime.UtcNow;Inject TimeProvider and call GetUtcNow()P:System.Threading.Tasks.Task`1.Result;Await the task instead of blockingM:System.Threading.Tasks.Task.Wait;Await the task instead of blockingM:System.Threading.Tasks.Task.Wait(System.Int32);Await the task instead of blockingM:System.Threading.Tasks.Task.Wait(System.TimeSpan);Await the task instead of blockingM:System.Threading.Tasks.Task.Wait(System.Threading.CancellationToken);Await the task instead of blockingM:System.Threading.Tasks.Task.Wait(System.Int32,System.Threading.CancellationToken);Await the task instead of blockingM:System.Runtime.CompilerServices.TaskAwaiter.GetResult;Await the task instead of blockingM:System.Runtime.CompilerServices.TaskAwaiter`1.GetResult;Await the task instead of blockingTest architektury utrzymuje warstwy solucji po 50 sesjach agenta:
[Fact]public void Domain_does_not_depend_on_infrastructure_or_web(){ var result = Types.InAssembly(typeof(Order).Assembly) .ShouldNot().HaveDependencyOnAny("Orders.Infrastructure", "Microsoft.AspNetCore") .GetResult();
Assert.True(result.IsSuccessful, string.Join(", ", result.FailingTypeNames ?? []));}Testy mutacyjne odpowiadają na pytanie, na które zielony przebieg nie odpowie: czy te testy zauważyłyby, że kod jest błędny? Uruchom dotnet tool install dotnet-stryker, a potem dotnet stryker w katalogu projektu testowego i przeczytaj mutanty, które przeżyły. Siła wyroczni wyjaśnia, jak zamienić ocalałe mutanty w brakujące przypadki testowe.
Zmiany w Directory.Build.props, .editorconfig, BannedSymbols.txt i każdy wpis NoWarn osłabiają same bramki, więc przypisz tym ścieżkom ludzkiego właściciela w CODEOWNERS. Strona pakiet dowodów pokazuje, jak dołączyć wyniki bramek i SQL migracji do pull requesta, żeby recenzent sprawdzał dowody, a nie kod.
Jak dać agentowi aktualną dokumentację .NET i nawigację po kodzie?
Dział zatytułowany „Jak dać agentowi aktualną dokumentację .NET i nawigację po kodzie?”W .NET najbardziej pomagają dwa dodatki: aktualna dokumentacja Microsoftu, bo API zmieniają się między wersjami głównymi, oraz serwer języka, bo wyszukiwanie tekstowe słabo znajduje wszystkie wywołania w dużej solucji.
Serwer MCP Microsoft Learn. Zdalny serwer pod https://learn.microsoft.com/api/mcp, bez uwierzytelniania, z trzema narzędziami: microsoft_docs_search, microsoft_docs_fetch i microsoft_code_sample_search. Parametr ?maxTokenBudget=2000 w adresie ogranicza, ile każda odpowiedź dokłada do kontekstu; poniższe fragmenty dla Codex i Cursora już go zawierają. Popularność: około 1,9 tys. gwiazdek na GitHubie dla MicrosoftDocs/mcp (GitHub, odczyt 2026-09-26).
Zainstaluj wtyczkę Microsoftu, która łączy serwer MCP z jego skillami (uruchom w sesji):
/plugin install microsoft-docs@claude-plugins-officialWtyczka rejestruje adres bez limitu. Żeby dodać sam serwer z limitem, uruchom zamiast tego w powłoce:
claude mcp add --transport http microsoft-learn "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000"Do nawigacji po kodzie zainstaluj serwer języka C# i wtyczkę, która go rejestruje. Wtyczka nie zawiera samego programu:
dotnet tool install --global csharp-lsclaude plugin install csharp-lsp@claude-plugins-officialcsharp-lsp miał 43 741 instalacji w katalogu wtyczek claude.com (odczyt 2026-09-26). Wtyczki LSP nie dokładają stałego kosztu kontekstu, bo serwer działa poza procesem.
codex mcp add microsoft-learn --url "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000"Dodaj serwer do .cursor/mcp.json:
{ "mcpServers": { "microsoft-learn": { "url": "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000" } } }Bez serwera agent łata luki danymi treningowymi i pisze na przykład bezparametrowy builder Testcontainers albo filtry dotnet test w stylu VSTest. Z serwerem jeden prompt najpierw sprawdza aktualne API:
Według README microsoft/skills zawiera 175 skilli do SDK we wtyczkach językowych dla Pythona, .NET, TypeScriptu, Javy i Rusta. Leżą poniżej katalogu głównego repozytorium, więc npx skills add microsoft/skills --list pokazuje tylko 13 skilli z korzenia; z --full-depth znajduje 192, czyli zestaw SDK oraz skille z korzenia i inne zagnieżdżone (sprawdzone 2026-09-26). README ostrzega też, że wczytanie wszystkich naraz psuje kontekst („context rot”), więc instaluj tylko skille do tych SDK Azure, których używa twoja usługa. Strona najlepsze skille backendowe i platformowe porównuje je z zestawami innych dostawców.