Dev Log 6: Fixing Bugs Like Treating Illness
In a broad sense, fixing bugs and treating illness are actually the same kind of work. The former targets code, the latter targets patients. Apart from the subj
In a broad sense, fixing bugs and treating illness are actually the same kind of work. The former targets code, the latter targets patients. Apart from the subject being different and the specific techniques being different, the goal they pursue is essentially the same: take an entity that has a partially broken component, and restore it to a state of complete functionality. In other words, for code or people that have something wrong, eliminate the impact of that problem so it poses no obstacle to the application or the body as a whole.
But this brings out another difference between fixing bugs and treating illness: if your skills are good enough, a bug can always be fixed to a state close to complete, fully meeting the expected outcome. But medicine is limited by the state of science and the progress of the times, and in more and more domains, doctors are often helpless in the face of difficult and unusual conditions.
I am not a medical student with medical knowledge, nor have I had any experience working in medicine. I am just an ordinary person who occasionally goes to the hospital, and I use what I see and hear there as an analogy to compare these two similar kinds of work, to look at what the two have in common in their approach to handling problems, and then borrow the thinking of this purely scientific discipline of fine-grained management to guide how we write code, using a systematic way of thinking to fix problems at the lowest cost and the highest return.
We all know that unless it is an emergency visit or a sudden situation like a car accident requiring urgent treatment, other medical visits follow a fixed process and sequence. The general process can be summarized as follows: first, self-examination. For example, you need to know exactly whether you have a headache and fever, or weakness in your limbs. You need a discomfort you can express clearly, or an abnormality you can show clearly. The former is self-judgment when symptoms are mild, the latter is outward manifestation when symptoms are obvious or severe. But either way, you have already made an abnormal judgment before seeing a doctor — that is, the origin of your need to fix this abnormality is that you feel uncomfortable somewhere, or that something is not normal somewhere.
Then you go to the hospital in different ways, register, choose a department, complete triage. After that, the doctor will base on the symptoms you describe, combined with your long-term medical records at this hospital, and the auxiliary data you can provide — for example, the daily heart rate, breathing, blood pressure and other health data recorded by the now-popular wrist-worn health devices — as supporting evidence. The doctor will establish a baseline from your historical health data, and combined with your description, your symptoms, and their own experience, make a preliminary diagnosis of your condition. After that, they will order some tests, such as an ECG, blood test, urine test, and so on. Once those tests are done, you go back to the doctor, who will combine the two previous types of data with the current test results to verify or correct the guess made during the first consultation.
For example, when you first consult the doctor, they might tell you that your symptoms look a bit like the flu, or that it could be some kind of viral infection. When you bring the test results back to them, they will check the results against their earlier judgment — which parts need to be corrected, whether the judgment needs to be remade from scratch. Then they will look at whether the new judgment and the first round of test data can corroborate each other. In other words, the initial guess, after being revised with the first round of test data into a second revision, can it cross-validate with the first round of test data. Put another way: the test data can prove the judgment is right, and the doctor's second revision, or second diagnosis, can also perfectly match the symptoms the test data shows, or should show. At this point, if the two match perfectly, the visit moves to the next stage: the doctor prescribes medication for the diagnosed illness, or explains some recovery methods, and you follow the process to complete the entire treatment. But if the second diagnosis — the revised judgment — still cannot be sufficiently substantiated, they will order a second round of tests, asking you to go provide the additional data they need, and repeat the previous process: can the second diagnosis, after revision by the second round of test data, mutually validate? If the answer is yes, the treatment can proceed to the next stage as before.
When you have the prescription in hand and have completed the treatment by following the medication or therapy it prescribes, there are also two possible outcomes: the illness is cured, and naturally all is well; or the problem isn't fully eradicated as expected, or isn't solved at all, or even gets worse. At that point we need to reassess our condition, re-evaluate the illness, and go back to the hospital to run through the whole process again.
This whole process is exactly like how we fix bugs. Sometimes we might think that fixing a bug just means correcting the function that throws the error, or changing a wrong value range to the right one — but that's not it at all. An application is a whole, a system, and any one function inside it doesn't exist in isolation; it has its own upstream and downstream consumers. It's like certain organs in our body — the stomach, for instance, belongs to the digestive system and doesn't exist in isolation; its health affects the entire digestive system, and the digestive system in turn affects the body's whole nutrient cycle. So fixing a bug isn't just a matter of changing one spot. It's not like a pothole in a paved road where you fill it in and you're done — it's nothing like that.
Based on this analogy with complex systems, fixing bugs follows a process much like medical diagnosis. We first notice a symptom — say a warning when a certain piece of code runs, or persistently abnormal latency in some business operation during a particular time window. This is like the way we feel when we fall ill: a slight headache, a bit of a fever, sluggish movements, and so on. Once you notice this symptom, you make a preliminary diagnosis based on the symptom and your understanding of the codebase. For example, an error in the log will list which line of code went wrong, with a rough error description, so you go find that line and do a simple localization. Of course, having said this, I've left out a premise: this whole bug-fixing process of mine is one carried out together with AI.
So after making a preliminary judgment based on the application's runtime state, we take this symptom and preliminary judgment and open up an AI tool, such as Claude Code. Then you'd say something like this to it: "I'm seeing such-and-such errors in the log; I took a rough look and it might be because of this reason. Could you browse through the whole codebase, read the relevant code and implementation closely, and help me diagnose what's really causing this problem?" At this point the AI is like a doctor you've registered to see at the hospital — it needs to know the symptoms of your problem, and then, armed with those symptoms and drawing on its training data and capabilities, it locates the crux of the problem in the codebase. Once it has made a preliminary diagnosis, it shouldn't rush or blindly start fixing the problem; instead, just as in a hospital visit, it needs to first find grounds and evidence to prove that the judgment is correct. For code, this means a process of reproducing the problem, in order to determine whether the cause we suspected is what's actually producing it.
Following the hospital's diagnostic process, this is the point where the patient takes the lab-test orders written by the doctor and goes to run a series of checks. But AI's capabilities now let it autonomously run all the operations and verification, so this step is really the AI guessing a possible cause on its own, then running some of the lab work it "prescribed" itself, and after getting the "lab results," using them to argue whether its preliminary diagnosis can solve our original problem. If it can, it then writes a prescription — which, in the programming domain, means it needs to write a plan, a process, spelling out how to fix it, i.e. how this "illness" should be treated, with clear steps. This plan is the treatment prescription the doctor writes for the patient; with the prescription in hand, the patient picks up the medicine accordingly, or undergoes other physical therapy. In programming terms, the AI takes this prescription, this plan, and carries out the fix at the code level.
From our experience getting treated, once we have the prescription and the medicine in hand, it's not as if we take the doses to the end, or finish the rehab routine by the book, and then stop caring. We actually make a judgment: after taking these medicines, the doctor said one treatment course is seven days — seven days have passed, so have my symptoms actually eased? Have I reached the relief the doctor described? Mapped onto software development, or the bug-fixing stage, this means: after the AI finishes executing the fix plan it drew up, it needs to verify — after applying these code changes, these fixes, has the original problem disappeared as we expected? Or have the symptoms been relieved? Because some problems don't disappear immediately. Take latency, for example: you can bring it down from several thousand milliseconds to a few dozen, just as some human symptoms can only be relieved, not eradicated.
Once this judgment is made, a fork appears: your expectation is a one-hundred-percent complete fix, but after this round of diagnosis, this prescription, this plan has been executed — to what degree was it fixed? A complete fix or a partial one? If it's a complete fix, then we stop here. If it's a partial fix, we need to return to the diagnosis–lab work–prescription loop and run through the whole process once more, until the effect of the prescription — that is, the plan's execution — approaches our expectation.
This, then, taking our ordinary hospital visit as the example, is the complete loop we go through when fixing bugs with the help of AI, explained by analogy. But someone might ask: "When I do it, I just have the AI fix the bug directly — I don't go through a process as long as yours, and it seems to fix it pretty perfectly." In that case I'd ask you to recall: have you ever had this experience — when you catch a minor cold, or come down with a slight chill, do you go register at the hospital, have the doctor diagnose you, and run through the entire consultation process? No, you don't. You go to the pharmacy, buy some medicine, take it yourself following the instructions, and ease the symptoms. It's not that once a process is developed, every related problem has to be forced into it; rather, a process is defined for a problem of a certain level of complexity. A problem more complex than that needs the process repeated multiple times, or embedded somehow — placed inside a more complex, more complete process, with some finer-grained sub-processes added. And for a problem simpler than that, there's no need to mechanically apply this whole complete system at all; just go to the pharmacy, buy the medicine that fits the symptoms, and take it on schedule.
Back to AI: if you know exactly which part, which point the problem lies in, and you have a very clear line for the fix, there's no need to run through this whole path from start to finish. It's like seeing the target right in front of you — you just fire a shot at it; there's no need to execute a complex military plan. But if your target is on the other side of the forest, then you might need to rely on drones and missiles to locate it, lock onto it, and then destroy it. Problems of different scales call for different frameworks. A framework is itself an approach to solving a problem, but if you pick the wrong one, it can also become an obstacle to solving it.
评论Comments
加载中…Loading…
留下评论Leave a comment