Як структураваць праекты Claude Code, каб агенты не губляліся ў вялікіх рэпазіторыях
Шэсць патэрнаў для вялікіх кодавых баз: шматузроўневыя файлы CLAUDE.md, навыкі, субагенты, правілы забароны, разрэджаныя worktree і плагіны моўных сервераў, якія трымаюць кантэкст агента чыстым.
Крыніцы: How I Structure Claude Code Projects So Agents Don’t Get Lost in Large Codebases
Уявіце саблікавы запрос да Claude Code: паспрацаваць з багам пра таймаут сесіі ў мідлвэрэ аўтэнтыфікацыі. Насамперадж, паспрацоўка выконуецца за тры рэядкі. Але перш чым дасягнуць іх, агент блукае праз сістэму логавання, історыю міграцый, палову з канцэнтраў API і, з прычын, якія ніхто не можа поясніць, праз настройкі Terraform. Пасля 147-го чытання файла распрацоўшчык проста натыкаецца на клавішу Escape.
У такім случае вінаватыкам не ёсць сама модэль. Вінаватыкам ёсць структура праекта. Кожная конвэнцыя, каманда будавання і архітэктурная рашэнне былі скупленыя ў аднам корневым файле CLAUDE.md дыяжнення 340 рэядкаў, які агент верна чытаў пад час запуску, перш чым выкорыстаць рэшту свайго часу на аналіз коду, які не стосуецца аўтэнтыфікацыі.
Гэта тое, што выходзіць, калі з агента ставяцца як з новым працавальнікам, які должны прачытаць усю інструкцыйную кнігу компаніі, прытымкі прабуючы выправіць практычную памялку. Ёму патрэбны правы кантэкст у правы момент, а не усё адразу. Далей прыводзяцца шасць способаў, якія гэта рашаюць, а таксама спосаб прыняць рашэнне, калі варта іх вжыць.
Чаму кантэкст шыбка заканчываецца
Вікна кантэксту Claude Code, якое становіць або 200 000 токенаў у выкарыстоўванай тут модэлі, здаецца вельмі вялікім, пакуль не перыяктуеце, што ўжо займае месца: кожная адправленая вамее паведамленне, кожны прачытаны файл, усе выходны даныя каманд, кожная інструкцыя CLAUDE.md і ўсе автаматычна зберагнутыя нотаткі. Адзін токен адпавядае прыблізна чатыром сімволам.
У вялікай базе коду 50 000 токенаў можа знікнуць прытым, як толькі пачнёма пісаць адзін радок коду. Файл CLAUDE.md з 300 радкамі коштае прыблізна 1 200 токенаў, файл з 500 радкамі — ўсё 2 000 токенаў, а выкарыстанне grep або find да дагледу за інфармацыяй дадае ўсё больш. Калі агент нарэшце зрозумее задачу, палова часовага прызначэння можа вяснуць. Калі часова рамка запоўняецца, выконвальная спроможнасць падваіцца: ранейшыя інструкцыі забываюцца, файлы чытаюцца зноў, і з’яўляюцца памылкі, якіх не было б у чыстым кантэксце. Большыя часовыя рамкі — не рашэння. Рашэнням ёсць выкарыстанне часовай рамкі, якая не містыць нерэлевантнай інфармацыі.
Шаблон 1: файлы CLAUDE.md з роўнамі
Першая памылка — запханне всьго ў файл-корань: команды для стварэння API, шаблоны компонентаў фронтэнду, правілы міграцыі, чарткі для развяртання і стандарты тэставання разам.
Калод Код чытае файлы CLAUDE.md з рабочага каталога аж да корана рэпазітарыя, калі пачынаецца сесія. Калі яго запусціць у падкаталозе, ён берае файлы з таго каталога плюс усі файлы з адпаведных верхніх каталогаў аж да корана. Таму раздзеліце контэнт па дзеяноснасці:
monorepo/
CLAUDE.md # repository-wide rules only
packages/
api/
CLAUDE.md # API-specific conventions
.claude/skills/
src/
web/
CLAUDE.md # frontend-specific conventions
.claude/skills/
src/
shared/
CLAUDE.md # shared library conventions
src/
Файл-корант зберагае толькі структуру рэпазітарыя і правілы віканання камітаванняў, якія складаюцься з апошніх 40 ліній, а кожны пакет несе сабе спецыфічныя дакладнасці, прызначаныя для яго сэрвісу. Запускайце агента ў катэгорыі packages/api/ — ён завантажыць файл-корант асо більш файл для API, не бачачы правіл, прызначаных для фронтэнду. Калі перэйсці ў packages/web/, тая ж логіка дае іншы фрагмент кантэксту.
У файле-коранце можа быць такі тэкст:
# Repository Structure
This is a monorepo with three packages under packages/:
- packages/api: Node.js REST API with Express, TypeScript, PostgreSQL
- packages/web: React frontend with Vite, TypeScript, TailwindCSS
- packages/shared: shared TypeScript utilities
Run commands from the package directory, not the monorepo root.
Each package has its own tsconfig.json, package.json, and test suite.
# Commit Conventions
- Prefix commits with the package name: "api: fix session timeout"
- One commit per logical change
- Run tests before committing
А пакет API дадзе толькі тое, што важлівае ў тым пакеце:
# API Package
This is the REST API server.
## Commands
- Run tests: `npm test` (uses Vitest)
- Run dev server: `npm run dev` (port 3001)
- Database migrations: `npm run migrate`
- Environment variables: copy `.env.example` to `.env`
## Code Patterns
API routes are in src/routes/. Each route file exports an Express router.
Database queries use Knex in src/db/. Never write raw SQL in route handlers.
## Testing
Tests are in src/__tests__/ mirroring the src/ directory.
Use supertest for HTTP assertions, not raw fetch.
Always wrap database tests in a transaction that rolls back.
У гэтым прыкладзе эфект заключаецца ў тым, што замест 340 ліній завантажанага кантэксту выкарыстоўваецца 80 ліній, а колькісць файлаў, неабходных для аўтэнтыфікацыі, складае 12 замест 147.
Шаблон 2: навыкі для знанняў на запіт
Нават многослойная структура можа стаць занадто вялікай. Шаблоны тэставання, чарткі для развертання і інструкцыі па адлагоджэнні — гэта процедуры, а не факты, і агенту яны не патрэбны пад час запуску, а толькі тады, калі задача гэта выклекае. Гэта і ёсць функцыя навыкаў.
Навыкі знаходзяцца пад падметам .claude/skills/ і завантажаюцца, калі Claude судзіць іх прыдатнымі, або калі яны явна запрашваюцца праз команду з слэшам. У опісе навыку паказана, калі яго трэба выкарыстоўваць, а ў яго тэле знаходзіцца сам фактычны контэнт. У гэтым прыкладзе інструкцыі па тэставанні пераходзяць з файла API ў навык:
# .claude/skills/api-testing/SKILL.md
---
name: api-testing
description: Testing patterns for the API package. Use when writing or modifying tests in packages/api/.
---
## Test Structure
Tests are in `src/__tests__/` mirroring the `src/` directory structure.
Each route file has a corresponding `.test.ts` file.
## Running Tests
- All tests: `npm test`
- Single file: `npm test -- src/__tests__/routes/users.test.ts`
- Watch mode: `npm test -- --watch`
## Test Utilities
- `src/__tests__/helpers/db.ts`: provides `setupTestDb()` and `teardownTestDb()`
- `src/__tests__/helpers/auth.ts`: provides `createTestUser()` and `getAuthToken()`
## Patterns
- Use `supertest` for HTTP assertions, not raw fetch
- Always wrap database tests in a transaction that rolls back
- Mock external services in `src/__tests__/mocks/`
Запытайце працэўніцу аб тэставанні сервіса аўтэнтыфікацыі, і яна запускае спэцыяльную навык для тэставання і дзеяе за ўзначанымі правіламі. Запытайце яе аб вылечэнні проблемы з таймаутам, але навык застанецца незапусканым, адтуды што тэставанне ня ўзначальнае.
Навыкі таксама падходзяць для павтаральных рабочых процэсаў. Навык, які запускаецца за дапамогою /fix-pr-comments, можа чытаць коментары да перагляду ў запрошэнні да змян у GitHub, вырахаваць неабходныя змяны, праверыць код, запустыць тэсты і выклаць змяны. Весь гэты процэс знаходзіцца ў самом навыку, а не ў файле CLAUDE.md, які з кожнай сесіі пераглядае кантэкст.
Аптовы прынцып: факты, якія неабходны ў кожной сесіі, кладуцца ў CLAUDE.md, а процедуры і матэрыялы для апылу стаюць навыкамі.
Шаблон 3: падагенты для ізольаванага аналізу
Нават з наявнасцю роўней і навыкаў, працэс аналізу ёсць занадта складным. Запітанне „Як працюе аўтэнтыфікацыя?“ можа прывесты да 40 запытанняў да чытання файлаў, калі агент ператварае працэсы входу, зберагання сесіі, апдэта токена і выходу з сесіі, і весь гэты тэкст застаецца ў главнай розмове пасля адпаведзі на запытанне, забрудняючы рэшту сесіі.
Падагент працуе у сваёй сабе окні кантэксту, выпрацоўвае аналіз і прысылае толькі статыстыку. Запытання да чытання файлаў і рэзультаты запытання grep застаюцца ў яго кантэксце. Главны поток отрымае толькі статыстыку, што дапамагае падтрымаць чыстоту розмовы. Запыт на даследжэнне можа выглядаць так:
Use a subagent to investigate how our authentication system handles
session timeout and token refresh. Report back what files are involved
and how the flow works.
Падзвінак чытае тое, што яму трэба, выявляе ход дзеяння і дае адказ, тады галоўная розмова атрымле чыстае адказаў пра 200 слоў, а не змест 40 файлаў. Падзвінакі таксама дапамагаюць у пераглядзе пасля адклёнення:
Use a subagent to review the session timeout fix for edge cases
and consistency with our existing auth patterns.
Падрэбнік, які адмацавае, бачыць сяродзець у свежым стане, без паслявыяння прычыны, якая спрычыніла змяну.
Адна парада: падсумкі выключаюць дакладнасць. Калі вам патрэбны точныя номеры ліній або фрагменты коду, галоўны агент можа быць змушаны перачытаць файлы, якія падрэбнік вялікі ўжо бачыў. Падрэбнікі падтрымліваюць галоўны направленні выканання, пакуль аналіз ведзецца ў іншым месцы.
Шаблон 4: захаванне створаных і падаўленых файлоў у непрачытаным стане
Усе, што знаходзіцца ў .gitignore, за замовчаннем ігнаруецца, таму node_modules/, dist/ і build/ не праблекаюцца ў рэзультатах пошуку. Частыя створаныя або падаўленыя коды такім чынам не фіксуюцца: скомпіляваныя вызначэнні protobuf, падаўленыя SDK-ы, створаныя тыпы GraphQL. Агент з радасцю адкрое іх, калі пошук іх выявіць, хоць гэта ніколі не должна выйсці.
Правіла адміністрацыі забараняюць чытанне выбраных шаблонаў файлаў. Апошнія правілы паказаны ніжэй, а точны сінтаксіс трэба пераканацца ў даследжэннях да вашай версіі Claude Code:
# packages/api/.claude/settings.json
{
"permissions": {
"deny": [
"Read(./**/dist/**)",
"Read(./**/build/**)",
"Read(./**/*.generated.*)",
"Read(./vendor/**)"
]
}
}
Калі пошук за фразай «GraphQL resolvers» знаходзіць файл схемы, створаныя програмай, рэзультат апыляецца, але адказчык інструмента Read паведамляе працоўкі з правамі, і агент зазвычай спытаецца, дзе знаходзіцца справжній адказ. Існуе дадатковы эфект, які варта ведаць: тыя ж правілы блакуець і ручныя запыты на чытанне ў вікні чату. Якша папросіць адказчыка ачысці src/schema.generated.ts, яго запыт будзе адхоўлены; тады трэба тымчасова адмяніць гэтае правіле. Гэта дапамагае утрымаць створаныя «шумы» парадульна ў кантэксце і направіць агента да справжньага адказу.
Шаблон 5: розрозненыя робочыя дрэвы
Claude Code можа ствараць git-робочыя дрэвы для паралельнай або ізольаванай працы, і за значэннем кожна з іх завантажае весь рэпазітарый. У монорэпазітарыі гэта ёсць некэрэйным, адколі для практычнага выправлення API не патрэбны фронтэнд-часткі.
Функцыя sparse-checkout у Git запісвае на дыск толькі выбраныя каталогі, а рэшту залішае ў індэксе, і наслаўванне worktree.sparsePaths будуе на гэтым прынцыпе. Пераканайцеся, што ключ настройкі супарадні з інструкцыямі да вашай версіі:
# packages/api/.claude/settings.json
{
"worktree": {
"sparsePaths": [
".claude",
"packages/api",
"packages/shared"
]
}
}
Worktrees з’яўляюцца толькі з катэгорыямі .claude/, packages/api/ і packages/shared/, а таксама з кантэнтам вышэйшага рэвёра, такімі як package.json і tsconfig.base.json. Іх лёгкая ствараць, і яны займаюць меншае прастору на дыску. Калі агент прабуе прачытаць файл, які не быў выкачаны, git выдае памылку, і агент зазвычай запытае, якія каталогі існуюць. Для рэжыму sparse-checkout патрэбен git 2.25 або новейшыя версіі, што можна паўнастая пераканацца за дапамогою команды git --version.
Шаблон 6: інтэлігэнція коду заместо сканавання файлаў
Шукаць месца, дзе функцыя візначана або выкарыстоўвана ў вялікай базе коду, вымагае багацько вызоваў команды grep і чытання файлаў, адколі агент скануе рэзультаты, ачынае кандыдаты і продовжае пошук.
Плагіні з розумнай кодаваннем спаўнаюць агента з серверам мовы. У замяну сканаванню ён запытаецца, дзе задана функцыя refreshAuthToken, і адразу ж атрымае файл і номер рэядка. Для праектаў на TypeScript офіцыйны плагін LSP інсталюецца так, хоць сінтаксіс інсталляцыі разніцяцца залежна ад версіі, таму пераканайцеся ў документацыі:
/plugin install typescript-lsp@claude-plugins-official
Запытайце, дзе выкарыстоўваецца refreshAuthToken, і агент запытае сервер мовы, і атрымвае:
src/middleware/auth.ts:47
src/routes/users.ts:103
src/__tests__/auth.test.ts:22
Не было неабяжнае чытанне файлаў, таму адпаведзі з’яўляюцца быстрэй, а кантэкст застаецца чыстым. Плагін таксама фіксуе памылкі тыпу пасля змян, не запускаючы tsc, таму памылкі стаюць відразу віднымі. Ён добра работае разам з правіламі адмовы: яны блакуюць непатрэбныя даны, а функцыя інтэлекту коду зменшае патрэбу сканаваць тое, што застаўся.
Усе шасць разам
Працюючы з кожным шаблонам, первісная практыка вылечэння бага выглядае прыбліжна так:
- Запускайце Claude з
packages/api/. - Ён завантажае галоўны файл
CLAUDE.md(40 ліній) і файл API (50 ліній). - Вы прасіце яго вылечыць баг з таймаутам сесіі ў сервісе аўтэнтыфікацыі.
- Ён апускае падагента для аналізу працэсу аўтэнтыфікацыі, які у своем кантэксце чытае або 20 файлаў.
- Падагент адмаўляе, што логіка таймауту знаходзіцца ў файле
src/middleware/auth.tsна 47-й лініі і ў яй вікорыстоўваецца неправільны оператор порэвання. - Галоўны агент чытае той файл, вылечвае баг, пішае тэст і запускае яго, працюючы з прыблізна чатырма файламі ў галоўнам кантэксце.
У гэтым апісанні «до» і «пасля» выглядаюць так: 147 чытанняя файлоў, тры невялікія неудачныя спробы і 35 хвілін проты прыблізна чатырох чытанняя, адна успешная спроба і 6 хвілін. Вважайце гэта анекдотам аднае з распрацоўшчыкаў, а не показнікам, але важнае — гэта напрамак: структура усунула пераканстаны межы пытаннем і адпаведным адпаведзеннем.
Выбір таго, што вам патрэбна
Не кожны праект патрэбуе ўсіх шасці элементаў. Одна рэпазітарыя з 50 файламі не патрэбуе шаравых файлоў чы розрозненых структурах працы. Калі база коду становіцца занадта вялікай, каб адна людзь могла ўсё запам’ятаваць, тады такія элементы пачынаюць даваць плоды:
- Разбітыя на шары файлы
CLAUDE.mdпадыходзяць, калі вы прасуеце далей за нерэлевантныя раздзелы у галоўным файле, або калі колегі спытваюць, чаму файл API містыць правілы фронтэнду. - Навыкі падыходзяць, калі раздзел
CLAUDE.mdстае процедурам або чарткай, або калі вы постаўляеце тыя ж інструкцыі ў чат раз за разам. - Падагенты падыходзяць, калі розследаванне заканчываецца патробам «прачытаць гэтыя 30 файлоў», або калі вы хачаце адзінакавую пераглядку.
- Правілы адмовы падыходзяць, калі агент продовжае ачынаць створаны або праданный код па-працэсу, незважаючы на наявнасць файла
.gitignore. - Розрозненыя робочыя дрэвы падыходзяць, калі монарэпа заўсёды трэба 10 секунд, каб яго запрацаваць, або калі вы ствараеце многа робочых дрэваў паралельна.
Мета не ў тым, каб слепа прыменяць усё. Гэта калі трэба з’явіць, калі кантэкст стае занадта заплутаным, і выбраць шаблон, які яго апрацоўвае. Іншыя фарматы таксама можу працаваць для большых баз коду, але гэтыя шасць ператвараюць агента, які чытае все, у таго, які чытае толькі правыя файлы, запісвае паследнія змяны і завершае працу.