ਪ੍ਰੋਂਪਟ ਸੁਝਾਅ ਹੁੰਦੇ ਹਨ। ਹੁੱਕਸ (Hooks) ਸਖ਼ਤ ਰੋਕ ਹਨ।
ਕਈ ਮਹੀਨਿਆਂ ਤੱਕ, ਮੈਂ Claude Code ਨੂੰ ਇੱਕ ਜੂਨੀਅਰ ਡਿਵੈਲਪਰ ਵਾਂਗ ਸਮਝਿਆ ਜਿਸਨੂੰ ਸਿਰਫ਼ ਸਪੱਸ਼ਟ ਨਿਯਮਾਂ ਦੀ ਲੋੜ ਸੀ। ਮੇਰੇ ਪ੍ਰੋਜੈਕਟ ਦੇ ਨਿਰਦੇਸ਼ ਸਪੱਸ਼ਟ ਸਨ: ਕਦੇ ਵੀ force-push ਨਾ ਕਰੋ, ਕਦੇ ਵੀ ਬ੍ਰਾਂਚਾਂ (branches) ਨੂੰ ਡਿਲੀਟ ਨਾ ਕਰੋ, ਕਦੇ ਵੀ ਵਿਨਾਸ਼ਕਾਰੀ (destructive) ਕਮਾਂਡਾਂ ਨਾ ਚਲਾਓ। ਜ਼ਿਆਦਾਤਰ ਸ਼ਾਮਾਂ ਨੂੰ, ਇਹ ਕੰਮ ਕਰਦਾ ਸੀ। ਏਜੰਟ ਨੇ ਟੈਸਟ ਲਿਖੇ, ਫੰਕਸ਼ਨਾਂ ਨੂੰ ਰੀਫੈਕਟਰ (refactor) ਕੀਤਾ, ਅਤੇ git history ਨਾਲ ਛੇੜਛਾੜ ਨਹੀਂ ਕੀਤੀ। ਫਿਰ ਇੱਕ rebase ਗਲਤ ਹੋ ਗਿਆ।
context window git error output ਨਾਲ ਭਰ ਗਈ। Conflict markers, detached HEAD messages, ਅਤੇ branch divergence warnings ਟੋਕਨ-ਦਰ-ਟੋਕਨ ਜਮ੍ਹਾਂ ਹੋ ਗਏ। ਉਸ ਸ਼ੋਰ ਦੇ ਹੇਠਾਂ force-pushing ਤੋਂ ਬਚਣ ਲਈ ਮੇਰਾ ਨਿਮਰਤਾ ਵਾਲਾ ਨਿਰਦੇਸ਼ ਦਬਿਆ ਹੋਇਆ ਸੀ। ਮਾਡਲ ਲਈ, ਥ੍ਰੈਡ ਵਿੱਚ ਸਭ ਤੋਂ ਤਾਜ਼ਾ ਅਤੇ ਪ੍ਰਮੁੱਖ ਟੈਕਸਟ error stream ਸੀ। ਅੰਕੜਾਤਮਕ ਧਿਆਨ (Statistical attention) ਨੀਤੀ (policy) ਉੱਤੇ ਭਾਰੀ ਪੈ ਗਿਆ। ਏਜੰਟ ਨੇ ਇੱਕ ਅਜਿਹੀ ਕਮਾਂਡ ਚਲਾਈ ਜਿਸ ਨੇ ਦੋ ਘੰਟਿਆਂ ਦੇ ਅਣ-ਕਮਿਟ ਕੀਤੇ (uncommitted) ਲੋਕਲ ਬਦਲਾਅ ਮਿਟਾ ਦਿੱਤੇ। ਇਹ ਕੋਈ ਬਦਲੇ ਦੀ ਭਾਵਨਾ ਨਹੀਂ ਸੀ; ਇਹ ਸਿਰਫ਼ ਧਿਆਨ ਭਟਕਣ ਕਾਰਨ ਸੀ। ਇਹ ਅੰਤਰ ਮਹੱਤਵਪੂਰਨ ਹੈ। ਇੱਕ LLM ਬਦਲੇ ਦੀ ਭਾਵਨਾ ਨਾਲ ਨਿਯਮ ਨਹੀਂ ਤੋੜਦਾ। ਇਹ ਨਿਯਮ ਇਸ ਲਈ ਤੋੜਦਾ ਹੈ ਕਿਉਂਕਿ context window ਵਿੱਚ ਇੱਕ ਉੱਚੀ ਆਵਾਜ਼ ਵਾਲਾ ਪੈਟਰਨ ਅਸਥਾਈ ਤੌਰ 'ਤੇ ਪਹਿਲਾਂ ਦਿੱਤੇ ਨਿਰਦੇਸ਼ ਨੂੰ ਦਬਾ ਦਿੰਦਾ ਹੈ।
ਉਸ ਘਟਨਾ ਨੇ ਏਜੰਟ ਸੁਰੱਖਿਆ (agent safety) ਬਾਰੇ ਮੇਰੀ ਸੋਚ ਬਦਲ ਦਿੱਤੀ। ਇੱਕ ਗਾਰਡਰੇਲ (guardrail) ਜੋ ਨੜਿੱਨਵੇਂ ਫੀਸਦੀ ਵਾਰ ਕੰਮ ਕਰਦਾ ਹੈ, ਉਹ ਇੱਕ ਜੋਖਮ ਹੈ। ਜੇਕਰ ਅਸਫਲਤਾ ਦਾ ਤਰੀਕਾ ਤੁਹਾਡਾ ਸਮਾਂ, ਪੈਸਾ, ਜਾਂ ਪ੍ਰੋਡਕਸ਼ਨ ਡੇਟਾ ਖਰਾਬ ਕਰਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਸਨੂੰ ਪ੍ਰੋਂਪਟ ਦੇ ਅੰਦਰ ਨਹੀਂ ਛੱਡ ਸਕਦੇ। ਤੁਹਾਨੂੰ ਮਾਡਲ ਦੇ ਤਰਕ ਲੂਪ (reasoning loop) ਤੋਂ ਬਾਹਰ ਲਾਗੂ ਕਰਨ ਵਾਲੇ ਸਾਧਨਾਂ ਦੀ ਲੋੜ ਹੈ।
Claude Code hooks ਬਿਲਕੁਲ ਇਸੇ ਸਮੱਸਿਆ ਦਾ ਹੱਲ ਕਰਦੇ ਹਨ। ਇਹ ਛੋਟੇ ਸਕ੍ਰਿਪਟ ਹਨ ਜੋ ਤਿੰਨ ਖਾਸ ਸਮੇਂ 'ਤੇ ਟੂਲ ਕਾਲਾਂ (tool calls) ਨੂੰ ਰੋਕਦੇ ਹਨ: ਟੂਲ ਚੱਲਣ ਤੋਂ ਪਹਿਲਾਂ (PreToolUse), ਟੂਲ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ (PostToolUse), ਅਤੇ ਜਦੋਂ ਏਜੰਟ ਇਹ ਫੈਸਲਾ ਕਰਦਾ ਹੈ ਕਿ ਉਹ ਕੰਮ ਖਤਮ ਕਰ ਚੁੱਕਾ ਹੈ (Stop)। ਕਿਉਂਕਿ ਉਹ ਬਾਹਰੀ ਕੋਡ ਵਜੋਂ ਚੱਲਦੇ ਹਨ, ਉਹ ਮਾਡਲ ਦੀ ਯਾਦਦਾਸ਼ਤ, ਮੂਡ, ਜਾਂ context ਦੇ ਦਬਾਅ 'ਤੇ ਨਿਰਭਰ ਨਹੀਂ ਕਰਦੇ। ਮਾਡਲ ਤੁਹਾਡੇ ਦੁਆਰਾ ਦਿੱਤੇ ਗਏ ਹਰ ਨਿਰਦੇਸ਼ ਨੂੰ ਭੁੱਲ ਸਕਦਾ ਹੈ; ਪਰ ਹੁੱਕ ਫਿਰ ਵੀ 'ਨਾ' ਕਹੇਗਾ।
ਇੱਥੇ ਉਹ ਹਾਰਨੈੱਸ (harness) ਹੈ ਜੋ ਮੈਂ ਉਸ ਗੁਆਚੀ ਹੋਈ ਸ਼ਾਮ ਤੋਂ ਬਾਅਦ ਬਣਾਇਆ ਸੀ।
ਗਾਰਡ ਹੁੱਕ (The Guard Hook): ਨੁਕਸਾਨ ਹੋਣ ਤੋਂ ਪਹਿਲਾਂ ਰੋਕੋ
ਮੇਰਾ PreToolUse ਹੁੱਕ ਹਰ Bash ਕਮਾਂਡ ਦੀ ਜਾਂਚ ਕਰਦਾ ਹੈ ਜਦੋਂ ਸ਼ੈੱਲ (shell) ਉਸਨੂੰ ਛੂਹਣ ਵਾਲਾ ਹੁੰਦਾ ਹੈ। ਮੈਂ ਵਿਨਾਸ਼ਕਾਰੀ ਪੈਟਰਨਾਂ ਦੀ ਇੱਕ ਸਖ਼ਤ denylist ਰੱਖਦਾ ਹਾਂ। ਜੇਕਰ ਕਮਾਂਡ ਸਟ੍ਰਿੰਗ ਕਿਸੇ ਖ਼ਤਰਨਾਕ ਚੀਜ਼ ਨਾਲ ਮੇਲ ਖਾਂਦੀ ਹੈ, ਤਾਂ ਹੁੱਕ ਅਮਲ (execution) ਨੂੰ ਰੋਕ ਦਿੰਦਾ ਹੈ ਅਤੇ ਸਿੱਧਾ ਏਜੰਟ ਨੂੰ ਇੱਕ ਗਲਤੀ (error) ਵਾਪਸ ਭੇਜ ਦਿੰਦਾ ਹੈ।
ਮੈਂ ਜੋ ਪੈਟਰਨ ਬਲੌਕ ਕਰਦਾ ਹਾਂ ਉਹ ਸਰਲ ਅਤੇ ਸਪੱਸ਼ਟ ਹਨ:
git push --forceਜਾਂ ਕੋਈ ਵੀ force-with-lease ਵੇਰੀਐਂਟ ਜਿਸ 'ਤੇ ਮੈਂ ਅਜੇ ਭਰੋਸਾ ਨਹੀਂ ਕਰਦਾgit reset --hardrm -rf
ਇਹ ਕੋਈ ਉੱਨਤ ਸੁਰੱਖਿਆ ਖੋਜ ਨਹੀਂ ਹੈ। ਇਹ ਇੱਕ ਸੀਟਬੈਲਟ ਹੈ। ਪਰ ਮਹੱਤਵਪੂਰਨ ਵੇਰਵਾ ਇਹ ਹੈ ਕਿ ਬਲੌਕ ਕਰਨ ਤੋਂ ਬਾਅਦ ਕੀ ਹੁੰਦਾ ਹੈ।
ਮੈਂ ਕਦੇ ਵੀ ਸਿਰਫ਼ “Blocked” ਨਹੀਂ ਕਹਿੰਦਾ। ਇੱਕ ਸਿੱਧਾ ਇਨਕਾਰ ਏਜੰਟ ਨੂੰ ਉਲਝਣ ਵਿੱਚ ਪਾ ਸਕਦਾ ਹੈ ਅਤੇ ਉਸਨੂੰ ਇੱਕ ਅਜਿਹੇ ਲੂਪ ਵਿੱਚ ਫਸਾ ਸਕਦਾ ਹੈ ਜਿੱਥੇ ਉਹ ਉਸੇ ਵਿਨਾਸ਼ਕਾਰੀ ਕਮਾਂਡ ਦੇ ਵੱਖ-ਵੱਖ ਰੂਪਾਂ ਨੂੰ ਅਜ਼ਮਾਉਂਦਾ ਰਹਿੰਦਾ ਹੈ। ਇਸ ਦੀ ਬਜਾਏ, ਗਲਤੀ ਦੇ ਸੰਦੇਸ਼ ਵਿੱਚ ਇੱਕ ਬਚਾਅ ਦਾ ਰਸਤਾ ਸ਼ਾਮਲ ਹੁੰਦਾ ਹੈ। ਜਦੋਂ ਹੁੱਕ ਇੱਕ hard reset ਨੂੰ ਫੜਦਾ ਹੈ, ਤਾਂ ਇਹ ਏਜੰਟ ਨੂੰ ਦੱਸਦਾ ਹੈ: “ਅਣ-ਕਮਿਟ ਕੀਤੇ ਕੰਮ ਦੀ ਰੱਖਿਆ ਲਈ ਇਹ ਕਮਾਂਡ ਬਲੌਕ ਕੀਤੀ ਗਈ ਹੈ। ਪਹਿਲਾਂ ਇੱਕ ਚੈੱਕਪੁਆਇੰਟ ਕਮਿਟ ਕਰੋ, ਫਿਰ ਦੁਬਾਰਾ ਵਿਚਾਰ ਕਰੋ।” ਉਹ ਵਾਧੂ ਵਾਕ ਏਜੰਟ ਦੇ ਵਿਵਹਾਰ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਬਦਲ ਦਿੰਦਾ ਹੈ। ਇਹ ਨੁਕਸਾਨ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਦੀ ਬਜਾਏ ਸੁਰੱਖਿਆ ਬਣਾਉਣ ਵੱਲ ਮੁੜ ਜਾਂਦਾ ਹੈ। ਹੁੱਕ ਸਿਰਫ਼ ਇੱਕ ਕੰਧ ਨਹੀਂ ਹੈ; ਇਹ ਟ੍ਰੈਫਿਕ ਕੰਟਰੋਲ ਹੈ।
ਮੈਂ ਸ਼ੈੱਲ ਕਮਾਂਡਾਂ ਲਈ allowlist ਦੀ ਬਜਾਏ denylist ਨੂੰ ਚੁਣਿਆ। ਸ਼ੁਰੂ ਵਿੱਚ, ਮੈਂ ਸਿਰਫ਼ ਸੁਰੱਖਿਅਤ git subcommands ਦੇ ਇੱਕ ਸਪੱਸ਼ਟ ਸੈੱਟ ਨੂੰ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਬਾਰੇ ਵਿਚਾਰ ਕੀਤਾ ਸੀ। ਉਹ ਜਲਦੀ ਹੀ ਅਸਫਲ ਹੋ ਗਿਆ। ਏਜੰਟ ਬਹੁਤ ਹੀ ਸ਼ਾਬਦਿਕ (literal) ਹੁੰਦੇ ਹਨ। ਉਹ ਸਥਿਤੀ ਦੀ ਜਾਂਚ ਕਰਨ ਲਈ git stash push -m "wip" ਜਾਂ git branch --show-current ਵਰਗੀਆਂ ਜਾਇਜ਼ ਪਰ ਅਣਕਿਆਸੀ ਕਮਾਂਡਾਂ ਚਲਾਉਂਦੇ ਹਨ। ਇੱਕ allowlist ਉਸੇ ਪਲ ਆਮ ਵਰਕਫਲੋ ਨੂੰ ਤੋੜ ਦਿੰਦੀ ਹੈ ਜਦੋਂ ਮਾਡਲ ਇੱਕ ਵੈਧ ਪਰ ਅਣ-ਲਿਸਟਡ ਕਮਾਂਡ ਬਣਾਉਂਦਾ ਹੈ। ਅਸਲ ਵਿਨਾਸ਼ਕਾਰੀ ਪੈਟਰਨਾਂ ਦੀ ਇੱਕ ਛੋਟੀ, ਚੁਣਵੀਂ denylist ਏਜੰਟ ਨੂੰ ਸਰਹੱਦਾਂ ਦੀ ਰੱਖਿਆ ਕਰਦੇ ਹੋਏ ਕੰਮ ਕਰਨ ਦੀ ਥਾਂ ਦਿੰਦੀ ਹੈ।
ਫਾਰਮੈਟਰ ਹੁੱਕ (The Formatter Hook): ਰੁਟੀਨ ਕੰਮਾਂ ਨੂੰ ਆਟੋਮੇਟ ਕਰੋ
ਮੈਂ ਏਜੰਟ ਨੂੰ “ਫਾਈਲ ਐਡਿਟ ਕਰਨ ਤੋਂ ਬਾਅਦ ਹਮੇਸ਼ਾ ਫਾਰਮੈਟਰ ਚਲਾਓ” ਕਹਿ ਕੇ ਪ੍ਰੋਂਪਟ ਟੋਕਨ ਬਰਬਾਦ ਕਰਦਾ ਸੀ। ਉਹ ਅੱਧੇ ਸਮੇਂ ਵਿੱਚ ਭੁੱਲ ਜਾਂਦਾ ਸੀ। ਬਾਕੀ ਅੱਧੇ ਸਮੇਂ ਵਿੱਚ, ਉਹ ਰੁਕ ਜਾਂਦਾ ਸੀ ਅਤੇ ਪੁੱਛਦਾ ਸੀ ਕਿ ਕੀ ਫਾਰਮੈਟ ਕਰਨਾ ਹੈ, ਜਿਸ ਨਾਲ ਇੱਕ ਅਜਿਹੇ ਫੈਸਲੇ 'ਤੇ ਟੂਲ ਕਾਲ ਬਰਬਾਦ ਹੋ ਜਾਂਦੀ ਸੀ ਜਿਸਦਾ ਸਿਰਫ਼ ਇੱਕ ਹੀ ਸਹੀ ਜਵਾਬ ਸੀ।
ਹੁਣ ਮੈਂ ਇਸਨੂੰ PostToolUse ਹੁੱਕ ਨਾਲ ਸੰਭਾਲਦਾ ਹਾਂ। ਏਜੰਟ ਦੁਆਰਾ ਫਾਈਲ ਐਡਿਟ ਕਰਨ ਤੋਂ ਬਾਅਦ, ਹੁੱਕ ਫਾਈਲ ਐਕਸਟੈਂਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰਦਾ ਹੈ। ਜੇਕਰ ਇਹ Python ਹੈ, ਤਾਂ ਇਹ Ruff ਚਲਾਉਂਦਾ ਹੈ। ਜੇਕਰ ਇਹ JavaScript ਜਾਂ TypeScript ਹੈ, ਤਾਂ ਇਹ Prettier ਚਲਾਉਂਦਾ ਹੈ। ਜੇਕਰ ਇਹ Go ਹੈ, ਤਾਂ ਇਹ gofmt ਚਲਾਉਂਦਾ ਹੈ। ਏਜੰਟ ਨੂੰ ਇਹ ਪਤਾ ਹੀ ਨਹੀਂ ਹੁੰਦਾ ਕਿ ਫਾਰਮੈਟਰ ਮੌਜੂਦ ਹੈ। ਉਸਨੂੰ ਇਸਦੀ ਲੋੜ ਵੀ ਨਹੀਂ ਹੈ।
ਇਸਨੂੰ ਪ੍ਰੋਂਪਟ ਤੋਂ ਬਾਹਰ ਕੱਢਣ ਦੇ ਦੋ ਪ੍ਰਭਾਵ ਹੋਏ। ਪਹਿਲਾ, ਮਾਡਲ 'ਤੇ ਬੋਝ ਪਾਏ ਬਿਨਾਂ ਕੋਡ ਲਗਾਤਾਰ ਸਾਫ਼ ਰਹਿੰਦਾ ਹੈ। ਦੂਜਾ, ਮੇਰੇ ਪ੍ਰੋਜੈਕਟ ਦੇ ਨਿਰਦੇਸ਼ ਛੋਟੇ ਹੋ ਗਏ। ਹਰ ਉਹ “always” ਅਤੇ “never” ਜੋ ਤੁਸੀਂ ਪ੍ਰੋਂਪਟ ਤੋਂ ਹਟਾਉਂਦੇ ਹੋ, ਉਹ ਇੱਕ ਟੋਕਨ ਹੈ ਜੋ ਮਾਡਲ ਅਸਲ ਸਮੱਸਿਆ ਹੱਲ ਕਰਨ 'ਤੇ ਖਰਚ ਕਰ ਸਕਦਾ ਹੈ। ਹੁੱਕ ਨਿਯਮਾਂ (invariant) ਨੂੰ ਸੰਭਾਲਦਾ ਹੈ; ਪ੍ਰੋਂਪਟ ਇਰਾਦੇ (intent) ਨੂੰ ਸੰਭਾਲਦਾ ਹੈ।
ਕੁਆਲਿਟੀ ਗੇਟ (The Quality Gate): “Done” ਦੀ ਮੁੜ ਪਰਿਭਾਸ਼ਾ
The Stop hook runs when the agent decides it has finished the task and attempts to terminate the session. I do not let it. Instead, the hook runs the full test suite. If any test fails, the hook blocks the stop command and returns the failure output to the agent.
This changes the definition of completion. “Done” is no longer a feeling the model has. It is a measurable gate. The agent can only finish when the harness confirms the code works. In practice, this creates a tight feedback loop. The agent writes code, thinks it is finished, hits the stop button, and immediately sees a pytest traceback. It then self-corrects, fixes the import error or broken assertion, and tries to stop again. I have watched agents iterate three or four times inside this loop without human intervention. The harness enforces quality; the model supplies the patches.
What This Teaches About Agent Engineering
Building reliable autonomous systems requires a shift in mindset. You move from writing longer prompts to building tighter harnesses.
Use hooks for enforcement and prompts for policy. If a rule must hold one hundred percent of the time, it belongs in code, not in natural language. Prompts excel at ambiguity, taste, and architecture. They are terrible at invariants. If a mistake would cost you an afternoon of recovery time or, worse, production uptime, write a hook.
Shorter prompts produce better results. When you move mechanical rules into scripts, the model has less to remember and less to contradict. The agent’s context window is a scarce resource. Do not fill it with formatting reminders.
Finally, accept that your role is changing. As agents gain autonomy, the human’s job shifts from generating content to designing the guardrails. You are building the harness that decides what the model can touch, when it can finish, and how it must behave when things go wrong. That is engineering, not prompting.
The source that inspired this approach and additional implementation detail can be found here.
If you are building with AI agents and want to trade notes with other practitioners, you can find the GyaanSetu learning community here.
