<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Prompt Engineering on kenji.blog</title><link>http://kenji.blog/en/tags/prompt-engineering/</link><description>Recent content in Prompt Engineering on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 20:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/en/tags/prompt-engineering/index.xml" rel="self" type="application/rss+xml"/><item><title>For Engineers: Basics of Prompt Engineering and Application to Development</title><link>http://kenji.blog/en/p/prompt-engineering-for-engineers/</link><pubDate>Fri, 11 Sep 2026 20:00:00 +0900</pubDate><guid>http://kenji.blog/en/p/prompt-engineering-for-engineers/</guid><description>&lt;img src="http://kenji.blog/p/prompt-engineering-for-engineers/img/eyecatch.jpg" alt="Featured image of post For Engineers: Basics of Prompt Engineering and Application to Development" />&lt;h1 id="introduction-why-engineers-should-learn-prompt-engineering">Introduction: Why Engineers Should Learn Prompt Engineering
&lt;/h1>&lt;p>The world of software development is in the midst of an unprecedented paradigm shift due to the rapid evolution of Large Language Models (LLMs). It is no exaggeration to say that we are transitioning from &amp;ldquo;Software 2.0&amp;rdquo; (development via neural networks), as proposed by Andrej Karpathy, to &amp;ldquo;Software 3.0&amp;rdquo; (prompt-driven development via natural language).&lt;/p>
&lt;p>With the spread of AI assistant tools using GitHub Copilot, Cursor, or various LLM APIs, the primary job of engineers is shifting from &amp;ldquo;writing code from scratch&amp;rdquo; to &amp;ldquo;designing instructions to make AI generate the intended code, and reviewing and integrating the generated code.&amp;rdquo;&lt;/p>
&lt;p>The most important skill in this new development methodology is &lt;strong>prompt engineering&lt;/strong>. Prompt engineering is often talked about as a buzzword for non-engineers, such as &amp;ldquo;having a good chat with AI,&amp;rdquo; but its essence is a &lt;strong>new form of programming language for non-deterministic computational systems&lt;/strong>.&lt;/p>
&lt;p>In this article, aimed at software engineers and architects, we will explain in extreme detail—with a volume of about 10,000 characters—from the mathematical and architectural foundations behind LLMs to advanced prompt engineering techniques such as Few-Shot, Chain-of-Thought, and ReAct, as well as how to integrate them into actual development workflows and APIs.&lt;/p>
&lt;hr>
&lt;h2 id="1-basics-and-mathematical-background-of-large-language-models-llms">1. Basics and Mathematical Background of Large Language Models (LLMs)
&lt;/h2>&lt;p>To optimize prompts and consistently obtain the intended output, it is essential to understand the &amp;ldquo;contents of the black box&amp;rdquo; mathematically and structurally: how LLMs process and generate text and code internally. Most modern LLMs are auto-regressive language models using the Transformer architecture.&lt;/p>
&lt;h3 id="11-tokenization-and-bpe">1.1 Tokenization and BPE
&lt;/h3>&lt;p>LLMs do not process raw text strings directly. Text is divided into smaller units called &lt;strong>Tokens&lt;/strong>. Many models use an algorithm called Byte-Pair Encoding (BPE).&lt;/p>
&lt;p>Understanding tokenization is important for engineers. This is because how indentations (spaces) and special symbols in programming languages are tokenized directly affects the quality of code generation. For example, in Python code generation, the number of whitespaces (four spaces or a tab) is often treated as an independent token, and failing to clarify indentation rules in the prompt can cause syntax errors.&lt;/p>
&lt;h3 id="12-next-token-prediction">1.2 Next Token Prediction
&lt;/h3>&lt;p>The fundamental task of an auto-regressive LLM is to predict the &amp;ldquo;most probable next single token&amp;rdquo; following a given input sequence (context). Expressed mathematically, this becomes a maximization problem of the following conditional probability.&lt;/p>
$$ P(w_t | w_{1}, w_{2}, \dots, w_{t-1}) $$
&lt;p>Here, $w_i$ represents a token, and $t$ is the current time step. The model calculates the probability distribution of the next token from the input tokens through an internal neural network. The generated token is auto-regressively added as the input for the next step, and this process is repeated until an end token (such as &lt;code>&amp;lt;EOS&amp;gt;&lt;/code>) is output.&lt;/p>
&lt;h3 id="13-attention-mechanism-and-context-window">1.3 Attention Mechanism and Context Window
&lt;/h3>&lt;p>The core of the Transformer architecture is the Self-Attention mechanism. This allows the model to calculate the dependencies between tokens that are far apart in a sequence.&lt;/p>
$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V $$
&lt;p>Here, $Q$ (Query), $K$ (Key), and $V$ (Value) are matrices generated from the input representation, and $d_k$ is a scaling factor. What this formula means is the process of &amp;ldquo;calculating which past words (Key) the currently processed word (Query) should pay attention to, and incorporating that information (Value).&amp;rdquo;&lt;/p>
&lt;p>Why is understanding this mechanism important in prompt engineering? It&amp;rsquo;s because it directly ties to the concept of the &lt;strong>Context Window&lt;/strong>. If the input prompt becomes too long, important instructions can get buried in the middle of the context, causing Attention weights to disperse, leading to a phenomenon known as &amp;ldquo;Lost in the middle&amp;rdquo;. Instead of throwing massive documents or entire codebases into the prompt, you need to devise ways to accurately extract and pass only the necessary chunks.&lt;/p>
&lt;h3 id="14-sampling-control-via-temperature">1.4 Sampling Control via Temperature
&lt;/h3>&lt;p>In the output layer, the Softmax function is typically used to convert logits (raw model output) into a probability distribution. Here, &lt;strong>Temperature ($T$)&lt;/strong> is introduced to control the diversity (randomness) of the generation.&lt;/p>
$$ p_i = \frac{\exp(z_i / T)}{\sum_j \exp(z_j / T)} $$
&lt;ul>
&lt;li>$z_i$ is the logit (score) of token $i$ in the vocabulary.&lt;/li>
&lt;li>When $T = 1.0$, it becomes a standard Softmax.&lt;/li>
&lt;li>As $T \to 0$, the probability distribution becomes sharper, and only the token with the highest probability is selected (deterministic, Greedy Decoding).&lt;/li>
&lt;li>When $T > 1.0$, the probability distribution flattens, making it easier for minor, usually unselected tokens to be chosen (increasing creativity).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Practical Approach for Engineers:&lt;/strong>
When having it perform code generation or JSON data extraction (Structured Output) via API, it is standard practice to set an extremely low value of $T=0.0 \sim 0.2$ to prevent hallucinations and increase reproducibility. On the other hand, for exploratory tasks such as architecture brainstorming or ideating naming conventions, set $T=0.7 \sim 1.0$.&lt;/p>
&lt;hr>
&lt;h2 id="2-prompt-structural-architecture-system-prompt-vs-user-prompt">2. Prompt Structural Architecture: System Prompt vs User Prompt
&lt;/h2>&lt;p>When building AI applications using OpenAI&amp;rsquo;s API (such as GPT-4) or Anthropic&amp;rsquo;s API (such as Claude), prompts are structured not as a single text block but as an array of messages. The most important among these is the separation of &amp;ldquo;System Prompt&amp;rdquo; and &amp;ldquo;User Prompt&amp;rdquo;.&lt;/p>
&lt;h3 id="21-system-prompt-global-constraints-and-persona-definition">2.1 System Prompt: Global Constraints and Persona Definition
&lt;/h3>&lt;p>The system prompt defines &lt;strong>global constraints, persona (role), and fundamental behavior rules&lt;/strong> for the LLM. To compare it to software design, it plays a role like the application&amp;rsquo;s &amp;ldquo;environment variables&amp;rdquo; or &amp;ldquo;base class,&amp;rdquo; or a container&amp;rsquo;s &amp;ldquo;Dockerfile.&amp;rdquo;&lt;/p>
&lt;p>An excellent system prompt dramatically stabilizes output quality and format.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># Example of a System Prompt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">You are a world-class senior Go engineer, highly proficient in concurrent processing (Goroutine/Channel) design.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Generate your answers strictly following the rules below.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Rules]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1. When providing code, always provide it as a complete, executable function.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2. Do not omit error handling; explicitly process errors with if err != nil following Go conventions.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">3. Use bullet points for explanations outside code blocks, keeping them to 3 sentences or less.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">4. If requested to implement something with security concerns (SQL injection, race conditions, etc.), propose safe alternatives.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">5. Output format must be strictly explanations and Markdown code blocks only.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="22-user-prompt-injecting-temporary-tasks-and-data">2.2 User Prompt: Injecting Temporary Tasks and Data
&lt;/h3>&lt;p>The user prompt provides specific tasks, questions, or input data to be processed. It corresponds to a &amp;ldquo;function call (passing arguments to a function)&amp;rdquo; executed within the context environment established by the system prompt.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># Example of a User Prompt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Implement a function that asynchronously downloads images from a large list of URLs and saves them to the local disk.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">The number of workers should be controllable via arguments, and the implementation should include timeout processing using the context (context.Context).
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>By robustly setting the system prompt, you can ensure output stability against highly variable user prompts injected by users (or other system components). It also functions as the first line of defense against &amp;ldquo;prompt injection&amp;rdquo; attacks from malicious user inputs.&lt;/p>
&lt;hr>
&lt;h2 id="3-core-prompt-engineering-techniques">3. Core Prompt Engineering Techniques
&lt;/h2>&lt;p>From here on, we will explain specific prompting paradigms to dramatically improve the accuracy of software development tasks.&lt;/p>
&lt;h3 id="31-zero-shot-prompting-and-few-shot-prompting">3.1 Zero-Shot Prompting and Few-Shot Prompting
&lt;/h3>&lt;p>&lt;strong>Zero-Shot Prompting&lt;/strong> is a technique where only task instructions are given, without any examples, to ask the model for an answer. For general requests like &amp;ldquo;Write a quicksort in Python,&amp;rdquo; current advanced LLMs function adequately even with Zero-Shot.&lt;/p>
&lt;p>However, when you want it to adhere to project-specific coding conventions or output a specific JSON schema, Zero-Shot has a high probability of breaking the format. &lt;strong>Few-Shot Prompting&lt;/strong> solves this.&lt;/p>
&lt;p>Few-Shot Prompting is a technique of presenting a few &amp;ldquo;input and expected output pairs (demonstrations)&amp;rdquo; within the prompt. It leverages a phenomenon called &amp;ldquo;In-Context Learning,&amp;rdquo; where patterns are learned within the prompt&amp;rsquo;s context without updating the model&amp;rsquo;s parameters.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># Example of Few-Shot Prompting (Log Analysis Task)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Parse the following raw logs and extract structured JSON objects.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Example 1:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Input: &amp;#34;[2023-10-01 10:00:05] ERROR [AuthService] Failed to authenticate user id=12345: Invalid password&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Output: {&amp;#34;timestamp&amp;#34;: &amp;#34;2023-10-01T10:00:05Z&amp;#34;, &amp;#34;level&amp;#34;: &amp;#34;ERROR&amp;#34;, &amp;#34;service&amp;#34;: &amp;#34;AuthService&amp;#34;, &amp;#34;message&amp;#34;: &amp;#34;Failed to authenticate user&amp;#34;, &amp;#34;user_id&amp;#34;: 12345}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Example 2:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Input: &amp;#34;[2023-10-01 10:05:12] WARN [DBPool] Connection timeout approaching for query_id=987&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Output: {&amp;#34;timestamp&amp;#34;: &amp;#34;2023-10-01T10:05:12Z&amp;#34;, &amp;#34;level&amp;#34;: &amp;#34;WARN&amp;#34;, &amp;#34;service&amp;#34;: &amp;#34;DBPool&amp;#34;, &amp;#34;message&amp;#34;: &amp;#34;Connection timeout approaching&amp;#34;, &amp;#34;query_id&amp;#34;: 987}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Task Input:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Input: &amp;#34;[2023-10-01 10:15:30] FATAL [PaymentGateway] API rate limit exceeded. Retry after 60s&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Output:
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>By giving examples in this way, the model implicitly learns the timestamp format (conversion to ISO 8601) and the naming convention for keys, enabling it to output perfect JSON.&lt;/p>
&lt;h3 id="32-chain-of-thought-cot-and-zero-shot-cot">3.2 Chain-of-Thought (CoT) and Zero-Shot CoT
&lt;/h3>&lt;p>A breakthrough regarding the reasoning capabilities of LLMs was &lt;strong>Chain-of-Thought (CoT)&lt;/strong>. In tasks requiring complex logic (e.g., implementing complex algorithms, tracking difficult bugs, constructing regular expressions), making an LLM abruptly output the final code often leads to logical leaps and errors (hallucinations).&lt;/p>
&lt;p>CoT is a technique that linguisticizes the intermediate reasoning process (thought process) before outputting the final answer. By making the model analyze the situation step-by-step itself, the context becomes richer with each token generated, dramatically improving the accuracy of the final conclusion.&lt;/p>
&lt;p>The simplest and most powerful technique is &lt;strong>Zero-Shot CoT&lt;/strong>, which appends the magic phrase &amp;ldquo;&lt;strong>Let&amp;rsquo;s think step by step&lt;/strong>&amp;rdquo; to the end of the prompt.&lt;/p>
&lt;p>In development, we apply this concept and structure the prompt as follows.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">Create a React component that meets the following specifications.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Specifications]...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Before generating the code, describe your thought process (inside &amp;lt;thinking&amp;gt; tags) using the following steps.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1. Identification of necessary States and design of data structures
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2. Consideration of possible edge cases and error handling
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">3. Consideration of component decomposition units
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">After completing the thought process, write the final TypeScript code.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="mermaid">graph TD
A["User Prompt: Complex Requirements Definition"] --> B["LLM Reasoning Process Starts"]
B --> C["Step 1: Logical Decomposition of Requirements"]
C --> D["Step 2: Design of Data Structures and Types"]
D --> E["Step 3: Algorithm Selection and Complexity Evaluation"]
E --> F["Step 4: Consideration of Corner Cases and Security"]
F --> G["Generation of Final Optimized Code"]&lt;/div>
&lt;h3 id="33-tree-of-thoughts-tot">3.3 Tree of Thoughts (ToT)
&lt;/h3>&lt;p>A further extension of the CoT concept is &lt;strong>Tree of Thoughts (ToT)&lt;/strong>. While CoT follows a single-path (linear) reasoning track, ToT is a technique that develops multiple reasoning paths (branches) in parallel like a search tree, has the model self-evaluate each path, and reaches the optimal solution while backtracking if necessary.&lt;/p>
&lt;p>ToT is extremely effective for problems with large search spaces that are prone to falling into local optima, such as system architecture design, complex database schema design, or large-scale refactoring planning.&lt;/p>
&lt;div class="mermaid">graph TD
Root["Initial Problem: Strategy for Splitting Monolith to Microservices"]
Root --> Path1["Thought Path A: Domain-Driven Design (DDD) Based Split"]
Root --> Path2["Thought Path B: Database Table Based Split"]
Root --> Path3["Thought Path C: Traffic/Load Based Split"]
Path1 --> Eval1["Self-Evaluation: High cohesion obtained, but initial modeling cost is large."]
Path2 --> Eval2["Self-Evaluation: Implementation is easy, but high risk of future service coupling."]
Path3 --> Eval3["Self-Evaluation: Scalability is ensured, but transaction management becomes complex."]
Eval1 --> Select["Decision: Adopt Path A (DDD Based) prioritizing long-term maintainability."]
Eval2 --> Discard1["Discard"]
Eval3 --> Discard2["Discard"]
Select --> Detail["Output specific service split plan and API design based on the adopted strategy."]&lt;/div>
&lt;p>To implement ToT in a prompt, you instruct it: &amp;ldquo;Propose multiple approaches, evaluate the pros and cons of each, and then adopt and implement the most superior approach.&amp;rdquo;&lt;/p>
&lt;hr>
&lt;h2 id="4-agentic-workflow-and-react-reasoning-and-acting">4. Agentic Workflow and ReAct (Reasoning and Acting)
&lt;/h2>&lt;p>The application of LLMs is rapidly evolving from single text input/output to the realm of &lt;strong>AI Agents&lt;/strong>, which autonomously make plans and interact with external environments to accomplish tasks. The core paradigm of this agent architecture is &lt;strong>ReAct (Reasoning and Acting)&lt;/strong>.&lt;/p>
&lt;h3 id="41-concept-of-the-react-framework">4.1 Concept of the ReAct Framework
&lt;/h3>&lt;p>While traditional LLMs could &amp;ldquo;think before answering (CoT),&amp;rdquo; they could not &amp;ldquo;act&amp;rdquo; to supplement their own knowledge gaps. The ReAct framework breaks through this limitation by making the LLM alternate between &amp;ldquo;Thought&amp;rdquo; and &amp;ldquo;Action&amp;rdquo;.&lt;/p>
&lt;p>The model analyzes the problem (Thought), and if it determines that information is lacking, it executes an external tool (Web search, database query, shell command, API call, etc.) (Action). It receives the execution result of the tool (Observation), advances its thoughts further using it as new context, and repeats this loop until it reaches the final answer (Finish).&lt;/p>
&lt;div class="mermaid">graph LR
Start["Task Start"] --> Thought["Thought (Situation Analysis and Planning)"]
Thought --> Action["Action (Selection and Execution of Appropriate Tools)"]
Action --> Environment["External Environment (API / DB / Shell / Code Interpreter)"]
Environment --> Observation["Observation (Execution Results / Error Logs from Tools)"]
Observation --> Thought
Thought -->|Sufficient Information Gathered| Finish["Finish (Final Answer / Code Output)"]&lt;/div>
&lt;h3 id="42-implementation-via-function-calling-tool-use">4.2 Implementation via Function Calling (Tool Use)
&lt;/h3>&lt;p>The standard interface for incorporating ReAct into a system is &lt;strong>Function Calling (Tool Use)&lt;/strong> provided by OpenAI and Anthropic.&lt;/p>
&lt;p>The engineer passes the &amp;ldquo;definition of available tools (JSON schema)&amp;rdquo; to the LLM along with the system prompt. The LLM analyzes the prompt&amp;rsquo;s context, and if it determines that a tool should be used, it outputs the &amp;ldquo;name of the function to call&amp;rdquo; and its &amp;ldquo;arguments in JSON&amp;rdquo; instead of normal text. The loop is formed by executing the function on the application side and returning the result to the LLM.&lt;/p>
&lt;p>&lt;strong>Application Example in Development (Autonomous Debugging Agent):&lt;/strong>
When building an agent that investigates the cause and generates a patch when a test fails in the CI/CD pipeline, provide the LLM with tools like the following.&lt;/p>
&lt;ol>
&lt;li>&lt;code>search_codebase(regex_pattern)&lt;/code>: Search code in the repository using regular expressions.&lt;/li>
&lt;li>&lt;code>view_file_content(file_path, start_line, end_line)&lt;/code>: Read the contents of a specified file.&lt;/li>
&lt;li>&lt;code>run_unit_test(test_file_path)&lt;/code>: Execute a specific unit test and retrieve the traceback.&lt;/li>
&lt;li>&lt;code>propose_patch(file_path, diff_content)&lt;/code>: Propose a fix patch.&lt;/li>
&lt;/ol>
&lt;p>The LLM autonomously reasons and acts as follows.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Thought&lt;/strong>: Looking at the test log, a &lt;code>KeyError: 'user_id'&lt;/code> occurs on line 45 of &lt;code>src/auth.py&lt;/code>. I need to check the surrounding code.&lt;/li>
&lt;li>&lt;strong>Action&lt;/strong>: &lt;code>view_file_content(file_path=&amp;quot;src/auth.py&amp;quot;, start_line=30, end_line=60)&lt;/code>&lt;/li>
&lt;li>&lt;strong>Observation&lt;/strong>: (The application reads the file content and returns it to the LLM)&lt;/li>
&lt;li>&lt;strong>Thought&lt;/strong>: I see, validation is missing for cases where &lt;code>user_id&lt;/code> is not included in the response JSON from the API. Let&amp;rsquo;s create a patch to rewrite it with a safe &lt;code>.get()&lt;/code> method.&lt;/li>
&lt;li>&lt;strong>Action&lt;/strong>: &lt;code>propose_patch(...)&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>In this way, prompt engineering is elevated in dimension from &amp;ldquo;control of text generation&amp;rdquo; to &amp;ldquo;definition of tools and loop design of agents (orchestration).&amp;rdquo;&lt;/p>
&lt;hr>
&lt;h2 id="5-rag-retrieval-augmented-generation-and-codebase-integration">5. RAG (Retrieval-Augmented Generation) and Codebase Integration
&lt;/h2>&lt;p>One of the biggest weaknesses of LLMs is that they do not know &amp;ldquo;private information&amp;rdquo; or &amp;ldquo;latest information&amp;rdquo; that is not included in their pre-training data. If you ask about an internal private repository or proprietary API specifications, the LLM will either calmly tell lies (hallucinations) or can only give general answers.&lt;/p>
&lt;p>The architecture that solves this is &lt;strong>RAG (Retrieval-Augmented Generation)&lt;/strong>. RAG is a technology that combines information retrieval with the generative capabilities of LLMs.&lt;/p>
&lt;h3 id="51-embeddings-and-vector-search">5.1 Embeddings and Vector Search
&lt;/h3>&lt;p>At the root of RAG is a mathematical vector space model. Source code and internal documents are converted into high-dimensional vectors (e.g., arrays of 1536-dimensional floating-point numbers) by an Embedding model (e.g., &lt;code>text-embedding-3-small&lt;/code>) and stored in a Vector Database.&lt;/p>
&lt;p>When a user inputs a question (query), the query is also vectorized using the same model, and the &lt;strong>Cosine Similarity&lt;/strong> is calculated between it and the document vectors in the database.&lt;/p>
$$ \text{Cosine Similarity}(A, B) = \frac{A \cdot B}{\|A\| \|B\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$
&lt;p>The top few code snippets or documents with high similarity (semantically close) are retrieved, and these are dynamically injected into the user prompt as &amp;ldquo;context.&amp;rdquo;&lt;/p>
&lt;h3 id="52-application-of-rag-to-development-workflows">5.2 Application of RAG to Development Workflows
&lt;/h3>&lt;p>By incorporating RAG into development tools, powerful features like the following are realized within the IDE.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant Engineer["Engineer"]
participant RAG_System["IDE Plugin (RAG)"]
participant VectorDB["Vector Database (Codebase)"]
participant LLM["LLM API"]
Engineer->>RAG_System: "Where is the transaction rollback process implemented in the current payment flow?"
RAG_System->>VectorDB: "Vectorize query and execute semantic search"
VectorDB-->>RAG_System: "Relevant code chunks (payment_service.go, db_tx.go, etc.)"
RAG_System->>LLM: "System prompt + Retrieved code chunks + Engineer's question"
LLM-->>RAG_System: "Accurate explanation and architectural breakdown based on the extracted code"
RAG_System-->>Engineer: "Present answers with links to the corresponding lines in the source code"&lt;/div>
&lt;p>As an important prompt engineering technique when building RAG for codebases, not only chunking the code but also including &amp;ldquo;summaries generated from each function&amp;rsquo;s docstring or class&amp;rsquo;s Abstract Syntax Tree (AST)&amp;rdquo; in the vectorization targets will drastically improve search accuracy.&lt;/p>
&lt;hr>
&lt;h2 id="6-practical-use-cases-and-advanced-prompt-examples-in-engineering">6. Practical Use Cases and Advanced Prompt Examples in Engineering
&lt;/h2>&lt;p>We introduce practical use cases and prompt techniques on how to apply prompt engineering theory to automate and streamline daily development tasks.&lt;/p>
&lt;h3 id="61-automating-code-review-and-supplementing-static-analysis">6.1 Automating Code Review and Supplementing Static Analysis
&lt;/h3>&lt;p>Incorporate LLMs into the CI pipeline to automatically perform code reviews upon Pull Request (PR) creation. The goal is to have it point out business logic inconsistencies and design anti-patterns that Lint tools and static analysis tools cannot detect.&lt;/p>
&lt;p>&lt;strong>Prompt Example (Requiring Structured Output):&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">You are a strict and experienced senior software engineer.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Analyze the provided Pull Request diff (Git Diff) and conduct a code review.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Focus Areas of Review]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1. Security vulnerabilities (Injection, XSS, Authorization bypass, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2. Performance bottlenecks (N+1 query problem, inefficient loop calculations, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">3. Maintainability and readability (Violation of SOLID principles, overly complex nesting, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Constraints]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- Do not point out mere formatting violations (indentations, etc.) as that is the role of Lint tools.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- If there are no issues, do not force yourself to come up with points; return an empty array.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- The output must strictly follow the JSON schema below. Do not wrap it in Markdown backticks (```json).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Expected JSON Output Format]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;review_comments&amp;#34;: [
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;file_path&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;line_number&amp;#34;: &amp;#34;integer&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;severity&amp;#34;: &amp;#34;High | Medium | Low&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;issue_title&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;detailed_description&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;suggested_code_fix&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Git Diff Data]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{PR_DIFF}}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The points of this prompt are forcing the LLM&amp;rsquo;s output into easily parsable JSON and clearly separating the roles of the Lint tool and the LLM (defining system boundaries).&lt;/p>
&lt;h3 id="62-defensive-prompting-in-zero-shot-code-generation">6.2 &amp;ldquo;Defensive Prompting&amp;rdquo; in Zero-Shot Code Generation
&lt;/h3>&lt;p>Common problems that occur when having AI write code are phenomena like &amp;ldquo;arbitrarily importing non-existent libraries (hallucination)&amp;rdquo; or &amp;ldquo;omitting necessary variable definitions (omitted with &lt;code># write processing here&lt;/code>, etc.).&amp;rdquo; To prevent this, we use &amp;ldquo;Defensive Prompting,&amp;rdquo; setting up strong guardrails within the prompt.&lt;/p>
&lt;p>&lt;strong>Important Elements of Defensive Prompts:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Prohibition of Omissions:&lt;/strong> &amp;ldquo;Do not omit code or use placeholders (&lt;code>// ...&lt;/code> etc.); generate a complete file that can be copied, pasted, and executed directly.&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>Prevention of Hallucinations:&lt;/strong> &amp;ldquo;If standard libraries to fulfill the requirements do not exist, do not fabricate non-existent third-party libraries. In that case, clearly state that external library installation is necessary, and propose code using the most standard library (e.g., requests).&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>Requirement for Self-Containment:&lt;/strong> &amp;ldquo;All variables and functions must be properly defined within the code block.&amp;rdquo;&lt;/li>
&lt;/ol>
&lt;h3 id="63-automated-generation-of-property-based-tests--edge-case-tests">6.3 Automated Generation of Property-Based Tests / Edge Case Tests
&lt;/h3>&lt;p>For functions implemented by engineers, have the LLM find corner cases and generate test code. This is highly effective in eliminating human assumptions.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">The following Python function determines whether a given string is a valid IPv4 address.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Write a comprehensive pytest-based unit test suite for this function.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Conditions]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- Exhaustively cover not only happy path test cases but also edge cases like the following:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> - Boundary values (0, 255, 256, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> - Different input types (integers, None, lists, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> - Strings containing spaces or special characters
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> - Cases with incorrect number of dots (less than 3, 4 or more)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- Utilize parameterized testing (`@pytest.mark.parametrize`) to keep the test code concise.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[Function Code]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">def is_valid_ipv4(ip_str):
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> # Implementation...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-prompt-evaluation-and-llmops-eval">7. Prompt Evaluation and LLMOps (Eval)
&lt;/h2>&lt;p>In the software engineering world, untested code is called legacy code. The exact same can be said for prompt engineering. It is extremely dangerous to deploy a &amp;ldquo;prompt that worked fine after trying it locally a few times&amp;rdquo; to a production environment.&lt;/p>
&lt;p>Prompt behavior easily breaks due to foundation model upgrades or changes in the domain data handled. To prevent this, it is essential to build an &lt;strong>Evaluation (Eval)&lt;/strong> mechanism (LLMOps) to quantitatively evaluate the prompt&amp;rsquo;s output.&lt;/p>
&lt;h3 id="71-llm-as-a-judge-evaluating-llms-with-llms">7.1 LLM-as-a-Judge (Evaluating LLMs with LLMs)
&lt;/h3>&lt;p>In tasks like code generation or text summarization, testing for an Exact Match is impossible. Classical natural language processing evaluation metrics (such as BLEU or ROUGE) are also insufficient for measuring semantic accuracy.&lt;/p>
&lt;p>The current industry standard is the &lt;strong>LLM-as-a-Judge&lt;/strong> approach, which uses powerful models (e.g., GPT-4o or Claude 3.5 Sonnet) as &amp;ldquo;Judges&amp;rdquo; to score the output results of the target LLM.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Preparation of Test Sets&lt;/strong>: Prepare tens to hundreds of pairs of input data and ideal outputs (or evaluation criteria).&lt;/li>
&lt;li>&lt;strong>Execution&lt;/strong>: Generate outputs against the test set using the prompt and model being evaluated.&lt;/li>
&lt;li>&lt;strong>Evaluation&lt;/strong>: Prepare an evaluation prompt (meta-prompt) and instruct the Judge LLM to &amp;ldquo;score on a scale of 1-5 whether the generated output meets the requirements.&amp;rdquo;&lt;/li>
&lt;/ol>
&lt;p>This makes it possible to automatically detect regressions (performance degradation) when modifying prompts on the CI/CD pipeline. Prompt engineering is evolving from artisanal &amp;ldquo;prompt tweaking&amp;rdquo; to data-driven, reproducible &amp;ldquo;engineering.&amp;rdquo;&lt;/p>
&lt;hr>
&lt;h2 id="8-conclusion-prompts-are-new-software-components">8. Conclusion: Prompts are New Software Components
&lt;/h2>&lt;p>In the era of AI writing code, the &amp;ldquo;end of programming&amp;rdquo; is sometimes proclaimed, but the reality is different. The layer of abstraction required from engineers has simply gone up one level.&lt;/p>
&lt;p>We once moved from assembly language to C, and then to high-level languages equipped with garbage collection, freeing ourselves from the hassle of memory management to focus on building more complex business logic. LLMs and prompt engineering are the next wave of abstraction following this.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Understanding Architecture&lt;/strong>: Understand the probabilistic nature of LLMs (auto-regression, Attention, Temperature) to control system non-determinism.&lt;/li>
&lt;li>&lt;strong>Context Design&lt;/strong>: Constraints via System Prompt and clear communication of intent leveraging Few-Shot/CoT.&lt;/li>
&lt;li>&lt;strong>Agentic Thinking and Tool Integration&lt;/strong>: Master the ReAct paradigm and utilize LLMs as system orchestrators.&lt;/li>
&lt;li>&lt;strong>Continuous Evaluation&lt;/strong>: Version control prompts as part of the code and continue to improve them in a test-driven manner through Eval.&lt;/li>
&lt;/ol>
&lt;p>By mastering these principles, prompts become not just text strings, but robust, scalable software components. We hope you will incorporate the advanced prompt engineering techniques explained in this article into your own development workflows and products, and thrive as an engineer leading the next generation of &amp;ldquo;Software 3.0.&amp;rdquo;&lt;/p>
&lt;hr>
&lt;p>&lt;em>Generated using Prompt Engineering Techniques.&lt;/em>&lt;/p></description></item></channel></rss>