Keep full materials online as versioned ZIPs; wire chapter cross-refs, assembler order, and rebuild the book PDF.
19 KiB
Kapitel 2
Grundlagen und Konfiguration – Instructions und Permissions
Kern in einem Satz: Was der Agent jedes Mal wissen müsste, gehört in Custom Instructions (weich); was er technisch dürfen soll, steuerst du über Tool-Approval, Flags und Deny (hart).
2.1 Szene: leeres Repo, falscher Stack
Dienstag, erstes Ticket im neuen Repo: „Bitte Tests grün machen.“ Copilot CLI tippt npm test. Dein Stack ist Python mit pytest. Fünf Minuten rote Logs, dann rät der Agent poetry run pytest – und mittendrin liegt schon eine „hilfreiche“ package.json im Diff.
Nichts davon war böse Absicht. Ohne Projektwissen rät das Modell den häufigsten Stack aus dem Training. Der Harness führt aus, was erlaubt ist – und du siehst entweder rote Logs oder, schlimmer, „erfolgreiche“ Änderungen am falschen Stack.
Zwei Hebel teilen die Arbeit:
| Hebel | Rolle | Wirkung |
|---|---|---|
| Custom Instructions | weiches Memory (Dateien, die du schreibst) | Build/Test, Layout, „immer/nie“ – steuert über Kontext |
| Permissions / Flags | harte Policy | Tools freigeben oder blocken – steuert über den Harness |
Kern: „Sollte nicht“ → Instructions. „Darf nicht“ → Deny, Hook oder Sandbox. Die Verwechslung ist der häufigste Config-Fehler: weiche Wünsche an harte Risiken.
Scope eng halten beginnt hier schon bei den Instructions: kurze, prüfbare Sätze statt Roman. Je vager die Dateien, desto breiter rät das Modell – und desto teurer wird der Diff.
Begriffsklärung: Im Buch meint weiches Memory vor allem Custom Instructions (und AGENTS.md). Das ist nicht dasselbe Produkt wie GitHub Copilot Memory (persistente Facts/Preferences, die der Agent aus der Arbeit ableitet) – dazu Abschnitt Copilot Memory vs. Custom Instructions.
2.2 Weich: Custom Instructions
Custom Instructions sind natürliche Sprache in Markdown-Dateien. Sie werden nicht im Chat angezeigt, stehen dem Modell aber als Kontext zur Verfügung. Du tippst „Tests: pytest -q“ einmal ins Repo – und sparst dir den Satz in jedem Prompt.
Stand der Fakten: Mitte/Ende 2026. Primär: Adding custom instructions for GitHub Copilot CLI. UI-Details und exakte Labels können driften; das Konzept bleibt: Discovery kombiniert, keine generelle Precedence.
Wo Instructions herkommen
| Ort | Scope |
|---|---|
.github/copilot-instructions.md |
Repo-weit, team-geteilt über Git |
.github/instructions/**/*.instructions.md |
path-scoped über YAML-Frontmatter applyTo |
AGENTS.md |
Agent-Instructions, Discovery in Standard-Locations |
~/.copilot/copilot-instructions.md |
User-weit, alle Repos |
~/.copilot/instructions/**/*.instructions.md |
modulare User-Instructions |
Discovery (vereinfacht): Repo-Root, aktuelles Arbeitsverzeichnis, Zwischenpfade und – bei Dateiarbeit – der Pfad der bearbeiteten Datei. Modular-Dateien (*.instructions.md) sind path-spezifisch: applyTo greift nur bei Match.
Setzt du COPILOT_HOME, ersetzt dieses Verzeichnis ~/.copilot für User-Instructions (und den Rest der CLI-Config).
Zusätzlich: Verzeichnisse in COPILOT_CUSTOM_INSTRUCTIONS_DIRS (kommagetrennt) für weitere AGENTS.md und *.instructions.md.
Mehrere Dateien: kombinieren, nicht „gewinnen“
Wenn mehrere User- und Repo-Instructions greifen, kombiniert Copilot CLI sie. Identische Duplikate bestimmter Dateitypen werden entfernt – es gibt keine generelle Precedence zwischen den Quellen. Widersprüche („Tests: npm“ vs. „Tests: pytest“) sind dein Problem, nicht das des Harness.
Path-scoped Instructions fließen nur ein, wenn applyTo zu einer Datei passt, an der der Agent arbeitet. Mit /instructions siehst du die für die Session entdeckten Dateien und kannst einzelne enable/disable.
Repo-weit: .github/copilot-instructions.md
Minimum – und oft genug:
# Projekt-Kompass
## Build & Test
- Python 3.9+, Install: `pip install -e ".[dev]"`
- Tests: `pytest -q`
- Lint: `ruff check .` (wenn im Repo)
## Layout
- App-Code unter `todo/`, Tests unter `tests/`
- Keine Secrets committen
## Immer
- Vor Commit: Tests grün
- Diff kurz zusammenfassen
## Nie
- `rm -rf` auf Projektwurzel oder Home
- Force-Push auf `main`/`master`
Was rein gehört:
- Build / Test / Lint – besonders nicht-offensichtliche Commands
- Layout in 5–15 Zeilen (Orientierung, kein Dateibaum-Roman)
- 2–3 Immer / Nie (prüfbar, wiederkehrend)
- Gotchas („Tests brauchen lokales Redis“)
Was raus gehört:
- Generische Floskeln („schreib sauberen Code“)
- 200-Zeilen-Dateibaum (veraltet, frisst Kontext)
- Lange Tutorials (besser Skill oder
@docs/…)
Vorlagen:
- Stabile Kernfassung im Buch: Anhang A.1
vorlagen/copilot-instructions.minimal.mdvorlagen/copilot-instructions.team.md
Vollständig und aktuell: Begleit-Service → Material → vorlagen.zip. Im Beispielprojekt: beispiele/todo-cli/ (README beschreibt das Harness-Layout). Was die Session dort mitbringt, siehst du an den Dateien – nicht erst im Prompt:
Path-scoped: *.instructions.md + applyTo
Dateiname muss auf .instructions.md enden. Frontmatter:
---
applyTo: "tests/**/*.py"
---
# Tests
- Arrange–Act–Assert, ein Verhalten pro Test
- Fixtures: `tmp_path` statt fester Home-Pfade
- Keine Netzwerk-Calls in Unit-Tests
Mehrere Globs: Komma-getrennt, z. B. applyTo: "**/*.ts,**/*.tsx".
Optional excludeAgent: "code-review" oder "cloud-agent", wenn die Datei nur für die CLI (bzw. nur für einen der Agenten) gelten soll – siehe Doku.
Vorlage: vorlagen/path-instructions.example.md.
AGENTS.md
Copilot CLI entdeckt AGENTS.md in den Standard-Locations. Inhalt ist dieselbe Klasse wie Custom Instructions: natürliche Sprache, reviewbar, team-geteilt. Viele Repos nutzen AGENTS.md als gemeinsame Agent-Baseline; .github/copilot-instructions.md bleibt die Copilot-typische Repo-Datei. Beides kann existieren – dann kombinieren und Konflikte vermeiden. Vorlage: vorlagen/AGENTS.md.example.
In .github/copilot-instructions.md, AGENTS.md (und verwandten Agent-Dateien) kannst du mit @relativer/pfad andere Dateien einbinden. Absolute Pfade und ~/… werden nicht geladen. In *.instructions.md werden @-Referenzen nicht expandiert.
User-Ebene
Persönliche Gewohnheiten – Ton, generische Git-Hygiene – gehören nach ~/.copilot/, nicht den Test-Command dieses Repos:
~/.copilot/copilot-instructions.md
~/.copilot/instructions/git-hygiene.instructions.md
Repo-Fakten ins Git; User-Prefs lokal. Sonst committest du deine Tastatur-Vorlieben und der Kollege bekommt deinen Editor-Stil als „Team-Policy“.
/instructions und Reload
/instructions
Zeigt die für die Session entdeckten Instruction-Dateien; einzeln ein-/ausschalten.
Achtung: Änderungen an Instruction-Dateien sind in laufenden Sessions nicht sofort aktiv. Session beenden und fortsetzen (
copilot --continue) oder neue Session (/new) – so steht es in der Doku.
copilot init – Generator, kein Source of Truth
cd dein-repo
copilot init
Initialisiert Custom Instructions für das Repository (Vorschlag/Gerüst laut CLI). Danach: lesen, kürzen, halluzinierte Commands streichen, speichern. Source of Truth ist die Datei nach deinem Review – nicht der Generator-Lauf.
Copilot Memory vs. Custom Instructions
GitHub Copilot Memory (öffentliche Preview, Stand Docs) speichert vom Agenten abgeleitete Fakten – z. B. Repo-Konventionen mit Code-Zitaten und persönliche Interaktions-Preferences. Es fließt u. a. in Cloud Agent, Code Review und Copilot CLI ein und kann die Last wiederholter Prompt-Erklärungen senken. Ungenutzte Einträge verfallen typisch nach einer Frist (Docs: u. a. 28 Tage ohne Nutzung).
| Custom Instructions (dieses Kapitel) | Copilot Memory | |
|---|---|---|
| Wer schreibt | du / Team in Markdown | Agent aus Aktivität (mit Validierung) |
| Sichtbarkeit | Dateien im Repo / ~/.copilot/ |
Produkt-UI / Admin-Pfade (Plan-abhängig) |
| Steuerung | Git-Review, /instructions |
Feature-Policy, Opt-out, manuell löschen |
| Für Teams | Baseline im PR reviewbar | Org/Enterprise-Policy, User-Prefs je Billing-Entity |
Praxis: Bleib bei expliziten Instructions für Build-Commands, „Immer/Nie“ und reviewbare Team-Normen. Copilot Memory ist Zusatz, kein Ersatz – und kann veralten oder Annahmen speichern, die du so nicht im PR hättest. Individuelle Pläne: oft an; Business/Enterprise: Admin-Policy, dann User-Opt-out. Verwaltung und Details: Docs About GitHub Copilot Memory und How-tos unter Copilot Memory.
/chronicle improve (Kapitel 7) kann aus Session-Historie Vorschläge für .github/copilot-instructions.md ableiten – das schreibt in die Instruction-Datei, nicht ins Memory-Produkt.
Jetzt selbst machen
cd beispiele/todo-cli
# Falls noch keine Instructions: copilot init – oder Vorlage kopieren:
# mkdir -p .github
# cp ../../vorlagen/copilot-instructions.minimal.md .github/copilot-instructions.md
copilot
In der Session:
/instructions
Dann:
Welche Test- und Install-Commands gelten in diesem Repo?
Nenne sie wörtlich aus den Instructions. Ändere nichts.
Wenn die Antwort npm test ist, fehlen oder greifen die Instructions nicht – Fix: Datei, CWD, Session neu.
2.3 Hart: Permissions und Tool-Approval
Instructions bitten. Permissions erzwingen (soweit der Harness greift). Ein eloquenter Prompt ändert kein Deny.
Tool-Approval in der Session
Wenn der Agent etwas potenziell Destruktives will (Schreiben, riskante Shell, URLs, …), fragt die CLI. Typische Wahl:
| Option | Bedeutung |
|---|---|
| Yes | Dieses Mal erlauben; nächstes Mal wieder fragen |
| Session-Allow (Formulierung driftet) | Für den Rest der Session freigeben – oft mit beliebigen Optionen desselben Tools |
| No + Feedback | Ablehnen; optional sagen, was stattdessen |
Achtung: Session-Allow für
rmbedeutet: der Agent darf im Session-Kontext löschen, ohne erneut zu fragen. Die Doku nennt genau dieses Beispiel. Session-Allow ist bequem fürpytestundgit status– und gefährlich für destruktive Commands.
Ablehnen ist kein Fehler – es ist Steuerung. „Nein, nutze pytest -q vom Repo-Root“ steuert oft besser als stilles Yes auf den falschen Command.
Flags beim Start
copilot \
--allow-tool='shell(pytest)' \
--allow-tool='shell(ruff)' \
--allow-tool='shell(git status)' \
--allow-tool='shell(git diff)' \
--allow-tool='shell(git log)' \
--deny-tool='shell(rm)' \
--deny-tool='shell(git push)'
Precedence: --deny-tool schlägt --allow-tool und auch --allow-all-tools / gespeicherte Approvals.
Muster (Form Kind(argument)):
| Pattern | Wirkung |
|---|---|
shell(git:*) |
git und Subcommands (Shell-Matching laut Doku) |
shell(git push) |
genau dieser Command |
write |
Datei-Schreiben |
write(secret.txt) |
Write nur für diesen Pfad (Deny/Allow scoped) |
MyMCP / MyMCP(tool) |
MCP-Server bzw. einzelnes Tool |
Weitere permissive Flags:
| Flag | Bedeutung |
|---|---|
--allow-all-tools |
alle verfügbaren Tools freigeben |
--allow-all / --yolo |
Tools + Paths + URLs (sehr weit) |
/allow-all / /yolo |
dasselbe in der Session |
Achtung: YOLO gibt dem Agenten im Wesentlichen dieselben Rechte wie dir – ohne Einzel-Approval. Deny und enge Allowlist vor Session-YOLO. Niemals als Shell-Alias für jeden Start. In isolierter Umgebung oder mit Sandbox; auf dem Alltags-Laptop mit Prod-Zugang und SSH-Keys ist das ein echtes Risiko, nicht nur „weniger Klicks“.
Optional zweite Schicht: --available-tools / --excluded-tools schränken ein, welche Tools das Modell überhaupt sieht (andere Story als Allow/Deny der Permission-Prompts). Details: copilot help permissions und die Tool-Doku.
permissions-config.json – gespeicherte Approvals
Pfad-Default: ~/.copilot/permissions-config.json (bzw. unter $COPILOT_HOME).
Speichert Approvals pro Location (Git-Root bzw. CWD) – z. B. „nicht wieder fragen in diesem Repo“ für pytest. Keine Deny-Regeln in dieser Datei. Denys kommen über Flags, Settings und Session-Ablehnung.
CLI-Flags (--allow-tool / --deny-tool) gelten nur für die aktuelle Session und schreiben diese Datei nicht. Deny schlägt trotzdem gespeicherte Approvals.
Schema und Matching: CLI configuration directory – und die kommentierte Startvorlage vorlagen/settings.permissions-hints.md. Stabile Kernfassung im Buch: Anhang A.3.
Reset in der Session (Approvals zurücksetzen):
/reset-allowed-tools
(setzt u. a. Session-Freigaben zurück und leert gespeicherte Tool-Approvals der aktuellen Location; Start-Flags bleiben die Baseline.)
Minimum-Allowlist für den Alltag
Ziel: Testen und Git lesen ohne Freifahrt für Write/Push/rm.
# Enge Allowlist – bewusst ohne Write-Freifahrt und ohne push
copilot \
--allow-tool='shell(pytest)' \
--allow-tool='shell(git status)' \
--allow-tool='shell(git diff)' \
--deny-tool='shell(rm)' \
--deny-tool='shell(git push)'
Headless-Beispiel (nur lesen/testen, nichts schreiben):
copilot -p "Führe die Unit-Tests aus und fasse Fehler zusammen. Keine Codeänderungen." \
--allow-tool='shell(pytest)' \
--deny-tool='shell(rm)' \
--deny-tool='write'
Settings (Ausblick)
Verhalten und Policy-Schalter liegen in der Settings-Hierarchie (User/Repo/Local, COPILOT_HOME, Flags). Für Kapitel 2 reicht:
- User:
~/.copilot/settings.json - Repo:
.github/copilot/settings.json - Local (gitignore):
.github/copilot/settings.local.json
Beispiel-Repo-Hints: beispiele/configs/settings.repo.example.jsonc. Tiefe Hierarchie, URL-Allow/Deny, Sandbox und MDM: Kapitel 4.
2.4 Faustregel und Checkliste
| Aussage | Mittel |
|---|---|
| „Sollte nicht force-pushen“ | Instructions (Nie-Liste) |
„Darf nicht rm / git push“ |
--deny-tool, Hook, Sandbox |
„Darf pytest ohne Rückfrage“ |
enge --allow-tool oder gespeicherte Approval |
| „YOLO für diesen Task“ | nur mit engem Scope, ideal Sandbox – und nach Deny-Baseline |
Vier Hebel in diesem Kapitel (kurz):
- Scope eng – kurze Instructions, path-scoped wo nötig
- Diff lesen – bevor du freigibst, was der Agent „nur schnell“ geschrieben hat
- Deny vor YOLO – Allowlist/Deny setzen, bevor
--allow-allverlockt - Weich vs. hart – bitten in Markdown, verbieten im Harness
Checkliste „Tag-2-Config sitzt“
.github/copilot-instructions.mdmit Build/Test + 2–3 Immer/Nie- optional path-scoped Datei für Tests oder Hot-Paths
/instructionszeigt die erwarteten Dateien- Startbefehl mit Minimum-Allowlist + Deny für
rm/git push - Kein dauerhaftes YOLO-Alias
- Nach Instruction-Edits: Session neu oder
--continue
Häufige Fehler
| Symptom | Typische Ursache |
|---|---|
Agent nutzt npm test im Python-Repo |
Instructions fehlen, falsch, oder Session ohne Reload |
| „Ich habe es in die Datei geschrieben, er ignoriert es“ | aktive Session ohne Restart/--continue |
| Widersprüchliche Commands | User- + Repo-Instructions ohne Abgleich |
| Zu viele Approval-Prompts | enge Allowlist für Test/Git-Status fehlt |
| Ungewollte Löschungen | Session-Allow auf rm oder YOLO ohne Deny |
Jetzt selbst machen (Permissions)
cd beispiele/todo-cli
copilot \
--allow-tool='shell(pytest)' \
--allow-tool='shell(git status)' \
--deny-tool='shell(rm)'
Prompt:
Führe pytest -q aus und fasse das Ergebnis in drei Zeilen zusammen.
Schreibe keine Dateien.
Beobachte: Wird pytest ohne Rückfrage ausgeführt? Wird Write/rm blockiert bzw. nachgefragt?
Was du jetzt kannst
- Die Trennlinie weich (Instructions) vs. hart (Permissions) erklären und anwenden
- Repo-, path-scoped und User-Instructions anlegen und mit
/instructionsprüfen - Custom Instructions von Copilot Memory (Produkt) unterscheiden
- Verstehen, dass mehrere Dateien kombinieren und Konflikte vermieden werden müssen
- Instruction-Änderungen mit Session-Neustart bzw.
--continueaktiv machen - Tool-Approval und Session-Allow-Risiko (z. B.
rm) einschätzen - Enge Allowlist und Deny-Flags setzen; Deny > Allow/All
- Wissen, dass
permissions-config.jsonApprovals speichert – keine Denys
Nächste Schritte
- Kapitel 3: Alltag – Explore → Plan → Code → Verify → Commit,
/review,/pr, Modelle - Kapitel 4: Settings-Hierarchie, Trusted Dirs, Sandbox, multi-repo
- Vorlagen kopieren und im eigenen Repo anpassen – nicht ungelesen committen (Kern: Anhang A; voll: Begleit-Service → Material)
- Enge Permissions als Session-Rezept:
beispiele/rezepte/01-enge-permissions.md· User-Vorlage:vorlagen/user/· Buch-Kern: A.2 / A.3
Primärquellen: Custom instructions, About Copilot Memory, Allowing and denying tool use, copilot help permissions.





