ਤੁਸੀਂ ਸੋਮਵਾਰ ਦੀ ਸਵੇਰ ਨੂੰ ਪੰਜ ਗੰਭੀਰ ਬੱਗ ਰਿਪੋਰਟਾਂ (bug reports) ਦੇ ਨਾਲ ਜਾਗਦੇ ਹੋ। ਤੁਹਾਡੇ ਰਿਵਿਊ ਮੋਨੀਟਰਿੰਗ ਟੂਲ ਨੇ ਆਪਣਾ ਕੰਮ ਕਰ ਦਿੱਤਾ ਹੈ। ਇਸਨੇ ਹਰ ਕ੍ਰੈਸ਼ ਰਿਪੋਰਟ, ਹਰ ਗੁੱਸੇ ਵਾਲੀ ਇੱਕ-ਸਟਾਰ ਰਿਵਿਊ, ਅਤੇ ਹਰ "ਸੇਵ ਕਰਨ 'ਤੇ ਐਪ ਫ੍ਰੀਜ਼ ਹੋ ਜਾਂਦੀ ਹੈ" ਨੂੰ ਫੜ ਲਿਆ ਹੈ। ਤੁਸੀਂ ਜਾਣਦੇ ਹੋ ਕਿ ਕੀ ਖਰਾਬ ਹੈ। ਪਰ ਤੁਸੀਂ ਇਹ ਨਹੀਂ ਜਾਣਦੇ ਕਿ ਕਿੱਥੇ ਦੇਖਣਾ ਹੈ।
ਮੇਰਾ ਪਹਿਲਾ ਪਾਈਪਲਾਈਨ (pipeline) ਬਣਾਉਣ ਤੋਂ ਬਾਅਦ ਮੈਨੂੰ ਇਸੇ ਮੁਸ਼ਕਲ ਦਾ ਸਾਹਮਣਾ ਕਰਨਾ ਪਿਆ। ਇਸਨੇ ਬਿਨਾਂ ਕਿਸੇ ਮੁਸ਼ਕਲ ਦੇ ਐਪ ਰਿਵਿਊਜ਼ ਅਤੇ ਆਉਣ ਵਾਲੇ ਕ੍ਰੈਸ਼ ਲੌਗਸ (crash logs) ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ, ਅਤੇ ਹਰ ਫੀਡਬੈਕ ਨੂੰ ਸਹੀ ਤਰੀਕੇ ਨਾਲ ਵੱਖ-ਵੱਖ ਸ਼੍ਰੇਣੀਆਂ ਵਿੱਚ ਵੰਡ ਦਿੱਤਾ: ਬੱਗਸ (bugs), ਕ੍ਰੈਸ਼ਸ (crashes), ਜਾਂ ਫੀਚਰ ਰਿਕੁਐਸਟਸ (feature requests)। ਡੈਸ਼ਬੋਰਡ ਸਹੀ ਲੱਗ ਰਿਹਾ ਸੀ, ਪਰ ਅਸਲ ਡੀਬੱਗਿੰਗ (debugging) ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ।
ਇਹ ਜਾਣਨਾ ਕਿ ਕੋਈ ਬੱਗ ਮੌਜੂਦ ਹੈ, ਇਹ ਸਿਰਫ਼ ਮੀਲ ਦਾ ਪਹਿਲਾ ਇੰਚ ਹੈ। ਮੈਨੂੰ ਅਜੇ ਵੀ IDE ਖੋਲ੍ਹਣਾ, ਮੋਡਿਊਲਜ਼ ਵਿੱਚ grep ਕਰਨਾ, ਮੌਜੂਦਾ ਕੋਡਬੇਸ (codebase) ਦੇ ਵਿਰੁੱਧ ਸਟੈਕ ਟ੍ਰੇਸ (stack traces) ਦੀ ਜਾਂਚ ਕਰਨਾ, ਅਤੇ ਮਨ ਵਿੱਚ ਫੇਲ੍ਹ ਹੋਣ ਦੇ ਪਾਥ (failure path) ਨੂੰ ਮੁੜ ਤੋਂ ਬਣਾਉਣਾ ਪੈਂਦਾ ਸੀ। ਜਦੋਂ ਟਿਕਟਾਂ ਦਾ ਢੇਰ ਲੱਗ ਰਿਹਾ ਹੋਵੇ ਅਤੇ ਕੌਫੀ ਅਜੇ ਵੀ ਗਰਮ ਹੋਵੇ, ਤਾਂ ਉਹ ਮੈਨੁਅਲ ਖੋਜ (manual archaeology) ਉਸ ਸਮੇਂ ਨੂੰ ਬਰਬਾਦ ਕਰਦੀ ਹੈ ਜੋ ਤੁਹਾਡੇ ਕੋਲ ਨਹੀਂ ਹੈ। ਮੈਨੂੰ ਪਾਈਪਲਾਈਨ ਦੀ ਲੋੜ ਸਿਰਫ਼ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਫਲੈਗ ਕਰਨ ਲਈ ਨਹੀਂ ਸੀ, ਸਗੋਂ ਉਹਨਾਂ ਦੀ ਜਾਂਚ ਕਰਨ ਲਈ ਸੀ।
ਇਸ ਲਈ ਮੈਂ ਇੱਕੋ ਇੱਕ ਟੀਚੇ ਦੇ ਆਲੇ-ਦੁਆਲੇ ਸਿਸਟਮ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਇਆ: ਇੱਕ ਕੱਚੀ ਬੱਗ ਰਿਪੋਰਟ ਲਓ ਅਤੇ ਇੱਕ ਵੈਲੀਡੇਟਡ (validated) ਨਤੀਜਾ ਵਾਪਸ ਕਰੋ। LLM ਦੇ ਲੰਬੇ-ਚੌੜੇ ਵਿਚਾਰ ਨਹੀਂ, ਸਗੋਂ ਇੱਕ ਅਜਿਹਾ ਸਟ੍ਰਕਚਰਡ (structured) ਨਤੀਜਾ ਜੋ ਫਾਈਲ ਦਾ ਨਾਮ ਦੱਸੇ, ਲਾਈਨ ਵੱਲ ਇਸ਼ਾਰਾ ਕਰੇ, ਜੋਖਮ ਦਾ ਅੰਦਾਜ਼ਾ ਲਗਾਵੇ, ਅਤੇ ਸੁਧਾਰ ਲਈ ਸੁਝਾਅ ਦੇਵੇ। ਇੱਥੇ ਦੱਸਿਆ ਗਿਆ ਹੈ ਕਿ ਇਹ ਕਿਵੇਂ ਸੰਭਵ ਹੋਇਆ।
ਕਿਉਂ ਸਟ੍ਰਕਚਰ (Structure) ਚੈਟ ਲੌਗ ਨਾਲੋਂ ਬਿਹਤਰ ਹੈ
ਮੈਂ ਇਨਵੈਸਟੀਗੇਟਿੰਗ ਏਜੰਟ (investigating agent) ਨੂੰ PydanticAI ਨਾਲ ਬਣਾਇਆ। ਇਸਦਾ ਕਾਰਨ ਸਧਾਰਨ ਸੀ। ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਲੈਂਗੂਏਜ ਮਾਡਲ (language model) ਨੂੰ ਕੋਡ ਬਾਰੇ ਸੋਚਣ ਲਈ ਕਹਿੰਦੇ ਹੋ, ਤਾਂ ਇਸਦਾ ਡਿਫੌਲਟ ਆਉਟਪੁੱਟ ਟੈਕਸਟ ਦੀ ਇੱਕ ਦੋਸਤਾਨਾ ਲੜੀ ਹੁੰਦੀ ਹੈ। ਇਹ ਇੱਕ ਮਨੁੱਖੀ ਪਾਠਕ ਦੀ ਮਦਦ ਕਰ ਸਕਦਾ ਹੈ, ਪਰ ਅਗਲੇ ਸਕ੍ਰਿਪਟ (downstream script) ਲਈ ਇਹ ਬੇਕਾਰ ਹੈ। ਮੈਨੂੰ ਇੱਕ ਮਸ਼ੀਨ-ਰੀਡੇਬਲ (machine-readable) ਸਮਝੌਤੇ ਦੀ ਲੋੜ ਸੀ।
ਏਜੰਟ ਚਾਰ ਖਾਸ ਫੀਲਡਾਂ ਵਾਲਾ ਇੱਕ ਵੈਲੀਡੇਟਡ ਡੇਟਾ ਮਾਡਲ ਵਾਪਸ ਕਰਦਾ ਹੈ: ਮੂਲ ਕਾਰਨ (root cause), ਪ੍ਰਭਾਵਿਤ ਫਾਈਲਾਂ, ਪ੍ਰਸਤਾਵਿਤ ਤਬਦੀਲੀਆਂ, ਅਤੇ ਜਟਿਲਤਾ (complexity) ਅਤੇ ਜੋਖਮ ਦਾ ਮੁਲਾਂਕਣ। ਜੇਕਰ ਮਾਡਲ ਵਿੱਚ ਕੋਈ ਫੀਲਡ ਗੁੰਮ ਹੈ ਜਾਂ ਉਹ ਕਿਸੇ ਗਲਤ ਫਾਈਲਪਾਥ (filepath) ਦਾ ਹਲੂਸੀਨਾਟ (hallucinates) ਬਣਾਉਂਦਾ ਹੈ, ਤਾਂ ਵੈਲੀਡੇਸ਼ਨ ਫੇਲ ਹੋ ਜਾਂਦਾ ਹੈ ਅਤੇ ਮੈਂ ਇਸਨੂੰ ਤੁਰੰਤ ਫੜ ਲੈਂਦਾ ਹਾਂ। ਇਹ ਸਖ਼ਤੀ ਪਾਈਪਲਾਈਨ ਨੂੰ ਸਹੀ ਰੱਖਦੀ ਹੈ।
ਅਸਲ ਡਿਟੈਕਟਿਵ ਕੰਮ ਕਰਨ ਲਈ, ਏਜੰਟ ਨੂੰ ਚਾਰ ਰੀਡ-ਓਨਲੀ (read-only) ਟੂਲ ਮਿਲਦੇ ਹਨ ਅਤੇ ਕੁਝ ਵੀ ਨਹੀਂ। ਇਹ grep ਰਾਹੀਂ ਕੋਡ ਸਰਚ ਕਰ ਸਕਦਾ ਹੈ, ਫਾਈਲ ਤੋਂ ਖਾਸ ਲਾਈਨ ਰੇਂਜ ਪੜ੍ਹ ਸਕਦਾ ਹੈ, ਡਾਇਰੈਕਟਰੀ ਦੀ ਸਮੱਗਰੀ ਦੀ ਸੂਚੀ ਬਣਾ ਸਕਦਾ ਹੈ, ਅਤੇ ਕਲਾਸਾਂ ਜਾਂ ਫੰਕਸ਼ਨਾਂ ਵਰਗੇ ਸਿੰਬਲ (symbols) ਲੱਭ ਸਕਦਾ ਹੈ। ਰੀਡ-ਓਨਲੀ ਹੋਣਾ ਮਹੱਤਵਪੂਰਨ ਹਿੱਸਾ ਹੈ। ਮੈਂ ਅਜਿਹਾ ਏਜੰਟ ਨਹੀਂ ਚਾਹੁੰਦਾ ਸੀ ਜਿਸ ਕੋਲ ਰਾਈਟ ਐਕਸੈਸ (write access) ਹੋਵੇ ਅਤੇ ਉਹ ਰਾਤ ਦੇ 2 ਵਜੇ ਮੇਰੇ ਰੈਪੋਜ਼ਟਰੀ (repository) ਵਿੱਚ ਘੁੰਮਦਾ ਰਹੇ। ਪਹਿਲਾਂ ਸਮਝੋ, ਫਿਰ ਐਡਿਟ ਕਰੋ।
ਰੈਪੋ ਮੈਪ (Repo Map): ਟੂਲਜ਼ ਤੋਂ ਪਹਿਲਾਂ ਸੰਦਰਭ (Context)
ਏਜੰਟ ਦਾ ਪਹਿਲਾ ਵਰਜ਼ਨ ਸਹੀ ਸੀ ਪਰ ਬਹੁਤ ਮਹਿੰਗਾ ਸੀ। ਇਹ ਟੋਕਨਾਂ (tokens) ਨੂੰ ਉਸੇ ਤਰ੍ਹਾਂ ਖਤਮ ਕਰ ਰਿਹਾ ਸੀ ਜਿਵੇਂ ਕੋਈ ਸੈਲਾਨੀ ਚੱਕਰਾਂ ਵਿੱਚ ਘੁੰਮ ਰਿਹਾ ਹੋਵੇ। ਮਾਡਲ list-dir ਕਾਲ ਕਰਦਾ, ਫਿਰ grep, ਫਿਰ ਇੱਕ ਫਾਈਲ ਪੜ੍ਹਦਾ, ਫਿਰ ਦੁਬਾਰਾ list-dir, ਅਤੇ ਹੌਲੀ-ਹੌਲੀ ਪ੍ਰੋਜੈਕਟ ਦੇ ਢਾਂਚੇ ਦਾ ਮਾਨਸਿਕ ਮਾਡਲ ਇੱਕ ਮਹਿੰਗੇ ਟੋਕਨ ਵਾਰ ਇੱਕ ਬਣਾਉਂਦਾ।
ਇਸਦਾ ਹੱਲ ਇਹ ਸੀ ਕਿ ਏਜੰਟ ਦੇ ਸ਼ੁਰੂ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕ ਸੰਖੇਪ ਰੈਪੋ ਮੈਪ (repo map) ਤਿਆਰ ਕੀਤਾ ਜਾਵੇ। ਇਹ ਮੈਪ ਰੈਪੋਜ਼ਟਰੀ ਦਾ ਇੱਕ ਨਿਚੋੜ ਦਿੱਤਾ ਗਿਆ ਵੇਰਵਾ ਹੈ: ਮੁੱਖ ਫਾਈਲਾਂ, ਉਹਨਾਂ ਦੇ ਮੁੱਖ ਫੰਕਸ਼ਨ ਜਾਂ ਕਲਾਸਾਂ, ਅਤੇ ਮੁੱਖ ਮੋਡਿਊਲ ਕਿਵੇਂ ਜੁੜੇ ਹੋਏ ਹਨ। ਇਸਨੂੰ ਏਜੰਟ ਨੂੰ ਗਲਤੀਆਂ ਅਤੇ ਕੋਸ਼ਿਸ਼ਾਂ ਰਾਹੀਂ ਸੜਕਾਂ ਲੱਭਣ ਲਈ ਕਹਿਣ ਦੀ ਬਜਾਏ ਇੱਕ GPS ਦੇਣ ਵਾਂਗ ਸਮਝੋ।
ਉਸ ਮੈਪ ਦੇ ਕੰਟੈਕਸਟ ਵਿੰਡੋ (context window) ਵਿੱਚ ਹੋਣ ਨਾਲ, ਏਜੰਟ ਇਹ ਪਤਾ ਲਗਾਉਣ ਵਿੱਚ ਟੂਲ ਕਾਲਜ਼ ਬਰਬਾਦ ਨਹੀਂ ਕਰਦਾ ਕਿ src/utils/parser.ts ਮੌਜੂਦ ਹੈ। ਉਹ ਪਹਿਲਾਂ ਹੀ ਇਲਾਕੇ ਨੂੰ ਜਾਣਦਾ ਹੈ। ਉਹ ਸਿੱਧਾ ਉਸ ਚੋਟੀ ਵੱਲ ਜਾਂਦਾ ਹੈ ਜਿੱਥੇ ਧੂੰਆਂ ਉੱਠ ਰਿਹਾ ਹੈ। ਉਸ ਇੱਕ ਬਦਲਾਅ ਨੇ ਭਟਕਣ ਵਾਲੇ ਪੜਾਅ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਖਤਮ ਕਰ ਦਿੱਤਾ।
ਟੂਲ ਫਨਲ (Tool Funnel): ਇੱਕ ਨਤੀਜੇ 'ਤੇ ਪਹੁੰਚਣ ਲਈ ਮਜਬੂਰ ਕਰਨਾ
ਮੈਪ ਹੋਣ ਦੇ ਬਾਵਜੂਦ, ਏਜੰਟ ਫੈਸਲਾ ਲੈਣ ਵਿੱਚ ਦੇਰੀ ਕਰ ਸਕਦਾ ਸੀ। ਇਹ ਇੱਕ ਸ਼ੱਕੀ ਫਾਈਲ ਲੱਭਦਾ, ਫਿਰ ਆਪਣੇ ਆਪ 'ਤੇ ਸ਼ੱਕ ਕਰਦਾ, ਫਿਰ ਦੁਬਾਰਾ ਸਰਚ ਕਰਦਾ, ਫਿਰ ਇੱਕ ਹੋਰ ਫਾਈਲ ਪੜ੍ਹਦਾ, ਅਤੇ "ਬਸ ਇੱਕ ਹੋਰ ਚੈੱਕ" ਦੇ ਅਨੰਤ ਲੂਪ ਵਿੱਚ ਫਸ ਜਾਂਦਾ। ਮੈਨੂੰ ਗਤੀ (momentum) ਲਿਆਉਣ ਦਾ ਇੱਕ ਤਰੀਕਾ ਚਾਹੀਦਾ ਸੀ।
ਮੈਂ ਇੱਕ ਤਿੰਨ-ਪੜਾਵੀ ਟੂਲ ਫਨਲ (tool funnel) ਲਾਗੂ ਕੀਤਾ ਜੋ ਏਜੰਟ ਦੀ ਪ੍ਰਗਤੀ ਦੇ ਨਾਲ ਉਸਦੇ ਕੰਮ ਨੂੰ ਸੀਮਤ ਕਰਦਾ ਹੈ।
ਪਹਿਲਾ ਪੜਾਅ ਖੋਜ (exploration) ਹੈ। ਏਜੰਟ ਕੋਲ ਚਾਰੇ ਟੂਲਜ਼ ਤੱਕ ਪੂਰੀ ਪਹੁੰਚ ਹੈ। ਉਹ ਆਪਣੀ ਸੋਚ ਵਿੱਚ ਬੱਗ ਨੂੰ ਦੁਹਰਾਉਣ ਲਈ ਜੋ ਵੀ ਲੋੜੀਂਦਾ ਹੈ, ਉਸਨੂੰ ਸਰਚ, ਬ੍ਰਾਊਜ਼ ਅਤੇ ਪੜ੍ਹ ਸਕਦਾ ਹੈ।
ਦੂਜਾ ਪੜਾਅ ਡੂੰਘਾਈ ਨਾਲ ਜਾਂਚ (deep-dive) ਹੈ। ਇੱਕ ਵਾਰ ਜਦੋਂ ਏਜੰਟ ਸੰਭਾਵੀ ਖ਼ਤਰੇ ਵਾਲੀਆਂ ਥਾਵਾਂ ਦੀ ਪਛਾਣ ਕਰ ਲੈਂਦਾ ਹੈ, ਤਾਂ ਉਹ ਖੋਜ ਵਾਲੇ ਟੂਲਜ਼ ਗੁਆ ਲੈਂਦਾ ਹੈ। ਉਹ ਸਿਰਫ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਸਕਦਾ ਹੈ। ਹੋਰ ਕੋਈ grep ਨਹੀਂ, ਕੋਈ ਡਾਇਰੈਕਟਰੀ ਲਿਸਟਿੰਗ ਨਹੀਂ। ਇਸ ਪੜਾਅ 'ਤੇ ਉਸਨੂੰ ਆਪਣੇ ਦੁਆਰਾ ਪਹਿਲਾਂ ਲੱਭੇ ਗਏ ਕੋਡ
I did not want to hardcode the system against a single model provider. I use different engines depending on the task. Sometimes Claude Code, sometimes Grok Build, sometimes whatever is cheapest at the moment. To keep the core logic provider-agnostic, I split the work into two stages.
Stage one is exploration. The coding agent, which can be any capable model, reads the repo map, uses the tools, and produces a raw markdown report. This is the expensive thinking part.
Stage two is structuring. A cheap, fast LLM takes that markdown and reformats it into the strict Pydantic model. This stage requires almost no reasoning. It is just extraction and formatting, so it runs on lightweight hardware.
Because the boundary is clean, I can swap the backend without touching the validation logic. The markdown report acts as a universal adapter between the exploratory brain and the structured output I actually use.
What Actually Worked
This setup changed how I handle incoming issues. The classification layer still sorts bugs from feature requests, but now the analysis layer picks up immediately after. By the time I open my editor, I have a file path, a line range, and a proposed change waiting for me. I still review everything manually. This is assistance, not autopilot. But the context gathering that used to
