Claude Code hooks: jinsi ya kugeuza kanuni za wakala kuwa dhamana
Hooks za Claude Code ni amri za shell ambazo Claude Code yenyewe huziendesha kwenye matukio fulani: kabla na baada ya kuita zana, wakati ombi linatumwa, wakati kikao kinaanza, na kabla wakala hajasimama. Zinasanidiwa kwenye settings.json, na exit code 2 huzuia kitendo na kumrudishia wakala ujumbe wa kosa, hivyo hook inageuza kanuni ya CLAUDE.md kuwa dhamana ambayo modeli haiwezi kuisahau.
Hooks za Claude Code ni nini
Hook ni amri inayoendeshwa si na modeli, bali na programu ya Claude Code yenyewe wakati fulani wa kazi ya wakala. Wakala anakaribia kuendesha rm -rf — hook inaanza na kuamua kama amri ipitishwe. Wakala amehariri faili — hook inaendesha formatter. Wakala anataka kumaliza kazi — hook inaendesha majaribio na haimruhusu kusimama mpaka yapite.
Tofauti kuu na maelekezo kwenye CLAUDE.md: maelekezo ni maandishi ambayo modeli huzingatia kwa uwezekano fulani, wakati hook ni msimbo wa uhakika. Itafanya kazi kila wakati, bila kujali muktadha ni mrefu kiasi gani, wakala ameamua nini, au kama amesahau kanuni dakika ya mia ya kikao. Ndiyo maana hooks za claude code ndiyo njia kuu ya kugeuza matakwa kuwa dhamana.
Kwa nini kanuni katika CLAUDE.md hazitoshi
Picha ya kawaida: wakala ameongeza kipengele, majaribio ya kitengo ni ya kijani, na kwenye gumzo kuna jibu la uhakika «Imekamilika». Lakini hakuna aliyeendesha mfululizo wa mwisho-hadi-mwisho, linter haikuendeshwa, na migration ilianguka katikati. Kwenye CLAUDE.md imeandikwa «kabla ya kumaliza endesha majaribio». Modeli haidanganyi kwa makusudi — inajitathmini yenyewe tu, na kujitathmini huko si cha kuaminika.
Hapa ndipo kanuni ya harness inapotokea: kila kinachoweza kukaguliwa kwa mitambo, mitambo ndiyo inayokikagua, si modeli. Kanuni «endesha linter» inakuwa hook inayoendesha linter. Kanuni «usiguse config ya uzalishaji» inakuwa hook inayozuia kuandika kwenye faili hilo. Maelekezo ya maandishi yanabaki, lakini yanaeleza tu kwa nini wakala amesimamishwa.
Matukio: hooks zinaanza lini
Kila hook imefungwa kwenye tukio la mzunguko wa maisha wa kikao. Matukio makuu:
| Tukio | Linaanza lini | Matumizi ya kawaida |
|---|---|---|
PreToolUse | kabla ya kuita zana (Bash, Edit, Write n.k.) | kuzuia amri hatari, kulinda faili |
PostToolUse | baada ya zana kufanikiwa | formatter, linter, majaribio ya haraka baada ya mabadiliko |
UserPromptSubmit | mtumiaji anapotuma ombi, kabla halijashughulikiwa | kuongeza muktadha, kukataa ombi lenye siri |
Stop | wakala anapokaribia kumaliza jibu | kuzuia kusimama hadi ukaguzi upite |
SubagentStop | subagent anapomaliza kazi | kukagua matokeo ya subagent |
SessionStart | kikao kinapoanza au kuendelea | kupakia hali: git status, mpango, jarida la maendeleo |
SessionEnd | kikao kinapomalizika | kusafisha, kuandika kumbukumbu |
Notification | Claude Code inapotuma arifa (kwa mfano, inangoja ruhusa) | sauti au ujumbe kwenye simu |
PreCompact | kabla ya kubana muktadha | kuhifadhi kilicho muhimu kabla ya compaction |
Yenye manufaa zaidi kwa uaminifu ni PreToolUse, PostToolUse na Stop: zinafunga udhaifu tatu wa wakala — vitendo hatari, mabadiliko yasiyokaguliwa, na «imekamilika» kabla ya wakati.
Mahali hooks zinapowekwa: settings.json
Hooks zinaelezwa kwenye faili za mipangilio za Claude Code:
~/.claude/settings.json— zako binafsi, kwa miradi yote;.claude/settings.jsonndani ya hazina — za timu nzima, zinaingizwa kwenye git;.claude/settings.local.json— za mradi wa ndani, haziingii kwenye git.
Muundo ni huu: tukio → orodha ya vikundi vyenye matcher → orodha ya amri.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/lint.sh",
"timeout": 60
}
]
}
]
}
}
matcher ni jina la zana au regular expression juu yake: Bash, Edit|Write, .*. Inahitajika kwa matukio yanayohusu zana; kwa Stop au UserPromptSubmit unaweza kuiacha. Kigezo CLAUDE_PROJECT_DIR kinaelekeza kwenye mzizi wa mradi, kwa hiyo ni vyema kuweka hati kwenye .claude/hooks/ na kuziita kupitia kigezo hicho. Hooks zilizopo unaweza kuziona kwa amri /hooks ndani ya Claude Code.
Hook inapokea data na kujibu vipi
Ingizo: JSON kwenye stdin
Claude Code inampa hook JSON yenye taarifa za tukio: kitambulisho cha kikao, saraka ya kazi, jina la tukio, na kwa zana — tool_name na tool_input. Kwa Bash, amri iko kwenye tool_input.command; kwa Edit na Write, njia ya faili iko kwenye tool_input.file_path. Kusoma ni rahisi kwa jq.
{
"session_id": "abc123",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": { "command": "rm -rf build/" },
"cwd": "/home/dev/project"
}
Matokeo: msimbo wa kurudi
| Msimbo | Kinachotokea |
|---|---|
0 | mafanikio, kazi inaendelea; kwa UserPromptSubmit na SessionStart stdout inaongezwa kwenye muktadha wa wakala |
2 | kosa la kuzuia: stderr inapelekwa kwa wakala, na kitendo kinasimamishwa (kwa PreToolUse — wito wa zana unaghairiwa, kwa Stop — wakala anaendelea kufanya kazi) |
| nyingine | kosa lisilozuia: stderr inaonyeshwa kwa mtumiaji, kazi inaendelea |
Exit code 2 ndiyo mtambo muhimu. Wakala anapokea maandishi ya stderr kama maoni na anaweza kujirekebisha: kuandika upya amri, kurekebisha jaribio, kutogusa faili. Kwa hiyo kwenye stderr andika si «kosa» tu, bali sababu wazi na kinachopaswa kufanywa badala yake.
Mbali na msimbo wa kurudi, hook inaweza kutoa kwenye stdout JSON yenye uamuzi, kwa mfano "decision": "block" na "reason". Hii ni kwa marekebisho ya kina, lakini kwa kazi nyingi inatosha code 2 na ujumbe kwenye stderr.
Mfano 1: linter na majaribio baada ya kila mabadiliko
Hook ya PostToolUse yenye matcher Edit|Write inaanza baada ya faili kubadilishwa. Zana tayari imeshatekelezwa, hivyo mabadiliko hayawezi kughairiwa, lakini code 2 inamrudishia wakala matokeo ya linter, naye atarekebisha kosa mara moja, si baada ya nusu saa.
#!/usr/bin/env bash
# .claude/hooks/lint.sh
file=$(jq -r '.tool_input.file_path // empty')
case "$file" in
*.py)
if ! out=$(ruff check "$file" 2>&1); then
echo "Linter imepata makosa katika $file:" >&2
echo "$out" >&2
exit 2
fi ;;
*.php)
if ! out=$(php -l "$file" 2>&1); then
echo "$out" >&2
exit 2
fi ;;
esac
exit 0
Usiweke hapa majaribio kamili ya dakika kumi: hook inaanza kwa kila mabadiliko. Baada ya mabadiliko endesha ukaguzi wa haraka (sintaksia, linter, majaribio ya moduli moja), na ukaguzi mzito uwe kwenye hook ya Stop.
Mfano 2: kuzuia amri hatari
Hook ya PreToolUse yenye matcher Bash inaona amri kabla haijatekelezwa. Code 2 inaghairi wito, na wakala anapata maelezo.
#!/usr/bin/env bash
# .claude/hooks/guard.sh
cmd=$(jq -r '.tool_input.command // empty')
if echo "$cmd" | grep -Eq 'rm -rf /|git push (-f|--force)|DROP (TABLE|DATABASE)'; then
echo "Amri imezuiwa na sera ya mradi: $cmd. Shughuli hatari hufanywa na binadamu." >&2
exit 2
fi
exit 0
Kwa njia hiyo hiyo mafaili yanalindwa: hook ya Edit|Write inakagua file_path na kuzuia kuandika kwenye .env, config za uzalishaji, msimbo uliozalishwa au faili za migration ambazo tayari zimetumika. Kumbuka kwamba utafutaji kwa regular expression unaweza kukwepwa — wakala anaweza kuandika amri kwa njia nyingine. Hook ni kinga imara, lakini si mbadala wa ruhusa za ufikiaji na sanduku la mchanga.
Mfano 3: wakala hawezi kusema «imekamilika» wakati majaribio ni nyekundu
Hook ya Stop inaanza wakati wakala anakaribia kumaliza. Majaribio yasipopita, code 2 inazuia kusimama, na matokeo ya majaribio yanaenda kwa wakala kama kazi inayofuata. Hii ni toleo la kimitambo la Definition of Done.
#!/usr/bin/env bash
# .claude/hooks/done.sh
input=$(cat)
# ulinzi dhidi ya mzunguko usio na mwisho: hook tayari iliongeza kazi mara moja
if [ "$(echo "$input" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0
fi
if ! out=$(npm test --silent 2>&1); then
echo "Majaribio yameshindwa, kazi haijakamilika:" >&2
echo "$out" | tail -n 40 >&2
exit 2
fi
exit 0
Sehemu stop_hook_active ina thamani true ikiwa wakala tayari anaendelea kazi kwa sababu ya stop hook. Bila ukaguzi huu hook inaweza kumzungusha wakala bila kikomo — hali hasa ya «anafanya kazi usiku kucha mahali pasipofaa». Katika mizunguko ya kujiendesha ongeza pia kikomo cha majaribio na sharti la kumwita binadamu.
Mfano 4: kupakia hali mwanzoni mwa kikao
Kwenye SessionStart, stdout ya hook inaingia kwenye muktadha. Ni vyema kuonyesha tawi la sasa, mabadiliko ambayo hayajawekwa commit, na kazi inayofuata kutoka kwenye mpango, ili wakala asianze kutoka mwanzo.
#!/usr/bin/env bash
echo "Tawi: $(git branch --show-current)"
git status --short | head -n 20
[ -f PROGRESS.md ] && tail -n 15 PROGRESS.md
exit 0
Jinsi hooks zinavyogeuza kanuni kuwa dhamana
Ni rahisi kugawanya kanuni za harness katika ngazi tatu. Ya kwanza ni maandishi kwenye CLAUDE.md: yanaeleza jinsi ya kufanya kazi, lakini yanafuatwa kwa uwezekano. Ya pili ni ukaguzi unaoweza kutekelezwa: majaribio, E2E, kanuni za usanifu kwa njia ya skripti inayoanguka inapovunjwa. Ya tatu ni hooks zinazoendesha ukaguzi huo kiotomatiki kwa wakati unaofaa, bila ushiriki wa modeli.
Kanuni ya vitendo: ikiwa wakala amevunja kanuni ileile mara mbili, usiongeze onyo jingine kwa herufi kubwa kwenye CLAUDE.md. Jiulize kama ukiukaji huo unaweza kukaguliwa kwa skripti. Ikiwezekana — tengeneza skripti na uiunganishe kwenye hook. Maelekezo ya maandishi yanakuwa mafupi, na tabia inakuwa thabiti zaidi.
| Kanuni kwa maandishi | Dhamana kupitia hook |
|---|---|
| «Panga msimbo kwa kiwango» | PostToolUse inaendesha formatter kwenye faili lililobadilishwa |
| «Usipushe kwa force» | PreToolUse kwenye Bash inazuia amri, exit 2 |
| «Usiseme imekamilika wakati majaribio ni nyekundu» | Stop inaendesha majaribio na haimruhusu kumaliza |
| «Usihariri .env» | PreToolUse kwenye Edit|Write inakagua njia |
| «Kumbuka ulipoishia» | SessionStart inaonyesha mpango na git status |
Makosa ya kawaida
- Code 1 badala ya 2. Skripti inaanguka kwa code 1, wakala hajui chochote, na kitendo kinapita. Ni code 2 pekee inayozuia.
- Ujumbe kwenye stdout. Kwa code 2 wakala anapokea stderr. Andika kupitia
>&2. - Hook ya polepole kwenye tukio la mara kwa mara. Majaribio kamili kwenye PostToolUse yanafanya kila mabadiliko kuwa ya dakika moja. Vitu vizito viwe kwenye Stop.
- Stop isiyo na mwisho. Hakuna ukaguzi wa
stop_hook_activewala kikomo — wakala anazunguka bila kikomo. - Njia za jamaa. Hook inaendeshwa kwenye saraka ya kazi ya kikao; tumia
$CLAUDE_PROJECT_DIR. - Hook ya mtu mwingine isiyokaguliwa. Hook inaendeshwa kwa ruhusa zako bila uthibitisho. Soma skripti za hazina za watu wengine kabla ya kuziamini.
Hitimisho
Hooks za Claude Code zinahamisha kanuni muhimu zaidi kutoka maandishi kwenda msimbo: PreToolUse inazuia vitendo hatari, PostToolUse inakagua kila mabadiliko, Stop haimruhusu wakala kutangaza utayari kabla ya wakati, na SessionStart inamrudishia wakala kumbukumbu ya mradi. Anza na hooks mbili au tatu kwa kanuni ambazo wakala tayari amezivunja, na weka ujumbe kwenye stderr uwe wazi — kwa njia hiyo wakala mwenyewe anarekebisha makosa, nawe unakagua matokeo, si mchakato. Uthibitisho, ukaguzi wa utayari na mizunguko ya kujiendesha tunafundisha kwa vitendo katika kozi.
Maswali ya mara kwa mara
Je, ninahitaji kuanzisha upya Claude Code baada ya kubadilisha hooks?
Mabadiliko kwenye settings.json yanaanza kutumika kwa uhakika zaidi kwenye kikao kipya; usanidi wa sasa wa hooks unaweza kuonekana kwa amri /hooks.
Je, hooks zinaweza kuandikwa kwa lugha nyingine isipokuwa bash?
Ndiyo, hook ni amri yoyote: skripti ya Python, Node.js au binary. Jambo la msingi ni kusoma JSON kutoka stdin na kurudisha msimbo sahihi wa kutoka.
Je, wakala anaona matokeo ya hook iliyofanikiwa?
Kwa kawaida hapana: kwa code 0 matokeo hayaingii kwenye muktadha. Isipokuwa ni UserPromptSubmit na SessionStart, ambapo stdout inaongezwa kwenye muktadha wa wakala.
Je, hooks zinafanya kazi kwa subagents?
Ndiyo, wito wa zana za subagents unapitia hooks zilezile za PreToolUse na PostToolUse, na kwa kumaliza kwao kuna tukio tofauti la SubagentStop.
Je, ni salama kuweka hooks kwenye hazina?
Ndiyo, .claude/settings.json na skripti za .claude/hooks/ ni mazoea ya kawaida kwa timu; hooks zako binafsi zihifadhiwe kwenye settings.local.json au ~/.claude/settings.json.
Mada hii inafundishwa kwa kina pamoja na mazoezi katika kozi “Harness Engineering: инженерия надёжности AI-агентов”.
- Агент написал «готово», а фича не работает: verification gap и Definition of Done
- Все тесты зелёные, а фича сломана: E2E-тесты и архитектурные правила для AI-агента
- Автономный AI-агент часами без присмотра: Loop Engineering и условия остановки