<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>Joye Personal Blog (EN)</title><description>English posts — agents, LLM internals, and engineering notes.</description><link>https://www.joyehuang.me/en</link><language>en-us</language><item><title>From Interviews to Agent Engineering: Why I Stay Calm</title><link>https://www.joyehuang.me/en/blog/20260615---frominternshipinterviewstoagentengineering/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260615---frominternshipinterviewstoagentengineering/post</guid><description>Prompt -&gt; Context -&gt; Harness -&gt; Loop: terms change faster than models, but the work is the same-build systems that keep running.</description><pubDate>Mon, 15 Jun 2026 00:00:00 GMT</pubDate><content:encoded>import TalkEpisodeCard from &apos;@/components/blog/TalkEpisodeCard.astro&apos;
import TalkSlideFigure from &apos;@/components/blog/TalkSlideFigure.astro&apos;
&lt;p&gt;Last week I gave a technical sharing session in my follower group. The video is already out, but some people prefer reading, so I turned it into this post. The structure maps one-to-one to the talk, just rewritten from spoken notes into an article, with a few arguments filled in more fully. All links referenced in the post are collected at the end.&lt;/p&gt;
&lt;p&gt;The talk started from an offhand observation: the words around &quot;Agent development&quot; keep changing, and job descriptions on Boss Zhipin update painfully fast. What I wanted to discuss was this: when the field iterates this quickly, whether you are looking for an internship or already building agents, &lt;strong&gt;what mindset should you use to keep up with it?&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Terms change faster than models - Prompt -&gt; Context -&gt; Harness -&gt; Loop - but they are all doing the same thing: building more system around the stable model core.&lt;/li&gt;
&lt;li&gt;Do not drown in new terms. Do not hoard links and never read them. Send them through your personal agent first; when learning a new area, scrape job descriptions and primary sources instead of letting AI teach you from zero.&lt;/li&gt;
&lt;li&gt;The real moat is not knowledge. Knowledge is abundant and AI can mass-produce it. The moat is your judgment, taste, and context; context comes from initiative - building, publishing, getting tested.&lt;/li&gt;
&lt;li&gt;In one sentence: &lt;strong&gt;do not chase every term; build a system that keeps running.&lt;/strong&gt; Technically, that is a persistent personal agent. For your growth, it is a loop of build -&gt; hit real problems -&gt; distill -&gt; publish.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This post has four parts: what these terms are really about, how I avoid getting overwhelmed, how I learn deliberately, and what the real moat is.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. A year of terms: four engineering waves and a year of open-source agents&lt;/h2&gt;
&lt;p&gt;There are too many new words. Feeling anxious when you see them is normal. So let us first align on what these words actually mean.&lt;/p&gt;
&lt;p&gt;If you put the keywords from the past few years on one line, you get a clear relay:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&apos;22-&apos;23 Prompt Engineering&lt;/strong&gt; - write the instruction well. The focus was on prompting an LLM to return better and more stable answers. Back then, people were still obsessed with magic words like &quot;think step by step&quot; and &quot;reflect before answering.&quot; See &lt;a href=&quot;https://www.promptingguide.ai/&quot;&gt;Prompt Guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&apos;25.6 Context Engineering&lt;/strong&gt; - manage everything the model sees. As tasks get longer, model attention drifts, so the problem becomes: how do we keep attention focused and feed only the context that matters? Shopify CEO Tobi Lutke proposed it, and &lt;a href=&quot;https://x.com/karpathy/status/1937902205765607626&quot;&gt;Karpathy&lt;/a&gt; made it catch fire.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Early &apos;26 Harness Engineering&lt;/strong&gt; - wrap the model in scaffolding. The &lt;a href=&quot;https://openai.com/index/introducing-codex/&quot;&gt;OpenAI Codex&lt;/a&gt; and &lt;a href=&quot;https://www.anthropic.com/engineering/harness-design-long-running-apps&quot;&gt;Anthropic&lt;/a&gt; posts share one important word: long-running. If you want an agent to work on longer tasks, you need a harness.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&apos;26.6 Loop Engineering&lt;/strong&gt; - stop manually prompting and design the loop instead. A &lt;a href=&quot;https://x.com/steipete/status/2063697162748260627&quot;&gt;tweet by Steinberger&lt;/a&gt;, the creator of OpenClaw, roughly argued that you should not be typing prompts for coding agents anymore; you should design the loops that prompt them. It hit 1.7M views and started a broader discussion. &lt;a href=&quot;https://addyosmani.com/blog/loop-engineering/&quot;&gt;Addy Osmani&lt;/a&gt; then systematized and named it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These four terms are one relay of engineering vocabulary: &lt;strong&gt;Prompt -&gt; Context -&gt; Harness -&gt; Loop&lt;/strong&gt;. In between sits the broader industry backdrop: &lt;strong&gt;2025 was widely treated as year one for Agent / multi-agent systems&lt;/strong&gt;. Open-source frameworks bloomed everywhere - &lt;a href=&quot;https://github.com/langchain-ai/deepagents&quot;&gt;LangChain deepagents&lt;/a&gt;, Goose, and many more. Big companies and startups all built agents and pushed multi-agent architectures, until by the end of the year people started questioning whether multi-agent was sometimes fake complexity. Multi-agent itself is not a new &quot;engineering term&quot; in this chain; it is the soil that made the four waves happen.&lt;/p&gt;
&lt;p&gt;The timeline makes the compression obvious: Prompt to Context took three or four years. After Context, Harness and Loop, plus the 2025 open-source agent wave, almost all arrived in one dense year. It moved so fast that &lt;a href=&quot;https://news.qq.com/rain/a/20260603A07TIY00&quot;&gt;Tencent&apos;s 30,000-word report&lt;/a&gt; from two weeks ago was still centered on Harness Engineering; Loop only appeared this week. I would not be surprised if Xiaohongshu and Boss Zhipin start showing &quot;Loop Engineering Intern&quot; roles in two weeks. Right now the job descriptions are still stuck in the OpenClaw and harness era.&lt;/p&gt;
&lt;h3&gt;The pattern: the engineering target keeps expanding outward&lt;/h3&gt;
&lt;p&gt;Put these waves together and one thing becomes clear: &lt;strong&gt;the model basically stays the same; what changes is the layer you operate on.&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;In one line: &lt;strong&gt;words -&gt; context -&gt; environment -&gt; mechanism.&lt;/strong&gt; The names change, but the work is the same: build a &lt;strong&gt;system&lt;/strong&gt; outward around the model core. In other words, the history of these terms is a history of the system boundary expanding.&lt;/p&gt;
&lt;h3&gt;This is not just hype: same model, better outer layer&lt;/h3&gt;
&lt;p&gt;Here is a hard number. LangChain&apos;s coding agent did not change the model at all (&lt;code&gt;gpt-5.2-codex&lt;/code&gt;, still a closed model). They only rebuilt the harness, and on &lt;a href=&quot;https://www.tbench.ai/leaderboard/terminal-bench/2.0&quot;&gt;Terminal-Bench 2.0&lt;/a&gt; they jumped from outside the top 30 (52.8%) into the &lt;strong&gt;top 5 (66.5%)&lt;/strong&gt;, a gain of 13.7 points - almost the kind of lift you would expect from a new model generation. Vivek Trivedy, who leads open-source agents and harness work at LangChain, put it well in &lt;a href=&quot;https://www.langchain.com/blog/improving-deep-agents-with-harness-engineering&quot;&gt;that post&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Agent = model + harness. You are either the model, or you are the harness - everything outside the model is harness.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is a subtler example too. When I used Grok&apos;s coding model before, its tool calling kept failing because arguments did not match the expected schema. I remember seeing research where simply aligning parameter formats made the same model perform nearly an order of magnitude better. So many problems that look like &quot;the model is bad&quot; are really harness problems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Small caveat: I cannot find the original source for that experiment right now, so I am writing from memory. I will add the link if I find it, and if you know the source, please point me to it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The essence: the name changes, the work does not&lt;/h3&gt;
&lt;p&gt;Go backward and you will see that earlier prompt and context work were also harness work; the word &quot;harness&quot; just did not exist yet.&lt;/p&gt;
&lt;p&gt;And the previous layer never disappears. It becomes a component of the next layer. Prompting did not die; it became one component inside a loop. Before, humans manually refined a better prompt. With Loop Engineering, agents refine prompts, run tests, and iterate inside the loop. It is layers wrapping layers. Often the old layer was already being used; it just had not been named separately.&lt;/p&gt;
&lt;p&gt;So why do the terms keep changing? Partly because there are real increments - Loop does add something beyond harness, and we should admit that. But a large part is also marketing. There is no need to panic every time a new term appears. They are doing the same underlying job: without changing the model itself, make an agent steadier and make the experience better than directly using ChatGPT or Claude. I call that &lt;strong&gt;Agent Engineering&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. Why I am not anxious&lt;/h2&gt;
&lt;p&gt;When people see a pile of new terms, their first reaction is often: &quot;I have so much to learn.&quot; But the problem is usually not that there are too many terms. The problem is that you &lt;strong&gt;save them and never read them&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;New terms pile up like deadlines. Most people only bookmark them and never spend the time to understand them. They quietly pretend that &quot;saved&quot; means &quot;read.&quot; I have done this too. But if you calculate the actual cost, understanding a new concept like Loop Engineering is much cheaper than it feels. &lt;strong&gt;Anxiety comes from the unknown itself.&lt;/strong&gt; What piles up is not knowledge; it is unknowns. Once you see that, the solution is straightforward.&lt;/p&gt;
&lt;h3&gt;Practice 1: send new things to my personal agent first&lt;/h3&gt;
&lt;p&gt;For example, when I saw Loop Engineering, the original tweet was long and I did not have time to read it closely. I sent it straight to my agent: &quot;Read this and explain what it is. It seems to be getting popular.&quot;&lt;/p&gt;
&lt;p&gt;With AI, the cost of quickly and partially understanding something new is extremely low. From its explanation alone, I roughly understood what the thing was. That was enough. If it looked important, I could read the original carefully; if not, I could skip it. Most new material does not deserve a line-by-line read. Let AI do the first pass.&lt;/p&gt;
&lt;p&gt;It often tells me something useful along the way: many cron jobs, skills, and workflows I built on my own devices were already basically Loop Engineering. That validates the earlier point: new terms often just label things many people were already doing.&lt;/p&gt;
&lt;h3&gt;Practice 2: do not ask &quot;what is it&quot;; ask &quot;how is it different from what I already do?&quot;&lt;/h3&gt;
&lt;p&gt;This requires your agent to know you, either through memory or by being placed inside your codebase.&lt;/p&gt;
&lt;p&gt;Then ask it: &lt;strong&gt;how is this new thing different from what I am already doing?&lt;/strong&gt; That lets you sort new terms into three buckets: a real thing worth chasing; something I am already doing; or pure hype I can skip. Even if you do not fully understand the new thing yet, you need to know the gap between it and your own work, what you would need to learn, and what practice would close that gap. If you can sort terms this way, they stop dragging you around.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. How to learn and where to find information&lt;/h2&gt;
&lt;p&gt;People are afraid of information gaps: &quot;I cannot reach primary sources&quot; or &quot;am I already behind?&quot; Meanwhile, the internet keeps telling you that you are doomed if you do not learn some new Claude Code / Codex trick. Most of that is anxiety manufacturing.&lt;/p&gt;
&lt;h3&gt;The first step in learning is not studying. It is scraping job descriptions.&lt;/h3&gt;
&lt;p&gt;I learn very pragmatically: for employability and for building real things. So when I enter a new direction, I first scrape a pile of job descriptions and look at the terms the market is using. Recently, when I wanted to learn agentic RL, I searched for roles from recognizable large companies and top startups.&lt;/p&gt;
&lt;p&gt;Why start from job descriptions? Because &lt;strong&gt;once you know the vocabulary, you can search and talk to AI precisely&lt;/strong&gt;, and you can start building a basic map of the field. This works when the direction already has real jobs, which is true for a relatively mature and fast-moving area like agents. If there are no jobs yet, you have to fall back to search and blogs.&lt;/p&gt;
&lt;p&gt;One trap: &lt;strong&gt;do not take very early-stage tiny-company job descriptions too seriously.&lt;/strong&gt; Their JDs are often vibe-generated and not very useful.&lt;/p&gt;
&lt;p&gt;For information sources, I recommend X/Twitter and official blogs first - OpenAI, Anthropic, and so on. There are good Chinese newsletters too, but many of the ones I see have clickbait titles and low information density. Primary signals are on X and official blogs; WeChat articles are often second-hand retellings.&lt;/p&gt;
&lt;h3&gt;Do not let AI teach you a new field from zero&lt;/h3&gt;
&lt;p&gt;This is a trap worth spelling out. Current large models have two common limitations. First, they tend to &lt;strong&gt;follow your framing&lt;/strong&gt;. However you ask, they continue along your assumptions. Second, when you have no foundation at all, you cannot detect hallucinations. This is a general limitation of current models, not one model&apos;s fault.&lt;/p&gt;
&lt;p&gt;Combined, these two problems are dangerous. If you are starting from zero and hand the entire &quot;teaching&quot; job to AI, it is easy to drift. It gives you a polished-looking learning path, you cannot judge whether it is right, and then it reinforces the direction you asked for. You end up with a self-consistent but distorted map.&lt;/p&gt;
&lt;p&gt;The correct order is the reverse:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Wrong: let AI teach from zero&lt;/strong&gt; - ask it for a learning path -&gt; you lack the foundation to judge it -&gt; it follows your framing -&gt; you drift.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Right: capture primary sources first&lt;/strong&gt; - scrape job descriptions or ask for a few good blogs -&gt; read the originals and build your own source of truth -&gt; when stuck, ask AI specific questions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I learn a new field, I ask AI to recommend a few good blogs, not to lecture from scratch. There will definitely be parts I do not understand. I then send those parts back and ask for help. That way, the model is anchored to my learning path and can understand my current stage.&lt;/p&gt;
&lt;h3&gt;Give the manual labor to agents&lt;/h3&gt;
&lt;p&gt;Instead of reading the information stream all day, let your agent act as a filter. You only receive the small set worth reading:&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;One common pitfall: if you ask an LLM to &quot;recommend a few papers,&quot; it may invent titles and links. The safer approach is to connect it to &lt;strong&gt;real, trusted tools&lt;/strong&gt; - for example, an arXiv skill that extracts data from the source site. Then the results are real links and real metadata, not model imagination. After collecting candidates, add a verification step: have the agent confirm that each link is reachable and that the title and abstract match before summarizing and filtering.&lt;/p&gt;
&lt;p&gt;Another simple heuristic: &lt;strong&gt;to decide whether a paper is worth tracking, first check whether it has an open-source repo.&lt;/strong&gt; Crude, but useful.&lt;/p&gt;
&lt;p&gt;To be clear, not everything should be handed to AI. Precisely because AI exists, independent learning and deep thinking matter more. You still have to decide which blogs and papers deserve careful reading, and which tasks can be fully delegated to an agent.&lt;/p&gt;
&lt;h3&gt;Everyone should have a personal agent with long-term memory&lt;/h3&gt;
&lt;p&gt;If you have used OpenClaw or Hermes Agent, you know the shape: a persistent agent that you talk to through WhatsApp or Telegram. The architecture roughly looks like this:&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;It is a persistent gateway running on your machine, turning the apps you already use into command surfaces. It has &lt;strong&gt;persistent memory&lt;/strong&gt;, hundreds of &lt;strong&gt;skills&lt;/strong&gt;, and a &lt;strong&gt;heartbeat&lt;/strong&gt; that wakes itself up on a schedule to help you follow up on email and calendar items.&lt;/p&gt;
&lt;p&gt;I think everyone should have this kind of long-memory personal agent now, &lt;strong&gt;even if long-term memory is still rough today&lt;/strong&gt;. When you write your own skills and use it deeply over time, you hit real problems. Those experiences are exactly what carry weight in interviews and technical conversations. This is the technical-system version of the main theme: something that runs on its own and helps you process the information flood.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. The real moat: initiative&lt;/h2&gt;
&lt;p&gt;This part starts from something my mentor once said: &lt;strong&gt;&quot;Interviewing is the only moat in our field.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I still agree, but I now understand it differently. I used to take it literally and grind interviews. Now I read &quot;interviewing&quot; more as a learning method. Its real core is forcing yourself into external evaluation instead of building behind closed doors. If that is the core, interviews are not the only path: group discussions, hackathons, and workshops are all versions of the same thing. Of course, I also admit that some interviews, especially at small companies, are tiring and not worth doing just for practice.&lt;/p&gt;
&lt;p&gt;Behind all these actions - pushing yourself out to be tested - is one thing: &lt;strong&gt;initiative&lt;/strong&gt;. That is the real moat.&lt;/p&gt;
&lt;h3&gt;Knowledge is the foundation. Context is the moat.&lt;/h3&gt;
&lt;p&gt;Here I want to borrow a distinction from &lt;a href=&quot;https://letters.thedankoe.com/p/the-most-important-skill-to-learn&quot;&gt;Dan Koe&lt;/a&gt;. You can treat some of his writing as motivational fluff, and I often do, but this point is right: we should become &lt;strong&gt;context creators&lt;/strong&gt;, not just content creators.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Knowledge / content&lt;/strong&gt; - fact-based and mass-producible. AI supplies it almost infinitely. It is increasingly like cabbage: everyone can get it, so it does not differentiate you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context&lt;/strong&gt; - your judgment, taste, path, and scars. This is the part AI cannot replace or mass-produce.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One misunderstanding needs to be cleared up: saying knowledge is &quot;cabbage&quot; does not mean knowledge is unimportant. It means knowledge is easy to obtain and therefore not the differentiator. When learning a new area, you still need a solid foundation. Without it, you cannot read primary sources and cannot tell whether AI is hallucinating. &lt;strong&gt;Foundational knowledge is the ticket. The real moat is the context you grow on top of it around your own path. Knowledge is easy to get; context is hard. Do not reverse the order.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In interviews, this becomes concrete. &quot;What are skills?&quot; AI can answer that perfectly. What you can answer is: which skills you have actually used, what was good and bad about them, what pitfalls you hit, and how you made tradeoffs. AI cannot replace that. Tencent&apos;s report puts it more brutally: AI replaces &quot;the reason you were hired.&quot;&lt;/p&gt;
&lt;p&gt;That is why I am skeptical of bootcamp projects and open-source projects with no substantial second-pass development. AI can produce those. Why would I hire someone who only proves they can build what AI can already build? I want to see the parts AI cannot replace, including taste. A very practical example: people with stronger visual taste often build better frontends, even if they use tools like Google AI Studio that developers may consider &quot;less advanced.&quot; Many PMs and designers produce better-looking interfaces than pure developers. So we developers need to train taste too.&lt;/p&gt;
&lt;h3&gt;The winner is not always the most technical. It is the most proactive.&lt;/h3&gt;
&lt;p&gt;Tencent&apos;s &lt;a href=&quot;https://news.qq.com/rain/a/20260603A07TIY00&quot;&gt;Super Individual Era report&lt;/a&gt; breaks &quot;super individuals&quot; into four capabilities. I think the framing is useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI First&lt;/strong&gt; - AI is the default starting point for work. In an interview a few days ago, the interviewer asked me whether I still hand-write code. I said: honestly, not much. My university years overlapped with AI becoming extremely capable, so AI First feels natural to me. People who lived through the older era of traditional programming often find this mindset shift harder.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capability leap&lt;/strong&gt; - order-of-magnitude improvement plus cross-domain loops. This is similar to why teams now hire full-stack engineers instead of neatly separating frontend and backend. AI has lifted the scope one person can cover. Later, we may see more &quot;product development engineers&quot; who build and also understand growth.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Active exploration&lt;/strong&gt; - this is the most important one: proactively pushing toward the boundary of AI capability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Influence spillover&lt;/strong&gt; - making the whole team faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The report also says something I strongly agree with, and it matches what Fan Ling, the founder of Tezign where I interned, has observed: &lt;strong&gt;the people who use AI best are often not engineers, but product managers and designers.&lt;/strong&gt; I felt this directly during my internship. The first person to think of using AI for video was an editor. Often you really do need to jump outside the engineering frame.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI has pulled almost everyone back toward the same starting line. In that world, initiative becomes the scarce thing.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Make your learning trail public and turn it into a loop&lt;/h3&gt;
&lt;p&gt;So how do you become proactive? &lt;strong&gt;Make your learning path and traces public, and turn them into a loop:&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;Build a small thing first. You will hit real problems. Distill those problems into articles, skills, or notes, then publish them - on a blog, in videos, on social media, or simply in a community group. After publishing, you either receive feedback or start the next thing, and you return to the beginning.&lt;/p&gt;
&lt;p&gt;This is the growth-system version of the main theme. It has the same shape as your personal agent, except it runs on you. The key is: &lt;strong&gt;do not only output content; output your judgment, pitfalls, and path - your context.&lt;/strong&gt; Publishing also forces clarity. It is like solving a science problem: if you really understand it, you should be able to explain it to someone else. This talk itself is me forcing myself to distill less than a year of experience into something public.&lt;/p&gt;
&lt;h3&gt;Why this is good news for young people: faster iteration flattens the starting line&lt;/h3&gt;
&lt;p&gt;Many companies do not only filter by school; they also filter by age - &quot;we only want people born after 2000,&quot; or &quot;only post-90s.&quot; A weaker school background can sometimes be compensated for with strong external projects. &lt;strong&gt;Age cannot be compensated for.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But the reverse is also true: &lt;strong&gt;no one has ten years of Loop Engineering experience.&lt;/strong&gt; The most senior engineer and you are reading the same tweet this week.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Credentials expire. Curiosity compounds. That is what overtaking on a curve looks like.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;A concrete way to overtake: do evaluation&lt;/h3&gt;
&lt;p&gt;Here is a very recent example. Vercel&apos;s &lt;a href=&quot;https://vercel.com/changelog/program-agent-harnesses-with-ai-sdk&quot;&gt;AI SDK update&lt;/a&gt; this week (6/12) lets you swap harnesses the way you swap models - Claude Code, Codex, Pi, all behind the same API, each running in its own sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const agent = new HarnessAgent({
  harness: claudeCode, // can also be codex / pi
  sandbox: createVercelSandbox()
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the first time, harness is being standardized as an official engineering layer. The real chain reaction is this: &lt;strong&gt;once harnesses can be swapped as easily as models, comparing which harness is better becomes both easy and valuable.&lt;/strong&gt; In other words: evaluation. And agent evaluation is still scarce. This opening has barely been explored systematically.&lt;/p&gt;
&lt;p&gt;So &quot;do evaluation&quot; is a very practical entry point. I have said this repeatedly on my blog: &lt;strong&gt;for your internship project or personal project, if you have the time and ability, do evaluation.&lt;/strong&gt; Evaluation forces you into real problems. Without evaluation, your agent is a black box and you do not know whether it works. Evaluation is also valuable in the job market. Last week, a student working in automotive, a very vertical domain, had done evaluation and accumulated many real cases and lessons. Those could directly feed into his next job.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Finally: turn anxiety into two actions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Build a real thing&lt;/strong&gt; - even a tiny agent is enough. Let it touch real problems first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Publish your learning trail&lt;/strong&gt; - blog, Xiaohongshu, GitHub, anything. Output context, not just content.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Terms will keep changing. But technically and personally, what you need is the same thing: &lt;strong&gt;a system that keeps running.&lt;/strong&gt; Technically, it is a persistent agent with memory, skills, and a heartbeat. Personally, it is a loop of &quot;build something -&gt; hit a real problem -&gt; distill -&gt; publish -&gt; build the next thing.&quot; Same shape, two systems. Once you build it, it helps you fight the noise that never stops changing.&lt;/p&gt;
&lt;p&gt;Terms are noise. Systems are signal. That is the talk. If you have questions, come chat in the group or comments.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Joye · &lt;a href=&quot;https://joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Prompt Engineering: &lt;a href=&quot;https://www.promptingguide.ai/&quot;&gt;promptingguide.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Context Engineering (Karpathy): &lt;a href=&quot;https://x.com/karpathy/status/1937902205765607626&quot;&gt;x.com/karpathy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open-source Agent / deepagents: &lt;a href=&quot;https://github.com/langchain-ai/deepagents&quot;&gt;github.com/langchain-ai/deepagents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Harness Engineering - OpenAI Codex: &lt;a href=&quot;https://openai.com/index/introducing-codex/&quot;&gt;openai.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Harness Engineering - Anthropic: &lt;a href=&quot;https://www.anthropic.com/engineering/harness-design-long-running-apps&quot;&gt;anthropic.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Loop Engineering - Steinberger original tweet: &lt;a href=&quot;https://x.com/steipete/status/2063697162748260627&quot;&gt;x.com/steipete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Loop Engineering - Osmani&apos;s naming post: &lt;a href=&quot;https://addyosmani.com/blog/loop-engineering/&quot;&gt;addyosmani.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LangChain harness benchmark post: &lt;a href=&quot;https://www.langchain.com/blog/improving-deep-agents-with-harness-engineering&quot;&gt;langchain.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Terminal-Bench 2.0 leaderboard: &lt;a href=&quot;https://www.tbench.ai/leaderboard/terminal-bench/2.0&quot;&gt;tbench.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Dan Koe on context vs content: &lt;a href=&quot;https://letters.thedankoe.com/p/the-most-important-skill-to-learn&quot;&gt;letters.thedankoe.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tencent Research Institute, Super Individual Era: &lt;a href=&quot;https://news.qq.com/rain/a/20260603A07TIY00&quot;&gt;news.qq.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Vercel AI SDK Harness: &lt;a href=&quot;https://vercel.com/changelog/program-agent-harnesses-with-ai-sdk&quot;&gt;vercel.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>I Grilled Another Agent Candidate: 46-Minute Mock Interview</title><link>https://www.joyehuang.me/en/blog/20260528---agentmockinterviewreview/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260528---agentmockinterviewreview/post</guid><description>A 46-minute 1v1 Agent engineer mock interview: deep-diving two personal projects, plus RAG, Agent evaluation, Skills, MCP, prefix caching, and Q&amp;A.</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><content:encoded>import WechatReveal from &apos;@/components/WechatReveal.astro&apos;
&lt;blockquote&gt;
&lt;p&gt;Date: May 28, 2026 | Duration: 46 min 41 sec
Interviewer: Joye (me) | Candidate: H
Format: paid mock interview · built around two personal Agent projects + Agent fundamentals + a reverse-question/debrief round&lt;/p&gt;
&lt;p&gt;Author: Joye | &lt;a href=&quot;https://www.joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt; | &lt;a href=&quot;https://github.com/joyehuang&quot;&gt;GitHub&lt;/a&gt; | WeChat &lt;code&gt;joye050604&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Before we start&lt;/h2&gt;
&lt;p&gt;My last post, &lt;a href=&quot;/en/blog/20260512---agentmockinterview/post&quot;&gt;&lt;em&gt;A 1-Hour-19-Minute Agent Engineer Mock Interview&lt;/em&gt;&lt;/a&gt;, was also a debrief from &lt;strong&gt;my seat as the interviewer&lt;/strong&gt; — except that one had two interviewers, whereas this time it was just me grilling H one-on-one.&lt;/p&gt;
&lt;p&gt;H booked a paid mock interview, targeting an Agent engineer role. I ran it at the same intensity as a real interview — digging deep into the two personal projects on his résumé, then filling in Agent fundamentals in the back half, and finally reserving nearly 20 minutes for a debrief and some sharing.&lt;/p&gt;
&lt;p&gt;Compared with the last post, this one is more focused on the &lt;strong&gt;deep-dive-into-projects + exposing-fundamentals-gaps&lt;/strong&gt; thread. The back-half material — reverse questions, the &quot;vibe coding gear&quot; playbook, résumé advice — is stuff I cover in every interview, but I always tune it to the candidate&apos;s weak spots. This time I specifically reinforced the areas H couldn&apos;t answer (RAG, Agent evaluation, the engineering tradeoffs around prefix caching).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ Annotation key for this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🟢 &lt;strong&gt;H answered well&lt;/strong&gt; | 🟡 &lt;strong&gt;H answered partially / off-target&lt;/strong&gt; | 🔴 &lt;strong&gt;H couldn&apos;t answer / got it wrong&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;💡 &lt;strong&gt;= the standard answer / correct line of thinking I gave on the spot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🔧 &lt;strong&gt;= corrections I made afterward against Anthropic&apos;s official docs&lt;/strong&gt; (I did a pass before publishing; there were a few spots where I wasn&apos;t precise enough during the interview either, and I&apos;m flagging them honestly — knowledge moves so fast that this is just the nature of the field)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Part 1 · Project One: a long-term personal assistant Agent&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;H&apos;s project is similar to &lt;a href=&quot;/en/notes/0526-hermes-fts5-session-search&quot;&gt;Hermes&lt;/a&gt; — a long-term personal AI Agent deployed on EC2, centered on a memory system (consolidation + memory.md) and prefix-cache optimization. This was H&apos;s strongest area, so I probed it the deepest.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.1 How often does consolidation (memory distillation) trigger? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: You said you do consolidation. After each conversation, how frequently does consolidation run? How do you decide?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consolidation isn&apos;t triggered on a time basis, but &lt;strong&gt;on a &quot;new-information-count&quot; threshold&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;He set a threshold on the count of new information; once it&apos;s hit, consolidation triggers once.&lt;/li&gt;
&lt;li&gt;The information counted toward that total has three parts: &lt;strong&gt;① the user&apos;s input ② the assistant&apos;s output after the ReAct loop ③ some tool output&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Once the accumulated count reaches a certain number, consolidation runs a round of summarization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.2 What exactly is the input to consolidation? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;I confirmed repeatedly: The stuff you feed in includes both assistant messages and user messages, right? You consolidate both of them?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Everything goes in&lt;/strong&gt; — user messages and the AI&apos;s responses are both added to the running total.&lt;/li&gt;
&lt;li&gt;The consolidation step uses a &lt;strong&gt;separate LLM (large language model)&lt;/strong&gt; of its own.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;extracts some long-term facts and the like&lt;/strong&gt; from this information, then stores them in a memory-like DB.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.3 Is consolidation a standalone agent? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: So is this consolidation done by another standalone agent with its own system prompt?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It shouldn&apos;t count as an agent; it&apos;s just &lt;strong&gt;a very simple tool call&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;I pressed: Does this consolidation step live inside your main conversation agent, or somewhere else? Who initiates the API call that runs consolidation — the main agent, or that extra standalone module?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Not the main agent.&lt;/strong&gt; It&apos;s &lt;strong&gt;a fixed process hardcoded into the workflow&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;At the end of a ReAct loop, it makes a judgment about whether to trigger consolidation.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 &lt;strong&gt;My debrief&lt;/strong&gt;: H&apos;s phrasing here was a bit tangled, and it took me several follow-ups to nail down &quot;who actually initiates the API call.&quot; His design is actually correct — consolidation is a fixed step in the workflow, independent of the main conversation agent, triggered by orchestration logic that checks the threshold at the end of each ReAct loop, using a separate LLM call (with a dedicated extraction prompt). He just didn&apos;t articulate it cleanly. &lt;strong&gt;Clarity of expression is itself an interview criterion&lt;/strong&gt; — especially when the interviewer is probing a core ownership question like &quot;who initiates the call,&quot; a vague answer makes people wonder whether you actually implemented it yourself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.4 What happens when the context overflows? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: People usually handle context overflow. How do you handle it on your end?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer (two parts):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inside the ReAct loop, after each call he runs a check, hanging a test: &lt;strong&gt;whether it has hit 80% of the context window&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The history isn&apos;t summarized-after-it-overflows; instead, &lt;strong&gt;history holds a fixed number of entries&lt;/strong&gt; that stay fixed — pulling the latest N rounds from the full record into the prompt.&lt;/li&gt;
&lt;li&gt;If it overflows, he &lt;strong&gt;just deletes&lt;/strong&gt;: e.g. cut from 40 entries straight down to 20, and if that&apos;s still not enough, down to 10.&lt;/li&gt;
&lt;li&gt;Summarization is &lt;strong&gt;already handled in consolidation&lt;/strong&gt; (consolidation summarizes this information and stores it in the memory base), so he &lt;strong&gt;doesn&apos;t do a separate summarization for &quot;overflow&quot; — the two are kept separate&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;I pressed: Why just delete?&lt;/strong&gt; 🔴&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🔴 &lt;strong&gt;H couldn&apos;t answer.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;💡 &lt;strong&gt;My standard line of thinking at the time&lt;/strong&gt;: The biggest problem with FIFO-deleting old messages is &lt;strong&gt;information loss&lt;/strong&gt; — the rounds you cut may contain key facts that later turns still need to reference. A better approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before cutting, do a &lt;strong&gt;summarization-compression&lt;/strong&gt; pass (compress the old rounds you&apos;re about to drop into 1-2 summary lines that stay in context) instead of mindlessly deleting.&lt;/li&gt;
&lt;li&gt;But summarization introduces a &lt;strong&gt;prefix-cache-invalidation&lt;/strong&gt; cost (see 1.6), so engineering-wise it&apos;s a tradeoff.&lt;/li&gt;
&lt;li&gt;Actually, there&apos;s a good reason H&apos;s project gets away with deleting directly — because consolidation has already extracted the long-term facts into storage, so what gets deleted is only the short-term conversation. He could absolutely have raised this argument himself, but in the moment he didn&apos;t realize he needed to connect &quot;my consolidation design already provides a backstop&quot; with &quot;so deleting directly is reasonable.&quot; &lt;strong&gt;This is the classic case of &quot;did the right thing but can&apos;t explain it.&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.5 Is memory.md fixed-length, or can it grow without bound? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Is your memory.md (the user-profile document) fixed-length, or can it keep growing?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;memory.md is tied to the &lt;strong&gt;padding layer (the cache layer)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If it gets updated at the end of every conversation, &lt;strong&gt;the cache won&apos;t hit&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;So consolidation &lt;strong&gt;asynchronously writes&lt;/strong&gt; the long-term user preferences, profession/job info, etc. &lt;strong&gt;into the padding-layer file&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;My question: Does this document have a cap? Like, only so many entries? Or can it accumulate indefinitely?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It &lt;strong&gt;has no cap set&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Because it&apos;s not all dumped into the prompt — there&apos;s &lt;strong&gt;a retrieval round&lt;/strong&gt; that pulls out the relevant info before injecting it into the prompt, so &lt;strong&gt;overflow shouldn&apos;t be a concern&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.6 &quot;memory.md in the middle of the prompt&quot; = full injection? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question (asking against his résumé/project doc): You wrote &quot;memory.md, as the user profile, sits in the middle of the prompt.&quot; Do you put the entire memory.md in there?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Not the whole thing&lt;/strong&gt; — what&apos;s written there is wrong (the résumé/doc phrasing is inaccurate).&lt;/li&gt;
&lt;li&gt;In the actual project it should be &lt;strong&gt;a retrieval round first&lt;/strong&gt;, then &quot;memory retrieval results + user profile&quot; both get injected — what goes in is the relevant portion that was retrieved.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 &lt;strong&gt;My debrief&lt;/strong&gt;: This is a textbook &lt;strong&gt;résumé landmine&lt;/strong&gt;. The wording on the résumé/doc (&quot;sits in the middle of the prompt&quot;) didn&apos;t match the real implementation (inject-after-retrieval), and I caught it on the spot. &lt;strong&gt;Every single sentence on your résumé has to map to a real implementation, otherwise it&apos;s a vulnerability that will get dug into&lt;/strong&gt; — especially since an Agent-track interviewer will almost certainly latch onto every technical term you wrote and grill you on the implementation details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.7 Should memory.md have a cap? (open design question) 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Suppose, like &lt;a href=&quot;/en/notes/0526-hermes-fts5-session-search&quot;&gt;Hermes agent&lt;/a&gt;, memory.md is fixed-length and stuffed in full into the system prompt. I give you two choices — ① with a cap (say 3000 tokens) ② can grow without bound. Which do you think works better?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I think &lt;strong&gt;a cap is better&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Because unbounded growth wastes resources no matter what, and may contain duplicate information, which means &lt;strong&gt;the model can&apos;t focus its attention&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🟢 The direction here is right (a cap is better).&lt;/p&gt;
&lt;h3&gt;1.8 You have a cap, but a genuinely useful new memory comes in — now what? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;I pressed: If there&apos;s a cap and I&apos;ve already hit it, but I now detect a genuinely useful memory that needs to be stored, what do you do?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First do &lt;strong&gt;dedup detection&lt;/strong&gt; — which existing memories does the new one overlap with, and is there any overlap at all.&lt;/li&gt;
&lt;li&gt;If business needs require a real-time update, update it in.&lt;/li&gt;
&lt;li&gt;If there&apos;s no overlap, &lt;strong&gt;merge (consolidate)&lt;/strong&gt; with the existing content — merge what can be merged, &lt;strong&gt;rather than dumping it in verbatim&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;I pressed: Do you think merging is a good operation?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Merging &lt;strong&gt;will definitely cause information distortion&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;But if there&apos;s a token-count limit, I think &lt;strong&gt;merging is a necessary operation&lt;/strong&gt; (distortion is an acceptable price paid for space).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🟢 This set was well answered — he gave both a plan (dedup → update/merge) and pointed out the trade-off (merge vs. distortion). This is an answer structure I appreciate: &lt;strong&gt;a plan plus a tradeoff&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;1.9 Any more techniques to improve the prefix cache? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: For prefix cache, what other techniques do you have to improve it?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Core idea: &lt;strong&gt;find the parts of each conversation round that don&apos;t change&lt;/strong&gt;, and put the unchanging content where the prefix cache can hit, to cut token consumption.&lt;/li&gt;
&lt;li&gt;Example: if the user profile &lt;strong&gt;updates frequently&lt;/strong&gt;, it definitely won&apos;t hit the cache; but if it&apos;s &lt;strong&gt;updated asynchronously on a schedule via a function&lt;/strong&gt; (so it changes infrequently), it can go in the cache-hit region.&lt;/li&gt;
&lt;li&gt;So it&apos;s a &lt;strong&gt;relative, depends-on-how-you-set-it-up&lt;/strong&gt; problem — separate volatile content from stable content, and front-load the stable part as much as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🟢 Well answered — he caught the core of &quot;front-load the stable, update the volatile asynchronously.&quot;&lt;/p&gt;
&lt;h3&gt;1.10 In Plan mode, how do you avoid breaking the prefix cache? (Claude Code scenario) 🔴&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: You know Claude Code / Codex has a Plan mode, right? In Plan mode we want to restrict tools — it can&apos;t have edit permissions. But I also want to guarantee the prefix cache stays alive, so I can&apos;t change the tool list (otherwise switching from plan mode back to work mode would invalidate the cache). How do you handle this?&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🔴 &lt;strong&gt;H started with &quot;I genuinely don&apos;t know this one.&quot;&lt;/strong&gt;
Then he tried to answer, but his thinking was wrong — he assumed &quot;the tools visible each round change, and you reassemble the currently active tools on every call.&quot;&lt;/p&gt;
&lt;p&gt;I corrected him on the spot: &lt;strong&gt;if the tools differ, the prefix cache invalidates.&lt;/strong&gt; His résumé also says &quot;40+ tools, full schema injection,&quot; and that tool schema should sit in the prefix-cache section and &lt;strong&gt;be touched as little as possible&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;H even pushed back, saying &quot;the prefix-cache section and this are separate; the tools section is rewritten every time&quot; — which is actually his project&apos;s design, but I&apos;d argue that design &lt;strong&gt;is wasteful instead&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;The standard answer (I wasn&apos;t precise enough live; filling it in here based on &lt;a href=&quot;https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything&quot;&gt;Anthropic&apos;s official blog &lt;em&gt;Lessons from building Claude Code: Prompt caching is everything&lt;/em&gt;&lt;/a&gt;)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What Claude Code does: &lt;strong&gt;the tool list is completely identical in plan and non-plan mode, byte-identical, with no disable flags or schema changes whatsoever.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The way Plan mode is implemented: &lt;strong&gt;&lt;code&gt;EnterPlanMode&lt;/code&gt; and &lt;code&gt;ExitPlanMode&lt;/code&gt; themselves exist as two tools in the tool list.&lt;/strong&gt; When the model calls &lt;code&gt;EnterPlanMode&lt;/code&gt;, a &lt;code&gt;&amp;#x3C;system-reminder&gt;&lt;/code&gt; is injected via the tool result (appended as a subsequent message, rather than modifying the system prompt), telling the model &quot;you&apos;re in plan mode now, you MUST NOT do any edits.&quot;&lt;/li&gt;
&lt;li&gt;This is a &lt;strong&gt;&quot;soft-constraint / trust-based&quot; design&lt;/strong&gt; — the model can still physically call Edit, Bash, and all other tools; it&apos;s just been explicitly instructed &quot;don&apos;t use them right now.&quot; By contrast, GitHub Copilot&apos;s plan mode &lt;strong&gt;physically removes 43 tools&lt;/strong&gt; (a hard constraint); Claude Code chose to keep all the tools + constrain behavior with a system reminder, &lt;strong&gt;for the core purpose of not blowing through the prefix cache.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A related design worth adding: Claude Code also has a &lt;strong&gt;&lt;a href=&quot;https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool&quot;&gt;&lt;code&gt;defer_loading&lt;/code&gt; tool-search mechanism&lt;/a&gt;&lt;/strong&gt; — a large set of MCP tools isn&apos;t injected with full schemas; instead only lightweight stubs are sent (just the tool name + &lt;code&gt;defer_loading: true&lt;/code&gt;), and the model &quot;discovers&quot; and loads full schemas on demand via the tool-search tool. This is another way to protect prefix-cache stability.&lt;/li&gt;
&lt;li&gt;The core principle: &lt;strong&gt;Tools are part of the cache prefix; any change to a tool schema blows through the entire cache — so engineering-wise, everything revolves around &quot;the tool list never changes.&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🔧 &lt;strong&gt;My own correction on review&lt;/strong&gt;: During the interview I said &quot;marked as disabled / inert,&quot; which isn&apos;t entirely accurate — Anthropic&apos;s actual approach is to &lt;strong&gt;leave the tool list completely untouched and switch modes via the extra EnterPlanMode/ExitPlanMode tools + a system-reminder soft constraint.&lt;/strong&gt; The direction was right (both are about preserving the prefix cache), but I got the specific implementation detail slightly off. This is also a reverse example — &lt;strong&gt;as the interviewer, you have to be willing to admit when you weren&apos;t precise; knowledge moves too fast.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Part 2 · Project Two: a music-radio Agent&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Core: a song semantic-retrieval pipeline + vector recall + async TTS narration, packaged into an &quot;interactive radio experience.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2.1 Which vector database do you use? Looked into others? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Your project implements a song semantic-retrieval pipeline and vector recall — which vector database do you use? Have you looked into others?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;He uses something very lightweight: &lt;strong&gt;SQLite&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;He&apos;s heard of &lt;strong&gt;Neoverse / the Neo family&lt;/strong&gt; (a slip of the tongue; he probably meant some other vector store).&lt;/li&gt;
&lt;li&gt;And &lt;strong&gt;PostgreSQL (PGSQL) probably has a vector store too&lt;/strong&gt; (meaning pgvector) — he&apos;d seen it before.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 &lt;strong&gt;My debrief&lt;/strong&gt;: His knowledge of vector stores is clearly thin. The common ones should roll off the tongue: &lt;strong&gt;Pinecone, Milvus, Qdrant, Weaviate, Chroma, pgvector, FAISS&lt;/strong&gt;, etc., along with their respective use cases (local/cloud, scale, whether hybrid retrieval is needed). I didn&apos;t keep pushing, because he couldn&apos;t answer the RAG pain points at all afterward, so I just skipped this part.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2.2 The biggest difficulty in vector recall / the biggest pain point of RAG? 🔴&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: What do you think is the biggest difficulty in the vector-recall process? Or what do you think is the biggest pain point of RAG technology today?&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🔴 &lt;strong&gt;H couldn&apos;t answer.&lt;/strong&gt; He only said &quot;it might recall some irrelevant stuff,&quot; and for pain points he &quot;hasn&apos;t really looked into it.&quot;&lt;/p&gt;
&lt;p&gt;💡 I&apos;ve put the complete answer to this in the big RAG primer in Part 4 (in the debrief I added a whole section on this), see 4.5.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2.3 What is the &quot;120-second black-box wait&quot;? How did you solve it? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question (pointing at his résumé): You wrote here &quot;unsolved / agent&apos;s synchronous 120-second black-box wait&quot; and &quot;users can confirm or skip after each round of recommendation, paired with async TTS&quot; — what is this?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The problem: the whole pipeline is &lt;strong&gt;generated as one chunk&lt;/strong&gt;. If you pick a song, you have to wait for the entire pipeline to finish generating before it returns, so the user has to &lt;strong&gt;sit there waiting&lt;/strong&gt; (the 120-second black box).&lt;/li&gt;
&lt;li&gt;His fix: &lt;strong&gt;it tells you the song as soon as it generates one&lt;/strong&gt;; if you decide to add it to the upcoming playlist, you click &quot;confirm&quot; and it&apos;s added to the playlist, with &lt;strong&gt;the subsequent steps pushed to the background.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;This turns &quot;synchronous waiting on a long pipeline&quot; into &quot;&lt;strong&gt;return first + user confirms + process asynchronously in the background&lt;/strong&gt;,&quot; eliminating the black-box wait.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🟢 After hearing this I said &quot;oh, I get it&quot; — this async interaction design is the highlight of Project Two, and he explained it clearly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After that I stopped asking about Project Two, my exact words: &lt;strong&gt;&quot;I feel like there&apos;s nothing worth asking about the project — let&apos;s do fundamentals.&quot;&lt;/strong&gt; → Project Two lacked depth overall and got skipped through quickly. This is also a hint: &lt;strong&gt;if a project has only one highlight, ten minutes is enough to grill it dry&lt;/strong&gt;; a project that genuinely holds up to grilling needs at least 3-5 design decisions you can discuss in depth.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Part 3 · Agent fundamentals&lt;/h2&gt;
&lt;h3&gt;3.1 How does an Agent become aware that Skills exist? 🟡→🔴&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Skills — how does an agent become aware that skills exist?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There should be some &lt;strong&gt;upfront toggle&lt;/strong&gt;, like how in a client you can switch certain skills on or off ahead of time.&lt;/li&gt;
&lt;li&gt;During use, you definitely don&apos;t dump them all in; you put some of their &lt;strong&gt;describe (description)&lt;/strong&gt; in, and if you think this round of conversation will need it, you read out the full skill like calling a tool.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡→🔴 My on-the-spot verdict: &lt;strong&gt;&quot;Said a lot, didn&apos;t hit the point.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;The standard answer I gave (verified against the &lt;a href=&quot;https://platform.claude.com/docs/en/agents-and-tools/skills/overview&quot;&gt;official Claude Skills docs&lt;/a&gt;, mostly accurate)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A skill has a &lt;strong&gt;fixed template&lt;/strong&gt;, and &lt;strong&gt;the first three lines are its frontmatter&lt;/strong&gt; — containing its &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;description&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;This part (name + description) is loaded into the system prompt at session startup&lt;/strong&gt; — so the LLM can &quot;see&quot; the existence of all skills from the start. In Anthropic&apos;s own words: &quot;Provides just enough information for Claude to know when each skill should be used without loading all of it into context.&quot;&lt;/li&gt;
&lt;li&gt;Only once the LLM decides which skill to use does it &lt;strong&gt;load the full body of SKILL.md into context via a file read (bash Read)&lt;/strong&gt; (the second level of progressive disclosure).&lt;/li&gt;
&lt;li&gt;If SKILL.md further references specific files under references/ or scripts/, the model can &lt;strong&gt;load them on demand one more level (the third level)&lt;/strong&gt;. This is why a project can mount dozens of skills with tiny startup overhead — each skill only costs ~30-60 tokens (frontmatter) at startup.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conclusion: this puts a lot of weight on how well you write your skill description&lt;/strong&gt; — because the model relies on the description to decide &quot;should I trigger this skill this round.&quot; Write the description imprecisely and the model will either misfire or miss the trigger.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.2 Should a skill&apos;s description be long or short? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;I followed up: Suppose a skill is &quot;do frontend design&quot; — do you think its description should be detailed (long) or concise (short)?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It depends on the skill&apos;s internal content:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;If it&apos;s &lt;strong&gt;high-level guidance&lt;/strong&gt;, write a &lt;strong&gt;brief description&lt;/strong&gt; — that way it gets pulled in for reference as long as there&apos;s &quot;a bit of relevance.&quot;&lt;/li&gt;
&lt;li&gt;If it targets a &lt;strong&gt;very specific scenario&lt;/strong&gt;, write it &lt;strong&gt;more detailed&lt;/strong&gt; — that way it only gets used when a scenario &quot;matches more closely.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🟢 Well answered — he caught the core that &quot;the verbosity of the description determines the granularity at which a skill triggers.&quot; He couldn&apos;t answer 3.1 but caught 3.2, which shows he actually has a feel for the underlying logic; he just hasn&apos;t encountered the concrete implementation.&lt;/p&gt;
&lt;h3&gt;3.3 Do you know Agent Evaluation? 🔴&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Have you looked into the Agent evaluation part at all?&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🔴 H flatly said &lt;strong&gt;&quot;haven&apos;t really looked into it.&quot;&lt;/strong&gt; This is one of the key things I told him to fill in (see the debrief checklist in Part 4).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.4 What&apos;s the relationship between MCP and Skills? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: What do you think the relationship is between MCP and Skills?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MCP &lt;strong&gt;provides some methods/tools&lt;/strong&gt;; a Skill is &lt;strong&gt;a methodology&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The two are a &lt;strong&gt;methodology vs. practice&lt;/strong&gt; relationship.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 &lt;strong&gt;My debrief&lt;/strong&gt;: This answer is fairly vague. A more accurate distinction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://modelcontextprotocol.io/docs/getting-started/intro&quot;&gt;MCP (Model Context Protocol)&lt;/a&gt;&lt;/strong&gt;: a &lt;strong&gt;standardized protocol&lt;/strong&gt; that lets an agent connect to external tools/data sources (essentially &quot;a standard for plugging in tools/capabilities&quot;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt;: a set of &lt;strong&gt;packaged, progressively loadable capability bundles&lt;/strong&gt; (SKILL.md + resources) that solve &quot;when and how to use a certain class of specialized capability.&quot;&lt;/li&gt;
&lt;li&gt;In short: &lt;strong&gt;MCP solves &quot;what to plug in and how to plug in external capabilities&quot;; Skills solve &quot;in what scenario the model should invoke which packaged approach.&quot;&lt;/strong&gt; The two can be combined.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.5 To save tokens / cut costs on an Agent project, what methods are there? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Suppose a business-research agent whose goal is to save tokens and cut costs — what specific methods do you generally use?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer (two points):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Progressive tool loading&lt;/strong&gt;: don&apos;t put all the tools in context; build a &lt;strong&gt;tool-ingestion (retrieval) tool&lt;/strong&gt; that progressively pulls out the tools you need.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Forced formatted output&lt;/strong&gt;: add constraints in the prompt so the model outputs &lt;strong&gt;formatted data&lt;/strong&gt;, reducing the tokens consumed in interaction (a hard constraint).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;I pressed: Besides relying on the prompt, what other methods are there for hard constraints?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a &lt;strong&gt;validation layer&lt;/strong&gt; after output finishes — validate whether it output in the required format, and &lt;strong&gt;if it doesn&apos;t pass, send it back for another round&lt;/strong&gt; (retry).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 &lt;strong&gt;My debrief&lt;/strong&gt;: Both points are correct, but not comprehensive. Other token-saving levers worth adding: &lt;strong&gt;prefix-cache-hit-rate optimization, context compression / summarization, using cheaper models for subtasks (model tiering), retrieval injection instead of full injection, trimming a redundant system prompt, batching, capping max_tokens and reasoning length&lt;/strong&gt;, etc. Among these, &lt;strong&gt;model tiering&lt;/strong&gt; and &lt;strong&gt;prefix-cache optimization&lt;/strong&gt; are the two biggest items, and he didn&apos;t bring them up unprompted — a bit of a shame, especially since he&apos;s already doing prefix caching in his own project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.6 Multi-Agent vs. single-Agent — when do you use which? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Multi-agent vs. single-agent — in what situations would you use each? Why? Pros and cons?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Projects where the functions can&apos;t be cleanly separated → single agent&lt;/strong&gt;: e.g. a personal assistant or a radio, where the functions aren&apos;t separated, a single agent is enough. Plus &lt;strong&gt;the context is shared across the various calls, so it works better too&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Big projects where responsibilities are cleanly separated → multi-agent collaboration&lt;/strong&gt;: e.g. one side does docs, another writes code, another does review, with each module&apos;s function clearly separated; if you merge them all together, &lt;strong&gt;the context gets messy&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;I pressed: For something like a research workflow (research first → read the literature → draft one → draft two → review), do you think that counts as multi-agent?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I think &lt;strong&gt;it probably doesn&apos;t / wouldn&apos;t use multi-agent&lt;/strong&gt;, because &lt;strong&gt;its workflow is fairly fixed&lt;/strong&gt; — there&apos;s no need for multiple agents to negotiate who goes first, and no need for a master agent to decide which agent to call.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;I didn&apos;t reject this; I added &quot;things orchestrated like a workflow&quot; (i.e. a fixed-orchestration workflow is another form, sitting between a single agent and a true multi-agent setup).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I kept pressing: Besides &quot;separating responsibilities,&quot; what other advantages does multi-agent have? Give me one advantage and one disadvantage.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Disadvantage (he said first)&lt;/strong&gt;: in multi-agent collaboration, &lt;strong&gt;how to coordinate the interactions between each agent&lt;/strong&gt; is a very hard point.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advantage&lt;/strong&gt;: it can accomplish complex tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 I rejected the &quot;accomplish complex tasks&quot; advantage, my exact words: &lt;strong&gt;&quot;After all that, all you&apos;ve said is multi-agent is complex and single-agent is simple.&quot;&lt;/strong&gt; This is a textbook &quot;looks like an answer but actually says nothing&quot; answer — a single agent plus workflow orchestration can equally accomplish complex tasks, so that&apos;s not a differentiating advantage of multi-agent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;The two core advantages of multi-Agent (my answer + post-hoc refinement)&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;You can swap models / combine multiple models&lt;/strong&gt;: for a company project, multi-model is very important —
&lt;ul&gt;
&lt;li&gt;Different features use different models: &lt;strong&gt;text features, reasoning features, image-generation features&lt;/strong&gt; each use the appropriate model.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The real logic of saving money&lt;/strong&gt;: it&apos;s not that &quot;multi-agent itself saves money,&quot; but that &lt;strong&gt;&quot;multi-agent lets you sensibly use cheap models for grunt work, so you don&apos;t pay top-tier-model prices for every subtask.&quot;&lt;/strong&gt; For example, Claude Code&apos;s Research system uses Opus 4 for orchestration and Sonnet 4 for subagents — total token volume goes up, but the per-token price comes down, and on balance it&apos;s reasonable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can run things concurrently in the background&lt;/strong&gt;: multiple agents can &lt;strong&gt;run at the same time&lt;/strong&gt;, saving wall-clock time. A single agent, even on the same task, can only run serially to completion; multi-agent can process things concurrently.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anthropic.com/engineering/multi-agent-research-system&quot;&gt;Anthropic&apos;s official data&lt;/a&gt;: their Research system (Opus 4 lead + Sonnet 4 subagents) outperforms a single-agent Opus 4 by &lt;strong&gt;90.2%&lt;/strong&gt;, and the core mechanism is exactly &lt;strong&gt;concurrent decomposition + an independent context window per sub-agent.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;🔧 &lt;strong&gt;A one-line post-hoc refinement&lt;/strong&gt;: In the interview I presented &quot;saving money&quot; as the core advantage of multi-agent, and that point is &lt;strong&gt;strictly speaking skewed&lt;/strong&gt; — according to &lt;a href=&quot;https://www.anthropic.com/engineering/multi-agent-research-system&quot;&gt;Anthropic&apos;s official data&lt;/a&gt;, a multi-agent system consumes roughly &lt;strong&gt;15×&lt;/strong&gt; the total tokens of a single agent; it is by no means a &quot;money-saving&quot; architecture. Its real value is &lt;strong&gt;&quot;spending more tokens to buy better results + shorter wall-clock time,&quot;&lt;/strong&gt; and &quot;swapping in cheaper models&quot; is merely an optimization for lowering the per-token cost. So the more precise statement is: &lt;strong&gt;the advantage of multi-agent is concurrent performance and the flexibility of model combination, not absolute cost savings.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.7 What orchestration / communication patterns does multi-Agent have? 🟡&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: Roughly what orchestration or communication patterns does multi-agent have?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer (three):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Master-slave&lt;/strong&gt;: a master agent decides which agent to call right now, with several agents below it in parallel.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sequential orchestration&lt;/strong&gt;: like a fixed workflow, run the agents in order.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loop-style&lt;/strong&gt;: like ReAct — run, check, and if it&apos;s not done, run another round.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;🟡 I said &quot;I roughly get what you mean, but it&apos;s not quite right,&quot; and gave a clearer classification:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Multi-Agent orchestration / communication patterns (my answer)&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Call a sub-agent like calling a tool&lt;/strong&gt;: the master agent tells the sub-agent what to do and hands it the task. In Claude Code / Codex you&apos;d use a &lt;strong&gt;cheap model&lt;/strong&gt; for tasks like searching and reading code, and once the sub-agent is done it returns a &lt;strong&gt;simple summary&lt;/strong&gt; to the master agent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agents talk to each other / share a document&lt;/strong&gt;: build a &lt;strong&gt;shared intermediate document&lt;/strong&gt; and constrain them to &quot;write whatever ideas you have into this document,&quot; communicating through the document.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Peer or hierarchical&lt;/strong&gt;: the core is whether there&apos;s &lt;strong&gt;a hierarchy&lt;/strong&gt; — it can be master-slave, or peer-to-peer.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3.8 What are your own techniques for writing code with AI? 🟢&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;My question: When you write code with AI yourself, what are your techniques?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s answer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Have the AI &lt;strong&gt;first produce something like a requirements doc&lt;/strong&gt;, so it&apos;s clear about what we&apos;re doing right now, and &lt;strong&gt;go step by step.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Have it &lt;strong&gt;lay out the work pipeline first, then go do it&lt;/strong&gt;, so it&apos;s less likely to get halfway through and lose track of what it&apos;s doing.&lt;/li&gt;
&lt;li&gt;Put &lt;strong&gt;repetitive conventions&lt;/strong&gt; straight into a file like &lt;code&gt;CLAUDE.md&lt;/code&gt; as fixed context, so &lt;strong&gt;you don&apos;t have to re-declare them each time — it reads them itself.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🟢 This was answered pragmatically, with real feel for it (requirements-first + pipeline planning + crystallizing conventions in CLAUDE.md). It&apos;s an open-ended question with no standard answer, but the way he answered made me feel he&apos;d genuinely used it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Part 4 · Debrief + reverse-question round (my &quot;exclusive stash&quot;)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;After the interview ended, I spent nearly 20 minutes on a debrief and sharing real-world experience. This part is the most valuable content of the whole session for H, and it&apos;s also the part I cover in every mock interview but that very few people have written out systematically.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4.1 The to-study checklist for H&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;🔴 &lt;strong&gt;RAG&lt;/strong&gt;: completely doesn&apos;t understand it; his biggest weakness.&lt;/li&gt;
&lt;li&gt;🔴 &lt;strong&gt;Agent Evaluation&lt;/strong&gt;: needs to fill it in.&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;Newer things like OpenClaw / Hermes / Skills&lt;/strong&gt;: skim them lightly, enough to &quot;hold your own / get by&quot; in an interview.&lt;/li&gt;
&lt;li&gt;Overall feedback: he was suddenly a bit unfamiliar with his projects (he said himself he&apos;d been fluent on them just two days ago); he needs another pass.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2 The reverse-question round: be &quot;aggressive&quot;&lt;/h3&gt;
&lt;p&gt;I&apos;ve stressed this repeatedly — &lt;strong&gt;your reverse-question time absolutely must be aggressive&lt;/strong&gt;, especially when facing a founder / CEO, where you can challenge them directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① Ask directly about product competitiveness (prerequisite: you understand the space and the product)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ask straight up: &lt;strong&gt;&quot;What advantages does your product have over competitors?&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;I asked exactly this in my own second-round interview, and discussed it with them for half an hour.&lt;/li&gt;
&lt;li&gt;The logic: &lt;strong&gt;if a founder isn&apos;t even confident in their own product and can&apos;t articulate how it differs from competitors, you can write this company off&lt;/strong&gt; (they may just be there to bait funding).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② Ask about the project&apos;s release cycle (especially for startups)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get clear on it: is the product &lt;strong&gt;in development, in closed beta (round one / round two of closed beta), or already launched&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;By analogy to how games split closed-beta rounds, ask down to the specific stage.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③ Ask about the business model / revenue projections (note: not everyone is willing to answer)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can ask about next quarter&apos;s expected &lt;strong&gt;ARR (annual revenue), MRR (monthly revenue)&lt;/strong&gt; magnitude, target user count, target revenue.&lt;/li&gt;
&lt;li&gt;The revenue model has nuances too: you can&apos;t price out of thin air — you look at &lt;strong&gt;competitors&apos; pricing logic&lt;/strong&gt; — is it &lt;strong&gt;subscription&lt;/strong&gt; or &lt;strong&gt;usage-based (API metering)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;④ Ask about team size&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ask about the company&apos;s total headcount + the engineering team&apos;s headcount.&lt;/li&gt;
&lt;li&gt;Ask &lt;strong&gt;who your mentor will be&lt;/strong&gt; — definitely get this clear, because many roles claim to be agent development but &lt;strong&gt;once you&apos;re in you do traditional development&lt;/strong&gt;, never touching agents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;⑤ Talk about growth (my personal preference)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I like talking about growth and target customers.&lt;/li&gt;
&lt;li&gt;My view: &lt;strong&gt;an early-stage startup&apos;s engineering team doesn&apos;t need that many people; what it needs more is a growth team&lt;/strong&gt; — building the product isn&apos;t the finish line; &lt;strong&gt;how to publicize it and get everyone to know about and use it is what matters.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.3 How to &quot;soft-handle&quot; questions you can&apos;t answer&lt;/h3&gt;
&lt;p&gt;I shared a few moves for dealing with questions you can&apos;t answer:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① Pivot via &quot;room for improvement&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For example, when asked about your memory system, you can say: &lt;strong&gt;&quot;I do think my memory system isn&apos;t done that well, and there&apos;s a lot of room for improvement.&quot;&lt;/strong&gt; Then ride that into your thinking.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② Proactively bring up things not on your résumé&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I discussed this in the interview — what&apos;s written on the résumé &lt;strong&gt;is only 30%-50%&lt;/strong&gt;; what I&apos;d rather do in this hour is &lt;strong&gt;draw out the things that aren&apos;t on the résumé.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;So: &lt;strong&gt;if a project has iterated (it&apos;s already at v2, v3, but the résumé is still stuck at v1), you can absolutely bring that up unprompted.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;On a cutting-edge topic like memory, you can proactively say: &lt;strong&gt;&quot;I recently read some fairly new papers and have some ideas...&quot;&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Benefit one: it proves you&apos;ve &lt;strong&gt;thought deeply about the project&lt;/strong&gt; and are continuously iterating, rather than finishing it and dumping it on the résumé.&lt;/li&gt;
&lt;li&gt;Benefit two: it shows you &lt;strong&gt;follow the frontier.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;⚠️ But read the room and manage the pacing — I got interrupted plenty of times myself this morning.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③ For brain-dead fundamentals, just admit it + dissolve it with an AI angle&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An example I gave: asked &quot;the difference between threads and processes&quot; or &quot;how to do inter-process communication,&quot; I just say I &lt;strong&gt;forgot / don&apos;t know.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;But add: &lt;strong&gt;&quot;There&apos;s AI now; if I hit this problem in engineering practice / an internship, I&apos;d definitely use AI to search and solve it. If it&apos;s a domain I&apos;ve never touched at all, I&apos;d worry about a single AI hallucinating, so I could use multi-agent to cross-verify.&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;This kind of answer &lt;strong&gt;sounds very pleasant and cleverly dodges the brain-dead fundamentals question.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;My attitude: &lt;strong&gt;fundamentals questions are brain-dead to begin with; who still asks traditional fundamentals now that there&apos;s AI&lt;/strong&gt; (but some interviewers still test them, see the résumé advice).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.4 Other questions worth asking in the reverse-question round&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;① Ask about the development program (depends on the company, depends on your own performance)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prerequisite: first &lt;strong&gt;assess your performance in this interview.&lt;/strong&gt; If even you don&apos;t think you&apos;re a sure pass, there&apos;s no point asking this kind of question — better to ask something else.&lt;/li&gt;
&lt;li&gt;When you&apos;re confident, you can ask: does the company have a &lt;strong&gt;complete intern development program&lt;/strong&gt;? Who&apos;s the mentor?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② Reverse-engineer your interview performance via a &quot;challenge question&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ask: &lt;strong&gt;&quot;For the role you&apos;re hiring for, what do you think the biggest challenge of the internship would be?&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;This kind of question suits big/mid-sized companies (they usually won&apos;t directly reveal your performance at the end of the interview).&lt;/li&gt;
&lt;li&gt;You can &lt;strong&gt;reverse-engineer the interviewer&apos;s assessment of today&apos;s performance from the answer to this question.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③ &quot;Besides money, what else can I get from joining the company?&quot; — ask with caution&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This question &lt;strong&gt;is better asked once you have plenty of offers&lt;/strong&gt;, otherwise it&apos;s a bit inappropriate.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.5 The big RAG primer (filling in everything H couldn&apos;t answer)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Because H completely doesn&apos;t understand RAG, I gave a whole long section on it. This is the complete RAG knowledge map, and it&apos;s the checklist I personally run through every time I prep RAG questions:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;RAG&apos;s overall flow has three steps: ① vectorize → ② store in a vector DB → ③ recall. Every step can be dug into.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step one: how to store vectors (vectorization + chunking)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dimension choice&lt;/strong&gt;: more dimensions = more information, but &lt;strong&gt;storage cost is higher too&lt;/strong&gt; — that&apos;s a trade-off.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key insight: vector distance is only an &quot;approximation&quot; of semantic distance&lt;/strong&gt; (in the interview I said &quot;close vectors ≠ close semantics,&quot; which strictly speaking isn&apos;t entirely accurate — embedding models are trained precisely to make &quot;close vectors ≈ close semantics&quot;; but &lt;strong&gt;this approximation frequently distorts&lt;/strong&gt;: homonyms, negation semantics, domain mismatch, content outside the training distribution all decouple vector distance from true semantic distance. A large part of RAG&apos;s pain points hides in this &quot;approximation distortion&quot;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chunking strategy&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;chunk size&lt;/strong&gt;: the strategy for how big to cut a chunk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;chunk overlap&lt;/strong&gt;: there should be &lt;strong&gt;overlap&lt;/strong&gt; between chunks, to avoid &quot;cutting on the dotted line&quot; and breaking the semantics. A common practice is 10-20% overlap (e.g. a 500-token chunk with 50-100 tokens of overlap).
&lt;ul&gt;
&lt;li&gt;The &quot;apple&quot; example I gave in the interview — the two characters of &quot;苹果&quot; getting split — is strictly not quite right; modern chunking is token-level or character-level and won&apos;t actually cleave the two characters of &quot;苹果&quot; apart. &lt;strong&gt;A more accurate example&lt;/strong&gt;: &quot;Apple released a new product. This product is powered by the M5 chip&quot; — if you cut between the two sentences, the latter chunk loses its subject, so you can&apos;t recall the semantics of &quot;Apple released the M5.&quot; That&apos;s the real problem overlap solves.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;late chunking&lt;/strong&gt;: vectorize &lt;strong&gt;the whole document first&lt;/strong&gt; (with a long-context embedding model), then chunk — that way each chunk&apos;s embedding &quot;knows&quot; the full-document context and preserves long-range semantic signal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;how to chunk PDFs / images&lt;/strong&gt;: this is a dedicated difficulty (some tools/solutions handle it).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;embedding model selection&lt;/strong&gt;: which embedding model to use is also a point you can go deep on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step two: storing (not much to say at the moment)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step three: recall (retrieval), where there&apos;s the most to optimize&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;query optimization&lt;/strong&gt;: before the user query comes in, you can do rewriting/expansion.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;recall count + rerank&lt;/strong&gt;: e.g. recall Top 50 — do you &lt;strong&gt;re-rank&lt;/strong&gt;? What&apos;s the re-rank based on? All optimizable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;recall quality evaluation (two dimensions)&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;recall rate (completeness)&lt;/strong&gt;: suppose there are 100 correct answers — did you recall all 100?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ranking quality&lt;/strong&gt;: how good is the ordering of what you recalled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Engineering level&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Model fallback strategy (&lt;a href=&quot;https://www.litellm.ai/&quot;&gt;LiteLLM&lt;/a&gt;)&lt;/strong&gt;: run LiteLLM in the project for &lt;strong&gt;model fallback&lt;/strong&gt; — if the first model provider goes down, automatically switch to the second.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 This whole section maps directly to that &quot;biggest pain point of RAG&quot; question in 2.2 that H couldn&apos;t answer — &lt;strong&gt;the pain points hide in the trade-offs at every step: close vectors ≠ close semantics, chunk boundaries breaking semantics, recall rate vs. ranking, dimensions vs. cost.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4.6 Treat the interview as &quot;making friends / exchanging ideas,&quot; don&apos;t get one-sidedly interrogated&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This field is very new, so &lt;strong&gt;an interview can be treated as a chance to make friends&lt;/strong&gt; — don&apos;t put too much pressure on yourself; go exchange ideas like you&apos;re chatting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Manage the interview&apos;s pacing&lt;/strong&gt; — don&apos;t let it become a one-sided interrogation. &lt;strong&gt;Grilling for the answer itself is pointless&lt;/strong&gt;; getting grilled for an hour and not even landing the offer is a pure loss.&lt;/li&gt;
&lt;li&gt;A reverse-question technique: when the interviewer asks you something (say &quot;what are your vibe coding techniques&quot;), after you answer in three sentences, &lt;strong&gt;turn around and ask the interviewer for their take&lt;/strong&gt;: &quot;I&apos;m not too familiar with this; I&apos;d love to hear your insights.&quot;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flatter them a little&lt;/strong&gt; — as long as the interviewer isn&apos;t out of their mind, they&apos;ll basically be happy to share.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.7 The &quot;gear&quot; techniques for the live vibe coding round&lt;/h3&gt;
&lt;p&gt;I shared practical techniques for doing screen-shared vibe coding problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Typical format&lt;/strong&gt;: share your screen and vibe code live.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The core mindset: no matter how simple the problem, pile on all the advanced gear.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Open your &lt;strong&gt;most expensive vibe coding software.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Definitely install skills&lt;/strong&gt; (never mind whether they&apos;re useful — installing them earns you big points with the interviewer).&lt;/li&gt;
&lt;li&gt;Or use &lt;strong&gt;MCP&lt;/strong&gt; — basically pile on all the fancy stuff.&lt;/li&gt;
&lt;li&gt;To install skills, don&apos;t install from GitHub; install from &lt;strong&gt;&lt;a href=&quot;https://www.skills.sh/&quot;&gt;skills.sh&lt;/a&gt;&lt;/strong&gt; (that website Vercel put out).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the waiting time&lt;/strong&gt;: vibe coding has wait time, during which you can &lt;strong&gt;open another model on the side&lt;/strong&gt; (Claude / ChatGPT — &lt;strong&gt;don&apos;t use Gemini, too bush-league&lt;/strong&gt;) and chat about technical choices or search for competitors&apos; solutions.&lt;/li&gt;
&lt;li&gt;My real case: I was asked to whip up a &quot;video-editing framework&quot; (a project my co-founder and I are building), and during the wait I chatted with the interviewer about other players in the space and searched the web for competitors.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.8 Résumé revision advice (the scattered tips at the end)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Put a tech stack on the résumé&lt;/strong&gt; (H left it out).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Put professional skills at the bottom and projects up top.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can write a bit more for professional skills.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get your projects live where possible&lt;/strong&gt;: build a website or get it deployed; if all else fails, &lt;strong&gt;put the repo link on there.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;(H&apos;s situation: Project Two isn&apos;t done yet; he plans to finish it before summer and then attach a link. It&apos;s a client tool, possibly with no frontend/backend.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You still have to memorize some backend fundamentals&lt;/strong&gt; — some interviewers (the &quot;moronic interviewers&quot; I griped about) will test them.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;One-line summary (my assessment as the interviewer)&lt;/h2&gt;
&lt;p&gt;| Dimension          | H&apos;s performance                                                                                                                                                       |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 🟢 Answered well   | the memory-system consolidation mechanism, the stable-front-loading idea for prefix caching, the dedup/merge trade-off for the memory cap, the async interaction design, judging skill-description verbosity, the AI-coding methodology |
| 🟡 Off / incomplete | tangled phrasing on consolidation, thin vector-store knowledge, vague MCP vs. Skills, incomplete token-saving, didn&apos;t fully answer multi-agent advantages, imprecise orchestration patterns |
| 🔴 Couldn&apos;t answer | why delete context directly, preserving the prefix cache in Plan mode, the Skills awareness mechanism (frontmatter), Agent Evaluation, the full RAG stack |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The three areas I&apos;d most recommend H fill in: RAG (the whole flow from vectorization to recall reranking), Agent Evaluation, and the engineering trade-offs between prefix caching and the tool list.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The core mindset I most want to share: be aggressive in the reverse-question round, soft-handle questions you can&apos;t answer with an &quot;AI angle + room for improvement,&quot; treat the interview as an exchange rather than an interrogation, and pile on all the advanced gear for vibe coding.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;A final word (a few feelings as the interviewer)&lt;/h2&gt;
&lt;p&gt;With every candidate I mock-interview, I understand one layer deeper —&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The core of an Agent engineer interview has never been &quot;how much you know,&quot; but &quot;whether you can clearly explain the things you&apos;ve done.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;H&apos;s project is actually well made — the consolidation mechanism shows thought, the prefix caching has real feel, the async interaction is a genuine highlight. &lt;strong&gt;But several times he clearly did the right thing yet couldn&apos;t explain &quot;why he did it that way&quot;&lt;/strong&gt; (e.g. that question about cutting context directly — he could absolutely have defended it with &quot;I have consolidation as a backstop,&quot; but didn&apos;t realize it).&lt;/p&gt;
&lt;p&gt;This is a problem most candidates share: &lt;strong&gt;they finish and stop, missing the &quot;reverse-SSH-into-your-own-brain&quot; debrief step.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&apos;re also prepping for an Agent-track interview, my advice:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ask &quot;why&quot; of every single design decision in every project&lt;/strong&gt; — only if you can say it clearly in one sentence do you actually understand it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For every sentence you write on your résumé, ask yourself &quot;if this gets dug into three layers deep, can I answer?&quot;&lt;/strong&gt; — if you can&apos;t, don&apos;t write it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG / Agent Evaluation / prefix caching — these three are the high-frequency deep-dive zones in 2026 Agent interviews&lt;/strong&gt; — don&apos;t wait to be asked before filling them in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Being aggressive in the reverse-question round isn&apos;t about one-upping the interviewer; it&apos;s about screening the company&lt;/strong&gt; — many people don&apos;t dare do this, but the effect is striking.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;About the paid service&lt;/h2&gt;
&lt;p&gt;Going forward I&apos;ll keep compiling these kinds of &lt;strong&gt;paid mock-interview debriefs.&lt;/strong&gt; Each one will try to preserve the real follow-up chain, the candidate&apos;s raw answers, my on-the-spot judgments, and the standard thinking I add afterward.&lt;/p&gt;
&lt;p&gt;A mock interview isn&apos;t just &quot;practicing answers&quot;; more than that, it &lt;strong&gt;lets you go through a complete experience of &quot;being seriously interrogated&quot; at the lowest possible risk.&lt;/strong&gt; Once you&apos;ve been through it once, your fear of the real interview drops by an order of magnitude.&lt;/p&gt;
&lt;p&gt;If you&apos;re also prepping for an Agent-track job search but don&apos;t know how to revise your résumé, how to pitch your projects, or how to prepare for the interview, I currently offer these three 1v1 services (please get in touch for specific pricing):&lt;/p&gt;
&lt;p&gt;| Service                        | Price tier | Who it&apos;s for                                                            |
| ------------------------------ | ---------- | ----------------------------------------------------------------------- |
| &lt;strong&gt;Résumé revision&lt;/strong&gt;            | ￥         | you have a résumé but don&apos;t know how to &quot;pitch&quot; it so the interviewer&apos;s eyes light up |
| &lt;strong&gt;1v1 mock interview&lt;/strong&gt;         | ￥￥       | interview coming up, need a complete live run-through + debrief         |
| &lt;strong&gt;Learning roadmap / onboarding companion&lt;/strong&gt; | ￥￥￥ | total beginner or lacking direction, need a 1-3 month weekly companion |&lt;/p&gt;
&lt;p&gt;Contact: WeChat &lt;div&gt;&lt;/div&gt; (note &quot;paid consult&quot; or &quot;mock interview&quot;).&lt;/p&gt;
&lt;p&gt;—— Joye · &lt;a href=&quot;https://www.joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Interviews Aren&apos;t Exams, They&apos;re Mutual Selection</title><link>https://www.joyehuang.me/en/blog/20260523---agentinterviewmindset/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260523---agentinterviewmindset/post</guid><description>After 100+ Agent interviews, how I redefined it: apply early, calibrate constantly, review recordings, ask hard questions, and meet founders as equals.</description><pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate><content:encoded>import WechatReveal from &apos;@/components/WechatReveal.astro&apos;
&lt;h2&gt;Before we start&lt;/h2&gt;
&lt;p&gt;This is my fourth blog post about getting into Agent work, job hunting, and interviewing. The first three were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/en/blog/20260309---agentinterview/post&quot;&gt;A Sophomore Intern&apos;s Field Guide to Agent Engineering Interviews&lt;/a&gt;&lt;/strong&gt; — a full retrospective of my own job search, leaning toward &quot;methodology&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/en/blog/20260512---agentmockinterview/post&quot;&gt;What We Actually Talked About in a 1-Hour-19-Minute Mock Agent Engineering Interview&lt;/a&gt;&lt;/strong&gt; — a complete walkthrough of a mock interview I did with interviewer W, leaning toward &quot;hands-on breakdown&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/en/blog/20260517---agentonboardingguide/post&quot;&gt;For Everyone Who Wants to Get Into Agents but Doesn&apos;t Know Where to Start&lt;/a&gt;&lt;/strong&gt; — an Agent engineer onboarding guide, leaning toward &quot;the lay of the land&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first three were about how to get started, how to prepare, how to answer questions, how to present your projects — they leaned toward &lt;strong&gt;roadmaps and hard skills&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But over these past few months of taking consulting calls, I noticed something: &lt;strong&gt;what actually trips most people up isn&apos;t skill, it&apos;s mindset.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Rewriting your resume eight times and never daring to send it. Finishing one interview and immediately moving on to the next without any review. Asking &quot;so what does your company actually do?&quot; in the closing questions. Walking into a founder interview positioning yourself as &quot;an intern candidate on trial&quot;... none of these are skill problems. They&apos;re a &lt;strong&gt;fundamental misunderstanding of what an interview even is.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So this post is specifically about mindset — more precisely, about &lt;strong&gt;how to redefine what an &quot;interview&quot; is&lt;/strong&gt;, and how your techniques should change under that new definition.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. An interview isn&apos;t an exam, it&apos;s mutual selection&lt;/h2&gt;
&lt;p&gt;I know this line has been repeated to death, but most people say &quot;mutual selection&quot; out loud while still putting themselves in the seat of the accused.&lt;/p&gt;
&lt;p&gt;When I take consulting calls, I keep seeing the same state of mind: rewriting the resume eight times and still not daring to send it; treating every interview as &quot;an exam I must pass&quot;; caring only about &quot;did I pass?&quot; afterward instead of &quot;what did I learn?&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This mindset is the root of every other problem.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Relax. Seriously.&lt;/p&gt;
&lt;p&gt;Especially in the Agent space — it&apos;s too new. So new there are no standard answers, so new that interviewers are still figuring it out themselves, so new that a lot of interviews end up being two peers swapping workflows. You&apos;re not there to &quot;pass&quot; an exam. You&apos;re there to talk with someone who might become your colleague, and to confirm whether you both want to build the same thing.&lt;/p&gt;
&lt;h3&gt;If you never send the resume, you&apos;ll never know what&apos;s wrong with it&lt;/h3&gt;
&lt;p&gt;A lot of people rewrite their resume eight times and still won&apos;t send it. The excuses are &quot;let me polish it a bit more,&quot; &quot;let me finish one more project first,&quot; &quot;applying now would waste the opportunity.&quot;&lt;/p&gt;
&lt;p&gt;But here&apos;s the reality: &lt;strong&gt;only an interviewer can tell you everything that&apos;s wrong with your resume.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Read your own resume eight times and you&apos;ll have fixed everything you&apos;re capable of catching. The remaining issues — the ones that &quot;look fine but are actually problems&quot; — you&apos;ll only discover &lt;strong&gt;when someone actually books an interview off that resume, asks you questions, drills into a detail until you get stuck, and ultimately rejects you.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My own first Agent-focused resume wasn&apos;t bottled up until perfect before I sent it either — I just shipped it out. What actually turned my resume from &quot;I think it&apos;s okay&quot; into &quot;it lands interviews and offers&quot; wasn&apos;t closed-door polishing before applying. It was &lt;strong&gt;the real feedback from the first three or four interviews&lt;/strong&gt; — which project interviewers drilled into most, which technical term they found least interesting, which detail suddenly made their eyes light up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So treat your first few interviews as practice.&lt;/strong&gt; Put the companies you love in the middle-to-late slots, and use 2–3 &quot;warm-up companies&quot; up front to expose the problems. This is the most efficient way to debug a resume, bar none.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Treat the interview as debugging — your resume is the code, the interviewer is the test case. Without running the test case, you&apos;ll never know where the bug is.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;What you&apos;re really afraid of: you overestimate the cost of &quot;failure&quot;&lt;/h3&gt;
&lt;p&gt;The deeper reason a lot of people won&apos;t interview is: &lt;strong&gt;they&apos;re afraid of rejection.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But think it through — in the Agent space, what&apos;s the real cost of getting rejected?&lt;/p&gt;
&lt;p&gt;Not money (interviews are free). Not time (one interview is an hour). Not opportunity (there are plenty of companies). &lt;strong&gt;The only real &quot;cost&quot; is a momentary bruise to your ego.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And what&apos;s the upside of getting rejected? &lt;strong&gt;Real, external feedback&lt;/strong&gt; — where you weren&apos;t clear enough, which project lacked depth, which technical point you hadn&apos;t prepared for, what signals the interviewer&apos;s reactions gave you.&lt;/p&gt;
&lt;p&gt;The cost is a few hours of frustration; the upside is a real calibration far more useful than &quot;carrying your resume around online asking people how to fix it.&quot; Because when you edit it back and forth online, what you&apos;re changing is ultimately just the content on the page. But in a real interview, the resume might only account for 50–70% of what&apos;s being assessed — the rest is how you present, how you handle follow-ups, how you explain your trade-offs on the spot. &lt;strong&gt;No matter how you do the math, this is a guaranteed win.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. Interviewing continuously is the moat in this field&lt;/h2&gt;
&lt;p&gt;This is the point I most want to emphasize, and the one I talk about most in consulting calls — yet it&apos;s also the most counter-consensus.&lt;/p&gt;
&lt;p&gt;By &quot;interviewing continuously&quot; I don&apos;t mean job-hopping. I mean regularly putting yourself in front of the external market to calibrate.&lt;/p&gt;
&lt;p&gt;Most people&apos;s attitude toward &quot;interviewing while employed&quot; is either &quot;looking around while still on the payroll feels dishonorable&quot; or &quot;I just started, I&apos;d feel awkward going to interviews.&quot; But let me offer a completely different angle:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interviewing is one of the few opportunities you have to forcibly calibrate yourself against the outside world.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&apos;m currently interning at a unicorn, but &lt;strong&gt;I&apos;ve kept interviewing throughout my time employed&lt;/strong&gt; — something I&apos;ve explicitly discussed with my current company, and which the company permits. I&apos;m not just interviewing to &quot;find the next job&quot;; more than that, I&apos;m doing it to &lt;strong&gt;confirm what the work I&apos;m doing right now is actually worth out there.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Inside a company, your level is &quot;encapsulated&quot;&lt;/h3&gt;
&lt;p&gt;When you write code inside a company day to day, your level is encapsulated by your desk, your project, and your colleagues&apos; perception of you.&lt;/p&gt;
&lt;p&gt;Stay on the same team long enough and it&apos;s easy to take the current project&apos;s evaluation system, tech choices, and workflow as the default frame of reference. It&apos;s not that they&apos;re bad — it&apos;s that your coordinate system narrows. It becomes hard to know how outsiders would judge the same project, the same technical trade-off, the same way of collaborating.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;These &quot;assumptions&quot; are very hard to fully verify from inside the company.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m not saying there&apos;s no growth environment inside a company. A good team will of course keep sharing AI developments, discussing new tools and workflows, and people will give you feedback. But internal discussion has an inherent problem: everyone is facing the same kind of business, the same tech debt, the same organizational context, so thinking easily ends up circling within the same framework.&lt;/p&gt;
&lt;p&gt;So you need outsiders. That&apos;s exactly where the value of interviewing lies — it forces you to re-explain your projects, your tech stack, and your way of articulating things in a different environment.&lt;/p&gt;
&lt;p&gt;After one interview, you immediately learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The project you&apos;re proud of — what will peers out there ask after hearing about it? Which point do they drill into most?&lt;/li&gt;
&lt;li&gt;The technical point you thought was rock-solid — has it already been replaced by a newer approach?&lt;/li&gt;
&lt;li&gt;The workflow you take for granted at your company — are peers outside using something completely different?&lt;/li&gt;
&lt;li&gt;What&apos;s the current salary range for this kind of role (if it comes up)?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More importantly, the interview itself is an output test: having built something doesn&apos;t mean you can explain it clearly; being able to drive a project on your team doesn&apos;t mean an outsider will understand your judgment the first time they hear it. An interview forces you to reorganize your projects, trade-offs, and thinking into language other people can follow.&lt;/p&gt;
&lt;h3&gt;The Agent space especially needs this calibration&lt;/h3&gt;
&lt;p&gt;There&apos;s no textbook for the Agent space. Every company&apos;s path is different.&lt;/p&gt;
&lt;p&gt;You might think at Company A that &quot;memory should obviously be done this way,&quot; then interview at Company B and find their thinking is completely different — and it&apos;s not necessarily a matter of who&apos;s right or wrong, &lt;strong&gt;just a different path.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You might use LangGraph smoothly at Company A, then interview at Company B and hear &quot;we&apos;ve already dropped all frameworks and built our entire Agent Loop in-house&quot;; you might use RAG to solve the knowledge-base problem at Company A, then interview at Company B and hear &quot;we&apos;ve moved entirely to LLM Wiki + Prefix Cache.&quot;&lt;/p&gt;
&lt;p&gt;So what really matters isn&apos;t &quot;you must keep interviewing forever&quot; — it&apos;s that you need to keep taking in new things and learning new things. Interviewing is one method. Reading frontier articles is one method. Talking with peers outside is one method.&lt;/p&gt;
&lt;p&gt;But for students and interns who haven&apos;t graduated yet, interviewing has an exceptional return on investment. It compresses external information, articulation practice, project feedback, and market judgment into a single hour, forcing you through one high-density calibration.&lt;/p&gt;
&lt;p&gt;A few of my own observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If someone only learns inside their company, it&apos;s easy to see only their current team&apos;s problems and solutions&lt;/li&gt;
&lt;li&gt;The Agent space changes too fast — a completely different engineering paradigm can emerge in just six months&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;When interviews end up discussing &quot;how you use AI,&quot; it&apos;s really peer exchange&lt;/h3&gt;
&lt;p&gt;The further into the interview process I go, the more I notice one thing: &lt;strong&gt;interviewers care less and less about &quot;assessing&quot; you, and more and more about &quot;aligning your understanding&quot; with theirs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In my most recent interviews, the closing stretch almost always covers questions like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;How do you use Claude day to day?&quot;&lt;/li&gt;
&lt;li&gt;&quot;How do you manage your Skills?&quot;&lt;/li&gt;
&lt;li&gt;&quot;When you write code, is the AI in the lead or are you? What&apos;s the rough split?&quot;&lt;/li&gt;
&lt;li&gt;&quot;What&apos;s the most inspiring Agent-related article you&apos;ve read recently?&quot;&lt;/li&gt;
&lt;li&gt;&quot;What do you think of XX company&apos;s product?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These questions aren&apos;t &quot;assessing&quot; you anymore — they&apos;re &lt;strong&gt;aligning worldviews&lt;/strong&gt; with you.&lt;/p&gt;
&lt;p&gt;The value of this kind of exchange isn&apos;t to replace internal company sharing sessions — good internal sharing is of course very useful — it&apos;s to give you a completely different external perspective. You learn how other teams use AI, how they organize Skills, how they understand product and engineering trade-offs; even if you don&apos;t walk away with one directly reusable workflow, the alignment of understanding itself is valuable.&lt;/p&gt;
&lt;h3&gt;A note on boundaries&lt;/h3&gt;
&lt;p&gt;I have to add one thing here: &lt;strong&gt;the premise of all this is that your company permits it, or that you exercise good judgment about the boundaries yourself.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&apos;t interview on your company laptop/network&lt;/li&gt;
&lt;li&gt;Don&apos;t interview during work hours (take leave, or do it after work)&lt;/li&gt;
&lt;li&gt;Don&apos;t interview with direct competitors (this is a bottom-line ethics issue)&lt;/li&gt;
&lt;li&gt;Don&apos;t leak your current company&apos;s sensitive information during interviews&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is basic professional ethics. &lt;strong&gt;&quot;Continuous calibration&quot; is not the same as &quot;disloyalty&quot;&lt;/strong&gt; — as long as you keep those boundaries in place, your current employer generally won&apos;t have a problem with it. My own employer explicitly knows I do this and is supportive of it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. Record and review: let AI be your personal interview coach&lt;/h2&gt;
&lt;p&gt;Record your interviews (for personal use only — never share them). Almost everyone will tell you this, but &lt;strong&gt;how you use the recording&lt;/strong&gt; is what matters.&lt;/p&gt;
&lt;p&gt;Many people listen to the recording trying to remember from memory &quot;where did I just stumble?&quot; — which is very inefficient and genuinely painful (hearing your own voice is one of the most awkward things in the world).&lt;/p&gt;
&lt;p&gt;The more efficient approach is: &lt;strong&gt;use AI to turn the recording into a reviewable interview log.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;How to actually do it&lt;/h3&gt;
&lt;p&gt;Today&apos;s mainstream tools — ChatGPT, Claude, Gemini — all support audio input. You don&apos;t need to transcribe first; &lt;strong&gt;just drop the entire interview recording in.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The most basic use is having it produce a list of interview questions — in chronological order, each question paired with the key points of your answer. But the genuinely valuable uses are these:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Have the AI infer where you stumbled.&lt;/strong&gt; You don&apos;t have to tell it where you got stuck — it can judge, from the pauses, filler words, and signals like &quot;um,&quot; &quot;uh,&quot; &quot;how do I put it&quot; in the audio, exactly which questions you struggled with. Far more accurate than your own recollection.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Have the AI play that company&apos;s interviewer and grade you.&lt;/strong&gt; Give it the interview recording + company background (the role you applied for, a rough picture of the company), and have it grade each of your answers from the angle of &quot;if I were this company&apos;s interviewer,&quot; pointing out where your logic jumped, where you missed the point, where you actually over-egged it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Have the AI ask you again.&lt;/strong&gt; Have it re-ask the extracted questions in a different phrasing — it&apos;s basically a free practice partner. You can say your answers out loud in your own room, then have it critique them — a complete iteration loop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Find systemic problems across interviews.&lt;/strong&gt; This is the most valuable approach — after three to five interviews, drop all the recordings in together and have it find the &quot;recurring weak points.&quot;&lt;/p&gt;
&lt;p&gt;A single-interview review only shows you &quot;where I answered poorly in this one&quot;; a cross-interview review shows you &quot;every time I&apos;m asked about Memory design, I can&apos;t explain it clearly&quot; — that&apos;s a &lt;strong&gt;systemic problem&lt;/strong&gt;, ten times more important than a one-off slip.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Have the AI teach you the questions you couldn&apos;t answer.&lt;/strong&gt; When you hit a question you can&apos;t answer in the interview, write it down first. Afterward, have the AI give you a reference answer — it&apos;s free, tailored to your specific interview context, and the most relevant study material there is. Far more useful than opening Google and searching &quot;common Agent interview questions.&quot;&lt;/p&gt;
&lt;h3&gt;Two things to focus on when reviewing&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Whether your answers are precise.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Take a recent example from a student I did a mock interview with — the interviewer asked him &quot;what are Claude&apos;s Skills,&quot; and his initial answer went like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Um, Skills are a product form Anthropic introduced, it&apos;s in the shape of a folder that contains a SKILL.md and some tool scripts, and Claude can load these Skills when needed to augment its capabilities, like generating PPTs, Excel, that kind of thing...&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Only during the review did we realize: &lt;strong&gt;that took 60 seconds to say, but the core information was really just three keywords — progressive disclosure, SOP standardization, easy to share.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Trimmed down, it should be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Skills are Anthropic&apos;s product form for packaging an Agent&apos;s capabilities into loadable modules. They solve three problems — &lt;strong&gt;progressive disclosure&lt;/strong&gt; (capabilities aren&apos;t all loaded into context up front, only when needed), &lt;strong&gt;SOP standardization&lt;/strong&gt; (writing out &apos;when to use which tool, and how&apos; clearly in natural language), and &lt;strong&gt;easy to share&lt;/strong&gt; (a single folder is a complete capability package that can be distributed, reused, and versioned).&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Same two minutes, but the second version is three times as information-dense as the first — that&apos;s the difference &lt;strong&gt;precision&lt;/strong&gt; makes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The interviewer&apos;s reactions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What you can hear in the recording isn&apos;t only your own answers — it&apos;s also the interviewer&apos;s reactions. Those reactions often tell you more about what needs fixing than your own answers do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Where did they follow up? A follow-up means the point either hit their interest or you didn&apos;t explain it clearly — both cases are worth revisiting&lt;/li&gt;
&lt;li&gt;Where did they go &quot;mm-hm&quot; and move on? That usually means they didn&apos;t follow, or weren&apos;t interested — phrase it differently next time&lt;/li&gt;
&lt;li&gt;Where did they start talking themselves? That&apos;s a golden signal — you hit a topic they wanted to discuss, and you can reuse it at similar companies next time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My own experience: &lt;strong&gt;the interviewer&apos;s reactions carry 2–3x more information than your own answers.&lt;/strong&gt; Learning to &quot;listen to the interviewer&quot; is the biggest dividend of reviewing recordings.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. Closing questions: the information gap is your leverage&lt;/h2&gt;
&lt;p&gt;The closing-questions segment is absolutely not a &quot;throw in a question for the sake of it&quot; segment — it&apos;s the &lt;strong&gt;highest-information-density part of the entire interview&lt;/strong&gt;, and the part where you show how seriously invested you are in this interview and this role.&lt;/p&gt;
&lt;p&gt;Why? Because &lt;strong&gt;during the forward Q&amp;#x26;A, the interviewer is evaluating you; during the closing questions, you&apos;re evaluating the company.&lt;/strong&gt; The pace of the former is controlled by the other side, so it&apos;s hard to proactively learn the company&apos;s true state; what you can mine in the latter is &lt;strong&gt;information that&apos;s never made public but that insiders face every single day.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;The essence of closing questions is information-gap arbitrage&lt;/h3&gt;
&lt;p&gt;The JD and the website are the company&apos;s external messaging — repeatedly polished by legal, HR, and marketing, the information in them is a &lt;strong&gt;packaged version&lt;/strong&gt;. But the information that comes out of the interviewer&apos;s mouth is what the company &lt;strong&gt;actually looks like.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So your closing questions should target the things that &quot;won&apos;t be written publicly, but that an insider can explain clearly the moment they open their mouth.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask for the real details of the business.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For example, I personally lean toward 2C and overseas business, so I&apos;ll directly ask whether they&apos;re 2B or 2C, domestic or overseas, what the main profile of their paying users is, whether they&apos;re comfortable sharing ARR/MRR at an order-of-magnitude level (you won&apos;t necessarily get a specific number, but you can read the rough tier from their reaction).&lt;/p&gt;
&lt;p&gt;The JD won&apos;t necessarily spell these out, but they&apos;re crucial for judging &quot;should I go?&quot; — &lt;strong&gt;a team doing overseas 2C and a team doing domestic 2B differ in everything: culture, pace, tech choices, promotion paths.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On &quot;will asking such detailed questions come across as abrupt?&quot; — it absolutely won&apos;t.&lt;/strong&gt; Someone who genuinely wants to join should be asking these things in the first place. The more specific your questions, the more the interviewer will think &quot;this person is actually evaluating our company, not mass-applying.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask for the team&apos;s real state.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;After this role joins, what&apos;s the most important problem to solve in the first three months?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Is this a newly created role or a backfill? If it&apos;s a backfill, what capability does the team hope the new person fills?&quot;&lt;/li&gt;
&lt;li&gt;&quot;What type of person does the team most lack right now?&quot;&lt;/li&gt;
&lt;li&gt;&quot;If I join the team, which business line or module am I most likely to be involved in early on?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These questions look ordinary on the surface, but the answers hide a lot of information. Take &quot;what problem needs solving in the first three months&quot; — it directly tells you whether the team has a real, clearly defined gap or is just vaguely &quot;wanting to hire someone.&quot; Same with the backfill reason: if they can candidly explain what the team lacks and what problems the previous person left behind, that itself is a real signal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask for performance feedback.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Big companies usually have compliance requirements that make it inconvenient to evaluate candidates directly, but interviewers at small companies and startups are often very willing to talk.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Direct version:&lt;/strong&gt; &quot;How do you think I did in this interview? What did I present well, and what not so well?&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tactful version:&lt;/strong&gt; &quot;If I wanted to join the team and excel at this job, where do you think I still need to improve?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The tactful version is more universal — it turns &quot;evaluate me&quot; into &quot;how should I improve,&quot; which is easier for the other side to answer, and the answer often &lt;strong&gt;carries more information than a direct score.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My own success rate with this trick is very high — about 80% of interviewers give at least 2–3 concrete pieces of feedback. Once you have that feedback, it&apos;s a &lt;strong&gt;precise upgrade manual&lt;/strong&gt; for your next interview.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. When interviewing at startups, ask these extra questions&lt;/h2&gt;
&lt;p&gt;A startup isn&apos;t a &quot;shrunk-down big company&quot; — the things that matter are completely different.&lt;/p&gt;
&lt;p&gt;Many people still apply the big-company closing-question template when interviewing at startups — asking about the tech stack, overtime, benefits — all of which are secondary for a startup. &lt;strong&gt;The factors that truly decide whether you should join a startup are different ones entirely.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;The team&lt;/h3&gt;
&lt;p&gt;Because headcount is small, you absolutely must get clear on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Who&apos;s your mentor?&lt;/strong&gt; This person is &lt;strong&gt;the single biggest variable affecting your growth&lt;/strong&gt; at a startup. Whether the actual mentor on a 0-to-1 project is the founder themselves or some engineer with one year of experience are two entirely different experiences&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exactly how many people are on the team?&lt;/strong&gt; &quot;The engineering team has 20 people&quot; and &quot;the AI team has 3 people and you&apos;d be the 4th&quot; are completely different signals&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Who do you report to?&lt;/strong&gt; Reporting directly to the CEO and reporting to some middle leader are two completely different work rhythms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The difference between one person and five is enormous.&lt;/strong&gt; On a team of five you might own a sub-module; on a team of one you are the entire AI of the company — the former lets you specialize, the latter lets you sweep across the whole line. Both paths have value, but you need to &lt;strong&gt;know which one you&apos;re choosing.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Pay attention to the GTM team, not just the engineering team&lt;/h3&gt;
&lt;p&gt;This is something a lot of people overlook: &lt;strong&gt;at big and mid-sized companies you can ask about the engineering team&apos;s makeup, but at a startup, the GTM (Go-to-Market) team is just as worth paying attention to.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Why? Because for a startup product, &lt;strong&gt;&quot;how to sell it / get it out there&quot; is often harder than &quot;how to build it.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Teams that can technically build an Agent product are everywhere in 2026; but the teams that can get that Agent product in front of users, build word of mouth, and drive retention or customer conversion — &lt;strong&gt;those are the ones that actually survive.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For a ToC product, you can ask:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;How many people are on your growth team? What are their backgrounds?&quot;&lt;/li&gt;
&lt;li&gt;&quot;What channels is customer acquisition mainly relying on right now? SEO? KOLs? Community? Paid acquisition?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Roughly what&apos;s the ratio of overseas to domestic users?&quot;&lt;/li&gt;
&lt;li&gt;&quot;If you&apos;re comfortable sharing, roughly what level are your customer acquisition cost (CAC) and retention numbers for the most recent quarter?&quot; (Very few people dare to ask this, but if you do and they&apos;re willing to answer, the information density is extremely high)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a ToB product, you&apos;d switch to a different set of questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Do you have customers already using it? Is it a pilot, a POC, or paying for real?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Who are the target customers? Who&apos;s the buyer, the user, and the decision-maker, respectively?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Is sales mainly the founder doing BD personally right now, or is there already a sales / customer-success team?&quot;&lt;/li&gt;
&lt;li&gt;&quot;From a customer&apos;s first contact to actually going live, roughly how long does it take? Where are the bottlenecks usually?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a startup&apos;s engineering team is 30 people but GTM is just 1 full-timer + 1 contractor — that&apos;s not an instant death sentence, but you absolutely must keep probing: what exactly are they relying on to push the product into the market?&lt;/p&gt;
&lt;h3&gt;Product status&lt;/h3&gt;
&lt;p&gt;Is the product already launched, or still in development? If the latter, &lt;strong&gt;be sure to confirm the specific launch plan, down to the month or quarter.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;ve seen far too many startups say &quot;we&apos;re almost there&quot; — and then &quot;almost there&quot; drags on for two years without launching.&lt;/p&gt;
&lt;p&gt;The right way to ask:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Is the product currently live, in closed beta, or still in development?&quot;&lt;/li&gt;
&lt;li&gt;&quot;If it hasn&apos;t launched yet, what&apos;s the expected launch date? To the quarter?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Who&apos;s the first batch of target users after launch? How will you acquire them?&quot;&lt;/li&gt;
&lt;li&gt;&quot;If two months after launch you haven&apos;t hit expectations, what&apos;s the team&apos;s Plan B?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last question is especially important — &lt;strong&gt;a founder who has thought about Plan B and a founder who hasn&apos;t are two completely different tiers of leader.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;6. The killer move for interviewing founders&lt;/h2&gt;
&lt;p&gt;If you&apos;re interviewing the founder, and you understand the space, you can ask directly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In this space, how do you plan to beat your competitors?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If a startup founder doesn&apos;t have a clear understanding of their own product and their competitors, that&apos;s a very strong risk signal.&lt;/p&gt;
&lt;h3&gt;The prerequisite for using this move: you genuinely have to have studied the space&lt;/h3&gt;
&lt;p&gt;Otherwise, when the founder turns it around and asks &quot;well, what do you think we should do,&quot; it gets awkward if you can&apos;t field it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So this is essentially a small-scale battle, not a one-way question.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The right posture is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Spend 30 minutes doing homework before the interview — who are the company&apos;s two or three main competitors, what are their respective strengths and weaknesses, how do others in the market view this company&lt;/li&gt;
&lt;li&gt;Throw out &quot;how do you plan to beat your competitors&quot; during the closing questions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Have your own answer ready&lt;/strong&gt; — even if they turn it around and ask &quot;what do you think,&quot; you can lay out 2–3 logically sound points&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This posture instantly upgrades the founder&apos;s read on you from &quot;intern candidate&quot; to &quot;potential early member.&quot;&lt;/p&gt;
&lt;h3&gt;How I talk with founders&lt;/h3&gt;
&lt;p&gt;In my own second-round interviews with CEOs or founders, &lt;strong&gt;I basically don&apos;t talk about tech.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Instead I talk about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The prospects of the product&apos;s space&lt;/strong&gt; — where&apos;s the ceiling for this space over the next 2–3 years? What stage is it at now?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Competitors&apos; strengths and weaknesses&lt;/strong&gt; — why is A better than B? What&apos;s B&apos;s moat?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The technical direction and goals for the next quarter&lt;/strong&gt; — what&apos;s the team&apos;s priority right now? Why this one?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Growth strategy&lt;/strong&gt; — is the product&apos;s biggest bottleneck right now technical, growth, or funding? How will you solve it?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I especially love talking growth with founders, because I do growth-related work myself (inside my company I&apos;ve been involved in user growth, content strategy, building out Tracking &amp;#x26; Analytics, and so on), so I have a real feel for it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Talking growth with a founder is essentially demonstrating your &quot;founder mindset.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What a startup founder lacks most isn&apos;t people who can write code — &lt;strong&gt;people who can write code are everywhere, especially in the AI era.&lt;/strong&gt; What they truly lack is &lt;strong&gt;someone who can think alongside them about &quot;once it&apos;s built, how do we sell it.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If an undergrad can talk growth with a founder for half an hour, market for half an hour, competitor strategy for half an hour — the founder&apos;s read on you shifts from &quot;intern candidate&quot; to &quot;potential early member.&quot; &lt;strong&gt;Conversion to full-time, getting handed core projects, even early-hire treatment — it all starts from that judgment.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The smoothest interviews I&apos;ve had myself — &lt;strong&gt;all of them, without realizing it, ran past 1.5 hours, the whole conversation more like two partners discussing how to grow the company than an interview.&lt;/strong&gt; The offers I got in that state were all very high quality.&lt;/p&gt;
&lt;h3&gt;The &quot;reverse evaluation&quot; at overseas startups&lt;/h3&gt;
&lt;p&gt;Also, a lot of overseas startup CEOs will chat with you about plenty of personal topics — behavioral questions, what you&apos;re proudest of, your personal interests, and so on.&lt;/p&gt;
&lt;p&gt;Don&apos;t deal with these questions like they&apos;re an exam. &lt;strong&gt;All of them are worth going deep on.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Why? Because for early-stage startups overseas (especially Silicon Valley ones), what matters most is &lt;strong&gt;&quot;Founding Team Fit&quot;&lt;/strong&gt; — whether your vibe meshes with the founding team, whether your values align, whether your long-term vision is consistent.&lt;/p&gt;
&lt;p&gt;They&apos;re not worried about tech — everyone started from zero; but &lt;strong&gt;&quot;are you the person who&apos;ll still be on Slack discussing an idea with me at 0:11 in the morning&quot; — that can only be judged through behavioral questions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So when you hit a behavioral question, don&apos;t phone it in. &lt;strong&gt;Tell a real story, share how you genuinely felt, talk about what you truly care about&lt;/strong&gt; — this matters more than any technical question.&lt;/p&gt;
&lt;h3&gt;The flip side: if the founder won&apos;t talk about these things with you&lt;/h3&gt;
&lt;p&gt;If you&apos;re interviewing the founder, but the whole interview he &lt;strong&gt;only wants to quiz you on technical questions and won&apos;t talk product, space, or vision with you&lt;/strong&gt; — this company may not be worth going all in on.&lt;/p&gt;
&lt;p&gt;Because at the very least it shows that, in this conversation, he&apos;s more inclined to treat you as &quot;current labor&quot; than as &quot;a future person.&quot;&lt;/p&gt;
&lt;p&gt;A founder who genuinely wants to grow big, &lt;strong&gt;when interviewing a potential early member, will proactively talk vision, roadmap, and ideas&lt;/strong&gt; — because he knows this is the most effective weapon for attracting talent.&lt;/p&gt;
&lt;p&gt;If a founder doesn&apos;t even have the interest to talk vision during an interview, then this company&apos;s ceiling is probably right there. Of course, don&apos;t draw conclusions from a single question; look at whether, across the whole conversation, he proactively revealed his own judgment, roadmap, and ambition.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;7. Some peculiarities of Agent roles&lt;/h2&gt;
&lt;p&gt;Finally, let&apos;s talk about the role itself. The Agent space has a few traits that shape how interviews play out:&lt;/p&gt;
&lt;h3&gt;No standard answers&lt;/h3&gt;
&lt;p&gt;So the interview is more like a two-way exchange. You can absolutely turn it around and discuss a design choice with the interviewer — &quot;I used to use ReAct, but I found that once the number of tools exceeds 10, selection accuracy drops, so we later switched to Skill routing + subagents. How does your team handle this problem?&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expressing &quot;I have my own judgment&quot; matters ten times more than &quot;I memorized this knowledge point.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Agent space is too new — interviewers are still figuring it out themselves. If you can voice an opinion with judgment behind it (even one that differs from theirs), they&apos;ll immediately reclassify you from &quot;applicant&quot; to &quot;peer.&quot;&lt;/p&gt;
&lt;h3&gt;Interviewer quality varies wildly&lt;/h3&gt;
&lt;p&gt;Some interviewers haven&apos;t done Agent work themselves, so their questions may be very surface-level (&quot;are you familiar with ReAct?&quot; &quot;have you used LangChain?&quot;); others are very deep and will directly ask you &quot;how do you handle context explosion,&quot; &quot;how do you do Eval,&quot; &quot;how do Subagents share Memory.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mindset-wise: don&apos;t get cocky with the former, don&apos;t panic with the latter.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you hit a surface-level question, don&apos;t phone it in just because &quot;the question is too easy&quot; — this is your chance to show &lt;div&gt;how clearly you can explain a fundamental concept&lt;/div&gt;. Being able to explain ReAct clearly in three sentences impresses an interviewer more than being able to rattle off 10 framework names.&lt;/p&gt;
&lt;p&gt;When you hit a deep question, don&apos;t panic just because &quot;you can&apos;t answer it&quot; — &lt;strong&gt;nobody understands everything.&lt;/strong&gt; Being able to say &quot;I haven&apos;t done this in depth, but my understanding is XXX, and our team handles it with YYY — what do you think?&quot; — that kind of answer beats faking it 100 times over.&lt;/p&gt;
&lt;h3&gt;Your project experience will be drilled on, detail by detail&lt;/h3&gt;
&lt;p&gt;The biggest trait of Agent projects is that &lt;div&gt;they look impressive but are easily just a wrapper&lt;/div&gt; — an &quot;AI health assistant&quot; vibe-coded with Cursor + Claude Code and an Agent project where real engineering trade-offs were made &lt;strong&gt;look identical on the surface, but the interviewer can tell them apart the instant they start drilling.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So interviewers use detail questions to distinguish them. &lt;strong&gt;Prepare three questions for each of your projects in advance:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Why did you design it this way?&lt;/strong&gt; (Why) — why RAG and not LLM Wiki? Why LangGraph and not Vercel AI SDK? Why Claude and not GPT?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What pitfalls did you hit?&lt;/strong&gt; (How it failed) — what problems did you run into? How did you spot them? How did you ultimately solve them? This question is hugely important — it can even distinguish at a glance whether this was a bootcamp project, a reworked open-source project, or something you genuinely built yourself. A project you really built will always have pitfalls, and those pitfalls are the most valuable experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you redid it, what would you change?&lt;/strong&gt; (What you learned) — looking back now, which decision did you get wrong? Why was it wrong?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you can explain all three questions for &lt;strong&gt;every project for 5 minutes or more&lt;/strong&gt;, you&apos;re already ahead of 80% of applicants.&lt;/p&gt;
&lt;h3&gt;When you hit a question you can&apos;t answer, just admit it&lt;/h3&gt;
&lt;p&gt;The Agent field updates too fast — nobody understands everything.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The best answer isn&apos;t to wing it, but:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I haven&apos;t done this in depth, but my understanding is XXX — how does your team handle it?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This move is especially effective in startup interviews — because the other side may be looking for the answer too, and by riding that you turn the interview into a discussion, which actually scores points.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The cost of being caught faking it far outweighs admitting you don&apos;t know.&lt;/strong&gt; I&apos;ve seen far too many cases of people getting drilled into a meltdown because they faked it — at first they can bluff their way through, but every layer the interviewer probes, you spring another leak, until the whole project&apos;s credibility is gone.&lt;/p&gt;
&lt;h3&gt;The full-stack requirement of the AI era&lt;/h3&gt;
&lt;p&gt;Why are so many Agent roles effectively full-stack by default? Because from Prompt design, Tool calling, and Memory architecture to frontend presentation, user experience, and the feedback loop — &lt;strong&gt;every layer is part of the product experience, mutually coupled, and very hard to cleanly separate.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An engineer who can only call APIs but doesn&apos;t understand the frontend can&apos;t build a good Agent; an engineer who can only write UI but doesn&apos;t understand model behavior can&apos;t build a good Agent either. &lt;strong&gt;Every experience problem in an Agent is coupled up and down the stack — one interaction detail on the frontend might send you back to change a Prompt, one model hallucination might require a fallback UI on the frontend.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So what the interviewer is looking for isn&apos;t &quot;an expert in some single domain,&quot; but &lt;strong&gt;&quot;someone with a feel for the entire Agent system.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That feel can&apos;t be ground out by grinding practice problems — it can only come out in conversation from having genuinely built projects.&lt;/strong&gt; That&apos;s also why interviews in the AI era look more and more like a chat — what the other side is gauging isn&apos;t your stock of knowledge, it&apos;s your &lt;strong&gt;systemic intuition.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;A final word&lt;/h2&gt;
&lt;p&gt;If you&apos;ve read this far — thank you for taking the time. If this post helped you, feel free to like it at the bottom of the article, or leave a comment with the specific problems, closing-question strategies, and mindset blockers you&apos;ve run into in Agent interviews; I&apos;ll pick the representative ones and keep writing.&lt;/p&gt;
&lt;p&gt;Back to this post&apos;s core thesis:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An Agent development interview is fundamentally not &quot;assessing / being assessed,&quot; but &quot;two people who want to build the same thing confirming with each other whether they&apos;re a fit.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This mindset shift looks tiny, but it changes &lt;strong&gt;every concrete behavior of yours:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shift the mindset and you&apos;ll dare to send the resume — because this isn&apos;t an &quot;exam,&quot; it&apos;s &quot;finding a fit&quot;&lt;/li&gt;
&lt;li&gt;Shift the mindset and you&apos;ll dare to interview continuously — because this isn&apos;t &quot;looking around on the payroll,&quot; it&apos;s &quot;continuous calibration&quot;&lt;/li&gt;
&lt;li&gt;Shift the mindset and you&apos;ll seriously record and review — because this isn&apos;t &quot;torturing yourself,&quot; it&apos;s &quot;deliberate practice&quot;&lt;/li&gt;
&lt;li&gt;Shift the mindset and you&apos;ll boldly ask hard questions — because this isn&apos;t &quot;throwing in a question,&quot; it&apos;s &quot;information-gap arbitrage&quot;&lt;/li&gt;
&lt;li&gt;Shift the mindset and you&apos;ll dare to battle with the founder — because this isn&apos;t &quot;being put on trial,&quot; it&apos;s &quot;two-way fit verification&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the interview as a peer exchange, and you&apos;ll find the whole experience is different.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;One last thing — if you&apos;re already preparing for Agent interviews but stuck on mindset-level problems like &quot;not daring to send the resume,&quot; &quot;not daring to interview,&quot; &quot;not knowing how to review afterward,&quot; I do 1-on-1 mock interviews myself. The biggest value of a mock interview isn&apos;t &quot;practicing answers&quot; — it&apos;s &lt;strong&gt;letting you go through the complete experience of &quot;being seriously drilled&quot; at the lowest possible risk.&lt;/strong&gt; Once you&apos;ve been through it once, your fear of real interviews drops by an order of magnitude.&lt;/p&gt;
&lt;p&gt;If you need it, add me on WeChat &lt;div&gt;&lt;/div&gt;, with a note saying &quot;paid consulting.&quot;&lt;/p&gt;
&lt;p&gt;—— &lt;strong&gt;Joye&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title>For Everyone Who Wants Into Agents But Doesn&apos;t Know Where</title><link>https://www.joyehuang.me/en/blog/20260517---agentonboardingguide/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260517---agentonboardingguide/post</guid><description>Joye&apos;s Agent Engineer Onboarding Guide v1.0: what an Agent is, why now, how to start, and how to land a job — for anyone who wants in but doesn&apos;t know where.</description><pubDate>Sun, 17 May 2026 00:00:00 GMT</pubDate><content:encoded>import WechatReveal from &apos;@/components/WechatReveal.astro&apos;
&lt;p&gt;&lt;em&gt;Joye&apos;s Agent Engineer Onboarding Guide · v1.0 · Free edition for followers&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Updated: 2026-05-17&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Opening | Before You Read On&lt;/h2&gt;
&lt;h3&gt;Who this document is for&lt;/h3&gt;
&lt;p&gt;If your situation lately looks like this — people around you are talking about Agents, about MCP, about Vibe Coding, you see a swarm of unfamiliar terms floating by, you have a vague sense that this is a direction worth getting into, but every time you try to start you get scared off, either because you don&apos;t know which term to look up first, or because you open a &quot;30-day crash course&quot; tutorial and close it by page three — then this document is written for you.&lt;/p&gt;
&lt;p&gt;I roughly divide readers into two groups, and this material is useful for both:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;People with zero programming or zero LLM background&lt;/strong&gt;: what you need is a &quot;map&quot; — something that shows you what the whole field looks like and where to start walking.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;People with some programming background but who haven&apos;t really touched LLM applications yet&lt;/strong&gt;: what you need is a &quot;translation table&quot; — something that builds the bridge between what you already know and this new direction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After reading this document, you should be able to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explain in three sentences what an Agent is and how it differs from an ordinary LLM application;&lt;/li&gt;
&lt;li&gt;Know what to learn, and in what order, over the next 1–2 months;&lt;/li&gt;
&lt;li&gt;Stop feeling lost when you hear the jargon;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stop being anxious&lt;/strong&gt; — knowing that this path has a direction, that it can be walked, and that it&apos;s not too late to start now.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Estimated reading time&lt;/strong&gt;: about 11,000 Chinese characters in the original. At a rate of 350 characters per minute for technical Chinese content, &lt;strong&gt;reading it straight through takes about 30 minutes&lt;/strong&gt;; if you read while looking things up and pause to think, &lt;strong&gt;it&apos;s more like 1–1.5 hours&lt;/strong&gt; in practice.&lt;/p&gt;
&lt;h3&gt;What this document is not&lt;/h3&gt;
&lt;p&gt;So your expectations land in the right place, let me also be clear about what this material is &lt;strong&gt;not&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Not a code tutorial&lt;/strong&gt; — there won&apos;t be large blocks of Python / TypeScript code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not a framework manual&lt;/strong&gt; — it won&apos;t walk you through the LangChain / Vercel AI SDK APIs one by one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not a paper survey&lt;/strong&gt; — it won&apos;t push Transformer formulas at you or walk you through papers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If those three things are what you came for, this material isn&apos;t for you — I&apos;d suggest going straight to the official docs of a top-tier company. If what you need is &quot;first help me figure out what kind of field I&apos;m even facing&quot; — you&apos;ve come to the right place.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;About the author&lt;/h3&gt;
&lt;p&gt;My name is Joye. I&apos;m an undergraduate in Computing and Software Engineering at the University of Melbourne, currently in my second year.&lt;/p&gt;
&lt;p&gt;I&apos;m currently doing a &lt;strong&gt;full-stack Agent development internship at a unicorn company in Shanghai&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Over the past few months I&apos;ve intensively interviewed for Agent-related roles at &lt;strong&gt;100+ AI companies&lt;/strong&gt; and received &lt;strong&gt;30+ offers&lt;/strong&gt;. I wrote these experiences up into two blog posts that are also the &quot;prequels&quot; to this document:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.joyehuang.me/en/blog/20260309---agentinterview/post&quot;&gt;&quot;A Second-Year Intern&apos;s Agent Development Interview Playbook&quot;&lt;/a&gt;&lt;/strong&gt; (March 2026, 440 reads) — a complete retrospective of my own job hunt. This post is where I started taking on consulting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.joyehuang.me/en/blog/20260512---agentmockinterview/post&quot;&gt;&quot;A 1-Hour-19-Minute Agent Engineer Mock Interview: What Did We Actually Talk About&quot;&lt;/a&gt;&lt;/strong&gt; (May 2026, 199 reads) — a full retrospective of an 80-minute paid mock interview I did together with another interviewer, W. After this one went out I got a ton of reader feedback: some people reorganized and deep-dived their projects using the methods in it and then landed offers at big companies, and others used this post to genuinely understand for the first time how to prepare for Agent development.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Open-source projects (GitHub &lt;a href=&quot;https://github.com/joyehuang&quot;&gt;@joyehuang&lt;/a&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt;&lt;/strong&gt; (109+ Stars): a detailed annotated tutorial for building an LLM from scratch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/joyehuang/Learn-Open-Harness&quot;&gt;Learn-Open-Harness&lt;/a&gt;&lt;/strong&gt;: a beginner-friendly interactive OpenHarness tutorial that walks you through the implementation of a real Agent Harness.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/joyehuang/skills&quot;&gt;skills&lt;/a&gt;&lt;/strong&gt;: my personal collection of Skills built on the Anthropic Skills paradigm.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m not the most senior person in the industry, but I&apos;ve &lt;strong&gt;just finished walking the exact path you&apos;re about to walk&lt;/strong&gt; — and that &quot;just walked it&quot; perspective is sometimes a better fit for a guide than the &quot;walked it long ago&quot; perspective.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;About the paid services&lt;/h3&gt;
&lt;p&gt;This document is free. But everyone&apos;s situation is different — how your résumé should be rewritten, how your projects should be pitched, how your learning pace should be set, all of these need a specific 1-on-1 discussion. If you need that kind of in-depth help, I offer the following three services (please contact me for specific pricing):&lt;/p&gt;
&lt;p&gt;| Service | Price tier | Who it&apos;s for |
|------|---------|--------|
| &lt;strong&gt;Résumé revision&lt;/strong&gt; | ￥ | You have a résumé but don&apos;t know how to &quot;tell the story&quot; so the interviewer&apos;s eyes light up |
| &lt;strong&gt;1-on-1 mock interview&lt;/strong&gt; | ￥￥ | You&apos;re about to interview and need a full live run-through + debrief |
| &lt;strong&gt;Learning roadmap / onboarding coaching&lt;/strong&gt; | ￥￥￥ | You&apos;re a complete beginner or lack a sense of direction and need weekly coaching over 1–3 months |&lt;/p&gt;
&lt;p&gt;A detailed description of each service is at the end of the document. Contact: WeChat &lt;div&gt;&lt;/div&gt; (with the note &quot;paid consulting&quot;).&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;How to use this document&lt;/h3&gt;
&lt;p&gt;I suggest you &lt;strong&gt;read it through in order the first time&lt;/strong&gt; to build an overall sense of the shape of things. After that, go back to the chapter that resonated most and read it closely a second time.&lt;/p&gt;
&lt;p&gt;Read with hands-on practice — after each chapter, pick the one point that struck you most and go search for a related open-source project, read a bit of official docs, or just open an LLM and have it explain it to you. &lt;strong&gt;Reading without doing is the single biggest trap in this field.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you find this helpful, feel free to share it on Xiaohongshu / X with friends who are also preparing. This document gets updated periodically (&lt;strong&gt;roughly one version every 3–6 months&lt;/strong&gt;), and future versions will continue to be free.&lt;/p&gt;
&lt;p&gt;Let&apos;s begin.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Chapter 1 | Getting to Know AI Agents&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Before you can &quot;develop Agents,&quot; you first have to be able to &quot;read Agents.&quot; This chapter helps you explain in three sentences what an Agent is and how it differs from the things you already know (ChatGPT, APIs, chatbots).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.1 An imprecise but easy-to-grasp definition&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If the large language model (LLM) is a &quot;brain,&quot; then an Agent is that brain with eyes, hands, memory, and a body that lets it work in a loop on its own.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A slightly more rigorous statement: &lt;strong&gt;an Agent is a system with an LLM as its decision-making core that can perceive its environment, call tools, maintain memory, and complete multi-step tasks through an autonomous loop.&lt;/strong&gt; Four keywords: &lt;strong&gt;LLM, perception, tools, loop&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;1.2 What an Agent is not: three common misconceptions&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Misconception 1: Agent ≠ chatbot.&lt;/strong&gt; The core of a chatbot is &quot;conversation&quot;; the core of an Agent is &quot;completing a task&quot; — conversation is just one of the ways it receives a task.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 2: Agent ≠ a single LLM API call.&lt;/strong&gt; A single-turn call is &quot;input → output&quot;; an Agent has to have at least one of these to count as an Agent: &lt;strong&gt;a loop, tools, state&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 3: Agent ≠ a form-filling app wrapped around an LLM.&lt;/strong&gt; Stuffing an LLM into a product where the user fills out a form is no different in essence from &quot;a search box with GPT-4 bolted on.&quot; A real Agent should let the model decide for itself &quot;what to do next,&quot; rather than running through a human-prescribed flow from start to finish.&lt;/p&gt;
&lt;p&gt;One thing to add: back in the early ChatGPT of 2023, you gave it an input and it gave you an output, and that was it. By 2025–2026, the mainstream web versions of ChatGPT, Claude, and Gemini have built quite a few Agent-ified capabilities into the product — web search, code execution, file read/write, MCP tool calls. &lt;strong&gt;But this is &quot;vendors packaging Agent capabilities at the product layer for users to use,&quot; not &quot;the LLM itself becoming an Agent.&quot;&lt;/strong&gt; The underlying model is still that brain; it can act because there&apos;s a whole stack of Agent engineering wrapped around it — and that whole stack is exactly what you&apos;re going to learn.&lt;/p&gt;
&lt;h3&gt;1.3 The Agent four-piece set&lt;/h3&gt;
&lt;p&gt;Understand these four pieces and you&apos;ve understood 80% of the engineering substance of Agents.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brain (LLM)&lt;/strong&gt;: thinking and decision-making. It takes in the current state and outputs the next action (answer the user / call a tool).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memory&lt;/strong&gt;: build the intuition in two layers first — &lt;strong&gt;short-term memory&lt;/strong&gt; is the context of the current task (what the user just said, what tool was just called); &lt;strong&gt;long-term memory&lt;/strong&gt; is persistent information across sessions (user preferences, key facts). In engineering practice it&apos;s actually further divided into three layers — Working / Short-term / Long-term — which Chapter 5 expands on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hands (Tools / Function Calling)&lt;/strong&gt;: the Agent&apos;s interface for interacting with the outside world — search engines, code execution, email APIs, database queries are all tools. All the major LLM vendors provide native Function Calling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loop (Agent Loop)&lt;/strong&gt;: &lt;code&gt;perceive → think → act → perceive → ...&lt;/code&gt; The most classic implementation is called &lt;strong&gt;ReAct&lt;/strong&gt; (Reason + Act). The termination condition is usually: the model decides it&apos;s done / it hits a max step count / the user interrupts.&lt;/p&gt;
&lt;h3&gt;1.4 A minimal Agent workflow: using &quot;order me lunch&quot; as an example&lt;/h3&gt;
&lt;p&gt;You say to an Agent: &quot;Order me a lunch, under 30 yuan, ideally Cantonese.&quot; Internally it runs roughly like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Round 1&lt;/strong&gt;: thinks &quot;first look up nearby Cantonese restaurants&quot; → calls &lt;code&gt;search_restaurants(cuisine=&quot;Cantonese&quot;)&lt;/code&gt; → gets 8 restaurants.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Round 2&lt;/strong&gt;: thinks &quot;filter by budget&quot; → calls &lt;code&gt;filter_by_price(max_price=30)&lt;/code&gt; → 3 left.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Round 3&lt;/strong&gt;: thinks &quot;I have enough info, give it to the user&quot; → answers directly: &quot;I found 3 — A, B, C. Which would you like?&quot;&lt;/p&gt;
&lt;p&gt;Note three key points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Every step is decided by the model itself&lt;/strong&gt; — it judges on its own whether to call a tool, which one, and when to stop. This is the most central difference between an Agent and a &quot;hardcoded workflow.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The tool execution is not done by the model&lt;/strong&gt; — the model only outputs &quot;I want to call this tool&quot;; the actual execution is your program&apos;s job.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory runs through the whole flow&lt;/strong&gt; — by the time it&apos;s thinking in round 3, the model still remembers the original budget and taste requirements.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1.5 This chapter in one sentence&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Agent = an LLM in a loop, repeatedly &quot;thinking a bit, doing a bit,&quot; until the task is done.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Chapter 2 | A Map of the Agent Ecosystem&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This chapter is written for the people who &quot;have to go look up 10 terms halfway through reading a job description.&quot; We won&apos;t dig deep into each concept, but we&apos;ll lay the terminology map of this field flat, so that afterward, when you read any JD, blog post, or open-source project README, you&apos;ll know roughly what each term is talking about.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The whole Agent tech stack splits into five layers. We&apos;ll go from the bottom up.&lt;/p&gt;
&lt;h3&gt;2.1 The model layer: which brain to choose&lt;/h3&gt;
&lt;p&gt;As of May 2026, the model landscape has split into &lt;strong&gt;two regional pools&lt;/strong&gt;: the three overseas closed-source giants + five domestic open-source players.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The three big overseas closed-source models:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude (Anthropic)&lt;/strong&gt;: currently the strongest reputation in Agent engineering. Opus 4.7 is the flagship, Sonnet 4.6 is the everyday workhorse, and both natively support a &lt;strong&gt;1M token context&lt;/strong&gt;. Its handling of structured output, sustaining attention over long tasks, and tool-calling stability is very mature. &lt;strong&gt;For a Coding Agent or complex Multi-Agent work, Claude is the current default choice.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT (OpenAI)&lt;/strong&gt;: the all-rounder in overall capability, with the most complete ecosystem and the most stable Function Calling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gemini (Google)&lt;/strong&gt;: the strongest native multimodal capability (native understanding of images, video, audio). The top pick for multimodal Agent scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The five domestic open-source / semi-open-source players&lt;/strong&gt; (by tier and differentiation):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Qwen (Alibaba Tongyi Qianwen)&lt;/strong&gt;: backed by the Alibaba Cloud ecosystem, Qwen3.6-Plus is strong on Chinese-language scenarios, tool-calling stability, and document processing; the open-source 35B MoE variant runs on a single GPU.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DeepSeek&lt;/strong&gt;: the poster child for extreme cost-effectiveness. The V4 series is open-source, with prices so low they&apos;re nearly free (output pricing is about 1/10–1/30 of Claude&apos;s), and a 1M context. &lt;strong&gt;For getting started and practicing API calls, DeepSeek is the top pick.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kimi (Moonshot AI)&lt;/strong&gt;: K2.6 briefly took the #1 spot in the world for open-source models on SWE-Bench Pro, and long context has historically been a strength.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GLM (Zhipu)&lt;/strong&gt;: GLM-5.1 is currently the only flagship coding model fully open-sourced under the MIT license, capable of sustained &quot;8-hour-scale&quot; Agent work. The default choice for on-premise deployment and academic research scenarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MiniMax&lt;/strong&gt;: M2.7&apos;s killer feature is multimodality (voice, video) and the cost advantage from its extremely low activated parameter count.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Three pieces of honest advice on model selection:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Bigger isn&apos;t better — use models tiered by task.&lt;/strong&gt; Use a cheap small model for simple intent recognition and routing; only use the flagship for complex code generation and reasoning. This is the key technique for controlling cost.&lt;/li&gt;
&lt;li&gt;Most domestic models provide an &lt;strong&gt;OpenAI-compatible API endpoint&lt;/strong&gt; — the same code can switch models just by changing &lt;code&gt;base_url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&apos;t bet everything on a single model&lt;/strong&gt; — a mature project will plug into 2–3 vendors at once and route by task.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.2 The framework layer: what scaffolding to build with&lt;/h3&gt;
&lt;p&gt;The mainstream choices fall into two categories: &lt;strong&gt;official SDKs&lt;/strong&gt; and &lt;strong&gt;third-party frameworks&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Official SDKs:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenAI SDK&lt;/strong&gt;: the oldest and most stable. &lt;strong&gt;But it can only call OpenAI&apos;s own models&lt;/strong&gt; — though, because the OpenAI-compatible protocol is the de facto standard, domestic models like DeepSeek / Qwen / Kimi / GLM can all be called with it by changing &lt;code&gt;base_url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anthropic SDK&lt;/strong&gt;: Claude&apos;s official SDK, and the smoothest way to wire up native capabilities like Tool Use and Computer Use.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Gen AI SDK&lt;/strong&gt;: Gemini&apos;s official SDK, with the most direct multimodal integration.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Third-party frameworks (in order of recommendation):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vercel AI SDK&lt;/strong&gt; (my personal top pick for getting started):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Model-agnostic&lt;/strong&gt; — &lt;code&gt;import { anthropic } from &apos;@ai-sdk/anthropic&apos;&lt;/code&gt; to use Claude, and switching to OpenAI / Google / DeepSeek only changes a single import while the rest of your code stays completely untouched.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It&apos;s just an SDK, not a framework&lt;/strong&gt; — it gives you primitive-level capabilities like &quot;streaming output,&quot; &quot;tool calling,&quot; and &quot;structured output,&quot; and it won&apos;t force you to organize your code around its abstractions (Chain / Graph / Node) the way LangChain / LangGraph do. How you orchestrate the Agent Loop is entirely up to you, and that degree of freedom is very friendly to anyone who genuinely wants to understand how Agents work.&lt;/li&gt;
&lt;li&gt;The TypeScript / Next.js ecosystem is especially smooth.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;LangChain / LangGraph&lt;/strong&gt;: the most established, the biggest ecosystem, the most extensive docs — but also the most frequently criticized for &quot;abstractions that are too heavy.&quot; Unless your project specifically needs LangChain&apos;s off-the-shelf components (200+ document loaders, LangSmith evaluation), &lt;strong&gt;I don&apos;t recommend it as a first stop.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CrewAI / AutoGen / Mastra&lt;/strong&gt;: aimed respectively at multi-Agent collaboration, enterprise-grade orchestration, and TypeScript full-stack — pick one once you have a concrete scenario.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advice for beginners&lt;/strong&gt;: for your first Agent, I recommend going straight to the &lt;strong&gt;Vercel AI SDK or a vendor&apos;s official SDK&lt;/strong&gt; — their abstractions are light enough that they won&apos;t get in the way of you seeing clearly &quot;what the Agent Loop is actually doing.&quot; &lt;strong&gt;Don&apos;t learn a framework for the sake of &quot;learning a framework&quot;&lt;/strong&gt; — the framework itself isn&apos;t a résumé asset; &quot;what valuable thing I built with some framework&quot; is.&lt;/p&gt;
&lt;h3&gt;2.3 The protocol layer: MCP and Skills&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; is an open protocol Anthropic launched in late 2024 that gives &quot;LLM applications&quot; and &quot;tools / data sources&quot; a &lt;strong&gt;standardized way to talk to each other&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;An analogy — in the past, every Agent that wanted to plug in a new tool had to write its own adapter code; MCP is like the &quot;USB standard&quot; of the Agent world. Anthropic, OpenAI, Cursor, Cline, and Claude Code all already support MCP — &lt;strong&gt;it has become the de facto standard.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The beginner advice is to first &lt;strong&gt;use MCP Servers other people have already written&lt;/strong&gt; (Anthropic maintains a public list) and plug tools like Notion / GitHub / Slack directly into your Agent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Skills is an equally important concept to understand.&lt;/strong&gt; It&apos;s a &lt;strong&gt;product form&lt;/strong&gt; that Anthropic officially launched in the second half of 2025 and that the industry gradually started following in 2026 — making a &quot;packaged, reusable Agent capability module&quot; a first-class citizen.&lt;/p&gt;
&lt;p&gt;To understand Skills, first look at an engineering reality: a genuinely usable Agent often isn&apos;t just &quot;a model + a few tools.&quot; It also needs — a set of &lt;strong&gt;dedicated tools&lt;/strong&gt; (generating a PPT needs a pptx library), a piece of &lt;strong&gt;carefully tuned prompt guidance&lt;/strong&gt; (when to use what, what the pitfalls are), some &lt;strong&gt;examples and reference materials&lt;/strong&gt; (so the model knows &quot;what good output looks like&quot;), and sometimes &lt;strong&gt;specific code snippets&lt;/strong&gt; as well.&lt;/p&gt;
&lt;p&gt;If these are scattered across the prompt, tool descriptions, and code comments, two things happen: the model doesn&apos;t know when to use what; and these capabilities can&apos;t be reused, distributed, or versioned.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Skills turns this &quot;capability package&quot; into a product form that can exist independently, be loaded, and be shared.&lt;/strong&gt; A Skill is usually a folder containing &lt;code&gt;SKILL.md&lt;/code&gt; (describing what this Skill does and when it triggers) + related scripts, tools, and reference materials. The Agent automatically loads the corresponding Skill when it needs it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A few key intuitions:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Skills are a &lt;strong&gt;&quot;user manual&quot; for the Agent to use&lt;/strong&gt;, not documentation for humans to read — the language is written for the model.&lt;/li&gt;
&lt;li&gt;Skills solve the problem of &quot;infinite tools confusing the model.&quot; If an Agent plugs in 50 tools, the model is extremely likely to pick the wrong one; but if you group them into 10 Skills, the model only sees the corresponding tools in scenarios that match that Skill — this is &lt;strong&gt;on-demand exposure&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills and MCP are complementary&lt;/strong&gt;: MCP solves &quot;how a tool gets called&quot; (interface standardization); Skills solves &quot;how tools get organized and triggered&quot; (capability packaging). A single Skill can internally call multiple MCP Servers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&apos;ve looked at Anthropic&apos;s official Skills repo, you&apos;ll find it has already turned common capabilities like &quot;create docx,&quot; &quot;create pptx,&quot; &quot;create xlsx,&quot; and &quot;fill out a PDF form&quot; into Skills — these Skills are exactly what runs behind Claude.ai&apos;s &quot;Create Files&quot; feature. &lt;strong&gt;This trend of &quot;turning general capabilities into Skills&quot; is being followed by the whole industry in 2026.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The relationship among the three:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Function Calling / Tool Use&lt;/strong&gt; actually refer to the same thing — OpenAI calls it Function Calling, Anthropic calls it Tool Use, and at bottom both are the underlying capability of &quot;can the LLM output the instruction &apos;I want to call this tool.&apos;&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill&lt;/strong&gt; is another layer of abstraction — packaging a set of tools + prompt guidance + reference materials into a reusable, loadable capability module.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.4 The data layer: RAG, Memory, LLM Wiki&lt;/h3&gt;
&lt;p&gt;This layer is changing fastest in 2026 — the traditional RAG paradigm is being partially replaced by several new forms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt; was the most mainstream way of &quot;giving an LLM its own knowledge&quot; in 2023–2024. The core component is a &lt;strong&gt;vector database&lt;/strong&gt; (Milvus, ChromaDB, Pinecone, pgvector, sqlite-vec).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But RAG is on the way out in 2026&lt;/strong&gt; — this is something that needs unpacking.&lt;/p&gt;
&lt;p&gt;Go back to the era when RAG emerged (early 2023): mainstream LLMs had a context window of only 4K–32K tokens, long documents couldn&apos;t fit, and the only option was &quot;chunk + vector retrieval + stitch back into the prompt.&quot; Today Claude Opus 4.7 / Sonnet 4.6 already natively support 1M tokens, and DeepSeek V4 Pro and Qwen3.6-Plus are also 1M — &lt;strong&gt;for many scenarios, the complex &quot;retrieve first, then generate&quot; pipeline isn&apos;t necessary at all&lt;/strong&gt;, and stuffing the document straight into the context actually works better.&lt;/p&gt;
&lt;p&gt;In May 2026, Karpathy explicitly promoted an alternative approach — &lt;strong&gt;LLM Wiki&lt;/strong&gt;: for an individual&apos;s or small team&apos;s medium-scale knowledge base (under 100K tokens), you can completely give up vector retrieval, organize all the content into a &quot;Wikipedia&quot;-style structure in Markdown, and stuff the relevant sections directly into the prompt context on demand. The upsides: no chunking errors, no retrieval-recall problems, dead-simple debugging and editing, and — by hitting the Prefix Cache — a massive cost reduction too.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But RAG isn&apos;t dead.&lt;/strong&gt; It&apos;s still the top choice in these scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Internal enterprise scenarios that emphasize data privacy&lt;/strong&gt; — documents can&apos;t leave the corporate network.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ultra-large-scale knowledge bases&lt;/strong&gt; (millions of documents and up) — the context can&apos;t hold them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-user, multi-tenant scenarios&lt;/strong&gt; — each user&apos;s data has to be isolated.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In short: &lt;strong&gt;for a personal project, try LLM Wiki first; for a toB enterprise project, RAG is still the default.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memory (the memory system)&lt;/strong&gt; overlaps with RAG but is different — Memory places more emphasis on &quot;personalized memory of the current user / session&quot; (user preferences, conversation summaries, key facts), usually divided into three layers: Working / Short-term / Long-term. Chapter 5 covers it specifically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agentic Retrieval / Agentic Memory&lt;/strong&gt; is the new trend of 2025–2026: traditional RAG is a &lt;strong&gt;passive pipeline&lt;/strong&gt; (retrieve first, then generate), whereas the Agentic mode lets the Agent decide for itself whether to retrieve, what to retrieve, whether to refine the retrieval results a second time, and whether to retrieve again. This &quot;proactive retrieval&quot; is rapidly replacing traditional RAG in complex scenarios.&lt;/p&gt;
&lt;h3&gt;2.5 The application layer: three mainstream landing scenarios&lt;/h3&gt;
&lt;p&gt;After nearly a year of observing the industry, the directions that get mentioned over and over and have proven out commercially are mainly these three:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI search&lt;/strong&gt;: from Perplexity to Metaso AI to Felo, all of these are essentially Agent-ified search — no longer &quot;keyword matching + ranking,&quot; but &quot;understanding intent + retrieval + synthesis + generation.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chat-to-BI&lt;/strong&gt;: letting business people query data, generate charts, and do attribution analysis in natural language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vibe Coding&lt;/strong&gt;: from Copilot to Cursor to Claude Code to OpenCode to v0 — this direction has progressed the fastest over the past year and has most directly disrupted traditional software development.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you&apos;re thinking about which vertical to pursue for an Agent, these three are the ones with the most commercial value and the largest talent demand right now.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;2.6 Tech stack map&lt;/h3&gt;
&lt;p&gt;| Layer | Key components | Representatives |
|------|---------|------|
| Application layer | AI search, Chat-to-BI, Vibe Coding | Perplexity, Cursor, Claude Code |
| Data layer | RAG, Memory, LLM Wiki | Pinecone, Milvus, pgvector |
| Protocol layer | MCP, Skills, Function Calling / Tool Use | Anthropic MCP, Anthropic Skills |
| Framework layer | Agent orchestration | Vercel AI SDK, LangChain, LangGraph |
| Model layer | LLM | Claude, GPT, Gemini, DeepSeek, Qwen, Kimi, GLM |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Chapter 3 | How to Think About This Direction: Trends, Mindset, and Pitfalls&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This chapter isn&apos;t about technology. It&apos;s about three things: why Agents are the most worthwhile direction to get into right now, why you don&apos;t need to be anxious, and how to avoid the opportunities that look beautiful but are actually traps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.1 &quot;Am I too late&quot; is a false question&lt;/h3&gt;
&lt;p&gt;The question I get asked most in consulting is: &quot;Joye, am I too late if I&apos;m only starting to learn now?&quot;&lt;/p&gt;
&lt;p&gt;My standard answer is: &lt;strong&gt;even the &quot;veterans&quot; on this track only have two years of experience.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A quick sketch of the timeline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;November 2022&lt;/strong&gt; ChatGPT released&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Early 2023&lt;/strong&gt; open-source projects like AutoGPT take off, and &quot;Agent&quot; starts being widely discussed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;June 2023&lt;/strong&gt; OpenAI launches Function Calling, and Agent engineering enters a new phase&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2024&lt;/strong&gt; Cursor enters its commercial explosion period&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Late 2024&lt;/strong&gt; Anthropic launches MCP, and the Agent protocol layer starts taking shape&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2025&lt;/strong&gt; Agent products like Manus, Claude Code, and Devin burst onto the scene all at once&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2025–2026&lt;/strong&gt; new paradigms like the Skills system, Agentic Search, and Agentic Memory evolve rapidly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words — &lt;strong&gt;the so-called &quot;senior Agent engineers&quot; in the industry today have at most two to three years from entry to now.&lt;/strong&gt; That means if you start getting into it today, in three years you&apos;ll be a &quot;veteran&quot; too. Compared with those directions in traditional development where people have ten or twenty years of experience, this is a direction you can genuinely &lt;strong&gt;catch up on through speed of learning&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;3.2 Why now: three judgments&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Judgment 1: Agents are moving from the &quot;Demo phase&quot; to the &quot;Production phase.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In 2023 and the first half of 2024, a huge number of Agent projects in the industry stalled at the Demo stage. Starting in the second half of 2024, &quot;industrial-grade&quot; problems like reliability, observability, Eval systems, and cost control started being taken seriously — &lt;strong&gt;this is the phase where an engineer can genuinely add value.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Judgment 2: a standardization window at the infrastructure layer.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The standards for infrastructure layers like MCP, Skills, and AI Gateway are still taking shape quickly. This means that if you enter now, &lt;strong&gt;you have a chance to genuinely participate in building the infrastructure of a new industry&lt;/strong&gt; — and that kind of window is extremely rare in traditional development.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Judgment 3: talent demand is growing systematically.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Starting in 2026, China&apos;s top tech companies have begun systematically opening Agent engineer / LLM application engineer roles in their regular internships, summer internships, and fall recruiting — something that was a rarity just two years ago.&lt;/p&gt;
&lt;p&gt;A more vivid signal comes from &lt;strong&gt;Y Combinator&apos;s W26 batch (Winter 2026)&lt;/strong&gt;: of 196 companies, about 60% are AI-native, and &lt;strong&gt;41.5% are building Agent infrastructure outright&lt;/strong&gt; — the &quot;selling shovels&quot; business of authentication, testing, security, observability, context management, billing, and other Agent-adjacent work. E2B (an AI code sandbox) officially mentioned that about 10% of W26 companies run Agents on its platform. &lt;strong&gt;When one of the most discerning incubators in the world places 40%+ of its bets on Agent infrastructure, the talent demand in this track is only going to keep growing.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;3.3 A few reasons you don&apos;t need to be anxious&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;First, the industry has no &quot;absolute authority.&quot;&lt;/strong&gt; Traditional computer science has those &quot;I&apos;ve read his paper,&quot; &quot;I&apos;ve read his book&quot; authority figures. This Agent direction is too new for that kind of figure to exist. OpenAI&apos;s and Anthropic&apos;s best practices are all written by engineers as they go — the gap between them and you is &quot;accumulated practice,&quot; not &quot;a gap in talent.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Second, the information asymmetry is tiny.&lt;/strong&gt; OpenAI and Anthropic publish best practices on prompt engineering, Agent design, and the Skills system directly on their company blogs, &lt;strong&gt;free for anyone to read&lt;/strong&gt;. That kind of transparency is unimaginable in traditional industries — most of what you want to learn has already been written down, and the only question is whether you&apos;re willing to spend the time reading it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Third, the &quot;easy part&quot; of the tooling barrier is dropping, but the &quot;deep part&quot; is rising.&lt;/strong&gt; This point needs to be told in two halves.&lt;/p&gt;
&lt;p&gt;Looking at the easy side: three years ago, integrating an LLM required understanding GPU deployment; today you only need to know how to call an API. Vibe Coding has made &quot;build a personal website&quot; and &quot;build a simple chatbot&quot; nearly barrier-free.&lt;/p&gt;
&lt;p&gt;But this is precisely why — &lt;strong&gt;when building a &quot;barrier-less Agent project&quot; becomes easy, a barrier-less project is itself worthless.&lt;/strong&gt; You can find a thousand &quot;AI health assistants&quot; and &quot;AI customer-service bots&quot; on GitHub, because everyone can build one in a weekend with Vibe Coding. Put these projects on a résumé and the interviewer knows their worth at a glance.&lt;/p&gt;
&lt;p&gt;The real entry barrier has been pushed to a &lt;strong&gt;deeper place&lt;/strong&gt;: can you pick a &lt;strong&gt;problem that genuinely exists and can&apos;t be solved with off-the-shelf ChatGPT&lt;/strong&gt; to build a project around? Can you make &lt;strong&gt;decent trade-offs&lt;/strong&gt; at the engineering level? Can you clearly articulate, for every technical choice, &quot;why this one&quot;?&lt;/p&gt;
&lt;p&gt;In short: this isn&apos;t &quot;the barrier dropping,&quot; it&apos;s &quot;the barrier shifting from coding ability to depth of thinking.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fourth, your opponent isn&apos;t other people — it&apos;s the you from last year who didn&apos;t take action.&lt;/strong&gt; What&apos;s truly &quot;competitive&quot; in the Agent field isn&apos;t your knowledge reserves, it&apos;s your &quot;volume of doing.&quot; Reading 100 blog posts is worth less than writing one small Agent that actually runs yourself. &lt;strong&gt;Even if you only start today, as long as you take action, you&apos;re already outrunning the 90% of people who &quot;watch but don&apos;t do.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;3.4 Six common misconceptions&lt;/h3&gt;
&lt;p&gt;These six misconceptions are the ones I run into most often in consulting; let me debunk them one by one —&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 1: &quot;I&apos;m bad at math, I can&apos;t do AI.&quot;&lt;/strong&gt; What you want to do is &lt;strong&gt;AI applications&lt;/strong&gt;, not &lt;strong&gt;AI algorithms&lt;/strong&gt;. Engineering practice at the application layer basically doesn&apos;t need math.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 2: &quot;I have to finish learning LLM theory before I can learn Agents.&quot;&lt;/strong&gt; Backwards. The application layer and the underlying algorithms are &lt;strong&gt;two relatively independent tracks&lt;/strong&gt;. Do applications first, and go back to fill in theory when you hit a specific problem — it&apos;s 10x more efficient.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 3: &quot;Doesn&apos;t learning this require knowing a lot of frameworks?&quot;&lt;/strong&gt; A framework is a tool, not a goal. Once you understand the essence, you can pick up any framework in minutes; if you only know how to use a framework but don&apos;t understand the underlying layer, you&apos;ll be completely helpless the moment you hit a scenario the framework doesn&apos;t support.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 4: &quot;I can&apos;t find a job without a big-company background.&quot;&lt;/strong&gt; This Agent direction happens to be &lt;strong&gt;the domain of startups&lt;/strong&gt;. What they value is &quot;can you do the work right away&quot; — your project experience, GitHub, and blog matter more than your school and your last employer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 5: &quot;AI is moving so fast, will what I learn be obsolete immediately?&quot;&lt;/strong&gt; What changes is the surface-level tooling; what stays is the underlying ideas. &lt;strong&gt;The ReAct paradigm, context engineering, memory systems, tool calling, Eval systems&lt;/strong&gt; — these core concepts haven&apos;t changed in the past two years and won&apos;t change in essence in the next five.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception 6: &quot;Isn&apos;t Agent already a red ocean?&quot;&lt;/strong&gt; The truly &quot;crowded&quot; fields are the traditional ones that have been deeply developed for twenty years. Agent penetration in fields like Coding, Research, Customer Support, BI, and Marketing is still under 10% — we&apos;ve barely scratched the surface.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Chapter 4 | How to Get Started and Prepare for the Job Hunt&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This is the most hands-on chapter of this document. Everything you need to do — from &quot;opening your IDE and writing your first LLM call&quot; to &quot;landing your first offer&quot; — is here.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4.1 Prerequisite skills: what you need to know, and what you can skip&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Let&apos;s start with languages.&lt;/strong&gt; Agent development is currently mainstream in two ecosystems — &lt;strong&gt;Python and TypeScript / JavaScript&lt;/strong&gt; — and &lt;strong&gt;knowing one of them already is enough to start&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For projects that lean backend, data, or algorithm integration, Python is more common.&lt;/li&gt;
&lt;li&gt;For projects that lean frontend or toward web product forms, TypeScript is more mainstream.&lt;/li&gt;
&lt;li&gt;In my own work, complex Agent projects are usually &lt;strong&gt;a Python backend + a TS frontend&lt;/strong&gt; — knowing a bit of both is the most comfortable, but it&apos;s not required.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What you must know:&lt;/strong&gt; either Python or TypeScript, with the ability to fluently write functions, handle JSON, and call an HTTP API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What you don&apos;t need to know (set it aside for now):&lt;/strong&gt; deep learning math, PyTorch / TensorFlow / model training / fine-tuning, the internals of the Transformer, and the APIs of Agent frameworks like LangChain / LangGraph (&lt;strong&gt;your first Agent should not start from any of these&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On Git and the command line:&lt;/strong&gt; these are an engineer&apos;s &quot;basic hygiene,&quot; but in 2026 their learning curve has been dramatically flattened by AI tools — when you hit something you don&apos;t know, just ask Cursor / Claude Code and it&apos;ll walk you through it step by step. &lt;strong&gt;Don&apos;t feel &quot;not ready to start learning Agents yet&quot; just because you&apos;re unfamiliar with Git — that&apos;s putting the cart before the horse.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;4.2 A three-stage learning roadmap&lt;/h3&gt;
&lt;p&gt;At this point in 2026, I &lt;strong&gt;no longer recommend&lt;/strong&gt; that newcomers hand-write a ReAct Loop from scratch — that kind of &quot;hand-writing&quot; was a necessary rite of passage three years ago, but today the abstractions of official SDKs like Vercel AI SDK and Anthropic SDK are light enough that the docs themselves are the best teaching material.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 1: Get an SDK running (3–5 days)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&apos;re a complete beginner, the only goal for week one is to &lt;strong&gt;manually get a single LLM API call working&lt;/strong&gt;: install Python or Node.js, sign up for an LLM vendor&apos;s API (I recommend DeepSeek — cheap enough that it won&apos;t hurt), write under 10 lines of code to send &quot;hello&quot; to the model, and then get it to hold a multi-turn conversation. &lt;strong&gt;The biggest asset you&apos;ll own at the end of this week isn&apos;t code — it&apos;s the visceral sense that &quot;an LLM isn&apos;t a black box; it&apos;s just an HTTP service you can call.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Then I strongly recommend going straight to the &lt;strong&gt;Vercel AI SDK&apos;s official docs&lt;/strong&gt; — the docs themselves are an excellent piece of &quot;Agent teaching,&quot; progressing layer by layer from &quot;call the model once&quot; to &quot;streaming output,&quot; &quot;tool calling,&quot; &quot;multi-step loops,&quot; and &quot;structured output.&quot; Why not start with the OpenAI Cookbook or Anthropic Cookbook? Because each of those only covers its own model, whereas the &lt;strong&gt;Vercel AI SDK is model-agnostic and has the lowest migration cost&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The Python route: use the &lt;strong&gt;OpenAI SDK + base_url pattern&lt;/strong&gt; to connect to OpenAI-compatible domestic models, or use the &lt;strong&gt;Anthropic SDK&lt;/strong&gt; to connect to Claude. Pydantic AI is a lightweight Python SDK that&apos;s the counterpart to the Vercel AI SDK.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 2: Understand the mechanics (1–2 weeks)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Add a few real tools to the Stage 1 Agent — web search (Tavily / SerpAPI), file read/write, third-party APIs. Focus on observing the model&apos;s &lt;strong&gt;&quot;selection behavior&quot; under multiple tools&lt;/strong&gt;: when does it pick the wrong one? when does it fall into an infinite loop? Write down every failure case — these notes are the best résumé material.&lt;/p&gt;
&lt;p&gt;Then run two comparison experiments: try &lt;strong&gt;LLM Wiki mode&lt;/strong&gt; once (organize a body of material into Markdown and stuff it straight into the system prompt), and then try &lt;strong&gt;RAG mode&lt;/strong&gt; once (vectorize and chunk the same material with pgvector / ChromaDB). &lt;strong&gt;Doing this comparison with your own hands is worth more than reading 10 blog posts.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 3: A real project (1–2 months)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Pick &lt;strong&gt;a real scenario you yourself would use every day&lt;/strong&gt; — don&apos;t build a played-out project like a &quot;general-purpose Q&amp;#x26;A assistant.&quot;&lt;/p&gt;
&lt;p&gt;The standard for judging whether a project is &quot;good enough&quot; — refer to W&apos;s soul-searching question in my &quot;Mock Interview&quot; post: &lt;strong&gt;&quot;If it were me, I could solve this directly with Doubao / ChatGPT — so why does this have to be built?&quot; If you can&apos;t answer, please change the scenario.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few entry-level project directions with &quot;résumé value&quot;: an AI topic-selection assistant (scraping trending content from Xiaohongshu / Twitter for topic suggestions), a personal Newsletter assistant (auto-summarizing your subscriptions weekly), a simple Chat-to-SQL, a personal email-classification Agent, a lightweight code-review assistant (hooked up to a GitHub Webhook).&lt;/p&gt;
&lt;p&gt;After finishing each project, &lt;strong&gt;write a blog retrospective&lt;/strong&gt; — &quot;what I built,&quot; &quot;what pitfalls I hit,&quot; &quot;how I solved them.&quot; &lt;strong&gt;This blog post is itself the strongest material for your résumé.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;4.3 Job-hunt prep: tell your project &quot;to the extreme&quot;&lt;/h3&gt;
&lt;p&gt;If you can only spend your prep time on one thing, &lt;strong&gt;it&apos;s pitching your project to the extreme&lt;/strong&gt; — making four things clear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What you did&lt;/strong&gt; (What): the project background, your role, the overall architecture&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why you did it this way&lt;/strong&gt; (Why): the rationale behind every key decision&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What pitfalls you hit&lt;/strong&gt; (How it failed): failure cases + solutions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What you learned&lt;/strong&gt; (What you learned): how you&apos;d redo it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Counter-example&lt;/strong&gt;: &quot;I used LangChain to build a RAG customer-service system.&quot; — a description like this says nothing; it&apos;s an interview killer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Positive example&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I built a customer-service RAG system. At first I used simple vector retrieval, and recall was only 60% — analysis showed customer questions were colloquial and worded very differently from the source documents. We introduced Query Rewriting: first use a lightweight model to rewrite the user&apos;s question into multiple candidate Queries, then retrieve each separately and merge with deduplication. This change lifted recall to 85%, but Token cost went up 30%. To balance the cost, we later added caching — the rewrite results for the same class of questions could be reused. In the end, while keeping recall above 80%, cost only went up 5%.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This passage has: &lt;strong&gt;a metric (60% → 85%) + a decision (Query Rewriting) + a trade-off (cost vs. recall) + a follow-up optimization (caching)&lt;/strong&gt;. That&apos;s what &quot;telling it to the extreme&quot; means.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Three points at the résumé level&lt;/strong&gt;: don&apos;t pile up technical terms (&quot;proficient in LangChain, LangGraph, Vercel AI SDK, CrewAI…&quot; — a résumé like that is laughable; the genuinely strong candidates actually have fewer technical words on their résumés); structure each project entry as &quot;problem — solution — result&quot;; quantify your results (even an estimate beats no number).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At the interview level&lt;/strong&gt; — Agent roles don&apos;t test rote memorization, they test &quot;what you&apos;ve been through.&quot; Four concrete dimensions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Foundational understanding&lt;/strong&gt;: the essential differences between LLM / Agent / Chatbot, how Function Calling works, what MCP is…&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System design&lt;/strong&gt;: context engineering approaches, memory layering, tool-calling reliability, multi-Agent collaboration…&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Engineering trade-offs&lt;/strong&gt;: the basis for model selection, balancing cost and quality, judgment in framework selection, failure-retry strategies…&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Industry awareness&lt;/strong&gt;: the design philosophies of Manus / Claude Code / OpenCode, what you&apos;ve read lately, which open-source projects you follow…&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first layer relies on experience, the second on understanding, the third on judgment, and the fourth on taste and how much you read. &lt;strong&gt;The further down you go, the more it separates candidates.&lt;/strong&gt; In my &quot;Mock Interview&quot; post I gave concrete examples for each category — go take a look if you need them.&lt;/p&gt;
&lt;h3&gt;4.4 Five detours not to take&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Detour 1: gnawing on the LangChain source code right away.&lt;/strong&gt; The design is complex and the source is extremely unfriendly to newcomers. Once you&apos;ve shipped a few projects with an SDK and then go look at it, the experience will feel completely different.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Detour 2: rushing into model fine-tuning too early.&lt;/strong&gt; 99% of application scenarios don&apos;t need fine-tuning; prompt engineering + RAG / LLM Wiki already solves most problems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Detour 3: chasing new frameworks without building your fundamentals.&lt;/strong&gt; There&apos;s a new framework every two weeks. Once you form a &quot;chase the new&quot; habit, you&apos;ll forever be learning new things and never have a project of your own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Detour 4: thinking you&apos;ve got it just from finishing a tutorial.&lt;/strong&gt; In this Agent field, every concept that &quot;looks simple&quot; turns out to have a pile of details once you actually do it. &lt;strong&gt;Watching without writing equals zero.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Detour 5: doing without producing output.&lt;/strong&gt; Building a project but not writing docs, not writing a blog, not open-sourcing it — that&apos;s as good as not having done it. &lt;strong&gt;Output is the most effective way to force input&lt;/strong&gt;, and it&apos;s also your strongest differentiating asset when you later look for a job.&lt;/p&gt;
&lt;h3&gt;4.5 Recommended learning resources (curated)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Official docs (read in order)&lt;/strong&gt;: the Vercel AI SDK official docs (the best starting point for getting into TypeScript) → the Tool Use / Skills / Prompt Engineering chapters of the Anthropic official docs → the OpenAI Cookbook (a Python hands-on supplement) → the docs of whichever domestic model vendor you chose (any of DeepSeek / Qwen / Kimi / GLM).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frontline blogs (skim weekly)&lt;/strong&gt;: the Anthropic Engineering Blog, the AI sections of Sequoia / a16z, and the AI section of Hacker News.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Community&lt;/strong&gt;: on Twitter / X, follow @karpathy, @AnthropicAI, @simonw, @_philschmid, @jxnlco.&lt;/p&gt;
&lt;p&gt;I &lt;strong&gt;don&apos;t recommend&lt;/strong&gt; any LLM-internals resources &lt;strong&gt;at this stage&lt;/strong&gt; (Karpathy&apos;s &quot;Let&apos;s build GPT&quot; series, the various minimind-style source-code tutorials — &lt;strong&gt;including my own minimind-notes&lt;/strong&gt;). They&apos;re all excellent, but they solve the problem of &quot;understanding how an LLM is trained,&quot; which is a different track from building Agent applications. Once you&apos;ve finished your first real project and have specific curiosity, going back to them will land much better.&lt;/p&gt;
&lt;h2&gt;Chapter 5 | The Few Things That Truly Matter&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The first four chapters made clear &quot;what it is, how to start, how to get a job.&quot; This last chapter is for those who&apos;ve already finished their first project and want to know &quot;what does going deeper look like&quot; — and it&apos;s the true inner skill of an Agent engineer.&lt;/p&gt;
&lt;p&gt;Each section uses an everyday analogy to help you build intuition. After reading this chapter, you&apos;ll have a shared language for talking with senior engineers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;5.1 Context engineering&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: when you hand off work to a colleague, do you give them a 100-page project archive, or a 1-page concise brief?&lt;/p&gt;
&lt;p&gt;An LLM&apos;s attention is finite — the longer the context and the lower the information density, the more easily it &quot;loses focus,&quot; and at the same time Token cost goes up and responses slow down. &lt;strong&gt;Context Engineering is exactly about &quot;presenting the information that most deserves to be seen, in the most effective way, within a finite space.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In a real project, a commercial-grade Agent might process dozens of interactions and call dozens of tools in a single conversation. Without context management, you&apos;ll blow the context out within 10 minutes. Common techniques —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Structured Prompt&lt;/strong&gt;: use XML tags, JSON blocks, and clear delimiters instead of a stream-of-consciousness natural-language dump.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Front-loading / back-loading key information&lt;/strong&gt;: the model pays more attention to the beginning and the end (the &quot;Lost in the Middle&quot; phenomenon). Put important constraints at the top of the System Prompt or at the end of the User message.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Replacing verbatim history with a summary&lt;/strong&gt;: compress early conversation in a long dialogue into a summary.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefix-Cache-friendly context design&lt;/strong&gt;: put unchanging content first and changing content last, which can massively reduce cost.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.2 Memory systems&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: how do people remember things? Short-term memory (things that just happened), long-term memory (important experiences from years ago), retrieval cues (seeing an old photo and suddenly recalling a story). An Agent&apos;s memory architecture basically mimics this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Three-layer architecture&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Working Memory&lt;/strong&gt;: the context the current task is actively using&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Short-term Memory&lt;/strong&gt;: the history of the current session&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Long-term Memory&lt;/strong&gt;: persistent information across sessions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are three key decision points for long-term memory —&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Write strategy&lt;/strong&gt;: what kind of information is worth writing? A temporary preference like &quot;I feel like eating spicy today&quot; shouldn&apos;t be remembered; a long-term fact like &quot;I&apos;m allergic to peanuts&quot; must be. This classification is usually judged by a dedicated &quot;Memory Agent.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read strategy&lt;/strong&gt;: when to retrieve, and how? Retrieve once on every turn or only under a specific intent? Use vector similarity, keywords, or graph retrieval?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forget strategy&lt;/strong&gt;: more long-term memory isn&apos;t better. Stale, low-value, or contradictory memories should be cleaned up or decayed.&lt;/p&gt;
&lt;h3&gt;5.3 Tool calling&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: getting a smart but handless person to complete a task for you — you have to tell them which tools are nearby, what each one does, and how to use it.&lt;/p&gt;
&lt;p&gt;A few common engineering difficulties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tool Schema design&lt;/strong&gt;: the clearer you write the parameter names and descriptions, the lower the chance the model misuses them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trade-off on the number of tools&lt;/strong&gt;: too few isn&apos;t enough, too many and the model can&apos;t pick correctly. Generally 10 is the upper limit — beyond that you need &quot;tool routing&quot; (which is exactly the problem Skills solves, discussed earlier).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Failure retry and idempotency&lt;/strong&gt;: retrying on failure is necessary, but it needs a cap — failing after 3 tries and reporting an error beats burning money on infinite retries.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Up-front constraints vs. after-the-fact fallbacks&lt;/strong&gt;: making the tool-usage boundaries clear at the prompt layer is far more efficient than doing permission control at the tool-execution layer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.4 Reliability&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: writing a Demo is like cooking in your own kitchen; writing Production is like running a restaurant — what you have to handle isn&apos;t just &quot;how good the food is,&quot; but also &quot;will it blow up at peak hours&quot; and &quot;will the occasional picky customer break the process.&quot;&lt;/p&gt;
&lt;p&gt;A traditional application is a &quot;deterministic system&quot; — the same input always yields the same output. An Agent is a &quot;probabilistic system&quot; — the same input may yield different outputs, or even fail outright. &lt;strong&gt;This means the &quot;test it once and it&apos;s OK&quot; development model completely fails to work for Agents.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Common reliability problems: hallucination, instruction drift, unstable formatting, infinite loops, and cascading collapses from tool failures.&lt;/p&gt;
&lt;p&gt;The core engineering ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Up-front constraints&lt;/strong&gt;: use the prompt to make &quot;how it should be done&quot; clear — lower cost than an after-the-fact fallback&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured output + Schema validation&lt;/strong&gt;: validate model output with Pydantic, Zod&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State machine + Checkpoint&lt;/strong&gt;: make the Agent flow explicit as a state machine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Degradation strategy&lt;/strong&gt;: have a fallback path when a tool fails&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.5 Cost control&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: driving — gas prices, distance, and the car model all affect the fuel bill. An Agent is the same: the model, context length, and number of calls together determine the cost of a single task.&lt;/p&gt;
&lt;p&gt;An Agent&apos;s cost is far higher than a traditional application&apos;s. A single complex task might take dozens of LLM calls and accumulate tens of thousands to hundreds of thousands of Tokens — a single task could cost anywhere from a few yuan to a few dozen yuan. &lt;strong&gt;If your product is free and toC, poor cost control means losing money for the applause.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few high-ROI optimization techniques:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prefix-Cache-friendly design&lt;/strong&gt;: both OpenAI and Anthropic offer caching discounts for &quot;prefix hits&quot; (Anthropic can save up to ~90% on a hit, OpenAI about 50%). Put unchanging content first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tiered model usage&lt;/strong&gt;: use a cheap model for simple tasks, and only use the flagship for complex ones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reducing the number of Agent Steps&lt;/strong&gt;: don&apos;t split something that can be said clearly in one step into multiple steps.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context pruning&lt;/strong&gt;: remove irrelevant tool results and stale conversation history from the context.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.6 Evaluation (Eval)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: traditional software can use unit tests — input 1+1, expect output 2, and if it&apos;s wrong, it&apos;s a Bug. An Agent has no &quot;standard answer&quot; — how do you know it did &quot;well&quot;?&lt;/p&gt;
&lt;p&gt;An Agent has no &quot;right or wrong,&quot; only &quot;good or bad.&quot; This means you need a mechanism to answer &quot;is my new version of the Agent better or worse than the last one?&quot; — without that mechanism, you can optimize all day and have no idea whether you&apos;re heading in the right direction. &lt;strong&gt;The Eval system is the marker of Agent engineering going from &quot;workshop&quot; to &quot;industry.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Mainstream evaluation methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Offline evaluation&lt;/strong&gt;: prepare a batch of test cases, run the Agent, and score by hand or with LLM-as-Judge&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Online evaluation&lt;/strong&gt;: collect real user feedback in production (thumbs up / down, dwell time, whether they keep following up)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM as a Judge&lt;/strong&gt;: use a stronger model as the judge — but watch out for its own biases (a tendency to score high, a preference for long answers, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Controlled experiments&lt;/strong&gt;: A/B Test, splitting the new and old versions to different users&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.7 These six things are an Agent engineer&apos;s true &quot;inner skill&quot;&lt;/h3&gt;
&lt;p&gt;To sum up —&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Context engineering&lt;/strong&gt;: maximize information density within a finite space&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory systems&lt;/strong&gt;: let the Agent remember things in layers, like a person&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool calling&lt;/strong&gt;: let the Agent &quot;act&quot; — and not run wild&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reliability&lt;/strong&gt;: switch from deterministic thinking to probabilistic thinking&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost control&lt;/strong&gt;: the money really does burn&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evaluation&lt;/strong&gt;: Agent optimization without Eval is all guesswork&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you can clearly articulate these six things in your résumé or interview, you&apos;re already ahead of 80% of applicants.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;A Few Final Words&lt;/h2&gt;
&lt;p&gt;If you&apos;ve read this far — thank you for taking the time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This document is free&lt;/strong&gt;, because I want to help everyone who wants to get into Agents. It will be updated periodically — roughly one version every 3–6 months, with &quot;incremental patches&quot; for major industry events. The version you&apos;re seeing is &lt;strong&gt;v1.0 (Updated: 2026-05-17)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But everyone&apos;s situation is different:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How your résumé should be rewritten — the document can&apos;t give specific paragraph-level advice;&lt;/li&gt;
&lt;li&gt;How your project should be pitched — the document can&apos;t give a &quot;problem — solution — result&quot; rewrite tailored to your specific project;&lt;/li&gt;
&lt;li&gt;How your learning pace should be set — the document can only give a generic three-stage plan, not a weekly plan calibrated to your starting point;&lt;/li&gt;
&lt;li&gt;What the company you&apos;re about to interview with might ask — the document can only give a four-dimension framework, not a question bank tailored to your résumé.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;If you need that kind of 1-on-1 specific help, I offer the following three tiers of service — all delivered by me personally, never outsourced, never mass-produced.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Detailed description of paid services&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;For the specific pricing of all services, please contact me&lt;/strong&gt; — the consultation itself is free, I&apos;ll first understand your situation and then judge which service suits you best. If none fits, I&apos;ll tell you straight that it&apos;s not a fit and won&apos;t push.&lt;/p&gt;
&lt;h4&gt;Service 1: Résumé revision (￥)&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Who it&apos;s for&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You already have a résumé and project experience, but you&apos;re not sure how to &quot;tell the story&quot; so the interviewer&apos;s eyes light up&lt;/li&gt;
&lt;li&gt;You have projects on your résumé but can&apos;t articulate &quot;problem — solution — result&quot;&lt;/li&gt;
&lt;li&gt;You want to pivot toward Agents, but you don&apos;t know how to retarget your old résumé&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What&apos;s included&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A detailed review of your résumé&lt;/li&gt;
&lt;li&gt;Revision suggestions &lt;strong&gt;down to the paragraph and sentence level&lt;/strong&gt; — not vague &quot;consider highlighting your strengths,&quot; but &quot;this paragraph should be rewritten as XXX&quot;&lt;/li&gt;
&lt;li&gt;Help reorganizing your project narrative — polishing scattered work into a story you &quot;can tell clearly in 5 minutes of an interview&quot;&lt;/li&gt;
&lt;li&gt;Keyword suggestions targeted at your goal direction (Agent engineering / LLM applications / Multi-Agent / RAG, etc.)&lt;/li&gt;
&lt;li&gt;One 30–60 minute 1-on-1 session to go over the revised version once more&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Service 2: 1-on-1 mock interview (￥￥)&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Who it&apos;s for&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;re already preparing for an Agent engineer role but lack real interview experience&lt;/li&gt;
&lt;li&gt;You&apos;ve debriefed your own projects, but you&apos;d like someone to professionally &quot;grill&quot; you on them once&lt;/li&gt;
&lt;li&gt;You&apos;re about to interview at a company you really want, and you&apos;d like to warm up in advance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What&apos;s included&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We communicate in advance about your résumé and target company&apos;s direction, and customize the question bank&lt;/li&gt;
&lt;li&gt;A complete interview simulation covering all four dimensions: foundational understanding + system design + engineering trade-offs + industry awareness&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Charged by time, with a 1-hour minimum&lt;/strong&gt; — 1 hour is 1 hour, 1.5 hours is 1.5 hours, with the price scaling linearly with duration&lt;/li&gt;
&lt;li&gt;Full audio / video recording (as you prefer)&lt;/li&gt;
&lt;li&gt;If resources worth a further look (papers, blogs, open-source projects) come up during the interview, I&apos;ll compile them for you afterward&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Service 3: Learning roadmap / onboarding coaching (￥￥￥)&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Who it&apos;s for&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;re a complete beginner, or have a foundation but lack a sense of direction, and want someone to systematically guide you for a while&lt;/li&gt;
&lt;li&gt;You tend to get stuck or give up when self-studying, and need external pacing, accountability, and Q&amp;#x26;A&lt;/li&gt;
&lt;li&gt;You want to hit a concrete goal within a fixed window (1–3 months), such as &quot;build a first Agent project I can actually show off&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What&apos;s included&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Onboarding assessment&lt;/strong&gt;: a 1-on-1 to understand your current foundation, goals, and available time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Customized learning roadmap&lt;/strong&gt;: a personalized weekly study plan tailored to your situation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weekly 1-on-1 Q&amp;#x26;A&lt;/strong&gt;: a 30–60 minute sync at a fixed time each week — reviewing last week&apos;s progress, answering questions, adjusting next week&apos;s plan&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project coaching&lt;/strong&gt;: I follow the project you&apos;re building throughout the coaching period + review it at key milestones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Final deliverable&lt;/strong&gt;: by the end of coaching, you&apos;ll have at least one complete Agent project you can put on your résumé, plus a complete retrospective document&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Typical coaching cycles&lt;/strong&gt;: 4 weeks / 8 weeks / 12 weeks — decided based on your goals and time.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;How to get in touch&lt;/h3&gt;
&lt;p&gt;Add me on WeChat &lt;div&gt;&lt;/div&gt;, with the note &lt;strong&gt;&quot;paid consulting&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Or through these other channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Personal website&lt;/strong&gt;: &lt;a href=&quot;https://www.joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href=&quot;https://github.com/joyehuang&quot;&gt;github.com/joyehuang&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;About future updates to this document&lt;/h3&gt;
&lt;p&gt;This document &lt;strong&gt;isn&apos;t a one-and-done deal&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Updated roughly every 3–6 months&lt;/strong&gt;, revised according to the latest industry developments&lt;/li&gt;
&lt;li&gt;Major industry events (a new major LLM version, a new protocol-layer standard) will get an &quot;incremental patch&quot;&lt;/li&gt;
&lt;li&gt;For readers who&apos;ve seen this document, all updated versions remain free&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;About feedback&lt;/h3&gt;
&lt;p&gt;If you have any opinions, suggestions, or spot any errors after reading this document, &lt;strong&gt;I&apos;d really love for you to tell me.&lt;/strong&gt; Through any channel — email, a comment on the site, a DM. Reader feedback is the single most important basis on which I revise this material.&lt;/p&gt;
&lt;p&gt;Types of feedback I especially welcome:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A concept you feel wasn&apos;t explained clearly enough&lt;/li&gt;
&lt;li&gt;A judgment you disagree with and want to discuss with me&lt;/li&gt;
&lt;li&gt;You followed the roadmap in practice and found some piece of advice didn&apos;t quite apply&lt;/li&gt;
&lt;li&gt;You worked out a good practice of your own that isn&apos;t in the document&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;A final blessing&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Build fast, learn faster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is my own blog&apos;s slogan, and it&apos;s my blessing to you.&lt;/p&gt;
&lt;p&gt;This document ends here — but your journey is only just beginning.&lt;/p&gt;
&lt;p&gt;If it helped you even a little, then it was worth it. And if you really do end up entering this line of work as an Agent engineer, I hope someday we cross paths at some AI company, in some open-source project, or under some GitHub Issue. When that day comes, remember to tell me — &quot;I read this document back then too.&quot;&lt;/p&gt;
&lt;p&gt;—— &lt;strong&gt;Joye&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Updated: 2026-05-17 · v1.0&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All rights reserved. Please contact the author for reprint permission.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>A 1h19m Agent Engineer Mock Interview: What We Asked</title><link>https://www.joyehuang.me/en/blog/20260512---agentmockinterview/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260512---agentmockinterview/post</guid><description>An 80-minute mock interview with a dev pivoting to Agent work. Every question, his answers, our feedback, and how I would have answered.</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This is a mock-interview retrospective. The candidate was a student from a 211 university, with two AI projects on his résumé: a multi-Agent healthy-eating assistant built on LangGraph, and a long-term memory engine for Agents. Another interviewer, W, and I interviewed him together for 80 minutes. Afterwards I felt this session was worth writing up as a blog post — not because the candidate did especially well or especially badly, but because it so completely exposed the problems with the mainstream &quot;pad your résumé with AI bootcamp projects&quot; path, while also walking through what an Agent engineer interview should test in 2026.&lt;/p&gt;
&lt;p&gt;This is going to be a long piece. I&apos;ll write down every question we asked, the candidate&apos;s answers at the time, our feedback, and &quot;how I would have answered.&quot; If future mock interviews turn out to be valuable, I&apos;ll write those up too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;A note up front: why I&apos;m writing this&lt;/h2&gt;
&lt;p&gt;Lately I&apos;ve been helping my mentor screen résumés for a full-stack Agent development internship and running first-round interviews, so I&apos;ve interviewed quite a few candidates; I&apos;ve also been booked by some followers for paid mock interviews. This was one of them. The candidate comes from a backend background and wants to pivot into Agent development; he listed two projects on his résumé. By the end, the overall verdict W and I reached was: &lt;strong&gt;learning Agent development by tweaking a bootcamp / open-source project makes it very hard for a candidate to form their own thinking — there&apos;s no depth, and one question from the interviewer makes it fall apart.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This isn&apos;t a personal failing of this particular candidate. Résumés produced by bootcamps, contract gig projects, or &quot;grab an open-source repo off GitHub and tweak it&quot; are pretty much all in this state. So this blog post isn&apos;t here to mock one specific résumé — it&apos;s an honest attempt to discuss: &lt;strong&gt;if you want to be an Agent engineer, how should you prepare your projects, how should you answer interview questions, and what do you need to think through before writing a single line of your résumé.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. The problem with the projects themselves: what real problem did you solve?&lt;/h2&gt;
&lt;p&gt;The candidate&apos;s two projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Project one&lt;/strong&gt;: an AI health assistant, with a diet-recommendation module underneath it. LangGraph orchestration, a Router + multi-Agent layered design; after intent recognition, it dispatches to a Text2SQL Agent / RAG Agent / knowledge-graph Agent, then aggregates. The retrieval layer has three hybrid pipelines including GraphRAG. A three-tier memory module. Fine-tuned on Qwen3-8B.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project two&lt;/strong&gt;: a long-term memory engine for Agents. Three-stage extraction (summary → entities → relations), written into ChromaDB + Neo4j; hybrid graph-vector retrieval (vector recall + BFS expansion + semantic re-ranking); memory decay based on the Ebbinghaus forgetting curve; at write time, it does semantic-similarity grading, contradiction detection, and similarity merging.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It all sounds very much the part. But after listening, W asked just one question that made the entire project collapse (this is aimed at &lt;strong&gt;project one&lt;/strong&gt; — its input is only two kinds: unstructured recipe content, or a structured nutrition table):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If it were me, I could just solve this with Doubao. Why does this have to be built at all?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Why this question is so lethal&lt;/h3&gt;
&lt;p&gt;When hiring, what an interviewer wants to see is &quot;you identified a real problem → picked the right technology → solved it better than the off-the-shelf option.&quot; &lt;strong&gt;A project&apos;s reason to exist = a real problem × the inadequacy of off-the-shelf solutions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I genuinely suggest finding projects from two directions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Start from a real need around you, something you personally ran into&lt;/strong&gt; — if you can clearly explain &quot;why I built this,&quot; the whole project&apos;s narrative stands on its own.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deeply use an open-source Agent (e.g. Hermes), find its shortcomings, and do a transformative second-pass development&lt;/strong&gt; — this is harder, but the value is extremely high.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that we have AI, &lt;strong&gt;the cost of building a project from scratch has dropped to almost nothing&lt;/strong&gt; — there&apos;s no need to copy.&lt;/p&gt;
&lt;p&gt;The candidate&apos;s project took the opposite path: first decide to use LangGraph / multi-Agent / GraphRAG / hybrid graph-vector retrieval / fine-tuning, then find a scenario to stuff all those technologies into. &quot;AI diet recommendation&quot; is a scenario that Doubao, ChatGPT, and Kimi solve directly out of the box, so all the architectural complexity he built had no corresponding payoff.&lt;/p&gt;
&lt;h3&gt;How to fix it&lt;/h3&gt;
&lt;p&gt;W&apos;s concrete advice was: &quot;change the soup but not the medicine&quot; — you can keep the tech stack, but the scenario has to change to one that &lt;strong&gt;genuinely needs an Agent&lt;/strong&gt;. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deep-research type&lt;/strong&gt; (the DeepResearch kind: multi-step retrieval, cross-source information integration, requires planning)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multimodal content creation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Complex task automation in a vertical domain&lt;/strong&gt; (not something QA can solve)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&apos;t title the project on your résumé &quot;AI Health Assistant&quot; — that name itself is telling the interviewer &quot;this is a scenario that doesn&apos;t need an Agent.&quot; &lt;strong&gt;A scenario that genuinely needs an Agent also gives you a lot more to talk about in the interview&lt;/strong&gt; — architecture, decisions, the pitfalls you hit, the improvements you made; there&apos;s plenty to discuss.&lt;/p&gt;
&lt;h3&gt;Advice for every Agent job seeker&lt;/h3&gt;
&lt;p&gt;Before writing up a project, ask yourself three questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Can this scenario be solved by just chatting directly with ChatGPT / Doubao / Claude? If yes, change the scenario.&lt;/li&gt;
&lt;li&gt;What substantive benefit does the multi-Agent architecture I used give me over a single Agent? If you can&apos;t articulate it, switch to a single Agent.&lt;/li&gt;
&lt;li&gt;For every tech choice I made (vector DB, graph DB, Redis, fine-tuning, RAG), can I clearly explain &quot;why this one and not something else&quot;? If you can&apos;t, either delete it or go do the homework.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;2. All those &quot;why&quot; questions we kept asking&lt;/h2&gt;
&lt;p&gt;Throughout the interview, the single most common category of question W and I asked was &quot;&lt;strong&gt;why did you choose X instead of Y&lt;/strong&gt;.&quot; This is the Agent-role interviewer&apos;s favorite question type, because in one sentence it separates &quot;actually used it, hit the pitfalls&quot; from &quot;read a blog and copied it onto a résumé.&quot;&lt;/p&gt;
&lt;p&gt;The candidate was almost completely wiped out on this category. Below I&apos;ll expand each &quot;why&quot; question.&lt;/p&gt;
&lt;h3&gt;2.1 Why Milvus / ChromaDB? What&apos;s the difference between them?&lt;/h3&gt;
&lt;p&gt;The candidate&apos;s answer: &quot;Milvus is for larger data volumes, ChromaDB is for smaller data volumes. I don&apos;t really know much about the others.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: the vector DB is the core storage of any RAG / Memory project, and the choice directly determines performance, cost, and operational complexity. The interviewer isn&apos;t asking this to hear you recite specs — they want to see &quot;what technical comparisons you did for your project.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;: at minimum you should be able to name a few dimensions of comparison —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deployment form&lt;/strong&gt;: Milvus is an industrial-grade distributed deployment; ChromaDB starts single-node and can be used purely embedded&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ecosystem&lt;/strong&gt;: Milvus has a full SDK / monitoring / ops toolchain; ChromaDB is simple but has a thin ecosystem&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alternatives&lt;/strong&gt;: pgvector (essentially a Postgres extension, lets you cut out a whole piece of infrastructure), Qdrant, Weaviate, Pinecone&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lighter options&lt;/strong&gt;: sqlite-vec / sqlite-vss also support vector retrieval — for a personal project&apos;s dataset, isn&apos;t SQLite enough?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A higher-scoring answer is to challenge the choice itself directly: &quot;Honestly, for the data volume in my project, pgvector is plenty — there&apos;s no need to spin up a separate vector DB.&quot; That&apos;s the &quot;engineering judgment&quot; the interviewer wants to hear, rather than &quot;I just happened to pick this technology, or the project already used it.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The actual direction to improve&lt;/strong&gt;: I don&apos;t need you to explain the index details of HNSW versus IVF, but I want to hear that you &lt;strong&gt;did the comparison and gave it some thought&lt;/strong&gt; before choosing this technology. Just go have an AI walk you through a comparison of the mainstream vector DBs and roughly know it. I&apos;ll also recommend the notes section of my blog, &lt;a href=&quot;https://joyehuang.me/notes&quot;&gt;joyehuang.me/notes&lt;/a&gt; — there&apos;s a lot of relatively fragmentary knowledge there that I&apos;ve accumulated over time, and one of them happens to be a comparison of vector databases.&lt;/p&gt;
&lt;h3&gt;2.2 Does each Agent in your multi-Agent setup use a different model?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;No, they all use one model, Qwen.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: in a multi-Agent system, &lt;strong&gt;the model choice should be split by each Agent&apos;s responsibility&lt;/strong&gt;. A simple classification task like intent recognition uses a small / cheap model, a complex reasoning task uses a large model, and long-text summarization uses a long-context model.&lt;/p&gt;
&lt;p&gt;To put it more sharply: &lt;strong&gt;if your multi-Agent is essentially a workflow orchestration with no communication between Agents, and you don&apos;t do model tiering either, then what is the point of this multi-Agent?&lt;/strong&gt; Conversely, if you do model tiering, you can at least name a few benefits:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cost control&lt;/strong&gt; — this is a must-consider for any production project&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capability matching&lt;/strong&gt; — for multimodal scenarios you can plug in the Gemini family, for code scenarios Claude, for domestic-compliance scenarios Qwen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It shows you&apos;ve tried quite a few models&lt;/strong&gt; — at least you roughly know what each model is good at&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A lot of people feel that &quot;I used multiple models&quot; is a mediocre answer, but I actually really endorse it — it shows you genuinely think about problems from a production perspective.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;: give a concrete scenario, e.g. &quot;intent recognition uses Qwen3-7B because the latency requirement is low and the task is simple; the final aggregated output uses Claude Sonnet or GPT-4 because it needs language-organization ability; background async summarization uses the cheap Qwen-Turbo because there&apos;s no real-time requirement.&quot;&lt;/p&gt;
&lt;p&gt;This connects to the &quot;Agent cost control&quot; topic we discussed later — I&apos;ll expand on it below.&lt;/p&gt;
&lt;h3&gt;2.3 Is there actually any &quot;communication&quot; between your Agents?&lt;/h3&gt;
&lt;p&gt;What I asked: &quot;Is there any communication between your Agents? Besides the aggregation step, do they talk to each other at all?&quot;&lt;/p&gt;
&lt;p&gt;Candidate: &quot;There&apos;s basically no communication, it&apos;s just a workflow, orchestrated ahead of time.&quot;&lt;/p&gt;
&lt;p&gt;Me: &quot;Then this isn&apos;t really multi-Agent.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: the industry has a shared definition of &quot;multi-Agent&quot; — &lt;strong&gt;Agents need to make autonomous decisions, call each other, and communicate with each other.&lt;/strong&gt; A fixed router that dispatches a task to a few independent processors and then aggregates is called a &lt;strong&gt;Workflow&lt;/strong&gt;, not Multi-Agent. These two terms basically settled after Anthropic&apos;s &lt;a href=&quot;https://www.anthropic.com/research/building-effective-agents&quot;&gt;Building Effective Agents&lt;/a&gt; post.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;: honestly admit this is a Workflow, then discuss &quot;how I&apos;d refactor it into a real multi-Agent system&quot; — e.g. letting an Agent call other Agents back, raise follow-up questions, and collaborate to complete a complex task.&lt;/p&gt;
&lt;p&gt;Going further, you can reflect: &quot;Actually my scenario doesn&apos;t need multi-Agent; a single Agent + tool calls would solve it.&quot; This kind of self-correction ability is worth far more than stubbornly insisting that what you built is multi-Agent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two things to remember for interviews&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Don&apos;t bluff.&lt;/strong&gt; If you&apos;re asked about something you&apos;re not familiar with, admit it; bluffing just gets you fished to death.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&apos;t insist that a bootcamp project is your own work.&lt;/strong&gt; The interviewer knows perfectly well whether you wrote the project yourself or copied it from a bootcamp, and if you keep insisting after being seen through, it escalates from &quot;the project lacks depth&quot; to &quot;an integrity problem.&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.4 The pros and cons of single-Agent vs. multi-Agent / Router orchestration?&lt;/h3&gt;
&lt;p&gt;I followed up: &quot;If you refactored this project into a single Agent, how would you design it? And what are the respective pros and cons of a single Agent versus your current orchestration?&quot;&lt;/p&gt;
&lt;p&gt;The candidate gave some stuff about &quot;prompt isolation, focusing on its own task,&quot; but didn&apos;t hit the point.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages of multi-Agent / Router orchestration&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Context isolation — each Agent only sees the content relevant to its own task and isn&apos;t distracted by irrelevant information&lt;/li&gt;
&lt;li&gt;Each subtask can have its prompt optimized separately and its model swapped separately&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parallelism&lt;/strong&gt; — independent tasks can run concurrently&lt;/li&gt;
&lt;li&gt;Good observability, you know which step went wrong — but this one &lt;strong&gt;requires you to actively design a whole observability system&lt;/strong&gt;, otherwise when something goes wrong you&apos;re still flying blind. If your project did &lt;strong&gt;replay&lt;/strong&gt; (replayable debugging), that&apos;s genuinely a big bonus&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages of multi-Agent / Router orchestration&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Higher overall latency (every extra call is another network round trip)&lt;/li&gt;
&lt;li&gt;Token consumption multiplies (context has to be passed between Agents)&lt;/li&gt;
&lt;li&gt;The routing itself can be wrong (if intent recognition is wrong, everything is wrong)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Advantages of a single Agent&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple, low latency, low cost&lt;/li&gt;
&lt;li&gt;The model sees all the context itself and can make more global judgments&lt;/li&gt;
&lt;li&gt;Modern large models&apos; function calling is already strong enough that a single Agent is enough for most scenarios&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boosted by Skills&lt;/strong&gt; — the single-Agent + Skills combo basically became the new paradigm after Claude Code (I&apos;ll expand on this in 3.5)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages of a single Agent&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The context easily explodes&lt;/li&gt;
&lt;li&gt;The model tends to lose early information in long contexts&lt;/li&gt;
&lt;li&gt;Cramming all responsibilities into one prompt easily turns it into a pile of spaghetti&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember one 2026 trend: &lt;strong&gt;the industry as a whole is regressing from &quot;fancy multi-Agent orchestration&quot; back toward &quot;a single strong Agent + good tools + good context engineering.&quot;&lt;/strong&gt; Claude Code, Cursor Agent, and Cline are all this paradigm.&lt;/p&gt;
&lt;h3&gt;2.5 How did you compute the 90.6% intent-recognition accuracy?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;I built about 200 questions and compared them against the labeled answers.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: every &quot;90%+ accuracy&quot; on a résumé will get questioned. &lt;strong&gt;An Agent project with no evaluation system is just bluffing.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;: you need to clearly explain —&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How was the test set built? What cases does it cover? What&apos;s the distribution? &lt;strong&gt;Why did you pick these cases? Do these cases reflect the ability you want to test?&lt;/strong&gt; — this is the easiest thing to get probed on; &quot;I just made up 200&quot; and &quot;I covered 5 common intent categories + 3 boundary cases + 2 adversarial samples&quot; are two completely different leagues&lt;/li&gt;
&lt;li&gt;What&apos;s the evaluation metric? Just accuracy? Or do you have precision / recall / F1?&lt;/li&gt;
&lt;li&gt;How is the evaluation automated? After you change a prompt, how do you regression-test?&lt;/li&gt;
&lt;li&gt;How are boundary cases handled? When it can&apos;t recognize something, how do you fall back?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The candidate mentioned that &quot;when it can&apos;t recognize something it falls back to Text2SQL&quot; — that&apos;s a bonus point, but he didn&apos;t elaborate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Direction to improve&lt;/strong&gt;: go look at the industry eval tools — LangSmith, Braintrust, Promptfoo — run one yourself, and understand what an eval platform actually solves.&lt;/p&gt;
&lt;h3&gt;2.6 Why Redis?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;Because LangGraph node state can be stored in Redis, and Redis supports TTL for memory expiration.&quot;&lt;/p&gt;
&lt;p&gt;W&apos;s rebuttal was direct and precise, roughly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If it&apos;s just for TTL, you shouldn&apos;t use Redis. Redis&apos;s TTL is designed for high-concurrency online business. &lt;strong&gt;User data is the most precious asset in the whole system — expiring a memory shouldn&apos;t mean deleting it, it should mean archiving it.&lt;/strong&gt; Redis&apos;s real use is state consistency across service nodes — caching, distributed locks, session-level state isolation.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: this is a very typical case of &quot;piling on technology without thinking.&quot; Redis is an old friend of backend developers; written on a résumé it looks professional, but using it in the wrong scenario instead exposes that you don&apos;t understand Redis&apos;s real positioning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;: reasonable uses of Redis in an Agent project include —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Caching&lt;/strong&gt;: caching model responses, caching vector-retrieval results&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distributed locks&lt;/strong&gt;: locking when multiple Agents concurrently write the same memory&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session-level state isolation&lt;/strong&gt;: synchronizing session state when a user is logged in on web and app at the same time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt;: API call quota management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Temporary checkpoints&lt;/strong&gt;: runtime state snapshots for LangGraph (the candidate got this one, but didn&apos;t emphasize the &quot;temporary&quot; part)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The memory data itself should be stored in persistent storage — a vector DB, graph DB, or relational DB all work. &lt;strong&gt;Never treat &quot;a user&apos;s long-term memory&quot; as cache data that can be automatically evicted.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;2.7 PostgreSQL vs MySQL — what&apos;s the biggest difference?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;I haven&apos;t really compared them; PG is enterprise-grade, fairly powerful, and you can add pgvector to use it as a vector DB.&quot;&lt;/p&gt;
&lt;p&gt;W&apos;s expansion was very practical:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;These days you basically don&apos;t use MySQL for a new project. The moment pgvector is in, it pretty much kills Milvus; jsonb is friendlier for storing JSON; geospatial and time-series support is good; in some scenarios it can replace Elasticsearch (though for tokenizer scenarios you still have to use ES).&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: this is a substantive shift in backend technology choices in 2025–2026. If your résumé says &quot;familiar with MySQL&quot; but you don&apos;t know Postgres&apos;s standing in new projects now, your understanding is out of date.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Direction to improve&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spin up a new project with PostgreSQL and run RAG with pgvector&lt;/li&gt;
&lt;li&gt;Learn about full-stack solutions built on Postgres like Supabase, and understand why Postgres has captured the &quot;default database of choice for small projects&quot; niche&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.8 Why use Neo4j instead of Redis to store graphs? And why not use Neo4j to store Agent state?&lt;/h3&gt;
&lt;p&gt;This stretch was W fishing. While explaining Redis&apos;s uses, the candidate unconsciously described &quot;graph storage&quot; as a Redis feature, and was immediately caught.&lt;/p&gt;
&lt;p&gt;The lesson: &lt;strong&gt;don&apos;t give a divergent answer in a domain you&apos;re not familiar with.&lt;/strong&gt; When asked about Redis, just honestly describe Redis&apos;s reasonable uses; don&apos;t, to look knowledgeable, expand into graphs, vectors, state-machine management, and other areas Redis isn&apos;t good at.&lt;/p&gt;
&lt;p&gt;A more universal rule: &lt;strong&gt;every single point on your résumé is something you need to understand thoroughly, otherwise don&apos;t write it.&lt;/strong&gt; As an interviewer, if you wrote it, I&apos;ll ask; if you can&apos;t answer, then it&apos;s &quot;well, yeah, not great.&quot;&lt;/p&gt;
&lt;h3&gt;2.9 Why fine-tune Qwen3-8B, when the upstream data used Kimi K2.5?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;Kimi K2.5 was used to build the QA-pair dataset, generating Q&amp;#x26;A pairs from different angles.&quot;&lt;/p&gt;
&lt;p&gt;W&apos;s critique:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Kimi K2.5 is definitely stronger than Qwen3-8B on benchmarks. &lt;strong&gt;Using a stronger model to generate data to fine-tune a weaker model is logically sound&lt;/strong&gt; (the data-distillation idea), but your scenario design here has a problem — you should write: use Claude Sonnet 4.6 + Kimi K2.6 to de-identify user privacy data and fill in multimodal training data, then do LoRA fine-tuning on the latest Qwen3 version (e.g. Qwen3.6-235B) on Alibaba&apos;s Bailian platform. Written that way, it makes sense.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: the justification for fine-tuning = data quality × task fit × cost. If you can&apos;t explain why you fine-tuned, don&apos;t write fine-tuning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to actually write it&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;For [specific task] in [vertical domain], used Claude Sonnet 4.6 and Kimi K2.6 to clean, de-identify, and complete multimodal data for the dataset, building a high-quality training set, and did LoRA fine-tuning on Qwen3-X on Alibaba&apos;s Bailian platform, improving [specific metric] by X% compared to directly calling a general-purpose model.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;W and I also threw in an offhand gripe: &lt;strong&gt;Qwen3-8B is way too common in bootcamp projects — I get PTSD just seeing it.&lt;/strong&gt; If you want to make the interviewer&apos;s eyes light up, at least use a latest model version from 2026.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. Core Agent knowledge: context engineering, memory, Skills, MCP&lt;/h2&gt;
&lt;h3&gt;3.1 Have you designed any context engineering?&lt;/h3&gt;
&lt;p&gt;The candidate described some things he&apos;d done: a 128K context window; when it reaches the 75% threshold, a sliding window kicks in to keep the last 5 turns of dialogue; after the session ends, a large model summarizes the history and writes it into long-term memory.&lt;/p&gt;
&lt;p&gt;My assessment: &lt;strong&gt;writing &quot;context management&quot; as one line on your résumé is empty fluff&lt;/strong&gt; — because it&apos;s the default operation of every Agent project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to write it so it has substance&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Don&apos;t write &quot;did context management,&quot; write —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How many layers of context I designed (system layer, task layer, user layer, session layer)&lt;/li&gt;
&lt;li&gt;When each layer gets triggered&lt;/li&gt;
&lt;li&gt;What trigger I use to decide to write to long-term memory / summarize old context / engage the sliding window&lt;/li&gt;
&lt;li&gt;How I handle &quot;noise&quot; in the context (irrelevant messages, user slips of the tongue, contradictory information)&lt;/li&gt;
&lt;li&gt;How I do prefix-caching-friendly context design (I&apos;ll cover this separately below)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.2 Writing to long-term memory: if a user says &quot;I feel like spicy food today,&quot; should it be recorded or not?&lt;/h3&gt;
&lt;p&gt;I asked:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;When a user says &apos;I like spicy food&apos; today, how does that point get written into memory? Is it an explicit user call, or the Agent&apos;s own judgment? And it&apos;s possible he&apos;s just in a bad mood today and wants something spicy — that&apos;s a short-term preference, which is different from &apos;I&apos;m someone who eats spicy food long-term.&apos; How do you design the Agent to distinguish them?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The candidate couldn&apos;t answer, and admitted &quot;this was done pretty crudely.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: this is one of the most core design questions in a Memory system. &lt;strong&gt;&quot;What to record, what not to record, how long to keep it, how to override it&quot; is the soul of a memory engine.&lt;/strong&gt; If your résumé lists a Memory project but you can&apos;t explain these questions, the whole project&apos;s credibility collapses.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Memory writing needs to consider —&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Factual vs. derived vs. preference&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Factual: &quot;My name is Joye, I study in Melbourne.&quot; → write directly, high confidence.&lt;/li&gt;
&lt;li&gt;Derived: &quot;I often work overtime on weekends.&quot; → no need to write; it can be derived from historical sessions.&lt;/li&gt;
&lt;li&gt;Preference: &quot;I like spicy food.&quot; → needs to be written, but tagged with &lt;strong&gt;confidence and recency&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Short-term vs. long-term&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Short-term preference (&quot;want spicy today&quot;) → write to session-level memory, decay or discard after the session ends.&lt;/li&gt;
&lt;li&gt;Long-term preference (mentioned multiple times, a stable preference) → promote to long-term memory.&lt;/li&gt;
&lt;li&gt;This promotion mechanism can be based on &quot;number of occurrences + time span.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Contradiction detection&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The user has said both &quot;I like spicy food&quot; and &quot;I can&apos;t eat spicy food&quot; — how do you handle it?&lt;/li&gt;
&lt;li&gt;Timestamps + context to judge which is the current fact.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Write triggers&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explicit trigger: &quot;Please remember that I...&quot;&lt;/li&gt;
&lt;li&gt;Implicit trigger: session end / message count reaches a threshold / a user statement of fact is detected&lt;/li&gt;
&lt;li&gt;Async trigger: a cheap model summarizes and extracts from the session in the background&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3.3 How is Memory used? Where in the system prompt is it placed?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;It should be added to the system prompt.&quot; Then he said &quot;toward the back is better, because the model&apos;s attention mechanism is more sensitive to later content.&quot;&lt;/p&gt;
&lt;p&gt;I corrected him immediately: &lt;strong&gt;that&apos;s exactly backwards — it goes at the very front, mainly for prefix caching.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: this is an engineering detail a 2026 Agent engineer must know.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prefix caching&lt;/strong&gt;: Anthropic / OpenAI / domestic model providers all support caching the prefix of a prompt; on a cache hit, the token price is much cheaper (with Anthropic, cache writes are more expensive than normal and cache reads are cheaper than normal).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Design principle&lt;/strong&gt;: put &lt;strong&gt;the least-changing content at the very front&lt;/strong&gt; (system prompt → long-term memory → tool descriptions → conversation history → current query). That way, most of the time only the last segment changes, and the prefix can all hit the cache.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you put memory at the end&lt;/strong&gt;, every memory update breaks the cache for the entire prefix, and token cost skyrockets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Follow-up question&lt;/strong&gt;: how often should your memory update?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update too frequently → too many prefix-cache misses → cost skyrockets&lt;/li&gt;
&lt;li&gt;Update too slowly → the user feels the Agent &quot;can&apos;t remember things&quot; → poor experience&lt;/li&gt;
&lt;li&gt;This trade-off needs to be clearly explained in your project&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.4 How many versions has the Memory system of OpenAI / Claude / open-source Agents gone through? Pros and cons of each?&lt;/h3&gt;
&lt;p&gt;W asked this, and the candidate couldn&apos;t answer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;: this gauges whether you&apos;re &quot;someone who genuinely follows this field.&quot; Someone researching Agents / Memory couldn&apos;t possibly have not seen these two companies&apos; product iterations, or the approaches of the mainstream open-source Agents.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt;: at minimum you should be able to name —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenAI&apos;s Memory evolution&lt;/strong&gt;: from the earliest &quot;Saved memories&quot; (explicit user trigger, pure list storage) → automatic memory (the model judges what to write on its own) → cross-session memory (&quot;reference chat history&quot;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anthropic / Claude&apos;s direction&lt;/strong&gt;: Claude&apos;s Memory is implemented via the Skills system and the conversation_search tool; structurally it&apos;s closer to &quot;tool calling + explicit storage&quot; than to automatic writing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open-source CLI Agents&apos; approaches&lt;/strong&gt;: represented by Hermes, OpenCode, OpenClaude, Aider — basically all use Markdown files as the memory carrier (memory.md / user.md), and the Agent restores context by explicitly reading them. The biggest advantage of this route is that &quot;memory is fully readable, editable, and versionable.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Direction to improve&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Actually use these companies&apos; products for a while and feel the differences firsthand. If you don&apos;t use them, at least learn about them through blogs or explainer videos — to prove you&apos;re genuinely curious about Agents&lt;/li&gt;
&lt;li&gt;Read &lt;a href=&quot;https://docs.claude.com&quot;&gt;Claude&apos;s Skills documentation&lt;/a&gt; and Anthropic&apos;s article on &lt;a href=&quot;https://www.anthropic.com/research/building-effective-agents&quot;&gt;Building Effective Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow the code of open-source CLI Agents like Hermes / OpenCode / OpenClaude / Aider&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.5 The relationship between Skills, MCP, and Function Calling?&lt;/h3&gt;
&lt;p&gt;W&apos;s question; the original wording was &quot;Skill plus MCP plus a CLI,&quot; but the candidate hadn&apos;t heard of CLI-type tools, so it focused on Skills and MCP.&lt;/p&gt;
&lt;p&gt;The candidate answered reasonably well: MCP provides data-source connections, and Skill teaches the model how to use that data to complete a specific task; the two are complementary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt; (more complete):&lt;/p&gt;
&lt;p&gt;| | What problem it solves | Form | Example |
|--|--|--|--|
| &lt;strong&gt;Function Calling&lt;/strong&gt; | Gives the model executable capability | A single function definition (schema + implementation) | &lt;code&gt;get_weather(city)&lt;/code&gt; |
| &lt;strong&gt;MCP&lt;/strong&gt; | Standardizes the &quot;model ↔ tool/data-source&quot; connection protocol | An MCP server exposing a set of tools / resources | Asana MCP, GitHub MCP |
| &lt;strong&gt;Skills&lt;/strong&gt; | Gives the model a programmatic guide on &quot;how to complete a class of task&quot; | A folder (SKILL.md + resources) | docx skill, pdf skill |
| &lt;strong&gt;CLI tools&lt;/strong&gt; (Lark CLI / Playwright / OpenCLI) | Lets the model operate the real world via the command line | Shell commands | &lt;code&gt;lark message send ...&lt;/code&gt; |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key insights&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MCP and Skill are &lt;strong&gt;complementary&lt;/strong&gt;: MCP provides data, Skill provides methodology.&lt;/li&gt;
&lt;li&gt;Skill&apos;s biggest advantage is &lt;strong&gt;turning things into SOPs / processes&lt;/strong&gt;: encoding domain experts&apos; best practices into a guide the model can read.&lt;/li&gt;
&lt;li&gt;Skill uses &lt;strong&gt;Progressive Disclosure&lt;/strong&gt;: the first layer only loads the skill&apos;s metadata (name + description); only after a hit does it load the full content, avoiding context explosion.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.6 How does an Agent &quot;perceive&quot; that a Skill exists?&lt;/h3&gt;
&lt;p&gt;A detail question from W; the candidate answered vaguely. The concrete mechanism is —&lt;/p&gt;
&lt;p&gt;The skill&apos;s metadata (name + description) is injected into the tool list in the system prompt (usually the tool-description area). At each decision step, the model sees this lightweight directory and judges whether the current task needs a particular skill. If it does, the model actively calls a &quot;read skill content&quot; tool (e.g. &lt;code&gt;view SKILL.md&lt;/code&gt;) to load the full skill content into context.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why it&apos;s designed this way&lt;/strong&gt;: to avoid cramming all skills&apos; full content into the context at once — a user might have dozens of skills, each several thousand words; stuffing them all in would blow up the prompt. Progressive disclosure is one of the core ideas of context engineering.&lt;/p&gt;
&lt;h3&gt;3.7 Is there an install limit for Skills / MCP?&lt;/h3&gt;
&lt;p&gt;Candidate: &quot;There&apos;s definitely a limit. Too many skills make the tool list very large, and the model&apos;s selection precision drops.&quot;&lt;/p&gt;
&lt;p&gt;He got this one. To add to it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Products like Claude Code have a soft limit on the number of skills (usually a few dozen), precisely because loading the metadata into the system prompt makes it bloat.&lt;/li&gt;
&lt;li&gt;The drop in selection precision also exists in tool calling (&quot;too many tools causes hallucinated calls&quot;).&lt;/li&gt;
&lt;li&gt;The solution: &lt;strong&gt;tiered loading&lt;/strong&gt; (dynamically loading the relevant subset of skills by scenario).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;s worth specifically mentioning the &lt;strong&gt;tool_search&lt;/strong&gt; mechanism in Claude Code — it essentially turns the &quot;tool/skill list&quot; itself into a searchable index: by default the model doesn&apos;t see the full definitions of all tools, and when it needs one, it queries by keyword via &lt;code&gt;tool_search&lt;/code&gt; and loads on demand. This is a further generalization of progressive disclosure along the &quot;tool dimension,&quot; and it&apos;s a paradigm very much worth borrowing in current Agent design.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. How an Agent controls cost&lt;/h2&gt;
&lt;p&gt;W&apos;s question. Candidate: &quot;You have to consider the number of large-model calls and merge some steps together.&quot;&lt;/p&gt;
&lt;p&gt;The two of us griped on the spot: &lt;strong&gt;an answer like &quot;reduce the number of calls&quot; is the same as &quot;I want to spend a bit less each month&quot; — that&apos;s an outcome, not a method.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How you should answer&lt;/strong&gt; (this section is the part of the interview I personally think is most worth writing down):&lt;/p&gt;
&lt;h3&gt;1. Prefix-caching-friendly context design&lt;/h3&gt;
&lt;p&gt;As described above. Put the least-changing content at the front so the cache hits as often as possible.&lt;/p&gt;
&lt;p&gt;Concrete actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Put the system prompt, long-term memory, and tool descriptions at the front&lt;/li&gt;
&lt;li&gt;Put the current query and the latest message at the end&lt;/li&gt;
&lt;li&gt;Don&apos;t update memory too frequently — every update invalidates the prefix&lt;/li&gt;
&lt;li&gt;Evaluate your model provider&apos;s cache billing policy: Anthropic is &quot;explicit checkpoint + write expensive, read cheap&quot;; OpenAI / Gemini auto-cache&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Tiered model usage&lt;/h3&gt;
&lt;p&gt;Use a cheap small model for simple tasks (intent recognition, classification, summarization), and a large model for complex reasoning. This is why &quot;all Agents using the same Qwen3-8B&quot; is a big problem.&lt;/p&gt;
&lt;h3&gt;3. Reduce the number of Agent steps&lt;/h3&gt;
&lt;p&gt;An Agent&apos;s token cost grows &lt;strong&gt;exponentially&lt;/strong&gt; — every extra step means the entire conversation history is sent as input again.&lt;/p&gt;
&lt;p&gt;Concrete actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&apos;t split into two steps what can be done in one&lt;/li&gt;
&lt;li&gt;Tool design should be &quot;wide-aperture&quot; — one tool solves a class of problems; don&apos;t make a separate tool for every fine-grained task&lt;/li&gt;
&lt;li&gt;Make the Plan phase as complete as possible, avoiding &quot;think as you go&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. Context pruning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If an old tool-call result has already been used, delete it from the history (keep a summary)&lt;/li&gt;
&lt;li&gt;For file-type content, keep only the diff&lt;/li&gt;
&lt;li&gt;Use a tool to &quot;read on demand&quot; for large blocks of irrelevant context; don&apos;t stuff them into the prompt by default&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. Rate-limiting failed retries&lt;/h3&gt;
&lt;p&gt;Agents auto-retry on failure. If you don&apos;t limit the retry count + don&apos;t do exponential backoff, one bug can blow up your bill.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. AI coding engineering practice: how do you write code and use AI?&lt;/h2&gt;
&lt;p&gt;W&apos;s question: &lt;strong&gt;&quot;What AI coding techniques did you use while building these projects?&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The candidate answered: &quot;I generally use Claude Code to help me write or read code.&quot;&lt;/p&gt;
&lt;p&gt;The answer W was hoping for:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I&apos;d build a doc tree (project index) for the project, write AGENTS.md / CLAUDE.md / Cursor rules so the Agent doesn&apos;t re-explore problems it&apos;s already explored. I&apos;d put the best practices for common frameworks (PostgreSQL, FastAPI, etc.) under .claude/skills/ as references.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why this question matters&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;What we care about more is how you did things in between. The &apos;results&apos; part on everyone&apos;s résumé is much of a muchness — everyone uses AI coding, everyone tweaks an open-source project, and the résumés all look alike. &lt;strong&gt;What truly distinguishes candidates is the process.&lt;/strong&gt;&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This holds for every job seeker in the AI era&lt;/strong&gt;: when AI drives the cost of &quot;writing code&quot; way down, your differentiation has to show up in —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How do you use AI tools?&lt;/li&gt;
&lt;li&gt;What kind of workflow have you established?&lt;/li&gt;
&lt;li&gt;How do you get AI tools to keep producing high-quality output in your project?&lt;/li&gt;
&lt;li&gt;How are your AGENTS.md / Skills / Memory designed?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Beyond coding scenarios, how else do you use AI?&lt;/strong&gt; — this is a great extension question. I don&apos;t mean &quot;asking GPT to do your homework,&quot; but rather things like: using Hermes to manage your schedule, using cronjob + Agent to push the AI world&apos;s hot topics to yourself every day, using an AI workflow to auto-edit videos, and so on. People who can show this are clearly a notch closer to the industry than those who&apos;ve &quot;only used Cursor.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;6. The macro talk: how we view Agent development and this industry&lt;/h2&gt;
&lt;p&gt;In the last stretch of the interview, W and I gave the candidate some more macro stuff. This part is valuable for everyone who wants to break into the field.&lt;/p&gt;
&lt;h3&gt;6.1 Don&apos;t pile on technology — solve problems&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I&apos;ve interviewed a lot of people, and they love to pile on technology — Redis, RAG, vector DBs, knowledge graphs, fine-tuning, all heaped together. Then for every technology written on the résumé, they can&apos;t answer &apos;why you used it.&apos;&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is the most common problem for Agent job seekers in 2026.&lt;/strong&gt; Bootcamps, contract gig projects, and résumé templates copied off the internet all teach you to &quot;pile on technology to look professional.&quot; But any experienced interviewer can see through it within 5 minutes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What a truly competitive résumé looks like&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The biggest problem with this résumé is there&apos;s no frontend, because when I hire, I only hire full-stack people.&quot;&lt;/p&gt;
&lt;p&gt;&quot;I&apos;d suggest you don&apos;t have many projects — just one project, which has Agent and frontend and Agent context engineering and backend high-concurrency handling; plus your thinking process, like what your AI coding best practices are, what skills you used to assist development, how you wrote the docs for the project, how you did observability, how you did the Agent&apos;s evaluation, how you proved it&apos;s good, and how the fine-tuning was done.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One project done deeply and thoroughly &gt;&gt; five projects done superficially.&lt;/p&gt;
&lt;h3&gt;6.2 Don&apos;t do RAG-for-the-sake-of-RAG&lt;/h3&gt;
&lt;p&gt;I strongly recommend first reading Karpathy&apos;s &lt;a href=&quot;https://karpathy.ai/&quot;&gt;LLM Wiki&lt;/a&gt; series — he explains very clearly &quot;why traditional RAG is gradually losing ground in the long-context era,&quot; which is one of the underlying ideas of this section.&lt;/p&gt;
&lt;p&gt;W asked a great question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;RAG is meant to solve the knowledge-base problem. So how do the latest Agents solve problems? Does Claude Code have RAG?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The candidate then realized: &lt;strong&gt;Claude Code has no RAG — it uses grep.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This observation is profound:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The traditional RAG paradigm is &quot;chunk and vectorize documents first, then retrieve at query time&quot;&lt;/strong&gt; — that&apos;s the 2023 methodology, on the assumption that &quot;the model&apos;s context is small, tokens are expensive, and retrieval must be precise.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The 2025–2026 paradigm is Agent + tools&lt;/strong&gt; — a long-context model + grep / glob / file-reading tools, letting the Agent explore the codebase itself. This approach has higher precision, doesn&apos;t depend on vectorization quality, and doesn&apos;t require maintaining an index.&lt;/li&gt;
&lt;li&gt;This isn&apos;t to say RAG is dead, but that &lt;strong&gt;RAG isn&apos;t the only answer.&lt;/strong&gt; In many scenarios, letting the Agent use basic tools (grep, find, read) is actually better than reaching for RAG.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Job-seeking advice: &lt;strong&gt;&quot;used RAG&quot; on a résumé is no longer a bonus.&lt;/strong&gt; If you write RAG, you&apos;d better be able to clearly explain &quot;why RAG is more suitable for this scenario than Agent + grep.&quot;&lt;/p&gt;
&lt;h3&gt;6.3 The project should be live — ideally let the interviewer try it&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If your project is something you built yourself but it&apos;s not live, I might not be very interested.&quot;&lt;/p&gt;
&lt;p&gt;&quot;I&apos;d suggest you deploy the project to Vercel — it takes half an hour to deploy — you should have a production-grade project that people can actually use.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why being live matters so much —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Only when it&apos;s live do you run into real problems (performance, concurrency, error handling, user behavior)&lt;/li&gt;
&lt;li&gt;Only when it&apos;s live does your résumé get hard metrics like &quot;traffic&quot; and &quot;user count&quot; — &lt;strong&gt;though you might not have these, and I don&apos;t insist on it&lt;/strong&gt;, since pulling in real users is a hard thing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But what I hope for is that you &lt;strong&gt;have at least a bit of deployment experience.&lt;/strong&gt; The ideal case is: during or before the interview, I can go try your project myself — even if it&apos;s just a demo page that doesn&apos;t require login. A &quot;project you can actually touch&quot; is far more credible and adds far more points than a project described purely in a résumé.&lt;/p&gt;
&lt;h3&gt;6.4 The overseas developer ecosystem: a bonus many domestic candidates overlook&lt;/h3&gt;
&lt;p&gt;I think W&apos;s section here is especially worth pulling out on its own:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The richest people in the world are all in the US, and the highest SaaS paying rates are in the US too. So &lt;strong&gt;the developer world should only be divided into China and overseas.&lt;/strong&gt;&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The specific skill stack:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to integrate Google OAuth, AWS, and Stripe payments&lt;/li&gt;
&lt;li&gt;Vercel deployment, Cloudflare attack protection (not the robot Turnstile kind)&lt;/li&gt;
&lt;li&gt;How to write a Vercel template, how to make an open-source project one-click deployable for others&lt;/li&gt;
&lt;li&gt;How to integrate into overseas developer communities (X, Hacker News, Reddit, Indie Hackers)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Domestic big tech is all going overseas too, and the whole pool of domestic capital is going overseas as well.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you want to be an Agent engineer and also land a good offer, &lt;strong&gt;an understanding of the overseas developer ecosystem is genuinely an ability that can open up a real gap.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;6.5 Information-gathering ability = a soft skill&lt;/h3&gt;
&lt;p&gt;In the last stretch of conversation, I said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Now that we have AI, the value, or the significance, of the ability to write code itself is gradually decreasing. So you definitely need to develop some so-called soft skills.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;W added:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Do you usually scroll Twitter? You should scroll the AI Twitter more — you&apos;ll get a lot of inspiration. The more you scroll and the more you know, the more it&apos;s a dimensionality-reduction strike — you go from being a job seeker to being someone in the AI world who&apos;s actually taking part in this carnival of building.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is the most important sentence of the whole interview.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In a field where technology changes on a weekly basis, &lt;strong&gt;your information sources determine your ceiling.&lt;/strong&gt; If you only read WeChat public accounts, Zhihu, and CSDN, what you see is forever translated, filtered, lagged second-hand information. When a new model, framework, or paradigm appears, you find out a week later than practitioners in Silicon Valley and three days later than the earliest people in China to know; three months later, what you see is a chewed-over &quot;explainer article.&quot;&lt;/p&gt;
&lt;p&gt;To build first-hand information sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;X / Twitter&lt;/strong&gt;: follow Anthropic and OpenAI employees, well-known indie developers, founders of AI infra companies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hacker News&lt;/strong&gt;: scan the frontpage every day&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Official docs / changelogs&lt;/strong&gt;: the product pages and release notes of Anthropic, OpenAI, Vercel, Cursor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: follow projects that just launched and went viral; read the code, file issues, join the discussion&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Personal blogs&lt;/strong&gt;: of course, you&apos;re also welcome to follow my &lt;a href=&quot;https://joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt; hhh — I sediment the interesting things I read each day in the notes section&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;You&apos;ll change — from being a job seeker to being someone in the AI world who&apos;s taking part in this carnival of building.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;6.6 On &quot;copying open-source projects&quot;&lt;/h3&gt;
&lt;p&gt;At the end, the candidate asked: &quot;Are there any recommended open-source projects I can pull down and work on?&quot;&lt;/p&gt;
&lt;p&gt;My answer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;I really don&apos;t intend to recommend any project. Now that we have AI, the cost of building a project from scratch is already very low. I&apos;d suggest you discover the needs in your daily life around you — that way, when you tell the whole story in an interview, it&apos;ll be more sincere and more convincing. Or you can heavily use Hermes Agent like I do, and wherever you think its code is bad, go change it — so far I haven&apos;t met an interviewer who understands the Hermes Agent source better than I do, and that kind of depth is itself scarce. But copying an open-source project directly is something I personally can&apos;t really accept.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A copied project — you can&apos;t explain &quot;why it&apos;s designed this way,&quot; so all the &quot;why&quot; questions crash and burn&lt;/li&gt;
&lt;li&gt;A copied project has no real motivation of your own for using it — you can&apos;t tell the use case&lt;/li&gt;
&lt;li&gt;AI coding tools have already driven the cost of &quot;writing from scratch&quot; down to a few hours — there&apos;s no need to copy&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;7. Communication ability: answers that don&apos;t hit the point&lt;/h2&gt;
&lt;p&gt;Throughout the interview I repeatedly pointed out one problem with the candidate: &lt;strong&gt;before answering, there&apos;d be a couple of meaningless filler sentences, and it took a long time to grab the core of the question.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The candidate realized it himself too: &quot;I really do need to work more on my verbal expression.&quot;&lt;/p&gt;
&lt;p&gt;This is actually a severely underrated job-seeking skill. With the same knowledge base, &lt;strong&gt;someone who can make a point clearly in 30 seconds versus someone who needs 3 minutes of beating around the bush get completely different interview ratings.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How to improve:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Record and replay&lt;/strong&gt;: record every mock interview, listen back afterward, and you&apos;ll find you have tons of filler words like &quot;um, like, that kind of thing&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conclusion first, details second&lt;/strong&gt;: the first sentence of every answer gives the conclusion directly, then you expand&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use technical terms&lt;/strong&gt;: not &quot;that thing&quot; or &quot;something like that,&quot; but &quot;prefix caching,&quot; &quot;AQS,&quot; &quot;weak reference&quot; — precise wording is itself a display of professionalism&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you&apos;re not clear, don&apos;t pretend to be&lt;/strong&gt; — this is the more core point. A lot of the time, the reason you beat around the bush and pile on filler is fundamentally that you&apos;re not sure of the answer itself and want to cover it with &quot;saying more.&quot; But saying more just gets more wrong; better to directly admit &quot;I&apos;m not too familiar with this.&quot; Admitting you don&apos;t know is far better than bluffing and getting fished to death.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One more thing W and I observed: &lt;strong&gt;sometimes the candidate had actually reached the answer, but just didn&apos;t say the term.&lt;/strong&gt; He&apos;d use an extra sentence or two to describe the concept. In that case, &quot;the knowledge is there but the term isn&apos;t,&quot; and the interviewer instead judges it as &quot;not familiar.&quot;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;8. Summary: if you also want to be an Agent engineer&lt;/h2&gt;
&lt;p&gt;Condensing all the lessons from this interview into a checklist:&lt;/p&gt;
&lt;h3&gt;Project layer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Does my project solve a problem that chatting directly with ChatGPT / Doubao / Claude &lt;strong&gt;can&apos;t&lt;/strong&gt; solve?&lt;/li&gt;
&lt;li&gt;[ ] Does my multi-Agent design give a substantive benefit over a single Agent?&lt;/li&gt;
&lt;li&gt;[ ] Is my project deployed and live? Can the interviewer try it?&lt;/li&gt;
&lt;li&gt;[ ] Is my project complete with Agent + frontend + backend + evaluation + observability + docs?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Tech-choice layer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] For every technology I used (Redis / vector DB / graph DB / fine-tuning / RAG), can I clearly explain &quot;why this one and not X / Y / Z&quot;?&lt;/li&gt;
&lt;li&gt;[ ] Do I know that PostgreSQL + pgvector can replace a standalone vector DB in many scenarios?&lt;/li&gt;
&lt;li&gt;[ ] Do I know why Claude Code uses grep instead of RAG?&lt;/li&gt;
&lt;li&gt;[ ] Did I use different models tiered for different tasks?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Agent-knowledge layer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Can I clearly explain the relationship between Function Calling / MCP / Skills / CLI tools?&lt;/li&gt;
&lt;li&gt;[ ] Do I know how Skill&apos;s progressive disclosure / Claude Code&apos;s tool_search work?&lt;/li&gt;
&lt;li&gt;[ ] Can I clearly explain prefix-caching-friendly context design?&lt;/li&gt;
&lt;li&gt;[ ] Can I clearly explain the memory system&apos;s &quot;factual / derived / preference&quot; classification, plus contradiction handling and decay mechanisms?&lt;/li&gt;
&lt;li&gt;[ ] Have I studied the Memory evolution of OpenAI / Claude / Hermes / OpenCode?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;AI-workflow layer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Do I have my own AI coding workflow? How do I use AGENTS.md / Skills / Memory?&lt;/li&gt;
&lt;li&gt;[ ] Beyond coding scenarios, how else do I weave AI into daily life (scheduling, information feeds, content creation)?&lt;/li&gt;
&lt;li&gt;[ ] Can I write Agent evaluations?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Soft-skill layer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[ ] What are my first-hand information sources? Do I read X, HN, and official changelogs every day?&lt;/li&gt;
&lt;li&gt;[ ] Do I understand the overseas developer ecosystem (Vercel / Stripe / Cloudflare / OAuth)?&lt;/li&gt;
&lt;li&gt;[ ] When answering, can I cut to the core in 30 seconds? Do I use technical terms?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;A final note&lt;/h2&gt;
&lt;p&gt;This interview lasted 1 hour and 19 minutes, and the overall feedback W and I gave the candidate was &quot;the projects need a rewrite, the information sources need to expand, the expression needs practice.&quot; It sounds harsh, but his own reaction was &quot;knowing the problems is better than not knowing them.&quot;&lt;/p&gt;
&lt;p&gt;I agree with that attitude.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Knowing the problems is already much better than not knowing them; what comes next is your follow-through.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All the problems discussed in this blog post are ones I&apos;m still continuously learning and stumbling through myself. Every day I&apos;m changing Hermes&apos;s source, reading Anthropic&apos;s official docs, and watching the latest discussions in the AI world on X — not because I&apos;m so great, but because this is the &lt;strong&gt;entry ticket&lt;/strong&gt; for this industry, not a bonus.&lt;/p&gt;
&lt;p&gt;If you&apos;re also preparing for an Agent-track job search, I hope this helps.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;📮 &lt;strong&gt;About paid mock interviews / résumé coaching&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m currently taking paid 1-on-1 mock interviews and résumé coaching for the Agent track, with questions customized to your specific projects and target role and concrete, actionable improvement directions (this blog post is the retrospective of one real mock interview). If you&apos;re interested, you can find me on my personal website &lt;a href=&quot;https://joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt;, or book directly through the contact info on the site.&lt;/p&gt;
&lt;p&gt;I&apos;ll keep writing up more mock-interview retrospectives going forward — feel free to follow along.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All names and sensitive information in this article have been de-identified.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>Reading OpenHarness: Inside an 11,733-Line Agent Harness</title><link>https://www.joyehuang.me/en/blog/20260410---openharnessphase1/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260410---openharnessphase1/post</guid><description>HKUDS open-sourced OpenHarness, an Agent Harness matching Claude Code. My notes from a day reading its core architecture: Phase 1, CLI startup to Agent Loop.</description><pubDate>Fri, 10 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Before we start&lt;/h2&gt;
&lt;p&gt;I&apos;ve been using Claude Code for almost half a year now — it&apos;s the main coding tool I reach for every single day. But one thing has always nagged at me: &lt;strong&gt;I&apos;ve never actually seen what it looks like on the inside.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Claude Code is a closed-source product written in TypeScript, and the code is obfuscated on top of that. As a developer who wants to grow into full-stack AI Agent work, I know perfectly well that just being able to &lt;em&gt;use&lt;/em&gt; it isn&apos;t enough — I need to understand how a production-grade Agent is actually built.&lt;/p&gt;
&lt;p&gt;A few days ago, the HKUDS lab (the same University of Hong Kong team behind Nanobot) open-sourced &lt;strong&gt;OpenHarness&lt;/strong&gt;, a project that reimplements Claude Code&apos;s core architecture in Python. It&apos;s only 11,733 lines of code, yet it delivers 43 tools, 54 commands, plus a complete Agent Loop, a permission system, a plugin system, and multi-Agent collaboration.&lt;/p&gt;
&lt;p&gt;For me, this was manna from heaven.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is a Harness?&lt;/strong&gt; If you&apos;ve read the recent papers from OpenAI and Anthropic on Agents, you&apos;ll recognize a shared premise: &lt;strong&gt;the model handles intelligence, the Harness handles everything else&lt;/strong&gt;. The Harness is the full layer of infrastructure wrapped around the LLM — tools, memory, permissions, context, multi-Agent coordination. In the project author&apos;s own words: &lt;em&gt;&quot;The model is the agent. The code is the harness.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This post is my notes from a day spent chewing through OpenHarness&apos;s core architecture. I&apos;ll take you all the way through Phase 1: &lt;strong&gt;from the moment you type the &lt;code&gt;oh&lt;/code&gt; command, right down to the beating heart of the Agent Loop.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Why is this project worth studying? Three reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;It&apos;s small enough&lt;/strong&gt;: 11,733 lines of Python vs. Claude Code&apos;s 512,664 lines of TypeScript — 44x leaner.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It&apos;s complete enough&lt;/strong&gt;: everything you&apos;d expect is there — Agent Loop, Tools, Hooks, MCP, Plugins, Multi-Agent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It&apos;s real enough&lt;/strong&gt;: it&apos;s not a teaching toy, it&apos;s a production-grade implementation you can actually run.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alright, let&apos;s hit the road.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. Fourteen subsystems: the big picture first&lt;/h2&gt;
&lt;p&gt;Open the &lt;code&gt;src/openharness/&lt;/code&gt; directory and you&apos;ll find the whole project carved into 14 submodules. The first time I looked at it I was a little dazed — that&apos;s a lot of stuff, where do you even begin?&lt;/p&gt;
&lt;p&gt;After spending a bit of time skimming each module&apos;s &lt;code&gt;__init__.py&lt;/code&gt;, I sketched out this structure diagram:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;src/openharness/
│
├── cli.py                 ← entry point: Typer CLI
│
├── engine/                ← 🧠 the core of the core: Agent Loop
│   ├── query_engine.py    ← while True: stream → tool_use → execute → loop
│   ├── query.py           ← the actual loop implementation
│   ├── messages.py        ← message formats
│   ├── cost_tracker.py    ← token billing
│   └── stream_events.py   ← streaming event types
│
├── tools/                 ← 🔧 43 Tools (Bash, Read, Write, Glob...)
│   ├── base.py            ← BaseTool + ToolRegistry
│   └── *_tool.py          ← one Tool implementation per file
│
├── permissions/           ← 🛡️ permission checks (default/plan/full_auto)
├── hooks/                 ← ⚡ lifecycle hooks (PreToolUse/PostToolUse)
│
├── prompts/               ← 📝 System Prompt assembly factory
├── skills/                ← 📚 on-demand .md knowledge files
├── memory/                ← 🧠 persistent cross-session memory
├── plugins/               ← 🔌 plugin system
├── commands/              ← 💬 slash command registry
├── mcp/                   ← 🌐 Model Context Protocol Client
├── tasks/                 ← 📋 background task management
├── coordinator/           ← 🤝 multi-Agent orchestration
│
├── config/                ← ⚙️ configuration management
├── state/                 ← state storage
├── services/              ← helper services
├── bridge/                ← Python ↔ React TUI communication bridge
├── ui/                    ← UI layer entry point
└── keybindings/           ← keybinding configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&apos;s a key observation: &lt;strong&gt;these 14 modules aren&apos;t all on the same level.&lt;/strong&gt; They split into three layers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Execution layer&lt;/strong&gt;: engine, tools, permissions, hooks — &lt;em&gt;how the Agent runs&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge layer&lt;/strong&gt;: prompts, skills, memory — &lt;em&gt;what the Agent knows&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extension layer&lt;/strong&gt;: mcp, plugins, coordinator, tasks, commands — &lt;em&gt;how the Agent connects to the outside world&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If this is your first time reading a project like this, I&apos;d suggest reading in the order execution layer → knowledge layer → extension layer. Once you&apos;ve grasped the trunk, everything else is just an ornament hanging off it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. From &lt;code&gt;oh&lt;/code&gt; to a ready Agent: the full startup chain&lt;/h2&gt;
&lt;p&gt;Let&apos;s start the moment the user types &lt;code&gt;uv run oh&lt;/code&gt; and follow the data all the way through.&lt;/p&gt;
&lt;h3&gt;Entry point: the Typer CLI&lt;/h3&gt;
&lt;p&gt;Open &lt;code&gt;src/openharness/cli.py&lt;/code&gt; and you&apos;ll see the familiar CLI argument definitions. This project uses &lt;a href=&quot;https://typer.tiangolo.com/&quot;&gt;Typer&lt;/a&gt; — if you&apos;ve written Python, think of it as the Python equivalent of &lt;code&gt;yargs&lt;/code&gt; or &lt;code&gt;commander&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# cli.py:12-21
app = typer.Typer(
    name=&quot;openharness&quot;,
    help=&quot;Oh my Harness! An AI-powered coding assistant.&quot;,
    invoke_without_command=True,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the CLI arguments are defined inside the &lt;code&gt;main()&lt;/code&gt; function (&lt;code&gt;cli.py:179-334&lt;/code&gt;), including &lt;code&gt;-p/--print&lt;/code&gt;, &lt;code&gt;--model&lt;/code&gt;, &lt;code&gt;--permission-mode&lt;/code&gt;, and so on. Once the arguments are parsed, the code reaches this point:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# cli.py:346-377
if print_mode is not None:
    # non-interactive mode
    asyncio.run(run_print_mode(...))
    return

# interactive mode
asyncio.run(run_repl(...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two paths: &lt;strong&gt;interactive mode&lt;/strong&gt; (the default) and &lt;strong&gt;print mode&lt;/strong&gt; (the &lt;code&gt;-p&lt;/code&gt; flag). Print mode runs single-process with direct output, which is great for scripting and integration; interactive mode launches the pretty React TUI, which is the interface you see in everyday use.&lt;/p&gt;
&lt;h3&gt;The dual-process architecture that confused me for a while&lt;/h3&gt;
&lt;p&gt;Reading &lt;code&gt;ui/app.py:27-47&lt;/code&gt;, I got stuck for a moment:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;async def run_repl(...) -&gt; None:
    if backend_only:
        await run_backend_host(...)
        return

    exit_code = await launch_react_tui(...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What on earth is this &lt;code&gt;backend_only&lt;/code&gt; branch? I kept tracing the code and opened &lt;code&gt;ui/react_launcher.py&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# react_launcher.py:78-102
env[&quot;OPENHARNESS_FRONTEND_CONFIG&quot;] = json.dumps({
    &quot;backend_command&quot;: build_backend_command(...),  # ← python -m openharness --backend-only
    &quot;initial_prompt&quot;: prompt,
})

process = await asyncio.create_subprocess_exec(
    npm, &quot;exec&quot;, &quot;--&quot;, &quot;tsx&quot;, &quot;src/index.tsx&quot;, ...
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s when it clicked: &lt;strong&gt;in interactive mode, OpenHarness actually runs two processes.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The full startup chain looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Step 1: you type `oh`
         → Python process A starts
         → its only job is to launch Node.js

Step 2: Node.js starts
         → it renders the TUI you see with React/Ink
         → but Node.js isn&apos;t where the AI logic lives
         → so it turns around and spawns Python process B (--backend-only mode)

Step 3: Python process B starts
         → this is the backend that does the real work
         → process A has fulfilled its purpose and exits
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the end only two processes are running: &lt;strong&gt;Node.js (the UI)&lt;/strong&gt; and &lt;strong&gt;Python B (the Agent engine)&lt;/strong&gt;. They communicate over a JSON-lines protocol on stdin/stdout.&lt;/p&gt;
&lt;h3&gt;Why design it this way?&lt;/h3&gt;
&lt;p&gt;This is the most interesting architectural decision in the whole startup flow. Put plainly, it comes down to &lt;strong&gt;picking the right language ecosystem&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| Need | Best tool |
|------|-----------|
| Rich terminal UI (syntax highlighting, popups, animations) | React/Ink (Node.js ecosystem) |
| AI Agent engine (LLM SDK, asyncio, filesystem) | Python ecosystem |&lt;/p&gt;
&lt;p&gt;The best tools for these two needs live in different languages. Rather than make do within a single language, let two processes each do what they&apos;re best at and talk over JSON.&lt;/p&gt;
&lt;p&gt;You&apos;ll find this pattern very familiar — &lt;strong&gt;when you write Next.js, the browser runs React, the server runs Node.js, and they talk over HTTP.&lt;/strong&gt; OpenHarness swaps HTTP for the simpler stdin/stdout JSON-lines, because both processes run on the same machine, in the same terminal, with no need for a network stack.&lt;/p&gt;
&lt;h3&gt;What the communication protocol looks like&lt;/h3&gt;
&lt;p&gt;Look at &lt;code&gt;ui/protocol.py&lt;/code&gt; — the message contract between frontend and backend is spelled out crisply with Pydantic models.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frontend → backend&lt;/strong&gt; (&lt;code&gt;protocol.py:15-22&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class FrontendRequest(BaseModel):
    type: Literal[
        &quot;submit_line&quot;,           # user typed a line
        &quot;permission_response&quot;,   # answer to the permission popup
        &quot;question_response&quot;,     # answer to the question popup
        &quot;list_sessions&quot;,
        &quot;shutdown&quot;,
    ]
    line: str | None = None
    allowed: bool | None = None
    answer: str | None = None
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Backend → frontend&lt;/strong&gt; (&lt;code&gt;protocol.py:55-86&lt;/code&gt;): 14 event types, including &lt;code&gt;assistant_delta&lt;/code&gt; (streaming text), &lt;code&gt;tool_started&lt;/code&gt;/&lt;code&gt;tool_completed&lt;/code&gt; (tool lifecycle), &lt;code&gt;modal_request&lt;/code&gt; (popup requests), and more.&lt;/p&gt;
&lt;p&gt;The essence of this protocol is: &lt;strong&gt;one JSON object per line, and reading/writing is just stdin/stdout.&lt;/strong&gt; No ports, no handshake, no timeout-and-retry. When you&apos;re debugging, you can just tail the log and see the entire conversation between the two sides.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;build_runtime()&lt;/code&gt;: the assembly line for the whole Harness&lt;/h3&gt;
&lt;p&gt;The very first thing backend process B does after it starts is call &lt;code&gt;build_runtime()&lt;/code&gt; in &lt;code&gt;ui/runtime.py:89&lt;/code&gt;. This is the single most important function in the whole project — it assembles every subsystem into one &lt;code&gt;RuntimeBundle&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# runtime.py:89-176 (simplified)
async def build_runtime(...) -&gt; RuntimeBundle:
    settings = load_settings().merge_cli_overrides(...)
    plugins = load_plugins(settings, cwd)

    resolved_api_client = AnthropicApiClient(
        api_key=settings.resolve_api_key(),
        base_url=settings.base_url,
    )
    mcp_manager = McpClientManager(load_mcp_server_configs(settings, plugins))
    await mcp_manager.connect_all()

    tool_registry = create_default_tool_registry(mcp_manager)
    hook_executor = HookExecutor(...)

    engine = QueryEngine(
        api_client=resolved_api_client,
        tool_registry=tool_registry,
        permission_checker=PermissionChecker(settings.permission),
        system_prompt=build_runtime_system_prompt(...),
        hook_executor=hook_executor,
        ...
    )

    return RuntimeBundle(
        api_client=resolved_api_client,
        tool_registry=tool_registry,
        hook_executor=hook_executor,
        engine=engine,
        ...
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pay attention to &lt;strong&gt;how&lt;/strong&gt; these dependencies are wired together:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First load settings and plugins (the config data).&lt;/li&gt;
&lt;li&gt;Use settings to create the &lt;code&gt;AnthropicApiClient&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create the &lt;code&gt;McpClientManager&lt;/code&gt; and connect to all external servers.&lt;/li&gt;
&lt;li&gt;Create the &lt;code&gt;ToolRegistry&lt;/code&gt; (registering all 43 tools into it).&lt;/li&gt;
&lt;li&gt;Create the &lt;code&gt;HookExecutor&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Finally, pass everything above into &lt;code&gt;QueryEngine&lt;/code&gt; as arguments.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is the classic &lt;strong&gt;dependency injection pattern&lt;/strong&gt;. &lt;code&gt;QueryEngine&lt;/code&gt; doesn&apos;t create any of its own dependencies — they&apos;re all passed in from outside. The benefits are immediate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;For testing&lt;/strong&gt;: you can pass a mock &lt;code&gt;api_client&lt;/code&gt; and a mock &lt;code&gt;tool_registry&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For switching to Kimi&lt;/strong&gt;: you just change &lt;code&gt;settings.base_url&lt;/code&gt;, without touching a single line of &lt;code&gt;QueryEngine&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For switching modes&lt;/strong&gt;: headless/print/interactive can all share the same core.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;RuntimeBundle: the container for every dependency&lt;/h3&gt;
&lt;p&gt;Look at &lt;code&gt;runtime.py:35-48&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;@dataclass
class RuntimeBundle:
    api_client: SupportsStreamingMessages   # LLM API client
    cwd: str                                 # working directory
    mcp_manager: McpClientManager           # MCP external tools
    tool_registry: ToolRegistry             # 43 Tools
    app_state: AppStateStore                # UI state
    hook_executor: HookExecutor             # lifecycle Hooks
    engine: QueryEngine                     # Agent Loop engine
    commands: object                        # slash commands
    external_api_client: bool
    session_id: str = &quot;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To put it in React terms you already know: &lt;strong&gt;&lt;code&gt;RuntimeBundle&lt;/code&gt; is like packing all your Context Providers into a single object.&lt;/strong&gt; From here on, no matter which function needs which subsystem, all it has to do is get hold of the bundle.&lt;/p&gt;
&lt;p&gt;This pattern is so much better than global variables — every dependency is explicit, and for testing you can construct a mock bundle to run against without touching any business code at all.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. The Agent Loop: the heart of the whole project&lt;/h2&gt;
&lt;p&gt;Finally we reach the core. Every critical question in Harness engineering boils down to one thing: &lt;strong&gt;how does the Agent Loop run?&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;The fundamental difference between a plain chatbot and an Agent&lt;/h3&gt;
&lt;p&gt;Anyone who&apos;s built a chat app with the Vercel AI SDK knows the simplest chat flow looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;user sends a message → call the API → AI replies → done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But an Agent is different. The AI might say &quot;I need to read this file first,&quot; then you hand it the file contents, and it says &quot;okay, now I&apos;m going to edit line 42,&quot; and after you run that and give it the result, it says &quot;done.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A single user message can trigger multiple rounds of AI ↔ Tool interaction.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That loop is the Agent Loop. Its implementation is surprisingly simple — only &lt;strong&gt;70 lines of code&lt;/strong&gt;, all in &lt;code&gt;src/openharness/engine/query.py&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;A line-by-line walkthrough of &lt;code&gt;run_query&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;I&apos;ll paste the key parts and we&apos;ll go through them section by section:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# query.py:53-86
async def run_query(
    context: QueryContext,
    messages: list[ConversationMessage],
) -&gt; AsyncIterator[tuple[StreamEvent, UsageSnapshot | None]]:
    &quot;&quot;&quot;Run the conversation loop until the model stops requesting tools.&quot;&quot;&quot;
    for _ in range(context.max_turns):
        final_message: ConversationMessage | None = None
        usage = UsageSnapshot()

        async for event in context.api_client.stream_message(
            ApiMessageRequest(
                model=context.model,
                messages=messages,
                system_prompt=context.system_prompt,
                max_tokens=context.max_tokens,
                tools=context.tool_registry.to_api_schema(),
            )
        ):
            if isinstance(event, ApiTextDeltaEvent):
                yield AssistantTextDelta(text=event.text), None
                continue

            if isinstance(event, ApiMessageCompleteEvent):
                final_message = event.message
                usage = event.usage

        if final_message is None:
            raise RuntimeError(&quot;Model stream finished without a final message&quot;)

        messages.append(final_message)
        yield AssistantTurnComplete(message=final_message, usage=usage), usage

        if not final_message.tool_uses:
            return
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code has six key points:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① The turn loop (line 58)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;for _ in range(context.max_turns):   # default 8 turns
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A safety backstop. It keeps the AI from getting stuck in an infinite loop of tool calls.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② Passing every tool&apos;s schema into the API call (line 68)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;tools=context.tool_registry.to_api_schema()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is what lets the AI &quot;know&quot; what it&apos;s capable of. The names, descriptions, and parameter formats of all 43 tools are told to the AI in one shot, so it can decide when to call which one. This maps to the &lt;code&gt;tools&lt;/code&gt; parameter in the Anthropic API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;③ Streaming handles two kinds of events (lines 71-77)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;if isinstance(event, ApiTextDeltaEvent):
    yield AssistantTextDelta(text=event.text), None  # typing increment
    continue

if isinstance(event, ApiMessageCompleteEvent):
    final_message = event.message  # full message
    usage = event.usage
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Delta events are yielded immediately so the UI can show the &quot;typing&quot; effect, while the Complete event records the full message and the token usage. This is the same playbook as the Vercel AI SDK&apos;s &lt;code&gt;onToken&lt;/code&gt; + &lt;code&gt;onFinish&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;④ The watershed between an Agent and a chatbot (lines 85-86)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;if not final_message.tool_uses:
    return
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Just these two lines.&lt;/strong&gt; If the AI&apos;s reply contains no tool_use request, it means it considers the task done, and the entire Agent Loop ends. If there is a tool_use, execution continues down to running the tools.&lt;/p&gt;
&lt;p&gt;If someone ever asks you &quot;what&apos;s the fundamental difference between an Agent and a chatbot,&quot; pointing at these two lines is all the answer you need.&lt;/p&gt;
&lt;h3&gt;Single tool vs. multiple tools: two execution strategies&lt;/h3&gt;
&lt;p&gt;Reading further, &lt;code&gt;query.py:88-118&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;tool_calls = final_message.tool_uses

if len(tool_calls) == 1:
    # Single tool: sequential (stream events immediately)
    tc = tool_calls[0]
    yield ToolExecutionStarted(tool_name=tc.name, tool_input=tc.input), None
    result = await _execute_tool_call(context, tc.name, tc.id, tc.input)
    yield ToolExecutionCompleted(
        tool_name=tc.name,
        output=result.content,
        is_error=result.is_error,
    ), None
    tool_results = [result]
else:
    # Multiple tools: execute concurrently, emit events after
    for tc in tool_calls:
        yield ToolExecutionStarted(tool_name=tc.name, tool_input=tc.input), None

    async def _run(tc):
        return await _execute_tool_call(context, tc.name, tc.id, tc.input)

    results = await asyncio.gather(*[_run(tc) for tc in tool_calls])
    tool_results = list(results)

    for tc, result in zip(tool_calls, tool_results):
        yield ToolExecutionCompleted(
            tool_name=tc.name,
            output=result.content,
            is_error=result.is_error,
        ), None
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&apos;s a very pragmatic design choice here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A single tool&lt;/strong&gt;: streaming events come first — started and completed arrive one after the other.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiple tools&lt;/strong&gt;: speed comes first — they run concurrently via &lt;code&gt;asyncio.gather&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why make the distinction? &lt;strong&gt;It&apos;s a balance between performance and user experience.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Imagine the AI asks to read 3 files at once:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequential: 100ms + 100ms + 100ms = &lt;strong&gt;300ms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Concurrent: max(100, 100, 100) ≈ &lt;strong&gt;100ms&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Running multiple tools in parallel collapses the latency down to the slowest single tool. That&apos;s exactly why Claude Code has increasingly favored letting the AI call several tools at once — the parallelism behind it is &lt;code&gt;asyncio.gather&lt;/code&gt;, the equivalent of &lt;code&gt;Promise.all&lt;/code&gt; in JS.&lt;/p&gt;
&lt;p&gt;But for a single tool there&apos;s no point reaching for &lt;code&gt;asyncio.gather&lt;/code&gt;; it would only cost you the immediate feedback — so the code deliberately splits into two branches.&lt;/p&gt;
&lt;h3&gt;The safety chain for tool execution&lt;/h3&gt;
&lt;p&gt;Before any tool actually runs, it passes through a complete chain of safety checks. This lives in the &lt;code&gt;_execute_tool_call&lt;/code&gt; function at &lt;code&gt;query.py:124-211&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;AI requests to execute a tool
    │
    ▼
① PreToolUse Hook
   → e.g. the security-guidance plugin checks for dangerous commands
   → the Hook can block this execution outright
    │
    ▼
② find the tool implementation
   → tool_registry.get(tool_name)
    │
    ▼
③ validate input parameters (with Pydantic)
   → tool.input_model.model_validate(tool_input)
   → wrong type errors out immediately
    │
    ▼
④ permission check
   → permission_checker.evaluate(...)
   → check mode (default/plan/full_auto)
   → check path_rules (some paths are off-limits)
   → check denied_commands (some commands are off-limits)
   → if confirmation is needed → trigger the permission_prompt popup
    │
    ▼
⑤ actually execute the tool
    │
    ▼
⑥ PostToolUse Hook (logging, etc.)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &quot;Allow / Deny&quot; popup you see every time in Claude Code is step ④. Here&apos;s the implementation in code (&lt;code&gt;query.py:168-182&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;decision = context.permission_checker.evaluate(
    tool_name,
    is_read_only=tool.is_read_only(parsed_input),
    file_path=_file_path,
    command=_command,
)
if not decision.allowed:
    if decision.requires_confirmation and context.permission_prompt is not None:
        confirmed = await context.permission_prompt(tool_name, decision.reason)
        if not confirmed:
            return ToolResultBlock(
                tool_use_id=tool_use_id,
                content=f&quot;Permission denied for {tool_name}&quot;,
                is_error=True,
            )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;context.permission_prompt&lt;/code&gt; is an async callback. In print mode it&apos;s a no-op (everything is allowed); in interactive mode it sends a &lt;code&gt;BackendEvent.modal_request&lt;/code&gt; to the React frontend, the frontend renders the popup, and after the user clicks Allow/Deny the result is sent back via &lt;code&gt;FrontendRequest.permission_response&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The dual-process architecture I described earlier shows itself most vividly right here — &lt;strong&gt;the permission popup is a cross-process async wait.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;One full Agent loop, end to end&lt;/h3&gt;
&lt;p&gt;Let&apos;s tie it together with a concrete example. Suppose you ask the AI to &quot;read README.md and then summarize it&quot;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Turn 1:
  messages = [{ role: &quot;user&quot;, text: &quot;read README.md and then summarize it&quot; }]
  → call the API, passing in all tool schemas
  → AI replies: &quot;Let me read it&quot; + tool_use: Read({ file_path: &quot;README.md&quot; })
  → tool_uses is non-empty, keep looping
  → execute the Read tool:
    ① PreToolUse Hook passes
    ② tool_registry.get(&quot;Read&quot;) finds the tool
    ③ Pydantic validates file_path
    ④ permission check (read-only operation, passes)
    ⑤ read the file
    ⑥ PostToolUse Hook
  → append the tool result as a user message
  → messages now has 3 entries

Turn 2:
  → call the API
  → AI replies: &quot;This README covers three main points: 1... 2... 3...&quot;
  → tool_uses is empty
  → return, loop ends
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s the Agent&apos;s complete lifecycle — two for-loops and one if-check. &lt;strong&gt;But those two lines, &lt;code&gt;if not final_message.tool_uses: return&lt;/code&gt;, are the soul of the Agent.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. A few design decisions worth remembering&lt;/h2&gt;
&lt;p&gt;After finishing Phase 1, there are a few design decisions I think are especially worth keeping in mind.&lt;/p&gt;
&lt;h3&gt;Decision 1: why use a &lt;code&gt;RuntimeBundle&lt;/code&gt; instead of globals?&lt;/h3&gt;
&lt;p&gt;Over a session&apos;s lifetime, a lot of things (the api client, the tool registry, the permission checker...) get used all over the place. The laziest approach is to make them module-level globals and import them wherever you need them.&lt;/p&gt;
&lt;p&gt;But OpenHarness chooses to pack them into a &lt;code&gt;RuntimeBundle&lt;/code&gt; and pass it along the way. The cost is longer function signatures; the benefit is that &lt;strong&gt;every dependency is explicit&lt;/strong&gt;, and it supports running multiple sessions at once.&lt;/p&gt;
&lt;p&gt;This is the difference between writing production-grade code and a toy project.&lt;/p&gt;
&lt;h3&gt;Decision 2: why split single-tool and multi-tool into two branches?&lt;/h3&gt;
&lt;p&gt;You could perfectly well unify everything under &lt;code&gt;asyncio.gather&lt;/code&gt;, treating a single tool as a one-element gather. The code would be cleaner.&lt;/p&gt;
&lt;p&gt;But OpenHarness deliberately splits them, because &lt;strong&gt;in the single-tool case, immediate feedback matters more than parallelism.&lt;/strong&gt; When a user&apos;s action runs just one tool, they want to see the complete &quot;started → (running) → completed&quot; stream.&lt;/p&gt;
&lt;p&gt;This is an easy-to-miss UX decision, but it reflects how much the author cares about the details.&lt;/p&gt;
&lt;h3&gt;Decision 3: why use Pydantic to validate tool inputs?&lt;/h3&gt;
&lt;p&gt;You could absolutely let each tool write &lt;code&gt;if not isinstance(x, str): raise&lt;/code&gt; inside its own &lt;code&gt;execute&lt;/code&gt;. But OpenHarness mandates an &lt;code&gt;input_model: type[BaseModel]&lt;/code&gt; in the &lt;code&gt;BaseTool&lt;/code&gt; base class — every tool has to provide a Pydantic model.&lt;/p&gt;
&lt;p&gt;The benefits run in several directions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Auto-generated JSON Schema&lt;/strong&gt;: the &lt;code&gt;tools&lt;/code&gt; parameter sent to the LLM can be generated straight from the Pydantic model.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unified error handling&lt;/strong&gt;: a single try/except at &lt;code&gt;query.py:150-157&lt;/code&gt; catches the argument errors of every tool.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type safety&lt;/strong&gt;: the tool&apos;s &lt;code&gt;execute&lt;/code&gt; method receives a strongly typed object, not a dict.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What you&apos;d do with zod in TypeScript, you do here with Pydantic.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. A suggested reading path&lt;/h2&gt;
&lt;p&gt;If you want to read this project yourself, here&apos;s the order I&apos;d recommend:&lt;/p&gt;
&lt;h3&gt;Day 1: the trunk (Phase 1)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;cli.py&lt;/code&gt; → see how the CLI arguments are organized&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/app.py&lt;/code&gt; + &lt;code&gt;ui/runtime.py&lt;/code&gt; → see the startup chain&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/react_launcher.py&lt;/code&gt; + &lt;code&gt;ui/backend_host.py&lt;/code&gt; → understand the dual-process architecture&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui/protocol.py&lt;/code&gt; → see the frontend/backend communication protocol&lt;/li&gt;
&lt;li&gt;&lt;code&gt;engine/query_engine.py&lt;/code&gt; + &lt;code&gt;engine/query.py&lt;/code&gt; → &lt;strong&gt;the key part, read it over and over&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;engine/messages.py&lt;/code&gt; + &lt;code&gt;engine/stream_events.py&lt;/code&gt; → the data structures&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Day 2: the tool system&lt;/h3&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;&lt;code&gt;tools/base.py&lt;/code&gt; → the Tool base class&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tools/__init__.py&lt;/code&gt; → the registry&lt;/li&gt;
&lt;li&gt;Pick 3 representative tools and read them deeply:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tools/bash_tool.py&lt;/code&gt; (shell execution)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tools/file_edit_tool.py&lt;/code&gt; (file editing)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tools/agent_tool.py&lt;/code&gt; (sub-Agent invocation)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Day 3: the knowledge system&lt;/h3&gt;
&lt;ol start=&quot;10&quot;&gt;
&lt;li&gt;&lt;code&gt;prompts/system_prompt.py&lt;/code&gt; → how the System Prompt is assembled&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skills/registry.py&lt;/code&gt; → how Skills are loaded on demand&lt;/li&gt;
&lt;li&gt;&lt;code&gt;memory/manager.py&lt;/code&gt; → how persistent memory works&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Day 4: the extension system&lt;/h3&gt;
&lt;ol start=&quot;13&quot;&gt;
&lt;li&gt;&lt;code&gt;permissions/checker.py&lt;/code&gt; → the details of permission checking&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hooks/executor.py&lt;/code&gt; → the Hook executor&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/loader.py&lt;/code&gt; → plugin discovery and loading&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mcp/client.py&lt;/code&gt; → the MCP protocol&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;6. Final thoughts&lt;/h2&gt;
&lt;p&gt;After finishing Phase 1, my understanding of the term &quot;Agent Harness&quot; changed completely.&lt;/p&gt;
&lt;p&gt;I used to think of an Agent as something mysterious. Only after reading the code did I realize — &lt;strong&gt;it&apos;s just a for-loop plus an if-check.&lt;/strong&gt; All the mystery lives in the model; what the Harness does is plain engineering: providing the model with tools, checking permissions, logging, managing sessions, assembling context.&lt;/p&gt;
&lt;p&gt;This realization is valuable to me, because it means: &lt;strong&gt;if you understand the structure of a Harness, you can build one yourself.&lt;/strong&gt; All those concepts the OpenAI and Anthropic papers keep mentioning — tool use, planning, reflection, memory, multi-agent — each one has a corresponding implementation you can find in the OpenHarness code.&lt;/p&gt;
&lt;p&gt;Next I&apos;ll keep reading Phases 2-6 and chew through the remaining 15 topics. Once I&apos;ve finished the whole project, I&apos;ll write a wrap-up.&lt;/p&gt;
&lt;p&gt;If you want to learn Agent development too, I highly recommend spending a few days reading OpenHarness. It&apos;s not long, but it&apos;s real.&lt;/p&gt;
&lt;p&gt;Project: &lt;a href=&quot;https://github.com/HKUDS/OpenHarness&quot;&gt;HKUDS/OpenHarness&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;About the author&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m Joye, a developer working toward full-stack AI Agent development, building internship projects day to day with TypeScript + Next.js + the AI SDK. This is the first post in my learning-notes series, and I&apos;ll keep updating it with the other Phases of OpenHarness.&lt;/p&gt;
&lt;p&gt;Blog: &lt;a href=&quot;https://joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If this post helped you, feel free to find me on Xiaohongshu to chat.&lt;/p&gt;</content:encoded></item><item><title>A Sophomore Intern&apos;s Field Guide to Agent Dev Interviews</title><link>https://www.joyehuang.me/en/blog/20260309---agentinterview/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20260309---agentinterview/post</guid><description>After interviewing nearly 10 AI startups, what Agent-role interviews actually test, and the things that matter a hundred times more than memorizing answers.</description><pubDate>Mon, 09 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;After interviewing with nearly 10 AI startups, I want to talk about what Agent-role interviews actually test, and the things that matter a hundred times more than &quot;memorizing answers.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Before We Start&lt;/h2&gt;
&lt;p&gt;I&apos;m Joye, a sophomore at the University of Melbourne studying Computing and Software Engineering. For the past few months I&apos;ve been doing an AIGC R&amp;#x26;D internship at Tezign in Shanghai, working mainly on Atypica — a Multi-Agent system focused on business research.&lt;/p&gt;
&lt;p&gt;I&apos;ve recently been looking for new opportunities and have interviewed with close to 10 companies, all of them AI startups or overseas startups, with roles concentrated in Agent development and LLM application engineering. Looking back after the fact, I realized that interview experience for this field is pretty scarce on the Chinese internet — unlike frontend and backend, where there&apos;s a systematic body of canned interview questions to grind, Agent development interviews feel more like a deep conversation about &quot;do you actually understand what you&apos;re building?&quot;&lt;/p&gt;
&lt;p&gt;So I&apos;m writing this article partly to organize and review my own interview notes, and partly to offer a reference to others exploring the same direction.&lt;/p&gt;
&lt;p&gt;But first I want to say one thing: &lt;strong&gt;this article isn&apos;t only for people preparing for interviews — it&apos;s just as much for people who are learning Agent development and building their own Agent projects.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Why do I say that? Because there&apos;s a fundamental difference between Agent development interview questions and frontend trivia — you might memorize frontend trivia and never use it in your life, but the questions you get asked in an Agent interview are &lt;strong&gt;design decisions you genuinely have to grapple with while building the project&lt;/strong&gt;. &quot;What do you do when the context overflows?&quot; isn&apos;t an interview question; it&apos;s an engineering problem you&apos;re guaranteed to hit when your Agent reaches its 20th turn of conversation. &quot;How do you stop the LLM from misusing tools?&quot; isn&apos;t the interviewer being difficult; it&apos;s a bug report you&apos;ll receive in your first week after shipping to production.&lt;/p&gt;
&lt;p&gt;Look at it from another angle: if you&apos;ve already done serious context engineering in your own project, built in reliability safeguards for tool-calling, and thought through defenses against prompt injection — then these aren&apos;t interview questions you need to &quot;prepare,&quot; they&apos;re hands-on experience you can naturally talk through, and that&apos;s what genuinely sets you apart. Going forward, I&apos;ll carry these same questions into the design of every new project I build.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;What Agent-Role Interviews Actually Test&lt;/h2&gt;
&lt;h3&gt;How It Differs from Traditional Dev Interviews&lt;/h3&gt;
&lt;p&gt;After this many rounds, my single biggest takeaway is that Agent development interviews have almost no &quot;right answers.&quot;&lt;/p&gt;
&lt;p&gt;In a traditional frontend interview you can memorize closures, the event loop, and the virtual DOM diff algorithm, and once you have, you&apos;re 70–80% covered. Agent interviews are different. A lot of the questions are open-ended — the interviewer isn&apos;t testing what you&apos;ve memorized, they&apos;re testing what you&apos;ve &lt;strong&gt;been through&lt;/strong&gt;. &quot;What did you do when your Agent got stuck in an infinite loop?&quot; — you can&apos;t make up an answer to that if you&apos;ve never fallen into the pit yourself.&lt;/p&gt;
&lt;p&gt;From what I&apos;ve observed, the things interviewers care about fall roughly into three layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Can you use it?&lt;/strong&gt; — Have you used LangChain? How did you build the RAG? How did you design the MCP Server?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do you understand why it&apos;s designed that way?&lt;/strong&gt; — Why does a structured Prompt work better? Why do memory layers matter? Why did you pick the Vercel AI SDK?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Can you make trade-offs under engineering constraints?&lt;/strong&gt; — What do you do when the token budget is tight? How do you balance response speed against quality? How do you guard against model hallucination?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first layer comes from experience, the second from understanding, the third from judgment. Each one is harder to prepare for than the last, but each also reveals more about a person&apos;s engineering maturity.&lt;/p&gt;
&lt;h3&gt;A Full Map of the Interview Questions&lt;/h3&gt;
&lt;p&gt;I sorted the questions I ran into over this period by theme. Together they cover most of what gets probed in an Agent development interview:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RAG and Retrieval Augmentation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The difference between multi-RAG and single-RAG, and when each fits&lt;/li&gt;
&lt;li&gt;How to do Retrieval Augmentation&lt;/li&gt;
&lt;li&gt;When RAG should use vector retrieval versus graph-database retrieval&lt;/li&gt;
&lt;li&gt;How to do data cleaning for RAG&lt;/li&gt;
&lt;li&gt;The evolution path of RAG → Agentic Search → Agentic Memory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Agent Architecture and Orchestration&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent routing design: how to decide which Sub-Agent to call&lt;/li&gt;
&lt;li&gt;Designing the Agent&apos;s fallback mechanism&lt;/li&gt;
&lt;li&gt;Are Sub-Agents parallel or asynchronous? Can they communicate with each other?&lt;/li&gt;
&lt;li&gt;How to stop the LLM from misusing tools&lt;/li&gt;
&lt;li&gt;How to handle the LLM calling tools in an infinite loop&lt;/li&gt;
&lt;li&gt;How to design an MCP Server&lt;/li&gt;
&lt;li&gt;Overall framework design for the Agent flow&lt;/li&gt;
&lt;li&gt;How to build a callback mechanism&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Context Engineering and Token Management&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to save tokens&lt;/li&gt;
&lt;li&gt;What to do when the context overflows (beyond FIFO, what other options are there?)&lt;/li&gt;
&lt;li&gt;How to convert short-term memory into long-term memory&lt;/li&gt;
&lt;li&gt;Prompt compression strategies&lt;/li&gt;
&lt;li&gt;Where to place Prompt Cache hits&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Prompt Engineering and Security&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why a structured Prompt helps improve response quality&lt;/li&gt;
&lt;li&gt;How to design a subtle, emotionally-aware CoT for affective tasks&lt;/li&gt;
&lt;li&gt;How to prevent malicious prompt injection&lt;/li&gt;
&lt;li&gt;How to translate abstract requirements into concrete ones (making the AI &quot;smarter&quot; and &quot;more human&quot;)&lt;/li&gt;
&lt;li&gt;Did you build prompt-injection protection at the start and end of the interview flow?&lt;/li&gt;
&lt;li&gt;The downside of one-shot: examples that aren&apos;t differentiated enough constrain the model&apos;s thinking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;LLM Fundamentals and Model Engineering&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Attention mechanism (general knowledge)&lt;/li&gt;
&lt;li&gt;Pretraining and LoRA fine-tuning&lt;/li&gt;
&lt;li&gt;The design and limitations of LLM-as-a-Judge&lt;/li&gt;
&lt;li&gt;The trade-off between response speed and response quality&lt;/li&gt;
&lt;li&gt;How to avoid OOC (Out of Character)&lt;/li&gt;
&lt;li&gt;How to handle LLM hallucination&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AI Infra and Productionization&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Designing a model gateway / Agent gateway&lt;/li&gt;
&lt;li&gt;Building an Eval platform&lt;/li&gt;
&lt;li&gt;Evaluating DPO / APO algorithms&lt;/li&gt;
&lt;li&gt;Why use the Vercel AI SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Industry Awareness and System Design&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How Manus, OpenClaw, and OpenCode each approach their architecture&lt;/li&gt;
&lt;li&gt;The main application scenarios for Agents: AI search, Chat-to-BI chart generation, Vibe Coding&lt;/li&gt;
&lt;li&gt;The relationship and difference between Skill and MCP&lt;/li&gt;
&lt;li&gt;Experience with LangChain / LangGraph&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you&apos;ve read this list, you&apos;ll probably notice that not a single one of these can be solved by &quot;memorizing.&quot; What they test is your holistic understanding of the system and your judgment in real engineering.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Questions That Made Me Grow the Most&lt;/h2&gt;
&lt;p&gt;Rather than listing a &quot;model answer&quot; for every question, I&apos;d rather share a few moments in interviews that genuinely made me grow. Some of these I answered well at the time, some I didn&apos;t — but all of them kept reshaping how I think about Agent development long after the interview ended.&lt;/p&gt;
&lt;h3&gt;&quot;What do you do when the context overflows? Besides FIFO, what else?&quot;&lt;/h3&gt;
&lt;p&gt;Almost every company asked this, and the interviewer usually wasn&apos;t satisfied with just &quot;FIFO — evict the oldest messages.&quot;&lt;/p&gt;
&lt;p&gt;The first time I got asked this, I really did only come up with FIFO. The interviewer pressed further: what if the user stated a critical constraint at the very start of the conversation, and FIFO just threw it away? I froze.&lt;/p&gt;
&lt;p&gt;It was only when I reviewed the interview afterward that I realized this question is fundamentally testing your big-picture grasp of &lt;strong&gt;Context Engineering&lt;/strong&gt;. On the Atypica project we were actually already doing all of this — memory layering (Working Memory / Short-term / Long-term), summary compression, retrieval splicing, token-budget control — but I hadn&apos;t strung them together into a complete pipeline in my answer.&lt;/p&gt;
&lt;p&gt;This experience taught me one thing: &lt;strong&gt;having done something isn&apos;t the same as being able to explain it clearly.&lt;/strong&gt; A lot of the time you&apos;ve already solved some problem in your project, but if you never abstracted it into a systematic approach, you&apos;ll fumble and fail to articulate it in the interview. From then on, I deliberately started re-mapping every design decision in Atypica using a &quot;problem → solution → trade-off → result&quot; framework.&lt;/p&gt;
&lt;h3&gt;&quot;How do you stop the LLM from misusing tools?&quot;&lt;/h3&gt;
&lt;p&gt;This sounds simple at first — just add some permission controls, right? But interviewers wanted far more than that.&lt;/p&gt;
&lt;p&gt;In Atypica we built an asynchronous state machine for tool-calling, with mechanisms like checkpoints, retries, idempotency, timeout rollback, and state recovery. But &quot;preventing misuse&quot; isn&apos;t only about backstopping after the fact — what matters more is the &lt;strong&gt;upfront constraints&lt;/strong&gt;: is the Tool Schema design clear enough? Are the Function Calling descriptions free of ambiguity? Does the routing logic correctly dispatch requests to the right tool?&lt;/p&gt;
&lt;p&gt;In one interview the interviewer kept pressing: what if the LLM enters an infinite loop and keeps calling the same tool over and over? I mentioned the watermark and deduplication mechanisms we built, plus the checkpoint-resume design. The interviewer nodded, but then said something that stuck with me: &quot;Have you ever considered that, rather than building so much defense at runtime, it might be better to spell out the boundaries of tool usage at the Prompt layer in the first place?&quot;&lt;/p&gt;
&lt;p&gt;That remark was a wake-up call. The root of many Agent reliability problems isn&apos;t in the runtime layer but in the Prompt layer — if the instructions you give the LLM are vague to begin with, no amount of engineering backstop is anything more than cleaning up after a bad Prompt. That&apos;s exactly why I&apos;ve come to put more and more weight on structured Prompt design and front-loaded guardrails.&lt;/p&gt;
&lt;h3&gt;&quot;Why does a structured Prompt work better than a natural-language Prompt?&quot;&lt;/h3&gt;
&lt;p&gt;I thought this one was easy at first: &quot;Because structured information is easier for the model to parse.&quot; But the interviewer followed up: &quot;From the standpoint of the Attention mechanism, can you explain why?&quot;&lt;/p&gt;
&lt;p&gt;At the time my understanding of Attention was still stuck at &quot;Q, K, V take dot products to compute relevance,&quot; and I&apos;d never thought deeply about its relationship to Prompt format. The interviewer offered a genuinely illuminating line of thinking: a structured Prompt (using XML tags, a JSON Schema, or explicit delimiters, say) is actually helping the model allocate its attention — it gives key information clearer &quot;anchors&quot; within the token sequence, lowering the difficulty of the model &quot;finding the point&quot; in a long context. Natural-language phrasing, by contrast, tends to bury key information under a pile of modifiers and transitional sentences, scattering attention.&lt;/p&gt;
&lt;p&gt;This conversation made me realize that a lot of the Prompt optimizations we do at the engineering level are actually backed by very solid model mechanics. &lt;strong&gt;Knowing the &quot;what&quot; matters, but knowing the &quot;why&quot; matters more&lt;/strong&gt; — and that&apos;s especially true in interviews, where an interviewer can quickly tell whether you&apos;re &quot;reciting experience&quot; or &quot;actually understand it.&quot;&lt;/p&gt;
&lt;h3&gt;&quot;How do you translate abstract requirements into concrete ones?&quot;&lt;/h3&gt;
&lt;p&gt;This might be the most &quot;soft&quot; hard question I ran into.&lt;/p&gt;
&lt;p&gt;The interviewer&apos;s exact words were roughly: &quot;The user says &apos;make the AI a bit smarter&apos; or &apos;make it feel more like a real person&apos; — how do you turn that kind of fuzzy requirement into a technical solution you can actually ship?&quot;&lt;/p&gt;
&lt;p&gt;This happened to be exactly what I&apos;d spent a huge amount of time on in Atypica. We designed a Counter-Questioning system: when a user&apos;s requirement is vague, the Agent doesn&apos;t grit its teeth and guess — instead, through explicit and implicit intent recognition, it decomposes the fuzzy requirement into structured constraints: what&apos;s the goal, who&apos;s the audience, what are the style preferences, what are the limitations.&lt;/p&gt;
&lt;p&gt;I walked through the full design rationale of this system in the interview, and after listening the interviewer asked a question I thought was really sharp: &quot;So how do you judge the quality of the Counter-Questioning? How do you know the questions you&apos;re asking are effective and not just burning the user&apos;s patience?&quot;&lt;/p&gt;
&lt;p&gt;Honestly, I didn&apos;t answer that one well at the time. I thought about it for a long while afterward and figured it would probably need LLM-as-a-Judge or indirect indicators like user satisfaction to evaluate — but that&apos;s a direction I genuinely haven&apos;t yet explored in depth. &lt;strong&gt;That&apos;s just how interviews work: they pinpoint the exact edge of your knowledge.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&quot;How do you prevent malicious prompt injection?&quot;&lt;/h3&gt;
&lt;p&gt;This question came up in multiple interviews, but what really benefited me wasn&apos;t the interview itself — it was the homework I did afterward.&lt;/p&gt;
&lt;p&gt;In the interviews I touched on some basic defensive ideas — input filtering, role locking, output validation, that sort of thing. But the interviewers were clearly hoping for a more systematic answer. So afterward I went and seriously read OpenAI&apos;s and Anthropic&apos;s respective technical blogs on prompt security, and found that the field actually has two very clear core ideas:&lt;/p&gt;
&lt;p&gt;One is OpenAI&apos;s &lt;strong&gt;Instruction Hierarchy&lt;/strong&gt; — the core idea is to assign priorities to instructions from different sources: System Prompt &gt; developer instructions &gt; user input, so the model knows whom to listen to when it hits conflicting instructions. The other is Anthropic&apos;s &lt;strong&gt;sandboxing approach&lt;/strong&gt; — isolating untrusted external content inside a restricted execution environment, limiting the blast radius of malicious instructions at the architectural level.&lt;/p&gt;
&lt;p&gt;Why do I single this out? Because I genuinely recommend that everyone doing Agent development spend time reading OpenAI&apos;s and Anthropic&apos;s technical blogs. These aren&apos;t academic papers stuck at the theoretical level — they&apos;re excellent, frontline engineering practice advice, and after reading them your understanding of many problems will level up. Papers are worth reading too, of course — I&apos;ll be putting out a &lt;strong&gt;curated paper series&lt;/strong&gt; on my personal blog, picking out and breaking down the papers most valuable to Agent development practice. I&apos;m also building an &lt;strong&gt;RSS subscription feed&lt;/strong&gt; that aggregates the latest Agent development practices from the major AI labs, daily or weekly, with my own take and commentary added — not just reposting, but opinionated curation and interpretation. If you&apos;re interested, follow my blog at &lt;a href=&quot;https://joyehuang.me&quot;&gt;joyehuang.me&lt;/a&gt; for updates.&lt;/p&gt;
&lt;h3&gt;&quot;Do you understand the design of Manus / OpenClaw / OpenCode?&quot;&lt;/h3&gt;
&lt;p&gt;This isn&apos;t a question about technical depth — it&apos;s a question about &lt;strong&gt;industry breadth&lt;/strong&gt;. What the interviewer wants to know is: are you paying attention to what&apos;s happening in this industry? Are you only heads-down grinding on your own project, or do you also look up and see how other people are solving similar problems?&lt;/p&gt;
&lt;p&gt;At the time I had some familiarity with Manus and OpenCode (I&apos;d studied OpenCode&apos;s architecture), but I didn&apos;t know much about OpenClaw and my answer was a bit weak. This question reminded me: &lt;strong&gt;Agent development is still in a phase of rapid evolution, and when interviewers probe industry awareness, they&apos;re essentially testing your learning speed and your sensitivity to new information.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you don&apos;t regularly check GitHub Trending, don&apos;t follow the AI discussion on Twitter/X, and don&apos;t dig into newly released open-source projects, you&apos;ll be in a really weak position when this kind of question comes up. I later built a habit of spending a fixed block of time each week looking at the changelogs and design docs of projects like Manus and OpenCode — not necessarily deeply, but at least enough to know which way the industry wind is blowing.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Things That Matter More Than &quot;Grinding Questions&quot;&lt;/h2&gt;
&lt;h3&gt;On the Interview Itself&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Reviewing afterward is the biggest lever in interviewing.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the point I most want to stress: an interview you don&apos;t review is meaningless. If recording isn&apos;t an option, then the moment the interview ends, find a place to sit down and — while your memory is still warm — write down every question and your own answer. Especially the ones you couldn&apos;t answer, or stumbled through — those are the most valuable review material. The list of interview questions you&apos;re reading in this article was recorded exactly this way, round after round.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let the interviewer review you.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A lot of people overlook the value of the part at the end where you get to ask the interviewer questions. I later made it a habit to always ask two questions in that segment: &quot;Where did I not do so well today, and what should I improve?&quot; and &quot;Where did I do reasonably well?&quot; You might think asking this is too direct, but in practice most interviewers are very willing to answer. The feedback they give you is far more precise than your own guessing, and it also shows you&apos;re someone who actively seeks growth.&lt;/p&gt;
&lt;p&gt;Besides those two questions, you can also ask &quot;What would the first project be that I&apos;d take on after joining?&quot; — this shows your sincerity and also helps you judge whether the actual work matches the JD.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The interviewer is also part of your network.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;After the interview, regardless of the outcome, try to add the person on WeChat or LinkedIn. You never know when that relationship will pay off. Here&apos;s a real story: I interviewed with a toB Fintech Agent company and passed the first round, but the interviewer felt their product direction might not fit my interests, so they proactively referred me to another company. I&apos;m now in that company&apos;s written-test stage. &lt;strong&gt;Sometimes opportunities come exactly like this — you never know where a &quot;failed&quot; interview will lead.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;On Choosing Offers: Advice for Interns and Startup-Bound Folks&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Use one question to filter out unreliable startups.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When interviewing with a startup, I always ask one question in the Q&amp;#x26;A segment: &quot;Compared to your competitors, what&apos;s the core advantage of your product?&quot; It sounds simple, but its filtering power is excellent — if a startup&apos;s interviewer can&apos;t even articulate their own product&apos;s differentiation, then that company&apos;s direction is probably fuzzy. If a startup doesn&apos;t even have confidence in its own product, what can you possibly learn there? Just steer clear.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t get suckered by &quot;raised X million in angel funding.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The funding amount is only one dimension for judging a startup — it&apos;s absolutely not the only one. That said, a company with no funding at all does warrant extra caution. But having funding doesn&apos;t mean everything&apos;s fine — you still need to look at whether the product direction is sound, the team&apos;s background, whether you&apos;ll genuinely learn something there, and whether there&apos;s a mentor to guide you. An internship isn&apos;t just selling time; it&apos;s a learning investment, and you need to think clearly about where your time yields the highest return.&lt;/p&gt;
&lt;p&gt;For me personally, the things I care about most when choosing an offer are: is the product interesting? Am I actually genuinely curious about it? Is it overseas-facing? Is it toC? These preferences vary from person to person, but the point is that you need your own framework for judgment, rather than being led around by the funding amount or a company&apos;s name.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Take the initiative — don&apos;t let the &quot;full-time&quot; label scare you off.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On Boss Zhipin and various recruiting platforms, a lot of postings say they&apos;re hiring full-time. But if you feel the role is a great fit, you can absolutely reach out proactively and explain your situation: &quot;I&apos;m still a student, but if your company has any need for interns, I hope you&apos;ll take a look at my résumé.&quot; The worst outcome is getting rejected, but a lot of the time the company actually does have intern headcount — they just didn&apos;t post it separately.&lt;/p&gt;
&lt;p&gt;A tangent: if your internship experience is solid enough, you can even go straight for full-time roles. I interviewed for a full-time Agent development role, got grilled badly, and somehow passed — the interviewer only realized at the very end that I hadn&apos;t graduated yet. That made me realize that &lt;strong&gt;you shouldn&apos;t limit yourself; other people&apos;s expectations of you are often not as low as your own expectations of yourself.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Industry Observations: Reading the Agent Dev Winds from Interview Questions&lt;/h2&gt;
&lt;p&gt;Interview questions are themselves an industry weathervane — what interviewers ask reflects, to some degree, what the industry cares about most right now. Across these nearly 10 interviews, I observed a few clear trends.&lt;/p&gt;
&lt;h3&gt;RAG Is Evolving Toward Agentic&lt;/h3&gt;
&lt;p&gt;Almost every interview asked about RAG, but not a single one stopped at the basic &quot;retrieval + generation&quot; level. Interviewers cared more about Agentic Search and Agentic Memory — meaning retrieval is no longer a passive pipeline, but something the Agent itself decides: &quot;when to search, what to search for, and how to use the results.&quot; This is a qualitative shift from a tool to a capability.&lt;/p&gt;
&lt;h3&gt;The Three Big Agent Use Cases Come Up Again and Again&lt;/h3&gt;
&lt;p&gt;In conversations with interviewers from different companies, three application scenarios came up most often: &lt;strong&gt;AI search&lt;/strong&gt; (the upgrade from keyword matching to semantic understanding), &lt;strong&gt;Chat-to-BI&lt;/strong&gt; (generating data-analysis charts from natural language), and &lt;strong&gt;Vibe Coding&lt;/strong&gt; (using AI to assist or even lead the writing of code). Each of these places different demands on Agent architecture design, but their common thread is the pursuit of stronger &quot;autonomy&quot; and &quot;reliability.&quot;&lt;/p&gt;
&lt;h3&gt;The AI Infra Layer Is Starting to Be Taken Seriously&lt;/h3&gt;
&lt;p&gt;In the early days of Agent development, everyone focused more on the upper-layer application logic — how to write Prompts, how to chain things together. But interviews increasingly feature AI Infra–layer questions: How do you design a model gateway? How does an Agent gateway handle routing and rate limiting? How do you build an Eval platform? How much do you know about alignment algorithms like DPO/APO? This signals that the industry is moving from the &quot;demo stage&quot; toward &quot;production-grade,&quot; and infrastructure maturity is becoming a key factor in determining product reliability.&lt;/p&gt;
&lt;h3&gt;MCP and the Skill System Are Standardizing&lt;/h3&gt;
&lt;p&gt;MCP (Model Context Protocol) came up very frequently in interviews; it represents a direction toward standardizing how Agents invoke capabilities. At the same time, the concept of Skill is emerging from products like Manus — packaging an Agent&apos;s capabilities into reusable, composable modules. For developers, this trend means: &lt;strong&gt;future Agent development may no longer be building from scratch, but assembling and orchestrating within a standardized capability marketplace.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Tool-Chain Choices Reveal Engineering Taste&lt;/h3&gt;
&lt;p&gt;Why use the Vercel AI SDK instead of LangChain? A question like this looks like it&apos;s testing your tech-stack choices, but it&apos;s really testing your understanding of the tool-chain ecosystem and your own engineering judgment. Being able to clearly explain in an interview &quot;why I chose this, what its trade-offs are, and in what scenarios I&apos;d switch to something else&quot; is far more convincing than simply saying &quot;I&apos;ve used X.&quot;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;After this many rounds, my biggest takeaway is: &lt;strong&gt;an interview is a mirror, and it won&apos;t lie to you.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It will pinpoint every gap in your knowledge, and it will make you discover the things you thought you understood but had really only &quot;used.&quot; Going from &quot;I&apos;ve used Agents in my project&quot; to &quot;I can design a reliable Agent system&quot; — what lies between them isn&apos;t more project experience, but deeper understanding and more systematic thinking.&lt;/p&gt;
&lt;p&gt;As a student still in my sophomore year, I know I still have a lot to learn. But this stretch of intensive interviewing gave me a far clearer panorama of Agent development than I had before — not just technically, but in terms of industry judgment too.&lt;/p&gt;
&lt;p&gt;Finally, a line for friends walking the same path:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build fast, learn faster.&lt;/strong&gt; An interview isn&apos;t the finish line; it&apos;s the starting line of the next stretch of growth.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If this article helped you, feel free to share your own interview experiences in the comments, and you can also find me on &lt;a href=&quot;https://github.com/joyehuang&quot;&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>FeedForward: The Transformer&apos;s Other Half Beyond Attention</title><link>https://www.joyehuang.me/en/blog/20251219---feedforward-transformer-block/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20251219---feedforward-transformer-block/post</guid><description>A deep dive into the FeedForward network and how RMSNorm, RoPE, Attention, and FeedForward assemble into a complete Transformer Block.</description><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This is the fourth post (of four) in my MiniMind learning series. It takes a deep dive into the FeedForward network and shows how the four core components — RMSNorm, RoPE, Attention, and FeedForward — assemble into a complete Transformer Block. By the end, you&apos;ll have a thorough grasp of the full Transformer architecture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;About this series&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt; is a concise yet complete project for training a large language model, covering the full pipeline from data processing and model training to inference and deployment. As I worked through it, I distilled the core technical points into the &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt; repository and produced this four-part blog series, walking through the core components of the Transformer in a systematic way.&lt;/p&gt;
&lt;p&gt;This series covers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Normalization&lt;/strong&gt; — why we need RMSNorm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RoPE positional encoding&lt;/strong&gt; — how to make the model understand word order&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Attention mechanism&lt;/strong&gt; — the core engine of the Transformer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FeedForward and the full architecture&lt;/strong&gt; (this post) — how the components work together&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;1. Introduction&lt;/h2&gt;
&lt;h3&gt;1.1 The neglected other half&lt;/h3&gt;
&lt;p&gt;When people think of the Transformer, the usual associations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ The Attention mechanism (the star component)&lt;/li&gt;
&lt;li&gt;✅ Positional encoding (RoPE)&lt;/li&gt;
&lt;li&gt;❓ FeedForward? What&apos;s that?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The facts&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FeedForward accounts for 40% of the code in a Transformer Block&lt;/li&gt;
&lt;li&gt;FeedForward makes up &lt;strong&gt;two-thirds&lt;/strong&gt; of the total parameters!&lt;/li&gt;
&lt;li&gt;You can&apos;t train a good model with Attention alone, without FeedForward&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.2 Questions this post answers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;What does FeedForward actually do?&lt;/li&gt;
&lt;li&gt;Why &quot;expand then compress&quot; (768 → 2048 → 768)?&lt;/li&gt;
&lt;li&gt;What makes SwiGLU better than a plain FFN?&lt;/li&gt;
&lt;li&gt;How do Attention and FeedForward divide the labor?&lt;/li&gt;
&lt;li&gt;How do the four components assemble into a complete Transformer Block?&lt;/li&gt;
&lt;li&gt;What does the residual connection do?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.3 Who this is for&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;ve studied Attention but FFN is still fuzzy&lt;/li&gt;
&lt;li&gt;You want a complete understanding of the Transformer architecture&lt;/li&gt;
&lt;li&gt;You&apos;re getting ready to implement a Transformer from scratch&lt;/li&gt;
&lt;li&gt;You want to know why the Transformer &quot;works&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. What is FeedForward?&lt;/h2&gt;
&lt;h3&gt;2.1 The core idea&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Apply a complex nonlinear transformation to each token&apos;s vector.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key characteristics&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Each token is processed &lt;strong&gt;independently&lt;/strong&gt; (no token-to-token interaction)&lt;/li&gt;
&lt;li&gt;✅ Input dimension = output dimension (768)&lt;/li&gt;
&lt;li&gt;✅ But the content changes completely (it goes through a nonlinear transformation)&lt;/li&gt;
&lt;li&gt;✅ It boosts expressive power by routing through a high-dimensional space&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 A typical structure&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;input:   [batch, seq_len, 768]
  ↓
expand:  Linear(768 → 2048)
  ↓
activate: a nonlinear function (ReLU/GELU/SiLU)
  ↓
compress: Linear(2048 → 768)
  ↓
output:  [batch, seq_len, 768]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.3 A simple implementation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
import torch.nn as nn
import torch.nn.functional as F

class SimpleFeedForward(nn.Module):
    def __init__(self, hidden_size=768, intermediate_size=2048):
        super().__init__()
        self.w1 = nn.Linear(hidden_size, intermediate_size, bias=False)
        self.w2 = nn.Linear(intermediate_size, hidden_size, bias=False)

    def forward(self, x):
        # x: [batch, seq_len, 768]
        h = self.w1(x)       # expand: [batch, seq_len, 2048]
        h = F.relu(h)        # activation
        output = self.w2(h)  # compress: [batch, seq_len, 768]
        return output
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.4 Comparison with Attention&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Attention
sentence: &quot;I love coding&quot;
# &quot;love&quot; can see &quot;I&quot; and &quot;coding&quot;
# → tokens interact, fusing context

# FeedForward
sentence: &quot;I love coding&quot;
# &quot;love&quot; only looks at itself, transformed independently
# → each token is independent, processed in depth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;An analogy&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Attention = a meeting where everyone exchanges information&lt;/li&gt;
&lt;li&gt;FeedForward = everyone thinking on their own, digesting that information independently&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;3. Why &quot;expand then compress&quot;?&lt;/h2&gt;
&lt;h3&gt;3.1 A common question&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Why not just go 768 → 768 directly? Taking a big detour out to 2048 and back — isn&apos;t that wasted compute?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&apos;s a great question!&lt;/p&gt;
&lt;h3&gt;3.2 The intuition: expressive power&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Option 1: a direct transformation&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 768 → 768
output = W @ x  # W is a [768, 768] matrix

# This is just a linear transformation!
# Expressive power = a single matrix multiply
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Option 2: expand then compress&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 768 → 2048 → 768
h = W1 @ x           # [2048, 768] @ [768] = [2048]
h = activation(h)    # nonlinear!
output = W2 @ h      # [768, 2048] @ [2048] = [768]

# Expressive power = two matrix multiplies + a nonlinear activation
# Can fit far more complex functions!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 The mathematical essence: the magic of high-dimensional space&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: in a high-dimensional space, vectors have more &quot;degrees of freedom.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A simplified view&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Direct transformation (768 → 768)&lt;/strong&gt;: can only form linear combinations, constrained by the original dimensionality&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expanding to high dimensions (768 → 2048)&lt;/strong&gt;: more degrees of freedom in the high-dimensional space&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nonlinear activation&lt;/strong&gt;: introduces nonlinear transformation capacity&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compressing back to the original dimension (2048 → 768)&lt;/strong&gt;: retains the complex patterns learned in the high-dimensional space&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Experimental verification&lt;/strong&gt;: when fitting a complex function (such as y = sin(x) + cos(2x)):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Direct transformation &lt;code&gt;Linear(1, 1)&lt;/code&gt;: can only fit a linear function, large error ❌&lt;/li&gt;
&lt;li&gt;Expand-compress &lt;code&gt;Linear(1, 64) → ReLU → Linear(64, 1)&lt;/code&gt;: can fit nonlinear functions, small error ✅&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: expand-compress = expressive power++&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.4 Analogies&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Analogy 1: cooking&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Direct transformation (768 → 768):
  raw ingredients → plated
  no processing, one-note flavor ❌

Expand-compress (768 → 2048 → 768):
  ingredients → chopped, seasoned, cooked (2048-dim high-dimensional space) → plated
  &quot;processed&quot; in a high-dimensional space, rich flavor ✅
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Analogy 2: photo editing&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Direct transformation:
  original → a simple filter → output
  limited effect ❌

Expand-compress:
  original → extract features (more dimensions) → complex transformation → compress back to original size
  enables complex operations like denoising and super-resolution ✅
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5 Why 2048 dimensions (and not 1024 or 4096)?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Rule of thumb&lt;/strong&gt;: intermediate_size ≈ &lt;strong&gt;hidden_size × 2.67 to 4&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;| Model | hidden_size | intermediate_size | Ratio |
|------|-------------|-------------------|------|
| BERT-Base | 768 | 3072 | 4.0 |
| GPT-2 | 768 | 3072 | 4.0 |
| Llama-7B | 4096 | 11008 | 2.69 |
| MiniMind | 768 | 2048 | 2.67 |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why not larger?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Larger = more parameters = slower and more memory-hungry&lt;/li&gt;
&lt;li&gt;2.67–4× is the empirically validated sweet spot&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;4. SwiGLU: the modern Transformer&apos;s choice&lt;/h2&gt;
&lt;h3&gt;4.1 The evolution of FeedForward&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Generation 1 (GPT-2 / BERT, 2018–2019)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;h = ReLU(W1 @ x)
output = W2 @ h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Generation 2 (GPT-3, 2020)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;h = GELU(W1 @ x)  # a smoother activation function
output = W2 @ h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Generation 3 (Llama / MiniMind, 2023)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;gate = SiLU(W_gate @ x)
up = W_up @ x
h = gate * up  # a gating mechanism! ⭐
output = W_down @ h
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 SwiGLU in detail&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Full name&lt;/strong&gt;: Swish-Gated Linear Unit&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Core idea&lt;/strong&gt;: use two branches, one controlling the other.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
import torch.nn as nn
import torch.nn.functional as F

class SwiGLU(nn.Module):
    def __init__(self, dim=768, hidden_dim=2048):
        super().__init__()
        # three linear layers
        self.gate_proj = nn.Linear(dim, hidden_dim, bias=False)  # gating branch
        self.up_proj = nn.Linear(dim, hidden_dim, bias=False)    # up-projection branch
        self.down_proj = nn.Linear(hidden_dim, dim, bias=False)  # down-projection

    def forward(self, x):
        # two branches
        gate = self.gate_proj(x)  # [batch, seq, 2048]
        up = self.up_proj(x)      # [batch, seq, 2048]

        # SiLU activation + gating (element-wise product)
        hidden = F.silu(gate) * up

        # compress back to the original dimension
        output = self.down_proj(hidden)
        return output
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Dimension changes&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;input:  [batch, seq, 768]
  ↓
gate:  [batch, seq, 2048]  ← W_gate @ x
up:    [batch, seq, 2048]  ← W_up @ x
  ↓
hidden: [batch, seq, 2048]  ← SiLU(gate) * up
  ↓
output:  [batch, seq, 768]   ← W_down @ hidden
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 The SiLU activation function&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# SiLU(x) = x * sigmoid(x)
def silu(x):
    return x * torch.sigmoid(x)

# also known as Swish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Compared with common activation functions&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| Activation | Formula | Characteristics |
|---------|------|------|
| ReLU | &lt;code&gt;max(0, x)&lt;/code&gt; | simple, but the gradient can be 0 |
| GELU | &lt;code&gt;x * Φ(x)&lt;/code&gt; | smooth, but slightly slower to compute |
| SiLU/Swish | &lt;code&gt;x * σ(x)&lt;/code&gt; | &lt;strong&gt;smooth and fast to compute&lt;/strong&gt; ✅ |&lt;/p&gt;
&lt;h3&gt;4.4 The power of the gating mechanism&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Intuition&lt;/strong&gt;: the gate branch controls which information from the up branch gets through.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# example
gate = torch.tensor([0.1, 0.9, 0.5, 0.2])  # gating values
up = torch.tensor([5.0, 3.0, 2.0, 8.0])    # up-projection values

# element-wise product
hidden = gate * up
# = [0.5, 2.7, 1.0, 1.6]

# observe:
# where gate=0.9: most of the information passes (2.7 ≈ 3.0)
# where gate=0.1: only a little passes (0.5 &amp;#x3C;&amp;#x3C; 5.0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;An analogy&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Plain FFN:
  all information passes through the same &quot;gate&quot; (a single activation function)

SwiGLU:
  the gate branch acts like a &quot;security guard,&quot; deciding which information from the up branch can enter
  a dynamic, more flexible choice!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 Plain FFN vs SwiGLU&lt;/h3&gt;
&lt;p&gt;| Feature | Plain FFN | SwiGLU |
|------|---------|--------|
| &lt;strong&gt;Number of branches&lt;/strong&gt; | 1 | 2 (gate + up) |
| &lt;strong&gt;Activation&lt;/strong&gt; | ReLU/GELU | SiLU |
| &lt;strong&gt;Gating&lt;/strong&gt; | none | yes (gate × up) |
| &lt;strong&gt;Parameters&lt;/strong&gt; | 2 × 768 × 2048 | 3 × 768 × 2048 (&lt;strong&gt;50% more&lt;/strong&gt;) |
| &lt;strong&gt;Compute&lt;/strong&gt; | less | slightly more |
| &lt;strong&gt;Performance&lt;/strong&gt; | good | &lt;strong&gt;better&lt;/strong&gt; (empirically proven) |
| &lt;strong&gt;Models used in&lt;/strong&gt; | GPT-2, BERT | Llama, MiniMind, PaLM |&lt;/p&gt;
&lt;h3&gt;4.6 Why the extra parameters are worth it&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# parameter comparison (using MiniMind as an example)
plain FFN parameters:
  W1: 768 × 2048 = 1,572,864
  W2: 2048 × 768 = 1,572,864
  total: 3,145,728

SwiGLU parameters:
  gate_proj: 768 × 2048 = 1,572,864
  up_proj: 768 × 2048 = 1,572,864
  down_proj: 2048 × 768 = 1,572,864
  total: 4,718,592 (50% more)

# but!
# Attention layer parameters: 768 × 768 × 4 ≈ 2.4M
# SwiGLU parameters: 4.7M

# FeedForward share of total parameters: 4.7M / (2.4M + 4.7M) ≈ 66%
# improving this part has a big effect on the model as a whole!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Experimental results&lt;/strong&gt; (the Llama paper):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At equal parameter counts, SwiGLU outperforms GELU by &lt;strong&gt;5–10%&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;For equal performance, SwiGLU trains faster (gradients are more stable)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;5. The division of labor: Attention vs FeedForward&lt;/h2&gt;
&lt;h3&gt;5.1 The full comparison&lt;/h3&gt;
&lt;p&gt;| Feature | Attention | FeedForward |
|------|-----------|-------------|
| &lt;strong&gt;How it processes&lt;/strong&gt; | tokens interact | each token independently |
| &lt;strong&gt;Role&lt;/strong&gt; | information exchange (a meeting) | deep thinking (digesting independently) |
| &lt;strong&gt;Input&lt;/strong&gt; | [seq, 768] | [seq, 768] |
| &lt;strong&gt;Intermediate dimension&lt;/strong&gt; | [seq, seq] (score matrix) | [seq, 2048] (expansion) |
| &lt;strong&gt;Output&lt;/strong&gt; | [seq, 768] | [seq, 768] |
| &lt;strong&gt;Positional encoding&lt;/strong&gt; | required (RoPE) | not needed |
| &lt;strong&gt;Parameters&lt;/strong&gt; | about 33% | about 67% |
| &lt;strong&gt;Compute bottleneck&lt;/strong&gt; | seq² (quadratic in sequence length) | batch×seq (linear) |
| &lt;strong&gt;Analogy&lt;/strong&gt; | looking up a dictionary, a meeting | solving a math problem, thinking |&lt;/p&gt;
&lt;h3&gt;5.2 Why you can&apos;t do without either one&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Attention only&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Tokens can interact&lt;/li&gt;
&lt;li&gt;❌ Lacks &quot;deep understanding&quot;&lt;/li&gt;
&lt;li&gt;It&apos;s like having meetings to discuss but never thinking on your own&lt;/li&gt;
&lt;li&gt;The model can&apos;t learn complex patterns&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;FeedForward only&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Each token can be transformed in complex ways&lt;/li&gt;
&lt;li&gt;❌ Has no sense of context&lt;/li&gt;
&lt;li&gt;It&apos;s like working in isolation, never listening to others&apos; input&lt;/li&gt;
&lt;li&gt;The model has no idea how tokens relate to one another&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The two combined&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Step 1: Attention
  → lets the model know &quot;which tokens are relevant&quot;
  → fuses contextual information

Step 2: FeedForward
  → lets the model know &quot;how to process that information&quot;
  → a deep nonlinear transformation

Step 3: repeat N times
  → refine the understanding layer by layer
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 A full walkthrough&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;sentence: &quot;I love coding&quot;

# ========== Attention stage ==========
# &quot;love&quot; gathers information from &quot;I&quot; and &quot;coding&quot;
&quot;love&quot; ← &quot;I&quot; (29%) + &quot;love&quot; (36%) + &quot;coding&quot; (25%)
# &quot;love&quot; now knows: it connects &quot;I&quot; and &quot;coding&quot;

# ========== FeedForward stage ==========
# &quot;love&quot; thinks deeply based on the information it gathered
representation of &quot;love&quot; [768-dim]
  ↓ expand into a high-dimensional space
[2048-dim]
  ↓ gating mechanism + nonlinear transformation
[2048-dim]  # complex reasoning in the high-dimensional space
  ↓ compress back to the original dimension
[768-dim]  # the refined understanding

# in the end
# &quot;love&quot; has both fused context (Attention)
# and completed a deep understanding (FeedForward)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;6. Assembling the Transformer Block&lt;/h2&gt;
&lt;h3&gt;6.1 The four core components&lt;/h3&gt;
&lt;p&gt;A recap of the four components we&apos;ve studied:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RMSNorm&lt;/strong&gt;: stabilizes the numbers (normalization)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt;: tokens interact (information exchange)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FeedForward&lt;/strong&gt;: independent deepening (deep thinking)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Residual Connection&lt;/strong&gt;: a safety net (the residual connection)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6.2 The complete Transformer Block structure&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
import torch.nn as nn

class TransformerBlock(nn.Module):
    def __init__(self, config):
        super().__init__()
        # RMSNorm #1: before Attention
        self.input_layernorm = RMSNorm(config.hidden_size)

        # Multi-Head Attention
        self.self_attn = Attention(config)

        # RMSNorm #2: before FeedForward
        self.post_attention_layernorm = RMSNorm(config.hidden_size)

        # FeedForward (SwiGLU)
        self.mlp = FeedForward(config)

    def forward(self, x, position_embeddings):
        # ========== Part 1: Attention ==========
        # 1. save the input (for the residual connection)
        residual = x

        # 2. RMSNorm #1 (normalization)
        x = self.input_layernorm(x)

        # 3. Multi-Head Attention
        x = self.self_attn(x, position_embeddings)

        # 4. residual connection
        x = residual + x

        # ========== Part 2: FeedForward ==========
        # 5. save the current state (for the residual connection)
        residual = x

        # 6. RMSNorm #2 (normalization)
        x = self.post_attention_layernorm(x)

        # 7. FeedForward (SwiGLU)
        x = self.mlp(x)

        # 8. residual connection
        x = residual + x

        return x
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 The data flow diagram&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;input x: [batch, seq_len, 768]
  ↓
  ├──────┐ (save residual)
  ↓      │
RMSNorm #1  ← normalization
  ↓
Multi-Head Attention (+ RoPE)  ← tokens interact
  ↓
  └──────┘ (add residual) ← residual connection
  ↓
  ├──────┐ (save residual)
  ↓      │
RMSNorm #2  ← normalization
  ↓
FeedForward (SwiGLU)  ← independent deepening
  ↓
  └──────┘ (add residual) ← residual connection
  ↓
output x: [batch, seq_len, 768]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 The residual connection&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The formula&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;y = x + F(x)

# rather than
y = F(x)  # no residual
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Three big benefits&lt;/strong&gt;:&lt;/p&gt;
&lt;h4&gt;Benefit 1: a safety net&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# worst case: F learns nothing
y = x + 0 = x  # at least you still have the input!

# without the residual
y = F(x) = noise  # completely broken ❌
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Benefit 2: incremental learning&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# with a residual: only need to learn the &quot;adjustment&quot;
y = x + Δx  # Δx is a small adjustment

# without a residual: need to learn the &quot;full output&quot;
y = F(x)  # F has to learn to build y from scratch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;An analogy&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Without a residual: each edit fully overwrites the original
  original → filter → new image (the original is lost)

With a residual: original + each adjustment
  original → original + adjustment 1 → original + adjustment 1 + adjustment 2 ...
  all the information is preserved!
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Benefit 3: a gradient highway&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# backpropagation
dy/dx = 1 + dF/dx

# even if F&apos;s gradient vanishes (dF/dx → 0)
dy/dx = 1  # the gradient can still flow back! ✅

# without a residual
dy/dx = dF/dx  # once it vanishes, the path is cut entirely ❌
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 Pre-Norm vs Post-Norm&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Post-Norm (the original Transformer, 2017)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# normalization comes after the sublayer
x = x + Attention(x)
x = Norm(x)
x = x + FeedForward(x)
x = Norm(x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pre-Norm (modern Transformers, Llama / MiniMind)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# normalization comes before the sublayer
x = x + Attention(Norm(x))
x = x + FeedForward(Norm(x))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pre-Norm&apos;s advantages&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| Feature | Post-Norm | Pre-Norm |
|------|-----------|----------|
| &lt;strong&gt;Training stability&lt;/strong&gt; | difficult for deep networks | more stable ✅ |
| &lt;strong&gt;Gradient flow&lt;/strong&gt; | can be interrupted by Norm | a cleaner residual path ✅ |
| &lt;strong&gt;Learning rate&lt;/strong&gt; | needs warmup | can use a larger learning rate ✅ |&lt;/p&gt;
/* | **Suitable for** | shallow networks (&amp;#x26;lt; 12 layers) | deep networks (&amp;#x26;gt; 12 layers) ✅ | */
&lt;p&gt;&lt;strong&gt;Every modern LLM uses Pre-Norm&lt;/strong&gt; (GPT-3, Llama, MiniMind, Mistral, …).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;7. The complete MiniMind architecture&lt;/h2&gt;
&lt;h3&gt;7.1 The overall structure&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;MiniMindForCausalLM
├─ lm_head: output layer (hidden_size → vocab_size)
│   maps a 768-dim vector to a probability distribution over 6400 tokens
│
└─ MiniMindModel
    ├─ embed_tokens: token embedding layer (vocab_size → hidden_size)
    │   converts a token ID into a 768-dim vector
    │
    ├─ layers: N TransformerBlocks (8 by default)
    │   └─ TransformerBlock × 8
    │       ├─ input_layernorm: RMSNorm
    │       ├─ self_attn: Multi-Head Attention
    │       ├─ post_attention_layernorm: RMSNorm
    │       └─ mlp: FeedForward (SwiGLU)
    │
    └─ norm: the final RMSNorm
        normalizes the last layer&apos;s output once more
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 The forward pass&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# input
token_ids = [34, 128, 556, 89, ...]  # the IDs for &quot;I love coding&quot;

# ========== token embedding ==========
x = embed_tokens(token_ids)
# [batch, seq_len] → [batch, seq_len, 768]

# ========== precompute RoPE ==========
cos, sin = precompute_freqs_cis(...)  # positional encoding

# ========== TransformerBlock #1 ==========
x = block_1(x, position_embeddings=(cos, sin))
# [batch, seq_len, 768] → [batch, seq_len, 768]

# ========== TransformerBlock #2 ==========
x = block_2(x, position_embeddings=(cos, sin))

# ...

# ========== TransformerBlock #8 ==========
x = block_8(x, position_embeddings=(cos, sin))

# ========== final normalization ==========
x = self.norm(x)
# [batch, seq_len, 768]

# ========== output layer ==========
logits = lm_head(x)
# [batch, seq_len, 768] → [batch, seq_len, 6400]
# each position predicts the probability distribution of the next token

# ========== generation ==========
next_token_id = torch.argmax(logits[:, -1, :], dim=-1)
# pick the highest-probability token
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.3 Parameter breakdown&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# MiniMind2 (104M parameters)

# token embedding
embed_tokens: 6400 × 768 = 4,915,200

# 8 TransformerBlocks
each Block:
  Attention:
    q_proj: 768 × 768 = 589,824
    k_proj: 768 × 768 = 589,824
    v_proj: 768 × 768 = 589,824
    o_proj: 768 × 768 = 589,824
    subtotal: 2,359,296

  FeedForward (SwiGLU):
    gate_proj: 768 × 2048 = 1,572,864
    up_proj: 768 × 2048 = 1,572,864
    down_proj: 2048 × 768 = 1,572,864
    subtotal: 4,718,592

  per-Block total: 7,077,888

8 Blocks: 8 × 7,077,888 = 56,623,104

# output layer
lm_head: 768 × 6400 = 4,915,200

# grand total
4.9M + 56.6M + 4.9M ≈ 104M ✅
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Observations&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FeedForward parameters (4.7M) are &lt;strong&gt;2×&lt;/strong&gt; the Attention parameters (2.4M)!&lt;/li&gt;
&lt;li&gt;FeedForward accounts for &lt;strong&gt;67%&lt;/strong&gt; of each Block&apos;s parameters&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7.4 Configuration parameters&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# MiniMind config (model/model_minimind.py)
class MiniMindConfig:
    hidden_size = 768           # hidden dimension
    num_hidden_layers = 8       # number of Transformer Block layers
    num_attention_heads = 8     # number of attention heads
    num_key_value_heads = 2     # GQA: number of KV heads
    intermediate_size = 2048    # FFN intermediate dimension
    vocab_size = 6400           # vocabulary size
    max_position_embeddings = 32768  # maximum sequence length
    rope_theta = 1000000.0      # RoPE base frequency
    rms_norm_eps = 1e-5         # RMSNorm epsilon
    use_moe = False             # whether to use MoE
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;8. Hands-on experiments&lt;/h2&gt;
&lt;p&gt;To really understand FeedForward, try the following experiments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Compare a plain FFN with SwiGLU&lt;/strong&gt;: implement both architectures and compare parameter counts (SwiGLU has 50% more) and training performance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify the necessity of expand-compress&lt;/strong&gt;: try a direct 768→768 transformation vs 768→2048→768, and observe the difference in fitting ability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test the residual connection&lt;/strong&gt;: compare the training stability and convergence speed of networks with and without a residual connection.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See the MiniMind project&apos;s &lt;code&gt;learning_materials/feedforward_explained.py&lt;/code&gt; for the complete experiment code.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;9. Summary&lt;/h2&gt;
&lt;h3&gt;9.1 Key takeaways&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;What FeedForward does&lt;/strong&gt;: independent deepening — a complex nonlinear transformation applied to each token&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Why expand-compress is necessary&lt;/strong&gt;: a high-dimensional space has greater expressive power and can fit complex functions&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;SwiGLU&apos;s advantage&lt;/strong&gt;: a gating mechanism with two branches, 5–10% better than a plain FFN&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Attention vs FFN&lt;/strong&gt;: interaction vs independence, a meeting vs thinking — you can&apos;t do without either&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The Transformer Block&lt;/strong&gt;: four components combined perfectly (Norm + Attn + Norm + FFN + Residual)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The residual connection&lt;/strong&gt;: a safety net + incremental learning + a gradient highway&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Pre-Norm&lt;/strong&gt;: the standard choice for modern deep Transformers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9.2 The Transformer Block mantra&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Norm → Attention → residual
Norm → FeedForward → residual
repeat N times → a complete model!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;9.3 A look back at the series&lt;/h3&gt;
&lt;p&gt;Congratulations on completing the study of MiniMind&apos;s core architecture!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A recap of the four posts&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;✅ &lt;strong&gt;RMSNorm&lt;/strong&gt;: the principles of normalization, and why it&apos;s 7.7× faster than LayerNorm&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;RoPE&lt;/strong&gt;: positional encoding, with an in-depth analysis of the multi-frequency mechanism&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Attention&lt;/strong&gt;: Q, K, V, and a complete understanding of Multi-Head&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;FeedForward + architecture&lt;/strong&gt;: expand-compress, and the full assembly&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;What you now have&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ All the core components of the Transformer&lt;/li&gt;
&lt;li&gt;✅ The mathematical principles and code implementation of each component&lt;/li&gt;
&lt;li&gt;✅ How the components work together&lt;/li&gt;
&lt;li&gt;✅ Why the Transformer &quot;works&quot;&lt;/li&gt;
&lt;li&gt;✅ The ability to implement a small Transformer from scratch!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9.4 Suggested next steps&lt;/h3&gt;
&lt;h4&gt;1. Get hands-on&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# clone MiniMind
git clone https://github.com/jingyaogong/minimind
cd minimind

# train a small model
cd trainer
python train_pretrain.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. Go deeper&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;GQA (Grouped Query Attention): saves memory&lt;/li&gt;
&lt;li&gt;Flash Attention: optimizes compute efficiency&lt;/li&gt;
&lt;li&gt;MoE (Mixture of Experts): increases capacity&lt;/li&gt;
&lt;li&gt;KV Cache: speeds up inference&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. The implementation challenge&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# challenge: implement MiniMind from scratch
class MyMiniMind(nn.Module):
    def __init__(self):
        # over to you!
        pass
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;10. References&lt;/h2&gt;
&lt;h3&gt;Papers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1706.03762&quot;&gt;Attention Is All You Need&lt;/a&gt; - the original Transformer paper&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2002.05202&quot;&gt;GLU Variants Improve Transformer&lt;/a&gt; - the SwiGLU paper&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1512.03385&quot;&gt;Deep Residual Learning for Image Recognition&lt;/a&gt; - ResNet / residual connections&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Code&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MiniMind source: &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;github.com/jingyaogong/minimind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;This post&apos;s learning materials: &lt;code&gt;learning_materials/feedforward_explained.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Transformer Block: &lt;code&gt;model/model_minimind.py:359-380&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Related reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251216---normalization/post&quot;&gt;Part 1: Why does the Transformer need normalization? From vanishing gradients to RMSNorm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251217---rope-position-encoding/post&quot;&gt;Part 2: RoPE positional encoding: from permutation invariance to the multi-frequency mechanism&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251218---attention-mechanism/post&quot;&gt;Part 3: The Attention mechanism explained&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: joye
&lt;strong&gt;Published&lt;/strong&gt;: 2025-12-30
&lt;strong&gt;Last updated&lt;/strong&gt;: 2025-12-30
&lt;strong&gt;Series&lt;/strong&gt;: MiniMind learning notes (4/4)&lt;/p&gt;
&lt;p&gt;If you found this helpful, feel free to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ Star the original project, &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⭐ Star my study notes, &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💬 Leave a comment with your own learning takeaways&lt;/li&gt;
&lt;li&gt;🔗 Share it with other friends learning about LLMs&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Understanding Attention: From Q, K, V to Multi-Head</title><link>https://www.joyehuang.me/en/blog/20251218---attention-mechanism/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20251218---attention-mechanism/post</guid><description>A deep dive into Attention, the Transformer&apos;s core engine: grasp Q, K, V via a database-query analogy, master Multi-Head, and clear up Softmax vs RMSNorm.</description><pubDate>Thu, 18 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This is the third post in my MiniMind learning series, a deep dive into Attention — the core engine of the Transformer. I&apos;ll use a database-query analogy to give you a thorough understanding of what Q, K, V actually mean, walk you through implementing Multi-Head Attention, and clear up the common confusion between Softmax and RMSNorm.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;About this series&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt; is a concise but complete large-language-model training project, covering the full pipeline from data processing to model training to inference deployment. While working through it, I distilled the key technical points into my &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt; repo and produced this four-part series of blog posts that systematically explain the core components of the Transformer.&lt;/p&gt;
&lt;p&gt;This series covers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Normalization&lt;/strong&gt; — why we need RMSNorm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RoPE positional encoding&lt;/strong&gt; — how to make the model understand word order&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt; (this post) — the core engine of the Transformer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FeedForward and the full architecture&lt;/strong&gt; — how the components work together&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;1. Introduction&lt;/h2&gt;
&lt;h3&gt;1.1 The soul of the Transformer&lt;/h3&gt;
&lt;p&gt;If the Transformer is a building:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Normalization (RMSNorm)&lt;/strong&gt; is the foundation — it stabilizes training&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Positional encoding (RoPE)&lt;/strong&gt; is the coordinate system — it distinguishes positions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt; is the core engine — it understands meaning ⭐&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Without Attention, there is no Transformer.&lt;/p&gt;
&lt;h3&gt;1.2 Questions this post answers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;What exactly are Q, K, and V? (It&apos;s not magic!)&lt;/li&gt;
&lt;li&gt;Why split into 8 heads?&lt;/li&gt;
&lt;li&gt;What&apos;s the difference between Softmax and RMSNorm? (a common point of confusion)&lt;/li&gt;
&lt;li&gt;How does Attention work together with RoPE?&lt;/li&gt;
&lt;li&gt;How do the dimensions change in Multi-Head Attention?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.3 Who this is for&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;ve heard of Attention but don&apos;t understand the computational details&lt;/li&gt;
&lt;li&gt;You want to grasp the Multi-Head mechanism at the code level&lt;/li&gt;
&lt;li&gt;You&apos;re getting ready to implement your own Transformer&lt;/li&gt;
&lt;li&gt;You&apos;re not afraid of the math (this post explains it in detail)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. The essence of Attention: relevance between words&lt;/h2&gt;
&lt;h3&gt;2.1 The core question&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;When understanding a word, which other words in the sentence should we pay attention to?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Sentence: &quot;Xiaoming loves his cat; it always sleeps by the window&quot;

When the model interprets the word &quot;it&quot;:
  &quot;it&quot; ← &quot;Xiaoming&quot;  relevance: 0.1   (unlikely — a pronoun rarely refers to a name)
  &quot;it&quot; ← &quot;loves&quot;     relevance: 0.05  (almost unrelated)
  &quot;it&quot; ← &quot;cat&quot;       relevance: 0.8   (highly relevant!) ✅
  &quot;it&quot; ← &quot;window&quot;    relevance: 0.05  (almost unrelated)

Final representation of &quot;it&quot; = 0.1×[Xiaoming] + 0.05×[loves] + 0.8×[cat] + 0.05×[window]
                             ≈ mostly information from &quot;cat&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;What Attention does&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Compute relevance scores&lt;/strong&gt; (between every pair of words)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Normalize them into a probability distribution&lt;/strong&gt; (Softmax — they sum to 1)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Take a weighted sum&lt;/strong&gt; (fuse in the context)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2.2 Input vs output&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Input: isolated word vectors (each word knows nothing about its context)
input = [
    [768-dim vector for &quot;I&quot;],         # doesn&apos;t know whether &quot;love&quot; or &quot;hate&quot; comes next
    [768-dim vector for &quot;love&quot;],      # doesn&apos;t know who the subject or object is
    [768-dim vector for &quot;programming&quot;] # doesn&apos;t know whether it&apos;s loved or hated
]

# Attention processing

# Output: word vectors that have absorbed the context
output = [
    [new vector for &quot;I&quot;],          # now knows: &quot;I&quot; is the subject of the action &quot;love&quot;
    [new vector for &quot;love&quot;],       # now knows: it connects &quot;I&quot; and &quot;programming&quot;
    [new vector for &quot;programming&quot;] # now knows: it&apos;s the object of the action &quot;love&quot;
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.3 Self-Attention vs Cross-Attention&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Self-Attention (used by MiniMind)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# The sentence attends to words &quot;within itself&quot;
sentence = &quot;I love programming&quot;
# Compute the relevance among: I ← → love ← → programming
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Cross-Attention (used by translation models)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Sentence A attends to sentence B
chinese = &quot;我爱编程&quot;
english = &quot;I love programming&quot;
# Compute: &quot;我&quot; ← &quot;I&quot;, &quot;爱&quot; ← &quot;love&quot;, &quot;编程&quot; ← &quot;programming&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Why is it called &quot;Self&quot;&lt;/strong&gt;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Because it computes relationships &lt;strong&gt;within the same sentence&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Not &quot;a token with itself&quot; (even though q_i · k_i is also computed)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;3. Q, K, V in detail: the database-query analogy&lt;/h2&gt;
&lt;h3&gt;3.1 The classic analogy: a database query&lt;/h3&gt;
&lt;p&gt;The best way to understand Q, K, V is to compare them to a SQL query:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT value          ← return the Value
FROM memory_bank      ← the memory bank (all the words)
WHERE key MATCHES query  ← the Key matches the Query
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The correspondence&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| SQL concept | Attention concept | Role | Analogy |
|---------|---------------|------|------|
| &lt;strong&gt;Query&lt;/strong&gt; | Query (Q) | &quot;What information am I looking for?&quot; | search condition |
| &lt;strong&gt;Key&lt;/strong&gt; | Key (K) | &quot;What information do I have here?&quot; | index label |
| &lt;strong&gt;Value&lt;/strong&gt; | Value (V) | &quot;My actual content&quot; | data value |&lt;/p&gt;
&lt;h3&gt;3.2 A concrete example: understanding &quot;love&quot;&lt;/h3&gt;
&lt;p&gt;Sentence: &quot;I love programming&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When interpreting the word &quot;love&quot;&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Query (what &quot;love&quot; wants to know)&lt;/strong&gt;: Who are the subject and object? What action am I expressing?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Keys (what information the other words offer)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Key(&quot;I&quot;) = &quot;I&apos;m the subject, a first-person pronoun&quot;&lt;/li&gt;
&lt;li&gt;Key(&quot;programming&quot;) = &quot;I&apos;m the object, denoting an activity&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Compute similarity&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Q of &quot;love&quot; · K of &quot;I&quot; = 0.6 (moderately relevant)&lt;/li&gt;
&lt;li&gt;Q of &quot;love&quot; · K of &quot;programming&quot; = 0.8 (highly relevant!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Softmax normalization&lt;/strong&gt;: &lt;code&gt;[0.25, 0.15, 0.60]&lt;/code&gt; (60% attention on &quot;programming&quot;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Weighted sum of Values&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New representation of &quot;love&quot; = 0.25×Value(&quot;I&quot;) + 0.15×Value(&quot;love&quot;) + 0.60×Value(&quot;programming&quot;)&lt;/li&gt;
&lt;li&gt;It has absorbed the context and knows it connects &quot;I&quot; and &quot;programming&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3.3 Where do Q, K, V come from?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The key insight&lt;/strong&gt;: Q, K, and V all come from the &lt;strong&gt;same input X&lt;/strong&gt;, transformed by &lt;strong&gt;different weight matrices&lt;/strong&gt;!&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Input X: [3, 768] (3 words, each 768-dimensional)
# Weight matrices W_Q, W_K, W_V: [768, 768]

Q = X @ W_Q  # Query: &quot;What do I want to know?&quot;
K = X @ W_K  # Key:   &quot;What information do I have?&quot;
V = X @ W_V  # Value: &quot;My actual content&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Same dimensions, different meanings.&lt;/strong&gt; The three matrices transform the input into three different &quot;perspectives.&quot;&lt;/p&gt;
&lt;h3&gt;3.4 What the weight matrices really are&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;A common question&lt;/strong&gt;: &quot;Where do W_Q, W_K, W_V come from?&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The answer&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What they are&lt;/strong&gt;: learnable parameters of the neural network&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Where they come from&lt;/strong&gt;: learned from training data via backpropagation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Where they&apos;re stored&lt;/strong&gt;: saved in the model file (.pth, .safetensors)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What they do&lt;/strong&gt;: transform the input into three different &quot;perspectives&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In MiniMind they are three &lt;code&gt;nn.Linear&lt;/code&gt; layers (&lt;code&gt;q_proj&lt;/code&gt;, &lt;code&gt;k_proj&lt;/code&gt;, &lt;code&gt;v_proj&lt;/code&gt;). After training, W_Q learns to extract &quot;query features,&quot; W_K learns to extract &quot;index features,&quot; and W_V learns to extract &quot;content features.&quot;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. The Attention computation pipeline&lt;/h2&gt;
&lt;h3&gt;4.1 The full formula&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Attention(Q, K, V) = softmax(Q @ K^T / √d_k) @ V
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This single formula captures the entire Attention mechanism!&lt;/p&gt;
&lt;h3&gt;4.2 Step by step&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Compute similarity (dot product)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;scores = Q @ K.T  # [seq_len, seq_len]
# scores[i, j] = Q[i] · K[j] (the more similar two vectors are, the larger the dot product)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Scale (divide by √d_k)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;scaled_scores = scores / math.sqrt(head_dim)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Why scale?&lt;/strong&gt; The larger the dimension, the larger the dot products. Without scaling, Softmax becomes too &quot;peaked&quot; and the gradients vanish. After scaling, the distribution is smoother and the gradients are more stable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Softmax normalization&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;attn_weights = softmax(scaled_scores, dim=-1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This turns the scores into a probability distribution: every weight is ≥ 0, each row sums to 1, and the result can be read as &quot;how much attention&quot; to pay.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4: Weighted sum of Values&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;output = attn_weights @ V
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example: new representation of &quot;love&quot; = 0.29×Value(&quot;I&quot;) + 0.36×Value(&quot;love&quot;) + 0.25×Value(&quot;programming&quot;)&lt;/p&gt;
&lt;h3&gt;4.3 Full code implementation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def attention(Q, K, V, mask=None):
    head_dim = Q.shape[-1]

    # 1-2. Compute similarity and scale
    scores = (Q @ K.transpose(-2, -1)) / math.sqrt(head_dim)

    # 3. Apply the mask (optional, for causal attention)
    if mask is not None:
        scores = scores.masked_fill(mask == 0, -1e9)

    # 4-5. Softmax + weighted sum
    attn_weights = F.softmax(scores, dim=-1)
    output = attn_weights @ V

    return output, attn_weights
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;5. Multi-Head Attention&lt;/h2&gt;
&lt;h3&gt;5.1 Why do we need multiple heads?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The limitation of a single head&lt;/strong&gt;: it can only attend to one aspect.&lt;/p&gt;
&lt;p&gt;Sentence: &quot;Xiaoming studies artificial intelligence at Tsinghua University in Beijing&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A single-head Attention might only attend to&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Subject-verb-object relations (grammar)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;But we want to attend to all of these at once&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Grammatical structure (subject-verb-object)&lt;/li&gt;
&lt;li&gt;Entity relations (Xiaoming–Tsinghua)&lt;/li&gt;
&lt;li&gt;Geographic location (Tsinghua–Beijing)&lt;/li&gt;
&lt;li&gt;Topic domain (artificial intelligence)&lt;/li&gt;
&lt;li&gt;Semantic relevance (studies–artificial intelligence)&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The solution&lt;/strong&gt;: Multi-Head Attention!&lt;/p&gt;
&lt;h3&gt;5.2 The &quot;multiple pairs of glasses&quot; analogy&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Head 1: grammar glasses 👓
  → attends to subject-verb-object relations and syntactic structure

Head 2: entity glasses 🕶️
  → attends to names of people, places, and organizations

Head 3: semantic glasses 👓
  → attends to synonyms and related concepts

Head 4: long-range-dependency glasses 🕶️
  → attends to words that are far apart but related

Head 5: sentiment glasses 👓
  → attends to emotional and attitudinal words

...

Head 8: topic glasses 🕶️
  → attends to topics and domain vocabulary

Finally: take off all the glasses and fuse the 8 perspectives!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 The Multi-Head implementation pipeline&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# MiniMind configuration
hidden_size = 768
num_heads = 8
head_dim = hidden_size // num_heads = 96

# Full pipeline
Input X: [batch, seq_len, 768]
  ↓
Generate Q, K, V: [batch, seq_len, 768]
  ↓
Split into 8 heads: [batch, seq_len, 8, 96]
  ↓
Transpose: [batch, 8, seq_len, 96]  # makes parallel computation convenient
  ↓
Each head computes Attention independently (in parallel)
  ↓
Output: [batch, 8, seq_len, 96]
  ↓
Transpose back: [batch, seq_len, 8, 96]
  ↓
Merge (reshape): [batch, seq_len, 768]
  ↓
Output projection: [batch, seq_len, 768]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 Code implementation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class MultiHeadAttention(nn.Module):
    def __init__(self, hidden_size=768, num_heads=8):
        super().__init__()
        self.num_heads = num_heads
        self.head_dim = hidden_size // num_heads  # 96

        self.q_proj = nn.Linear(hidden_size, hidden_size, bias=False)
        self.k_proj = nn.Linear(hidden_size, hidden_size, bias=False)
        self.v_proj = nn.Linear(hidden_size, hidden_size, bias=False)
        self.o_proj = nn.Linear(hidden_size, hidden_size, bias=False)

    def forward(self, x, mask=None):
        batch, seq_len, _ = x.shape

        # 1. Generate Q, K, V and split into multiple heads
        Q = self.q_proj(x).view(batch, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
        K = self.k_proj(x).view(batch, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
        V = self.v_proj(x).view(batch, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
        # [batch, num_heads, seq_len, head_dim]

        # 2. Compute Attention (8 heads in parallel)
        scores = (Q @ K.transpose(-2, -1)) / math.sqrt(self.head_dim)
        attn_weights = F.softmax(scores, dim=-1)
        output = attn_weights @ V

        # 3. Merge the heads and apply the output projection
        output = output.transpose(1, 2).contiguous().view(batch, seq_len, -1)
        return self.o_proj(output)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 Tracking the dimensions&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Input: [batch, seq_len, 768]
  → Q, K, V: [batch, seq_len, 768]
  → Split + transpose: [batch, 8, seq_len, 96]
  → Attention: [batch, 8, seq_len, 96]
  → Merge: [batch, seq_len, 768]
  → Output projection: [batch, seq_len, 768]

Key invariant: num_heads × head_dim = 768
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.6 Why concatenate after splitting?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Splitting&lt;/strong&gt;: lets each head focus on a different aspect&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Head 1 learns to attend to grammar
# Head 2 learns to attend to entities
# ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Concatenating&lt;/strong&gt;: fuses the information from all perspectives&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Analogy: 8 experts each analyze the same case
# Each expert writes a 96-word report
# In the end they&apos;re stitched into one 768-word combined report
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Why not just average?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Concatenating preserves all the information (768 dimensions)&lt;/li&gt;
&lt;li&gt;Averaging would lose information (still only 96 dimensions)&lt;/li&gt;
&lt;li&gt;The downstream FFN can learn how to fuse this information&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;6. A common point of confusion: Softmax vs RMSNorm&lt;/h2&gt;
&lt;h3&gt;6.1 A question many people have&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The Softmax inside Attention and the RMSNorm in the Transformer block are both normalization. What&apos;s the difference?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is a common point of confusion!&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;6.2 The key differences&lt;/h3&gt;
&lt;p&gt;| Property | Softmax (inside Attention) | RMSNorm (between blocks) |
|------|------------------------|---------------------|
| &lt;strong&gt;Location&lt;/strong&gt; | &lt;strong&gt;inside&lt;/strong&gt; the Attention computation | &lt;strong&gt;before&lt;/strong&gt; Attention/FFN |
| &lt;strong&gt;What it normalizes&lt;/strong&gt; | similarity scores (each row of the score matrix) | word vectors (the magnitude of each vector) |
| &lt;strong&gt;Purpose&lt;/strong&gt; | turn them into a probability distribution | stabilize the values, prevent exploding gradients |
| &lt;strong&gt;Input&lt;/strong&gt; | arbitrary scores (-∞ to +∞) | a 768-dim vector |
| &lt;strong&gt;Output&lt;/strong&gt; | values in [0, 1] that sum to 1 | a normalized vector (direction unchanged) |
| &lt;strong&gt;Formula&lt;/strong&gt; | &lt;code&gt;exp(x_i) / Σexp(x_j)&lt;/code&gt; | &lt;code&gt;x / sqrt(mean(x²))&lt;/code&gt; |
| &lt;strong&gt;Scope&lt;/strong&gt; | each row is normalized independently | each vector is normalized independently |&lt;/p&gt;
&lt;h3&gt;6.3 Where they sit in the code&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Transformer Block
def forward(self, x):
    # ========== RMSNorm ==========
    residual = x
    x = self.input_norm(x)  # ← RMSNorm: normalizes the word vectors

    # ========== Inside Attention ==========
    Q, K, V = self.q_proj(x), self.k_proj(x), self.v_proj(x)

    # Split into heads...

    scores = Q @ K.T
    weights = F.softmax(scores, dim=-1)  # ← Softmax: normalizes the scores
    output = weights @ V

    # ==========  Residual connection ==========
    x = residual + output

    return x
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 A detailed side-by-side example&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Softmax example&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# One row of the Attention score matrix
scores = torch.tensor([2.5, 1.3, 3.7, 0.8])

# Softmax normalization
weights = F.softmax(scores, dim=-1)
print(weights)
# Output: tensor([0.1722, 0.0518, 0.5678, 0.0082])
# Characteristics:
# - all values are in [0, 1]
# - they sum to 1
# - the large ones grow larger (3.7 → 0.5678, accounting for 56.78%)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;RMSNorm example&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# One word vector
x = torch.tensor([2.5, 1.3, 3.7, 0.8])

# RMSNorm normalization
rms = torch.sqrt((x ** 2).mean())
x_norm = x / rms
print(x_norm)
# Output: tensor([1.0698, 0.5563, 1.5833, 0.3424])
# Characteristics:
# - values can be any positive or negative number
# - RMS ≈ 1
# - direction unchanged (only the magnitude is scaled)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 A mnemonic&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Softmax: normalizes a &quot;score distribution&quot; → turns it into probability weights
RMSNorm: normalizes a &quot;vector&apos;s magnitude&quot; → stabilizes training

Completely different kinds of normalization!
Different location, different purpose, different formula!
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;7. How RoPE is applied within Attention&lt;/h2&gt;
&lt;h3&gt;7.1 Where it&apos;s applied&lt;/h3&gt;
&lt;p&gt;RoPE is applied after Q and K are generated but before Attention is computed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def forward(self, x, position_embeddings):
    # 1. Generate Q, K, V
    Q = self.q_proj(x)
    K = self.k_proj(x)
    V = self.v_proj(x)

    # 2. Split into heads
    Q = Q.view(batch, seq_len, num_heads, head_dim)
    K = K.view(batch, seq_len, num_heads, head_dim)
    V = V.view(batch, seq_len, num_heads, head_dim)

    # 3. Transpose
    Q = Q.transpose(1, 2)  # [batch, num_heads, seq_len, head_dim]
    K = K.transpose(1, 2)

    # 4. ⭐ Apply RoPE (only to Q and K)
    cos, sin = position_embeddings
    Q, K = apply_rotary_pos_emb(Q, K, cos, sin)

    # 5. Compute Attention
    scores = Q @ K.transpose(-2, -1) / sqrt(head_dim)
    attn = softmax(scores, dim=-1)
    output = attn @ V

    return output
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 Why rotate only Q and K?&lt;/h3&gt;
&lt;p&gt;Recall what I covered earlier:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The reason&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Q and K compute &lt;strong&gt;similarity&lt;/strong&gt; → they need positional information&lt;/li&gt;
&lt;li&gt;V represents &lt;strong&gt;content&lt;/strong&gt; → it doesn&apos;t need positional information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The flow&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. scores = Q @ K.T  ← compute similarity (needs position)
2. weights = softmax(scores)
3. output = weights @ V  ← weighted sum of content (doesn&apos;t need position)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Q and K are &quot;map coordinates&quot; → they need RoPE&lt;/li&gt;
&lt;li&gt;V is the &quot;treasure content&quot; → it doesn&apos;t need RoPE&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;8. Hands-on experiments&lt;/h2&gt;
&lt;p&gt;The full learning materials are open source, so you can run them and verify everything yourself:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Clone the code
git clone https://github.com/joyehuang/minimind-notes
cd minimind-notes/learning_materials

# Experiment 1: the basics of Q, K, V
python attention_qkv_explained.py

# Experiment 2: implementing Multi-Head Attention
python multihead_attention.py

# Experiment 3: Softmax vs RMSNorm
python softmax_vs_rmsnorm.py
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;9. Summary&lt;/h2&gt;
&lt;h3&gt;9.1 Key takeaways&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;The essence of Attention&lt;/strong&gt;: compute relevance between words and fuse in the context&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Q, K, V&lt;/strong&gt;: a database-query analogy, not magic&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Weight matrices&lt;/strong&gt;: parameters learned through training, stored in the model file&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The 4-step pipeline&lt;/strong&gt;: similarity → scaling → Softmax → weighted sum&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Multi-Head&lt;/strong&gt;: 8 pairs of glasses looking at the same sentence, fusing multiple perspectives&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Softmax ≠ RMSNorm&lt;/strong&gt;: completely different kinds of normalization, different location and purpose&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;RoPE is only for Q and K&lt;/strong&gt;: similarity needs position, content doesn&apos;t&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9.2 The 4-step Attention pipeline (to memorize)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;1. Q @ K.T          → compute similarity
2. / √d             → scale
3. softmax(...)     → normalize into probabilities
4. @ V              → weighted sum
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;9.3 The Multi-Head dimension changes (to memorize)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[batch, seq, 768]
  → generate Q, K, V
  → split into 8 heads: [batch, seq, 8, 96]
  → transpose: [batch, 8, seq, 96]
  → Attention (in parallel)
  → transpose back: [batch, seq, 8, 96]
  → merge: [batch, seq, 768]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;9.4 Key code locations (MiniMind)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Attention implementation: &lt;code&gt;model/model_minimind.py:140-220&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Q, K, V projections: &lt;code&gt;model/model_minimind.py:159-161&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;RoPE application: &lt;code&gt;model/model_minimind.py:182&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Learning example: &lt;code&gt;learning_materials/attention_qkv_explained.py&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9.5 Going further&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GQA (Grouped Query Attention)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MiniMind uses GQA (&lt;code&gt;num_key_value_heads=2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Saves memory and speeds up inference&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flash Attention&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Optimizes Attention&apos;s computation and memory access&lt;/li&gt;
&lt;li&gt;2-3× faster training&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sparse Attention&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Not every word needs to attend to every other word&lt;/li&gt;
&lt;li&gt;An optimization for long-text scenarios&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;10. References&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Papers&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1706.03762&quot;&gt;Attention Is All You Need&lt;/a&gt; — the original Transformer paper&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2305.13245&quot;&gt;GQA: Training Generalized Multi-Query Transformer&lt;/a&gt; — the GQA paper&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2205.14135&quot;&gt;FlashAttention: Fast and Memory-Efficient Exact Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MiniMind source: &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;github.com/jingyaogong/minimind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Attention implementation: &lt;code&gt;model/model_minimind.py:140-220&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Other posts in this series&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251216---normalization/post&quot;&gt;Part 1: Normalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251217---rope-position-encoding/post&quot;&gt;Part 2: RoPE positional encoding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251219---feedforward-transformer-block/post&quot;&gt;Part 4: FeedForward and the full architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: joye
&lt;strong&gt;Published&lt;/strong&gt;: 2025-12-29
&lt;strong&gt;Last updated&lt;/strong&gt;: 2025-12-29
&lt;strong&gt;Series&lt;/strong&gt;: MiniMind learning notes (3/4)&lt;/p&gt;
&lt;p&gt;If you found this helpful, feel free to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ Star the original project &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⭐ Star my learning notes &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💬 Leave a comment with what you&apos;ve learned&lt;/li&gt;
&lt;li&gt;🔗 Share it with other friends learning about LLMs&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>RoPE: From Permutation Invariance to Multi-Frequency</title><link>https://www.joyehuang.me/en/blog/20251217---rope-position-encoding/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20251217---rope-position-encoding/post</guid><description>A deep dive into RoPE (Rotary Position Embedding), the standard position encoding for modern LLMs: the math, the engineering, and floating-point precision.</description><pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This is the second post in my MiniMind learning series, a deep dive into RoPE (Rotary Position Embedding) — the standard position encoding for modern large language models. We&apos;ll go from the math to the engineering, including the floating-point precision issue that rarely gets discussed, so you can fully understand this elegant design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;About this series&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt; is a concise but complete LLM training project, covering the full pipeline from data processing and model training to inference and deployment. As I worked through it, I distilled the core technical points into my &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt; repo and produced this four-part blog series, walking through the core components of the Transformer in a systematic way.&lt;/p&gt;
&lt;p&gt;The series includes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Normalization&lt;/strong&gt; - why we need RMSNorm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RoPE position encoding&lt;/strong&gt; (this post) - how to make a model understand word order&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attention&lt;/strong&gt; - the core engine of the Transformer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FeedForward and the full architecture&lt;/strong&gt; - how the components work together&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;1. Introduction&lt;/h2&gt;
&lt;h3&gt;1.1 Starting with a bug&lt;/h3&gt;
&lt;p&gt;Suppose you&apos;ve implemented a simple Attention mechanism:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def simple_attention(query, key, value):
    scores = query @ key.T  # compute similarity
    weights = softmax(scores)
    output = weights @ value
    return output

# Test
sentence1 = tokenize(&quot;我喜欢你&quot;)
sentence2 = tokenize(&quot;你喜欢我&quot;)

# Compute Attention
output1 = simple_attention(Q1, K1, V1)
output2 = simple_attention(Q2, K2, V2)

# Surprisingly:
assert torch.allclose(output1, output2)  # True!?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;: two sentences with completely opposite meanings produce the exact same Attention output?&lt;/p&gt;
&lt;p&gt;This is the &lt;strong&gt;permutation invariance problem of Attention&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;1.2 What this post will answer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;What is Attention&apos;s &quot;permutation invariance,&quot; and why is it a problem?&lt;/li&gt;
&lt;li&gt;Why do we need position encoding?&lt;/li&gt;
&lt;li&gt;How does RoPE encode position using rotation?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why do we need 32 frequencies?&lt;/strong&gt; (the core difficulty, involving floating-point precision)&lt;/li&gt;
&lt;li&gt;How does RoPE encode both absolute and relative position information at the same time?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.3 Who this is for&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;People with a basic understanding of the Transformer&lt;/li&gt;
&lt;li&gt;Anyone who wants to deeply understand position encoding&lt;/li&gt;
&lt;li&gt;Researchers curious about the &quot;engineering details&quot;&lt;/li&gt;
&lt;li&gt;Anyone about to implement their own Transformer&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. The problem: Attention&apos;s permutation invariance&lt;/h2&gt;
&lt;h3&gt;2.1 What is permutation invariance?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;: for a set operation, the order of elements doesn&apos;t affect the result.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mathematical statement&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f({a, b, c}) = f({c, a, b}) = f({b, c, a})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Classic examples&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sum: sum([1, 2, 3]) = sum([3, 1, 2]) = 6&lt;/li&gt;
&lt;li&gt;Mean: mean([1, 2, 3]) = mean([2, 3, 1]) = 2&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 Why is Attention permutation invariant?&lt;/h3&gt;
&lt;p&gt;Let&apos;s look at the core computation in Attention:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;scores = Q @ K.T  # [seq_len, seq_len]
weights = softmax(scores, dim=-1)
output = weights @ V
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Key observation&lt;/strong&gt;: the result of the matrix product &lt;code&gt;Q @ K.T&lt;/code&gt; depends only on the row vectors of Q and K, not on the order of the rows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A simplified example&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Suppose we have two sentences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sentence 1: &quot;我 喜欢 你&quot; → Q1, K1&lt;/li&gt;
&lt;li&gt;Sentence 2: &quot;你 喜欢 我&quot; → Q2, K2 (just a reordering)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Their Attention score matrices:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Sentence 1: [[1.25, 1.00, 0.95],
             [1.00, 1.25, 0.70],
             [0.95, 0.70, 0.73]]

Sentence 2: [[0.73, 0.70, 0.95],
             [0.70, 1.25, 1.00],
             [0.95, 1.00, 1.25]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Observation&lt;/strong&gt;: the two matrices contain &lt;strong&gt;exactly the same values&lt;/strong&gt;, just in different positions (the rows and columns are reordered). After softmax, the weight distribution in each row is also just a reordering. &lt;strong&gt;The model has no way to tell which word is in which position!&lt;/strong&gt;&lt;/p&gt;
/* ![Figure 1: Permutation invariance — comparing the Attention matrices of two sentences](placeholder_permutation_invariance.png) */
&lt;h3&gt;2.3 Why is this a problem?&lt;/h3&gt;
&lt;p&gt;In natural language, &lt;strong&gt;position information is crucial&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;猫追老鼠&quot; vs &quot;老鼠追猫&quot;  ← completely opposite meanings
&quot;我没说她偷了钱&quot; vs &quot;我说她没偷钱&quot;  ← completely different semantics
&quot;吃饭了吗&quot; vs &quot;饭吃了吗&quot;  ← different tone
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: Attention needs some mechanism to perceive position information!&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. Three generations of position encoding&lt;/h2&gt;
&lt;h3&gt;3.1 First generation: absolute position encoding (BERT, 2018)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Core idea&lt;/strong&gt;: assign a fixed vector to each position.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class AbsolutePositionEmbedding(nn.Module):
    def __init__(self, max_len, hidden_size):
        super().__init__()
        # learnable position embedding
        self.position_embedding = nn.Embedding(max_len, hidden_size)

    def forward(self, x):
        batch_size, seq_len, hidden_size = x.shape

        # position IDs: [0, 1, 2, ..., seq_len-1]
        position_ids = torch.arange(seq_len, device=x.device)
        position_ids = position_ids.unsqueeze(0).expand(batch_size, -1)

        # look up the position vectors
        pos_embed = self.position_embedding(position_ids)

        # add directly
        return x + pos_embed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Simple and direct&lt;/li&gt;
&lt;li&gt;✅ Learnable (adjusts to the data)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;❌ Can&apos;t extrapolate to unseen lengths (train on 512, test on 1024 and it falls apart)&lt;/li&gt;
&lt;li&gt;❌ No explicit relative position information&lt;/li&gt;
&lt;li&gt;❌ Requires storing a lot of parameters (max_len × hidden_size)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.2 Second generation: relative position encoding (T5, 2019)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Core idea&lt;/strong&gt;: encode the relative distance between two words.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# compute relative position
relative_distance = pos_j - pos_i  # -seq_len to +seq_len

# look up the bias for the relative position
bias = relative_position_bias[relative_distance]

# add to the Attention scores
scores = (Q @ K.T) + bias
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Has relative position information&lt;/li&gt;
&lt;li&gt;✅ Can extrapolate to some degree&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;❌ Requires an extra bias matrix (O(seq_len²) space)&lt;/li&gt;
&lt;li&gt;❌ Computationally complex&lt;/li&gt;
&lt;li&gt;❌ Tedious to implement&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.3 Third generation: RoPE (Llama/MiniMind, 2021) ⭐️&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Core idea&lt;/strong&gt;: encode position by rotating vectors.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# apply rotation to Query and Key
Q_rot = rotate(Q, position × θ)
K_rot = rotate(K, position × θ)

# compute Attention (relative position is included automatically!)
scores = Q_rot @ K_rot.T
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Naturally includes relative position information (a mathematical property)&lt;/li&gt;
&lt;li&gt;✅ Can extrapolate to longer sequences (with YaRN)&lt;/li&gt;
&lt;li&gt;✅ Computationally efficient (O(1) extra space)&lt;/li&gt;
&lt;li&gt;✅ Clean, elegant implementation&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The standard for modern LLMs&lt;/strong&gt; (GPT-3, Llama, Mistral, MiniMind)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Comparison table&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| Feature | Absolute | Relative | RoPE |
|------|---------|---------|------|
| &lt;strong&gt;Relative info&lt;/strong&gt; | ❌ | ✅ | ✅ |
| &lt;strong&gt;Extrapolatable&lt;/strong&gt; | ❌ | △ | ✅ |
| &lt;strong&gt;Compute efficiency&lt;/strong&gt; | ✅ | ❌ | ✅ |
| &lt;strong&gt;Space complexity&lt;/strong&gt; | O(L×D) | O(L²) | O(1) |
| &lt;strong&gt;Implementation difficulty&lt;/strong&gt; | Simple | Complex | Medium |
| &lt;strong&gt;Models&lt;/strong&gt; | BERT | T5 | GPT-3+, Llama |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. RoPE core principle: rotary encoding&lt;/h2&gt;
&lt;h3&gt;4.1 The basic idea&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Encode position with a rotation angle&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Intuition&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;position 0 → rotate 0°
position 1 → rotate θ°
position 2 → rotate 2θ°
position 3 → rotate 3θ°
...
position m → rotate m×θ°
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like the hands of a clock, different moments point at different angles!&lt;/p&gt;
/* ![Figure 2: RoPE rotary encoding — vectors rotated for different positions](placeholder_rope_rotation.png) */
&lt;h3&gt;4.2 Mathematical derivation (simplified)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Rotating a 2D vector&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rotation matrix R(θ) = [cos(θ)  -sin(θ)]
                       [sin(θ)   cos(θ)]

vector v rotated by θ degrees:
v_rot = R(θ) @ v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Rotating the word vector at position m&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;q_m = R(m × θ) @ q  # rotate Query by m×θ degrees
k_n = R(n × θ) @ k  # rotate Key by n×θ degrees
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Computing the Attention score&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;score = q_m · k_n
      = (R(mθ) @ q) · (R(nθ) @ k)
      = q^T @ R(mθ)^T @ R(nθ) @ k   # transpose of the dot product
      = q^T @ R(-mθ) @ R(nθ) @ k     # transpose of a rotation matrix = reverse rotation
      = q^T @ R((n-m)θ) @ k          # rotation angles add up
      = q^T @ R(Δθ) @ k              # Δ = n-m (relative distance)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The magical conclusion&lt;/strong&gt;: the Attention score depends only on the relative distance (n-m)!&lt;/p&gt;
&lt;h3&gt;4.3 RoPE&apos;s twofold advantage&lt;/h3&gt;
&lt;h4&gt;Advantage 1: it has absolute position information&lt;/h4&gt;
&lt;p&gt;Every position has a unique rotation angle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Query at position 5: rotated to 5θ&lt;/li&gt;
&lt;li&gt;Query at position 8: rotated to 8θ&lt;/li&gt;
&lt;li&gt;The model can know &quot;this word is at position 5&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Advantage 2: it has relative position information&lt;/h4&gt;
&lt;p&gt;The Attention score depends only on the relative distance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Position 5 looking at position 8 = &lt;code&gt;q @ rotate(k, 3θ)&lt;/code&gt; (distance 3)&lt;/li&gt;
&lt;li&gt;Position 0 looking at position 3 = &lt;code&gt;q @ rotate(k, 3θ)&lt;/code&gt; (distance 3)&lt;/li&gt;
&lt;li&gt;The two scores are the same, so the model knows &quot;these two words are 3 positions apart&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Best of both worlds!&lt;/strong&gt; It has both absolute and relative position.&lt;/p&gt;
/* ![Figure 3: RoPE&apos;s twofold advantage — absolute and relative position](placeholder_rope_dual_advantage.png) */
&lt;hr&gt;
&lt;h2&gt;5. The core difficulty: why do we need multiple frequencies? ⭐⭐⭐&lt;/h2&gt;
&lt;h3&gt;5.1 Setting up the problem&lt;/h3&gt;
&lt;p&gt;By this point, you might be wondering:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If rotating 360 degrees brings you back to the start, then aren&apos;t position 0 and position 360 indistinguishable?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;That&apos;s an excellent question!&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;5.2 The intuitive fix: lower the frequency&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The idea&lt;/strong&gt;: if it only completes one full turn every million tokens, wouldn&apos;t that cover all positions?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# ultra-low frequency
θ = 2π / 1_000_000  # one full turn every million tokens

# in theory
position_0 → 0°
position_1 → 0.00000628°
position_1000000 → 360° (back to the start)

# can uniquely identify a million positions!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Here&apos;s the catch&lt;/strong&gt;: why don&apos;t we actually do this?&lt;/p&gt;
&lt;h3&gt;5.3 The real reason: floating-point precision limits ⭐⭐⭐&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The key finding&lt;/strong&gt;: it works in theory, &lt;strong&gt;but not in engineering&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;When using an ultra-low frequency (one full turn every million tokens):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cos value at position 0: 1.0&lt;/li&gt;
&lt;li&gt;cos value at position 1: 0.999999999980261&lt;/li&gt;
&lt;li&gt;Difference: about &lt;code&gt;1.97e-11&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Where the problem lies&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;float32&apos;s precision is about &lt;code&gt;10^-7&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
/* - the difference between adjacent positions $1.97 \times 10^{-11} \ll 10^{-7}$ */
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The computer can&apos;t distinguish adjacent positions!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After computing in float32, the cos values for position 0 and position 1 are both 1.0 — completely indistinguishable.&lt;/p&gt;
/* ![Figure 4: The floating-point precision problem — single frequency vs. multiple frequencies](placeholder_float_precision.png) */
&lt;h3&gt;5.4 Mathematical analysis&lt;/h3&gt;
&lt;p&gt;A Taylor expansion proves it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Angle difference: θ ≈ 6.28e-6 radians&lt;/li&gt;
&lt;li&gt;cos difference: Δcos ≈ θ²/2 ≈ 2e-11&lt;/li&gt;
&lt;li&gt;float32 precision: about 10^-7&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Conclusion: &lt;code&gt;2e-11 &amp;#x3C;&amp;#x3C; 10^-7&lt;/code&gt;, the computer can&apos;t distinguish adjacent positions.&lt;/p&gt;
&lt;p&gt;It&apos;s like measuring millimeter-scale differences with a meter stick — the markings are too coarse to read them.&lt;/p&gt;
&lt;h3&gt;5.5 The multi-frequency solution&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Strategy&lt;/strong&gt;: use 32 different frequencies (MiniMind, head_dim=64), one frequency per pair of dimensions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frequency range&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| Frequency type | Period (tokens) | Role |
|---------|-------------|------|
| High (0) | 6.3 | Precisely distinguish adjacent positions (angle difference 57.3°) |
| Medium (15) | 6,283 | Balance precision and range |
| Low (31) | 6,283,185 | Identify distant positions |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The combined effect&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Position 0 encoding: &lt;code&gt;[1.0, 1.0, 1.0, ..., 1.0]&lt;/code&gt; (32 values)&lt;/li&gt;
&lt;li&gt;Position 1 encoding: &lt;code&gt;[0.5403, 0.9997, 0.9999, ..., 1.0]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The high-frequency components differ noticeably (0.5403 vs. 1.0), so adjacent positions can be distinguished&lt;/li&gt;
&lt;li&gt;The low-frequency components cover long distances, so positions in the millions can be identified&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The key point&lt;/strong&gt;: high frequencies see the detail, low frequencies see the big picture — together they&apos;re both precise and comprehensive!&lt;/p&gt;
&lt;h3&gt;5.6 An analogy: the clock system&lt;/h3&gt;
&lt;p&gt;It&apos;s just like a clock&apos;s hour, minute, and second hands:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Second hand (high frequency)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Completes a turn every minute, precise to the second&lt;/li&gt;
&lt;li&gt;But returns to the start after an hour, so it can&apos;t distinguish on its own&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Minute hand (medium frequency)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Completes a turn every hour, precise to the minute&lt;/li&gt;
&lt;li&gt;Together with the second hand it can distinguish 3,600 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Hour hand (low frequency)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Completes a turn every 12 hours, covering a wide range&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Combine all three → you can uniquely identify any moment!&lt;/strong&gt; RoPE&apos;s multi-frequency mechanism works exactly the same way.&lt;/p&gt;
/* ![Figure 5: The clock analogy — the multi-frequency mechanism](placeholder_clock_analogy.png) */
&lt;hr&gt;
&lt;h2&gt;6. The full RoPE implementation&lt;/h2&gt;
&lt;p&gt;The RoPE implementation breaks down into three steps:&lt;/p&gt;
&lt;h3&gt;6.1 Precompute the frequencies and cos/sin values&lt;/h3&gt;
&lt;p&gt;The core idea: precompute the cos and sin values needed for rotation, for every position and every frequency.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def precompute_freqs_cis(dim, end, rope_base=1e6):
    # 1. compute frequencies: freqs[i] = 1 / (rope_base ^ (2i / dim))
    freqs = 1.0 / (rope_base ** (torch.arange(0, dim, 2).float() / dim))

    # 2. build the angle matrix: positions × freqs
    t = torch.arange(end)
    freqs = torch.outer(t, freqs)  # [end, dim/2]

    # 3. compute cos and sin
    freqs_cos = torch.cos(freqs).repeat(1, 2)  # [end, dim]
    freqs_sin = torch.sin(freqs).repeat(1, 2)

    return freqs_cos, freqs_sin
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 Apply the rotation&lt;/h3&gt;
&lt;p&gt;The core formula: &lt;code&gt;q_rotated = q * cos + rotate_half(q) * sin&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def apply_rotary_pos_emb(q, k, cos, sin):
    q_embed = (q * cos) + (rotate_half(q) * sin)
    k_embed = (k * cos) + (rotate_half(k) * sin)
    return q_embed, k_embed

def rotate_half(x):
    # split the vector in half and swap: [x1, x2] → [-x2, x1]
    x1, x2 = x.chunk(2, dim=-1)
    return torch.cat((-x2, x1), dim=-1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is essentially the real-valued implementation of complex rotation: &lt;code&gt;(a + bi) × (cos + i·sin)&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;6.3 Using it inside Attention&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class Attention(nn.Module):
    def forward(self, x, position_embeddings):
        # 1. produce Q, K, V and split into heads
        q, k, v = self.q_proj(x), self.k_proj(x), self.v_proj(x)

        # 2. ⭐ apply RoPE (to Q, K only)
        cos, sin = position_embeddings
        q, k = apply_rotary_pos_emb(q, k, cos, sin)

        # 3. compute Attention
        scores = q @ k.T / sqrt(head_dim)
        output = softmax(scores) @ v

        return output
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Full code&lt;/strong&gt;: see the MiniMind source &lt;code&gt;model/model_minimind.py:108-182&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;7. YaRN: long-context extrapolation&lt;/h2&gt;
&lt;h3&gt;7.1 The problem&lt;/h3&gt;
&lt;p&gt;The model was trained with a maximum length of 2048, but at inference time you want to handle 8192 tokens — what do you do?&lt;/p&gt;
&lt;p&gt;Extrapolating directly runs into trouble:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;High frequencies&lt;/strong&gt;: short period, seen many full turns, extrapolates well ✅&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Low frequencies&lt;/strong&gt;: long period, only a small slice of angles ever seen, so &quot;unseen angles&quot; appear and quality drops ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7.2 The YaRN solution&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Core idea&lt;/strong&gt;: dynamically adjust the low frequencies so that &quot;unseen angles&quot; become &quot;seen angles,&quot; while leaving the high frequencies unchanged.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Results&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Llama 2: trained on 4k → extrapolated to 32k&lt;/li&gt;
&lt;li&gt;Code Llama: trained on 16k → extrapolated to 100k&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is an advanced topic; for the full details see the &lt;a href=&quot;https://arxiv.org/abs/2309.00071&quot;&gt;YaRN paper&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;8. Summary&lt;/h2&gt;
&lt;h3&gt;8.1 Recap of the key points&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;The permutation invariance problem&lt;/strong&gt;: Attention can&apos;t tell word order apart, so it needs position encoding&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;RoPE&apos;s advantage&lt;/strong&gt;: encodes position with rotation, automatically including relative position information&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Why multiple frequencies are necessary&lt;/strong&gt;: floating-point precision limits mean a single frequency can&apos;t distinguish adjacent positions&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The clock analogy&lt;/strong&gt;: high frequencies see the detail, low frequencies see the big picture, and together they cover everything perfectly&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Twofold information&lt;/strong&gt;: both absolute and relative position&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Rotate only Q, K&lt;/strong&gt;: position is used for similarity and doesn&apos;t affect the content V&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;8.2 One sentence to remember&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;RoPE is the perfect balance of mathematical theory and engineering practice&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;8.3 Self-test questions&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Why is Attention permutation invariant?&lt;/li&gt;
&lt;li&gt;How does RoPE include both absolute and relative position?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why can&apos;t we just use a single ultra-low frequency?&lt;/strong&gt; (the core point)&lt;/li&gt;
&lt;li&gt;How does YaRN achieve length extrapolation?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;8.4 Key code locations (MiniMind)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;RoPE precompute: &lt;code&gt;model/model_minimind.py:108-128&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;RoPE application: &lt;code&gt;model/model_minimind.py:131-137&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Used in Attention: &lt;code&gt;model/model_minimind.py:182&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;9. Hands-on experiments&lt;/h2&gt;
&lt;p&gt;The full learning materials are open source, so you can run and verify everything yourself:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# clone the code
git clone https://github.com/joyehuang/minimind-notes
cd minimind-notes/learning_materials

# Experiment 1: RoPE basics
python rope_basics.py

# Experiment 2: the multi-frequency mechanism
python rope_multi_frequency.py

# Experiment 3: the floating-point precision problem (core)
python rope_why_multi_frequency.py
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;10. References&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Papers&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2104.09864&quot;&gt;RoFormer: Enhanced Transformer with Rotary Position Embedding&lt;/a&gt; - the original RoPE paper&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.09288&quot;&gt;Llama 2: Open Foundation and Fine-Tuned Chat Models&lt;/a&gt; - the Llama technical report&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.00071&quot;&gt;YaRN: Efficient Context Window Extension of Large Language Models&lt;/a&gt; - the YaRN paper&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MiniMind source: &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;github.com/jingyaogong/minimind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RoPE implementation: &lt;code&gt;model/model_minimind.py:108-182&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Other posts in this series&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251216---normalization/post&quot;&gt;Part 1: Normalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251218---attention-mechanism/post&quot;&gt;Part 3: Attention&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251219---feedforward-transformer-block/post&quot;&gt;Part 4: FeedForward and the full architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: joye
&lt;strong&gt;Published&lt;/strong&gt;: 2025-12-17
&lt;strong&gt;Last updated&lt;/strong&gt;: 2025-12-17
&lt;strong&gt;Series&lt;/strong&gt;: MiniMind learning notes (2/4)&lt;/p&gt;
&lt;p&gt;If you found this helpful, feel free to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ Star the original project &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⭐ Star my learning notes &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💬 Leave a comment with your own takeaways&lt;/li&gt;
&lt;li&gt;🔗 Share it with others learning about LLMs&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Why Transformers Need Normalization: Gradients to RMSNorm</title><link>https://www.joyehuang.me/en/blog/20251216---normalization/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20251216---normalization/post</guid><description>A deep dive into why deep neural networks need normalization, and how RMSNorm became standard in modern LLMs</description><pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This is the first post in my MiniMind learning series, a deep dive into why deep neural networks need normalization, and how RMSNorm became standard in modern LLMs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;About This Series&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt; is a concise but complete large language model training project, covering the full pipeline from data processing and model training to inference and deployment. As I worked through it, I collected the core technical points into the &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt; repo and produced this four-part blog series, walking through the core components of the Transformer systematically.&lt;/p&gt;
&lt;p&gt;This series includes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Normalization&lt;/strong&gt; (this post) — why we need RMSNorm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RoPE positional encoding&lt;/strong&gt; — how to make the model understand word order&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Attention mechanism&lt;/strong&gt; — the core engine of the Transformer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FeedForward and the complete architecture&lt;/strong&gt; — how the components work together&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;1. Introduction&lt;/h2&gt;
&lt;h3&gt;1.1 A Common Question&lt;/h3&gt;
&lt;p&gt;If you open up the code for a Transformer, you&apos;ll find Normalization layers everywhere:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class TransformerBlock(nn.Module):
    def forward(self, x):
        x = self.input_norm(x)        # ← Norm layer
        x = self.attention(x)

        x = self.post_attn_norm(x)    # ← another Norm layer
        x = self.feedforward(x)
        return x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The questions&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why do we need so much normalization?&lt;/li&gt;
&lt;li&gt;Can&apos;t we just drop it?&lt;/li&gt;
&lt;li&gt;What&apos;s the difference between RMSNorm and LayerNorm?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.2 What This Post Answers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Why do deep networks suffer from &lt;strong&gt;vanishing gradients&lt;/strong&gt;? (It&apos;s not magic — there&apos;s a mathematical proof.)&lt;/li&gt;
&lt;li&gt;What does RMSNorm actually do? (It&apos;s not throwing away information.)&lt;/li&gt;
&lt;li&gt;Why have modern LLMs all migrated from LayerNorm to RMSNorm?&lt;/li&gt;
&lt;li&gt;Where exactly does RMSNorm sit inside a Transformer?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. The Truth About Vanishing Gradients&lt;/h2&gt;
&lt;h3&gt;2.1 A Demonstration: The Disaster of an 8-Layer Network&lt;/h3&gt;
&lt;p&gt;Let&apos;s use code to show what happens in an 8-layer network without normalization:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
import torch.nn as nn

# An 8-layer network without normalization
class DeepNetworkWithoutNorm(nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = nn.ModuleList([
            nn.Linear(512, 512) for _ in range(8)
        ])

    def forward(self, x):
        for i, layer in enumerate(self.layers):
            x = layer(x)
            x = torch.relu(x)
            print(f&quot;Layer {i+1} std: {x.std().item():.4f}&quot;)
        return x

# Test
model = DeepNetworkWithoutNorm()
x = torch.randn(32, 512)
print(f&quot;Input std: {x.std().item():.4f}&quot;)

output = model(x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Input std: 1.0405
Layer 1 std: 0.8932
Layer 2 std: 0.6421
Layer 3 std: 0.4156
Layer 4 std: 0.2387
Layer 5 std: 0.1024
Layer 6 std: 0.0432
Layer 7 std: 0.0198
Layer 8 std: 0.0163  ← nearly zero!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.2 Why Does It Keep Shrinking?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The mathematical explanation&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The matrix multiplication in each layer&lt;/strong&gt;: &lt;code&gt;y = Wx&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the weights W are initialized as a normal distribution with mean 0 and standard deviation 1&lt;/li&gt;
&lt;li&gt;The standard deviation of the output is approximately: &lt;code&gt;std(y) ≈ std(x) × sqrt(input_dim) / sqrt(output_dim)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The effect of the ReLU activation&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReLU(x) = max(0, x)&lt;/li&gt;
&lt;li&gt;All negatives become 0&lt;/li&gt;
&lt;li&gt;This shrinks the standard deviation further (roughly halving it)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The cumulative effect across layers&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each layer&apos;s standard deviation × k, where k &amp;#x3C; 1&lt;/li&gt;
&lt;li&gt;After 8 layers: &lt;code&gt;std_8 = std_0 × k^8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Exponential decay!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;An analogy&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;It&apos;s like photocopying a photocopy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1st copy: slightly blurry&lt;/li&gt;
&lt;li&gt;2nd copy: blurrier&lt;/li&gt;
&lt;li&gt;8th copy: you can barely read the text anymore&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.3 The Consequences of Vanishing Gradients&lt;/h3&gt;
&lt;p&gt;What&apos;s worse is the gradient during backpropagation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Compute the loss and backpropagate
loss = output.sum()
loss.backward()

# Inspect the gradient magnitude of each layer
for i, layer in enumerate(model.layers):
    grad_norm = layer.weight.grad.norm().item()
    print(f&quot;Layer {i+1} gradient norm: {grad_norm:.6f}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Layer 1 gradient norm: 0.000012  ← nearly 0!
Layer 2 gradient norm: 0.000045
Layer 3 gradient norm: 0.000231
...
Layer 7 gradient norm: 0.123456
Layer 8 gradient norm: 0.432156  ← normal
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The gradients in the earlier layers are close to 0, so their weights barely update&lt;/li&gt;
&lt;li&gt;Only the later layers are learning&lt;/li&gt;
&lt;li&gt;A deep network degenerates into a shallow one!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.4 What Happens with Even Deeper Networks?&lt;/h3&gt;
&lt;p&gt;If a network has 100 layers, or 1,000 layers (Transformers sometimes have 96):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100 layers → std ≈ 10^-10 (completely vanished)&lt;/li&gt;
&lt;li&gt;1,000 layers → simply impossible to train&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Without normalization, deep Transformers cannot be trained at all!&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. The Salvation of RMSNorm&lt;/h2&gt;
&lt;h3&gt;3.1 The Core Idea&lt;/h3&gt;
&lt;p&gt;The design philosophy of RMSNorm:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Don&apos;t change the direction, just control the magnitude.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;The math&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;x_norm = x / sqrt(mean(x²) + eps) × weight
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Step by step&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Compute the &quot;magnitude&quot; of the vector (Root Mean Square)&lt;/li&gt;
&lt;li&gt;Divide by that magnitude (normalizing it to roughly unit length)&lt;/li&gt;
&lt;li&gt;Multiply by the learnable scaling parameter &lt;code&gt;weight&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3.2 The Implementation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
import torch.nn as nn

class RMSNorm(nn.Module):
    def __init__(self, dim: int, eps: float = 1e-5):
        super().__init__()
        self.eps = eps
        # Learnable scaling parameter
        self.weight = nn.Parameter(torch.ones(dim))

    def _norm(self, x):
        # Compute the RMS and normalize
        # rsqrt(x) = 1/sqrt(x), which is more efficient
        return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)

    def forward(self, x):
        # Normalize + scale
        output = self._norm(x.float()).type_as(x)
        return output * self.weight
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x.pow(2).mean(-1)&lt;/code&gt;: computes the mean of the squares of each vector&lt;/li&gt;
&lt;li&gt;&lt;code&gt;torch.rsqrt(...)&lt;/code&gt;: computes the reciprocal square root (1/√x)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;keepdim=True&lt;/code&gt;: keeps the dimension so broadcasting works&lt;/li&gt;
&lt;li&gt;&lt;code&gt;self.weight&lt;/code&gt;: a learnable parameter that lets the model adjust the scaling ratio itself&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.3 Verifying the Effect&lt;/h3&gt;
&lt;p&gt;Now let&apos;s add RMSNorm to the 8-layer network:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class DeepNetworkWithNorm(nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = nn.ModuleList()
        for _ in range(8):
            self.layers.append(nn.Linear(512, 512))
            self.layers.append(RMSNorm(512))  # add RMSNorm after each layer
            self.layers.append(nn.ReLU())

    def forward(self, x):
        for i in range(0, len(self.layers), 3):
            x = self.layers[i](x)      # Linear
            x = self.layers[i+1](x)    # RMSNorm
            x = self.layers[i+2](x)    # ReLU
            print(f&quot;Block {i//3 + 1} std: {x.std().item():.4f}&quot;)
        return x

# Test
model = DeepNetworkWithNorm()
x = torch.randn(32, 512)
output = model(x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Block 1 std: 0.9823
Block 2 std: 1.0142
Block 3 std: 0.9956
Block 4 std: 1.0089
Block 5 std: 0.9934
Block 6 std: 1.0023
Block 7 std: 0.9987
Block 8 std: 0.9956  ← stable around 1!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: the standard deviation stays around 1, so the gradient can propagate smoothly!&lt;/p&gt;
&lt;h3&gt;3.4 The Key Properties of RMSNorm&lt;/h3&gt;
&lt;p&gt;RMSNorm normalizes while keeping the vector&apos;s direction unchanged, adjusting only its magnitude. This means:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Semantic information is preserved&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A vector&apos;s direction represents its &quot;meaning&quot;&lt;/li&gt;
&lt;li&gt;The cosine of the angle is almost identical before and after normalization (difference &amp;#x3C; 10^-9)&lt;/li&gt;
&lt;li&gt;It only adjusts the magnitude, not the meaning, so no information is lost&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Training is stable&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each layer&apos;s output standard deviation is roughly 1&lt;/li&gt;
&lt;li&gt;Gradients neither explode nor vanish&lt;/li&gt;
&lt;li&gt;You can stack very deep networks (96+ layers)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;4. RMSNorm vs LayerNorm&lt;/h2&gt;
&lt;h3&gt;4.1 Comparing the Formulas&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;LayerNorm (the BERT/GPT-2 era)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mean = mean(x)
var = mean((x - mean)²)
x_norm = (x - mean) / sqrt(var + eps) × weight + bias
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;RMSNorm (the Llama/MiniMind era)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rms = sqrt(mean(x²) + eps)
x_norm = x / rms × weight
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 A Detailed Comparison&lt;/h3&gt;
&lt;p&gt;| Property | LayerNorm | RMSNorm |
|------|-----------|---------|
| &lt;strong&gt;Step 1&lt;/strong&gt; | compute the mean | none |
| &lt;strong&gt;Step 2&lt;/strong&gt; | subtract the mean (centering) | none |
| &lt;strong&gt;Step 3&lt;/strong&gt; | compute the variance | compute the root mean square |
| &lt;strong&gt;Step 4&lt;/strong&gt; | divide by the standard deviation | divide by the RMS |
| &lt;strong&gt;Parameters&lt;/strong&gt; | weight + bias | weight only |
| &lt;strong&gt;Compute&lt;/strong&gt; | 2 passes over the data | 1 pass |
| &lt;strong&gt;Speed&lt;/strong&gt; | baseline (1x) | &lt;strong&gt;7.7x faster&lt;/strong&gt; |
| &lt;strong&gt;Effect&lt;/strong&gt; | very good | comparable or better |
| &lt;strong&gt;Used by&lt;/strong&gt; | BERT, GPT-2 | Llama, MiniMind |&lt;/p&gt;
&lt;h3&gt;4.3 A Speed-Comparison Experiment&lt;/h3&gt;
&lt;p&gt;Timing 1,000 forward passes, here are the measured results on an NVIDIA A100:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LayerNorm time: 0.0234s
RMSNorm time: 0.0030s
Speedup: 7.80x  ← nearly 8x faster!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 Why Can We Skip Subtracting the Mean?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The key question&lt;/strong&gt;: LayerNorm subtracts the mean and RMSNorm doesn&apos;t — so why does it still work?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The theoretical explanation&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The statistical properties of deep networks&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;After many layers of transformation, the mean of the activations is usually close to 0&lt;/li&gt;
&lt;li&gt;This is especially true in networks with residual connections&lt;/li&gt;
&lt;li&gt;Controlling only the variance/RMS is enough for stable training&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Empirical validation&lt;/strong&gt; (the Llama paper):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Measuring the mean of each layer&apos;s output in a 100-layer network&lt;/li&gt;
&lt;li&gt;The means ranged over [-0.0234, 0.0187], very close to 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The compute-efficiency trade-off&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The benefit of subtracting the mean: a more symmetric distribution&lt;/li&gt;
&lt;li&gt;The cost of subtracting the mean: extra computation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In deep networks, the benefit &amp;#x3C; the cost&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.5 Comparing the Actual Results&lt;/h3&gt;
&lt;p&gt;Experimental results from Meta&apos;s Llama paper:&lt;/p&gt;
&lt;p&gt;| Configuration | LayerNorm | RMSNorm | Difference |
|---------|-----------|---------|------|
| 7B model PPL | 12.34 | 12.31 | -0.24% ✅ |
| Training speed | 100% | 112% | +12% ✅ |
| Memory usage | 100% | 98% | -2% ✅ |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: comparable results, faster speed!&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. Where RMSNorm Sits in the Transformer&lt;/h2&gt;
&lt;h3&gt;5.1 A Common Misconception&lt;/h3&gt;
&lt;p&gt;❌ &lt;strong&gt;Wrong&lt;/strong&gt;: &quot;A Transformer has an RMSNorm layer.&quot;&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;Right&lt;/strong&gt;: &quot;A Transformer Block has RMSNorm components &lt;strong&gt;inside&lt;/strong&gt; it.&quot;&lt;/p&gt;
&lt;h3&gt;5.2 The Structure of a Transformer Block&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class MiniMindBlock(nn.Module):
    def __init__(self, config):
        super().__init__()
        # 1st RMSNorm: before Attention
        self.input_layernorm = RMSNorm(config.hidden_size)

        # Attention
        self.self_attn = Attention(config)

        # 2nd RMSNorm: before FeedForward
        self.post_attention_layernorm = RMSNorm(config.hidden_size)

        # FeedForward
        self.mlp = FeedForward(config)

    def forward(self, x):
        # ========== Part 1: Attention ==========
        residual = x
        x = self.input_layernorm(x)        # ← RMSNorm #1
        x = self.self_attn(x)
        x = residual + x                    # residual connection

        # ========== Part 2: FeedForward ==========
        residual = x
        x = self.post_attention_layernorm(x)  # ← RMSNorm #2
        x = self.mlp(x)
        x = residual + x                    # residual connection

        return x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Data-flow diagram&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;input x
  ↓
  ├─────┐ (save residual)
  ↓     │
RMSNorm #1  ← normalize
  ↓
Attention  ← attention mechanism
  ↓
  └─────┘ (add residual)
  ↓
  ├─────┐ (save residual)
  ↓     │
RMSNorm #2  ← normalize
  ↓
FeedForward  ← feed-forward network
  ↓
  └─────┘ (add residual)
  ↓
output
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 Counting Them in a Full Transformer&lt;/h3&gt;
&lt;p&gt;Taking MiniMind as an example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;MiniMindModel
├─ embed_tokens (token embeddings)
├─ layers: 8 MiniMindBlocks
│   ├─ Block #1
│   │   ├─ input_layernorm (RMSNorm)      ← #1
│   │   ├─ self_attn
│   │   ├─ post_attention_layernorm (RMSNorm)  ← #2
│   │   └─ mlp
│   ├─ Block #2
│   │   ├─ input_layernorm (RMSNorm)      ← #3
│   │   └─ ... (same as above)
│   └─ ... (Blocks #3-8, two RMSNorms each)
└─ norm (final RMSNorm)                    ← #17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The count&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each Block: &lt;strong&gt;2 RMSNorms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;8 Blocks: 8 × 2 = &lt;strong&gt;16 RMSNorms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Before the final output: &lt;strong&gt;1 RMSNorm&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: 17 RMSNorms&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.4 Why Place It &lt;em&gt;Before&lt;/em&gt; Attention/FeedForward?&lt;/h3&gt;
&lt;p&gt;This comes down to the &lt;strong&gt;Pre-Norm vs Post-Norm&lt;/strong&gt; design choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Post-Norm (the original Transformer, 2017)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# normalization comes after the sublayer
x = x + Attention(x)
x = Norm(x)
x = x + FeedForward(x)
x = Norm(x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pre-Norm (modern Transformers, Llama/MiniMind)&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# normalization comes before the sublayer
x = x + Attention(Norm(x))
x = x + FeedForward(Norm(x))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The advantages of Pre-Norm&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;| Property | Post-Norm | Pre-Norm |
|------|-----------|----------|
| &lt;strong&gt;Training stability&lt;/strong&gt; | hard for deep networks | more stable ✅ |
| &lt;strong&gt;Gradient propagation&lt;/strong&gt; | can be interrupted by Norm | cleaner residual path ✅ |
| &lt;strong&gt;Learning rate&lt;/strong&gt; | needs warmup | can use a larger learning rate ✅ |
| &lt;strong&gt;Best suited for&lt;/strong&gt; | shallow networks (&amp;#x3C; 12 layers) | deep networks (&gt; 12 layers) ✅ |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modern LLMs all use Pre-Norm&lt;/strong&gt; (GPT-3, Llama, MiniMind, Mistral...).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;6. Hands-On Experiments and References&lt;/h2&gt;
&lt;h3&gt;6.1 Running the Example Code&lt;/h3&gt;
&lt;p&gt;The complete learning materials are open source, so you can run and verify them yourself:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Clone the code
git clone https://github.com/joyehuang/minimind-notes
cd minimind-notes/learning_materials

# Experiment 1: observe vanishing gradients
python why_normalization.py

# Experiment 2: a demonstration of how RMSNorm works
python rmsnorm_explained.py

# Experiment 3: LayerNorm vs RMSNorm comparison
python normalization_comparison.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 References&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Papers&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1910.07467&quot;&gt;Root Mean Square Layer Normalization&lt;/a&gt; — the original RMSNorm paper&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.09288&quot;&gt;Llama 2 Technical Report&lt;/a&gt; — includes practical experience with RMSNorm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MiniMind source: &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;github.com/jingyaogong/minimind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RMSNorm implementation: &lt;code&gt;model/model_minimind.py:95-105&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Other articles in this series&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251217---rope-position-encoding/post&quot;&gt;Part 2: RoPE positional encoding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251218---attention-mechanism/post&quot;&gt;Part 3: The Attention mechanism&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/en/blog/20251219---feedforward-transformer-block/post&quot;&gt;Part 4: FeedForward and the complete architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;7. Summary&lt;/h2&gt;
&lt;h3&gt;7.1 Key Takeaways&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Vanishing gradients aren&apos;t magic&lt;/strong&gt;: there&apos;s a clear mathematical principle behind them, and you can verify it with code&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;What RMSNorm does&lt;/strong&gt;: it stabilizes the numerical scale and preserves the vector&apos;s direction, without losing information&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Why it&apos;s faster than LayerNorm&lt;/strong&gt;: it skips the mean-subtraction step and finishes in a single pass&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Where it sits in the Transformer&lt;/strong&gt;: two inside each Block, not as a standalone layer&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The Pre-Norm design&lt;/strong&gt;: the standard choice for modern deep Transformers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7.2 One Sentence to Remember&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Normalization is the water-pressure stabilizer of deep networks, and RMSNorm is the more efficient version.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;7.3 Key Code Locations (MiniMind)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;RMSNorm implementation: &lt;code&gt;model/model_minimind.py:95-105&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Used in the Block: &lt;code&gt;model/model_minimind.py:359-380&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Learning example code: &lt;code&gt;learning_materials/why_normalization.py&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: joye
&lt;strong&gt;Published&lt;/strong&gt;: 2025-12-16
&lt;strong&gt;Last updated&lt;/strong&gt;: 2025-12-16
&lt;strong&gt;Series&lt;/strong&gt;: MiniMind learning notes (1/4)&lt;/p&gt;
&lt;p&gt;If you found this helpful, feel free to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ Star the original project &lt;a href=&quot;https://github.com/jingyaogong/minimind&quot;&gt;MiniMind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⭐ Star my learning notes &lt;a href=&quot;https://github.com/joyehuang/minimind-notes&quot;&gt;minimind-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💬 Leave a comment with your own learning insights&lt;/li&gt;
&lt;li&gt;🔗 Share it with others studying LLMs&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Frontend Intern Interviews at Chinese Startups: A Prep Guide</title><link>https://www.joyehuang.me/en/blog/20251023---internshipexperience/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20251023---internshipexperience/post</guid><description>A systematic rundown of the technical topics, application data, and a complete prep checklist for frontend internship interviews at smaller Chinese companies.</description><pubDate>Thu, 23 Oct 2025 16:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;As a second-year student at the University of Melbourne, I spent late 2025 looking for a frontend internship in Shanghai (React stack) for the November–March break. After about a week of back-to-back interviews, I ended up with roughly 10 offers. Drawing on that firsthand experience, this post summarizes the main technical topics that come up in frontend internship interviews at smaller Chinese companies, along with how to prepare for them. I&apos;ll also share some practical tips for staying sharp and performing well during a stretch of high-frequency interviewing.&lt;/p&gt;
&lt;h2&gt;Application Data&lt;/h2&gt;
&lt;h3&gt;The numbers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Positions contacted&lt;/strong&gt;: 210 (including both cold applications and HR outreach, for the main one-week push only)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resumes exchanged&lt;/strong&gt;: 51&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interview conversion rate&lt;/strong&gt;: ~15%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offers&lt;/strong&gt;: ~10&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Primary channel&lt;/strong&gt;: BOSS Zhipin&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What the data tells me&lt;/h3&gt;
&lt;p&gt;Looking at the conversion rate, resume screening for frontend internships at smaller companies is relatively lenient: about 1 in 6 conversations made it to a technical interview, and the final offer rate hit 70%. In other words, as long as you interview well, you&apos;re very likely to land an offer.&lt;/p&gt;
&lt;h2&gt;Breakdown of Technical Interview Topics&lt;/h2&gt;
&lt;p&gt;Based on every technical interview I went through (smaller companies usually run a single round, with the occasional second round or lead interview), it&apos;s clear they care more about fundamentals and practical framework usage. Below I only keep the &quot;what gets asked&quot; points; the &quot;how to prepare&quot; part comes later, to avoid repetition.&lt;/p&gt;
&lt;h3&gt;React (high frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hooks: common Hooks and their use cases, &lt;code&gt;useEffect&lt;/code&gt; dependencies and the closure/render pitfalls&lt;/li&gt;
&lt;li&gt;Component communication and state: parent-child (props), cross-level (Context), global (lightweight state libraries, e.g. the basics of Zustand/Redux)&lt;/li&gt;
&lt;li&gt;Performance optimization: controlling re-renders, &lt;code&gt;memo&lt;/code&gt;/&lt;code&gt;useMemo&lt;/code&gt;/&lt;code&gt;useCallback&lt;/code&gt;, the gist of virtual lists&lt;/li&gt;
&lt;li&gt;New features: how React 18/19 affect concurrency, forms, and server-side capabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;JavaScript (high frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ES6+: destructuring/spread, modules, the differences between arrow functions and regular functions (&lt;code&gt;this&lt;/code&gt;, &lt;code&gt;arguments&lt;/code&gt;, can&apos;t be used as constructors), &lt;code&gt;var&lt;/code&gt; vs &lt;code&gt;let/const&lt;/code&gt; (scope, hoisting, the temporal dead zone)&lt;/li&gt;
&lt;li&gt;Async: Promise chains, &lt;code&gt;async/await&lt;/code&gt;, error boundaries and unified handling&lt;/li&gt;
&lt;li&gt;Coding questions: debounce/throttle, array deduplication, and (at the conceptual level) deep copy&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;TypeScript (medium frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Common types, &lt;code&gt;interface&lt;/code&gt; vs &lt;code&gt;type&lt;/code&gt;, basic generics, frequently used utility types&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Build Tools and Frameworks (medium frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Next.js: why choose it, SSR/SSG scenarios, and the SEO differences&lt;/li&gt;
&lt;li&gt;Build tools: how Vite and Webpack work and their performance differences&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;CSS Layout (high frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Types of responsive layout:
&lt;ul&gt;
&lt;li&gt;Media queries: breakpoint-driven; the upside is fine-grained control, the downside is the maintenance cost of breakpoints; good for B2C pages with clearly defined device breakpoints&lt;/li&gt;
&lt;li&gt;Fluid layout (percentages + max/min): shrinks naturally with the container; simple to implement, but elements can become unbalanced at extreme widths; good for information-oriented content pages&lt;/li&gt;
&lt;li&gt;Flexbox: distributes along the main axis/cross axis; strong for one-dimensional layouts, limited for two-dimensional arrangements; good at the component level and for linear arrangements&lt;/li&gt;
&lt;li&gt;CSS Grid: a two-dimensional grid; very expressive, but with a steeper learning curve; good for complex panels/dashboards&lt;/li&gt;
&lt;li&gt;Modern responsiveness (&lt;code&gt;clamp&lt;/code&gt;/container queries): adapts based on container/font size; closer to a component-based approach, though you&apos;ll need to verify browser support; good for design systems and component libraries&lt;/li&gt;
&lt;li&gt;Combined strategy: mobile-first, content-driven breakpoints&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The classic three-column layout (Holy Grail / Twin-Wing): the underlying principles and differences, plus the trade-offs between Flex and Grid implementations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Networking and Browsers (low frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP status codes and how redirects work&lt;/li&gt;
&lt;li&gt;Cross-origin issues (CORS/proxies) and how to debug using the DevTools Network tab&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Git (low frequency)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Branching strategy, &lt;code&gt;git rebase&lt;/code&gt;, &lt;code&gt;git fetch&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other (role-specific)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deployment: the typical frontend deployment flow and basic troubleshooting&lt;/li&gt;
&lt;li&gt;AI/LLM (specialized roles): RAG, long-context quality assurance, API response structures&lt;/li&gt;
&lt;li&gt;Forms: ways to inject/prefill data into a form library&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Where to Focus Your Prep&lt;/h2&gt;
&lt;p&gt;Based on the &quot;what gets asked&quot; above, here&apos;s an action checklist for &quot;how to prepare efficiently,&quot; keeping repetition to a minimum:&lt;/p&gt;
&lt;h3&gt;Core stack (80% of your effort)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The React ecosystem:
&lt;ul&gt;
&lt;li&gt;Go through the common Hooks and practice them with small demos; get a solid grasp of &lt;code&gt;useEffect&lt;/code&gt; dependencies and pitfalls&lt;/li&gt;
&lt;li&gt;Get comfortable with props/Context and one lightweight state library (I&apos;d suggest Zustand)&lt;/li&gt;
&lt;li&gt;Do a focused performance exercise: track down redundant re-renders, apply &lt;code&gt;memo&lt;/code&gt;/&lt;code&gt;useMemo&lt;/code&gt;/&lt;code&gt;useCallback&lt;/code&gt;, and build a basic virtual list&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CSS layout: build a responsive page once using Flex and media queries&lt;/li&gt;
&lt;li&gt;JavaScript fundamentals:
&lt;ul&gt;
&lt;li&gt;Shore up ES6+ (modules, destructuring/spread, &lt;code&gt;this&lt;/code&gt; behavior)&lt;/li&gt;
&lt;li&gt;The async trio: Promise chains, &lt;code&gt;async/await&lt;/code&gt;, error-handling patterns&lt;/li&gt;
&lt;li&gt;Three coding questions: debounce, throttle, array deduplication (optional: the approach to deep copy)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Supporting knowledge (20% of your effort)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TypeScript: basic types, &lt;code&gt;interface&lt;/code&gt; vs &lt;code&gt;type&lt;/code&gt;, one generics example, common utility types&lt;/li&gt;
&lt;li&gt;Computer networking (just the basics is fine):
&lt;ul&gt;
&lt;li&gt;The four-layer TCP/IP model; what happens from typing a URL to the page rendering&lt;/li&gt;
&lt;li&gt;Common status codes; TCP&apos;s three-way handshake / four-way teardown; TCP vs UDP; cross-origin issues (CORS/proxies)&lt;/li&gt;
&lt;li&gt;Recommended: &lt;a href=&quot;https://xiaolincoding.com/network/&quot;&gt;Xiaolin Coding - Illustrated Networking&lt;/a&gt; (lots of diagrams, which makes it easier to understand and remember)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Build tools/Git: understand the differences between Vite and Webpack; day-to-day branch management and the basics of &lt;code&gt;rebase&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Resume Tips&lt;/h2&gt;
&lt;h3&gt;Choosing a tool&lt;/h3&gt;
&lt;p&gt;I recommend &lt;a href=&quot;https://rxresu.me/&quot;&gt;Reactive Resume&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open source and free, with data export&lt;/li&gt;
&lt;li&gt;Professional templates and clean typography&lt;/li&gt;
&lt;li&gt;Supports Markdown and custom styling&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Content principles&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Skills section&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Group by proficiency (proficient, comfortable, familiar)&lt;/li&gt;
&lt;li&gt;Only list technologies you&apos;ve actually used, not ones you&apos;ve merely read the docs for&lt;/li&gt;
&lt;li&gt;Highlight the skills that match the role&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Projects section&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two or three representative projects is plenty; highlight the stack you know well (React / Next.js / TypeScript, etc.).&lt;/li&gt;
&lt;li&gt;I&apos;d suggest a concise structure for each description:
&lt;ul&gt;
&lt;li&gt;Overview: one sentence on what it does and where it sits (e.g. &quot;a voice-interaction platform for AI-powered mock interviews&quot;).&lt;/li&gt;
&lt;li&gt;Technical highlights: focus on the features you built yourself or the problems you solved (e.g. &quot;implemented the login/registration logic and database integration,&quot; &quot;built a reusable form component&quot;).&lt;/li&gt;
&lt;li&gt;What you learned: things like &quot;got the hang of the SSR rendering flow&quot; or &quot;understood how Zustand&apos;s state management works.&quot;&lt;/li&gt;
&lt;li&gt;Real over flashy: don&apos;t force performance metrics; focus on which key technologies you mastered and which problems you solved.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ship it if you can: even deploying to Vercel / Netlify demonstrates completeness and hands-on ability.&lt;/li&gt;
&lt;li&gt;Stack consistency: the frameworks and libraries mentioned in your projects should line up with the skills section — keep everything consistent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The key principle&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every technology and project detail on your resume needs to be something you can explain in depth. Interviewers ask questions based on your resume, and listing things you&apos;re not familiar with is an easy way to get exposed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Interview Strategy&lt;/h2&gt;
&lt;h3&gt;Technical interviews&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fundamentals first&lt;/strong&gt;: smaller companies weigh fundamentals over projects — solid JavaScript and React basics matter more than a complicated project&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured delivery&lt;/strong&gt;: when answering, lead with the conclusion, then fill in the details&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be honest&lt;/strong&gt;: for things you don&apos;t know, &quot;I&apos;m not deeply familiar with this, but my understanding is...&quot; beats winging it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Make the most of the Q&amp;#x26;A&lt;/strong&gt;: never waste the chance to ask questions — you can ask about the specifics of the internship, the team and the product, or where you could improve based on the interview&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Communication tips&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Stay active on BOSS Zhipin and reply to messages promptly&lt;/li&gt;
&lt;li&gt;When cold-applying, briefly explain why you&apos;re a good fit&lt;/li&gt;
&lt;li&gt;Send a thank-you note after the interview to express your interest&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Review and practice&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Interview enough that nerves fade: pack your interviews into a short window so you get into the groove quickly&lt;/li&gt;
&lt;li&gt;Record and review (for your own use only): replay the questions and your answers, mark each as &quot;good / okay / needs work,&quot; and patch the gaps accordingly&lt;/li&gt;
&lt;li&gt;Turn it into a checklist: organize the frequent questions and common mistakes into flashcards and practice them with spaced repetition&lt;/li&gt;
&lt;li&gt;Ship your projects if you can: put the live URLs on your resume and personal homepage — HR and interviewers will actually visit them, and it&apos;s a clear plus&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;The technical bar for frontend internships at smaller Chinese companies is fairly clear: &lt;strong&gt;solid JavaScript fundamentals + comfortable React usage + reasonable resume packaging&lt;/strong&gt;. Compared to the big players, smaller companies care more about &quot;can you get up to speed and do the work&quot; than about algorithms and system design.&lt;/p&gt;
&lt;p&gt;In terms of return on effort, I&apos;d suggest spending 80% of your time on React and JavaScript fundamentals (the classic interview canon) and 20% on resume polishing and project prep.&lt;/p&gt;
&lt;p&gt;I hope this rundown helps anyone out there looking for an internship.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://react.dev/&quot;&gt;React Official Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/&quot;&gt;MDN Web Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rxresu.me/&quot;&gt;Reactive Resume&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zh.javascript.info/&quot;&gt;The Modern JavaScript Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xiaolincoding.com/network/&quot;&gt;Xiaolin Coding - Networking section&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>My First-Ever Pull Request</title><link>https://www.joyehuang.me/en/blog/20250701---firstpr/post</link><guid isPermaLink="true">https://www.joyehuang.me/en/blog/20250701---firstpr/post</guid><description>A sophomore reflects on landing his first successful open-source pull request</description><pubDate>Tue, 01 Jul 2025 22:06:36 GMT</pubDate><content:encoded>import { GithubCard } from &apos;astro-pure/advanced&apos;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;On June 27, 2025, around 7 PM Melbourne time, I opened the first pull request of my life — for the VMind project in the VisActor community. It would be a lie to say that moment wasn&apos;t exciting. After all, in my mind, open source had always been something only seriously skilled people could do. I&apos;d tried to break into open source before, but those attempts clearly failed. Maybe my approach was wrong, maybe my goals weren&apos;t clear enough, or maybe it was just my tendency to give up halfway.&lt;/p&gt;
&lt;h2&gt;How I found this project&lt;/h2&gt;
&lt;p&gt;It was a lucky break, honestly. I discovered this open-source project through OSPP (and if the event hadn&apos;t been postponed, I probably wouldn&apos;t have applied at all). To be honest, I do have a bit of an aversion to high-difficulty tasks. At the time, I browsed every JavaScript project in this round of OSPP and noticed a few of the VisActor community&apos;s foundational projects. One of them was building a candlestick chart for VChart — I was really interested in it, so that same night I did some research and reached out to the mentor.
The reply, however, made it clear that all VisActor projects would be judged on cumulative contributions made during the OSPP registration window. In other words, someone like me, hoping to &quot;snag a leftover spot&quot; a week after the deadline, basically had no chance of being accepted. Still, the mentor&apos;s email included a QR code for the VisActor Contributors Group on Feishu, and I joined right away. As a newcomer, I didn&apos;t dare say much at first — mostly I just scrolled through the past chat history (Feishu keeps message history) and quietly learned.&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h2&gt;Picking an issue&lt;/h2&gt;
&lt;p&gt;I found the group&apos;s atmosphere incredibly welcoming. When someone wanted to claim an issue, they&apos;d simply comment under the GitHub issue and give a heads-up in the Feishu group, and a core contributor or maintainer would respond. For someone like me, participating in open source for the first time, this was genuinely a great fit — it spared me a lot of the &quot;nobody&apos;s responding&quot; anxiety, and I could ask questions in the group anytime.
I went through the issue trackers of all four open-source projects in the VisActor community and found that VMind currently had mostly beginner-friendly unit-test tasks, many of them tagged &quot;good first issue.&quot; Through AI and online searches, I also confirmed that writing unit tests really is a solid entry point into open source (along with non-coding tasks like fixing documentation).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.joyehuang.me/_astro/second.DFoL_xXt_1hopyx.webp&quot; alt=&quot;second&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Getting started for real&lt;/h2&gt;
&lt;p&gt;I picked an issue and left a comment saying I wanted to claim it (later I confirmed it again in the Feishu group — everyone&apos;s busy, so I&apos;d recommend just saying it in the group directly). From there it was the standard open-source contribution flow: fork the repo, clone it locally, set up the remote and upstream, then start studying the project code.
Since this was about writing unit tests, I first looked at the test folder and quickly found where I needed to add my test (and discovered the existing tests for other chart types). What I wrote this time was the test file for getChartSpecWithContext_boxplot — essentially adding BoxPlot-type tests for VMind&apos;s getChartSpecWithContext function, to verify the data-field mapping and chart-spec logic when AI generates charts.
At first my head really was spinning a bit (maybe I&apos;m just too much of a noob), so I handed the issue to an AI and asked it to lay out the rough steps for me (plenty of small problems cropped up along the way, of course), along with the concepts I needed to grasp. For instance, this project uses Jest, so I had to go learn it (checking the official site, or a crash-course video on YouTube / Bilibili — a one-hour speedrun is plenty).
What I think you absolutely must do is read the test code already written in the project and learn how others write it. Even if everyone uses Jest, different projects still differ a bit. And the process of understanding someone else&apos;s code deepens your understanding of the project itself.
My first draft was actually modeled on the pie chart&apos;s test file — I then tweaked the data (which I found in the mockdata) and asked the AI to take a look at the problems. I&apos;d specifically point out: &lt;strong&gt;I don&apos;t need the answer directly; I just need you to point out the problems and the approach — I&apos;ll write the code myself.&lt;/strong&gt; I think this distinction matters a lot. AI can certainly handle simple test tasks, but if you let it, you won&apos;t learn a thing.
If you let AI generate complete, ready-to-use code, very few people would bother studying the reasoning behind each line. But writing it yourself means hitting pitfalls and debugging, and that process is enormously valuable for improving your skills — in any field.&lt;/p&gt;
&lt;h2&gt;The PR gets merged&lt;/h2&gt;
&lt;p&gt;I posted in the Feishu group asking a contributor to review my work, and feedback came quickly: I&apos;d written two pointless lines of code. After fixing that and pushing a new commit, my PR was successfully merged today (July 1, 2025)!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.joyehuang.me/_astro/third.DXXeNODx_Z2wlt3o.webp&quot; alt=&quot;third&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Takeaways&lt;/h2&gt;
&lt;p&gt;This experience taught me a lot. First, I learned how to get started on an issue, including how to locate the corresponding spot and function within a project. In my case, I needed to find where to add the test file, the definition of the getChartSpecWithContext function, the core code for the BoxPlot chart (which defines the fields that needed testing), and the mockdata (which could be used directly for testing).
Once I&apos;d found that code, I read and understood it, then extracted the parts I needed for the test. Second, I think imitation is a great friend of learning. Human learning often starts with imitation. My first draft was modeled on the pie chart&apos;s test — it had bugs (for instance, I used the pie spec but was testing a boxplot), but this &quot;imitate and improve&quot; process is important. Once you have a framework, asking an AI for help becomes more efficient too.
I also ran into the kind of small problems common to &quot;big projects,&quot; like Node.js version incompatibility. That&apos;s when you need nvm to install and switch between multiple versions. And here&apos;s something amazing: once you claim an issue in an open-source project, you feel a powerful sense of responsibility — you genuinely want to do the job well.
So now I&apos;ve gone and left a comment on another issue in this project, ready to keep contributing!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you found this experience helpful, or you&apos;re thinking about giving open source a try yourself, consider following the VisActor community&apos;s projects or dropping by the group — maybe you&apos;ll find a &quot;first time&quot; of your own too.&lt;/p&gt;</content:encoded></item></channel></rss>