All writing

Work & Career

Translated from the original Chinese essay · Read the Chinese original →

The other day I used GPT-4 to generate a complete API endpoint—from signature to test cases—in one shot, with almost no changes needed. I was pretty pleased, and a smug thought crossed my mind: “AI has finally become my tool.”

Then, when I merged the PR, a colleague left a comment:

“Can your pagination logic support both offset-based and cursor-based? Have you verified performance with large data volumes?”

I froze for three seconds before remembering—I hadn’t tested any of those edge cases.

What threw me wasn’t that the code had issues. It was the bigger question that suddenly popped into my head:

If I’m just copying AI-generated code, am I still a programmer?


The real panic is a loosening sense of identity

Many people think programmers’ anxiety about AI is about being laid off or running out of work. But I increasingly feel that what truly unsettles us is a sense of loss—the feeling that we can still write code, yet we’re no longer sure we still count as programmers.

I can have AI generate scaffolding, configuration parameters, and test cases with one click, but I find it harder and harder to explain the trade-offs and logical reasoning behind them. My debugging instincts are atrophying, and my sense of control over the system is fading.

As a friend put it: “I haven’t lost my job, but I feel like I’ve lost my qualification.”

We used to build professional confidence by “writing correct code from scratch.” Now AI-generated code is more standardized, with cleaner naming and more systematic structure, and we start to doubt:

  • Am I just someone who prompts AI?
  • Is ten years of hands-on experience no match for a single prompt?
  • Do I still deserve the title of engineer?

This isn’t a problem of coding ability; it’s an identity crisis. When we are no longer the person who “understands it, can write it, and can fix it fast,” who are we?

Similar anxieties have appeared many times in tech history.

When IDEs emerged, old-school programmers said “real experts use vim.” When Stack Overflow became popular, some worried that “copy-paste would destroy thinking ability.” But in the end, we accepted the efficiency gains of tools and reshaped our professional judgment under new rules.

So the issue isn’t the strength of the tool, but that this time, the speed and depth of the tool’s evolution are truly different.


This isn’t just a tool upgrade—it’s outsourcing our abilities

We have to admit that today’s AI doesn’t just help us write faster; it’s starting to “write it all by itself.”

It can generate Kafka consumer logic with retry and timeout handling, and produce an explanatory diagram of B+ tree principles with one click. It can even offer three solutions before you’ve fully clarified the requirements.

Recently I used Claude to write a JVM performance tuning script, including G1GC parameter suggestions. When it recommended setting

G1MixedGCLiveThresholdPercent

to 45%, I didn’t think twice and followed it. But after closing the editor, I suddenly realized:

I had no idea what that parameter actually does.

Isn’t this the early sign of hollowing out our abilities?

Just as GPS makes us lose our sense of direction and calculators weaken our mental arithmetic, AI is making us “look like we’re writing code” while actually being mere porters of API interfaces.

Worse: when AI makes mistakes, we also lose the ability to recognize them.

So do these underlying abilities really no longer matter?

My answer: they matter, but we need to redefine the boundaries of their importance.

We don’t need to hand-write quicksort every day, but when a system hits a performance bottleneck, we must be able to understand why the time complexity of sorting algorithms affects overall performance. We don’t need to implement database indexes from scratch every time, but when queries slow down, we must know the difference between B+ trees and hash indexes.

In other words, we need to maintain the ability to understand underlying principles, not the ability to implement them. If we don’t even know what a “good solution” is, how can we guide AI to give better suggestions? If we lose our understanding of underlying principles, how can we detect and correct AI when it gives wrong advice?

What we need isn’t rejecting AI, but upgrading how we collaborate

I once tried to completely detach from AI to regain a sense of professionalism, like hand-writing red-black tree insertion logic again, but I found that kind of bare-metal challenge too extreme and impossible to fit into my daily rhythm.

Later I changed my approach: treat AI as a collaboration partner and divide usage into three modes, maintaining both efficiency and judgment.


Level 1: AI as a tool

At this stage, I treat AI as a StackOverflow that can write code. For example:

Write a Spring Data JPA repository method that supports time-range queries.

It gives a standard implementation, and I integrate it, then fine-tune edge conditions with my own business understanding.

The key: don’t merge directly. Review AI’s code like a code review—check for exception handling, pagination performance, and thread safety.


Level 2: AI as a collaborator

When I start involving AI in solution design, its value truly shines.

I prompt like this:

I’m designing a user behavior scoring system that needs high concurrency, low latency, and easy scalability. Please list three implementation approaches and analyze their pros and cons.

At this point, I’m not waiting for an answer; I’m having a dialogue with it, co-designing the solution. It gives a draft, I improve it with my experience, and then I question its logical gaps in return.

This back-and-forth feels a lot like pairing with a senior colleague.


Level 3: AI as a commander

When I can turn a vague problem into a set of structured instructions and guide AI to continuously optimize results, letting AI agents set up context according to my commands and execute step by step, I’m not using AI to write code—I’m using code to command AI.

For example, this prompt:

I’m tuning Kafka consumer code. Here’s my current configuration: [paste config]. Please explain each parameter’s meaning, performance impact, and suggested tuning direction one by one, and explain your reasoning.

It explains like a teaching assistant:

fetch.min.bytes

affects throughput,

max.poll.records

trades off with latency, and it even points out deoptimization risks under JIT compilation.

This process isn’t surrendering control; it’s training myself to re-understand principles and build the ability to supervise AI output.


Baseline exercises to prevent skill degradation

Besides the layered collaboration approach, I also keep several cognitive training methods to prevent myself from becoming a copy-paste operator.

  1. Spend 4–6 hours a month on offline practice: grind LeetCode problems (no AI, only documentation) to maintain system-level thinking.
  2. Reverse-engineering AI code: for complex AI-generated logic (like Kafka rebalancing or message idempotency), force myself to draw call graphs and sequence diagrams to deduce the core mechanisms.
  3. Extreme scenario rehearsal: imagine scenarios AI can’t handle (JVM memory leaks, frequent GC triggers, deadlocks) and ask myself: can I independently inspect dumps and debug the issue?

These exercises aren’t to prove I’m better than AI, but to preserve the instinct to find solutions in chaos.


Who we are is not defined by AI

AI writing fast doesn’t mean you’re unimportant. Whether you still deserve the title “programmer” was never determined by how many lines of code you hand-type.

Our real role is to ask good questions, make good choices, spot errors, and improve solutions.

Just as a product manager doesn’t stop being a designer because they didn’t draw the interface, a programmer shouldn’t lose professionalism because they write fewer lines of code.

What we should do isn’t resist tools, but reshape our ability boundaries, strengthen our judgment authority, and maintain our thinking inertia.


So in the end, I come back to that saying:

A real programmer is not a porter of code, but a solver of problems.

AI will make us faster, but it cannot replace our curiosity and judgment to “understand how this world works.”

At the end, here are a few practical templates. Three ready-to-use AI collaboration templates

From my practice, I’ve summarized three particularly useful collaboration templates that boost efficiency while maintaining learning and thinking:

Template 1: Code review partner

"I need to implement [specific feature description]. First, analyze what the core challenge of this problem is, then give a solution approach, and finally provide the code implementation. After implementation, review it from three angles—performance, security, and maintainability—and point out potential issues."

The benefit of this template is that it makes AI show its complete thought process, not just output results. You can see its reasoning, making it easier to spot problems.

Template 2: Technical solution advisor

"I’m working on [project background] and need to solve [specific problem], with constraints including [performance requirements/cost limits/time limits, etc.]. Please give me three different solutions, each including: 1) core idea 2) pros and cons analysis 3) applicable scenarios 4) implementation difficulty assessment. No specific code needed—the focus is on helping me clarify my thinking."

This template is especially good for pre-research, letting you see all options before you start.

Template 3: Debugging assistant

"My [language/framework] code has encountered [specific problem description]. Here is the relevant code [paste code]. Please: 1) analyze the possible root cause 2) provide troubleshooting steps 3) give fix suggestions. Importantly, explain your reasoning process so I understand why this problem occurred."

The key of this template is explaining the reasoning process, so you learn debugging approaches, not just fix this one bug.