In the era of large language models, how to "converse" with models
has become an art form. The same model can produce dramatically
different results depending on the prompt used. Prompt engineering is
the discipline of designing effective inputs to unlock the best
performance from models. From simple zero-shot prompts to complex
chain-of-thought reasoning, from role assignment to template design,
prompt engineering has become a core skill for working with large
models.
In-Context Learning (ICL) is the theoretical foundation of prompt
engineering. It reveals how models learn from examples, how they
dynamically adjust behavior during inference, and why few-shot prompts
often outperform zero-shot prompts. Understanding these mechanisms not
only helps us write better prompts but also deepens our understanding of
how large language models work.
This article systematically introduces the core concepts and
practical techniques of prompt engineering, including zero-shot,
few-shot, and chain-of-thought prompting, role assignment and formatting
techniques, prompt template design, advanced techniques like
Self-Consistency and ReAct, and demonstrates how to build efficient
prompt systems through practical examples.
Fundamentals
and Principles of Prompt Engineering
The core idea of prompt engineering is: guide models to
produce desired outputs through carefully designed input text.
A good prompt should be clear, specific, and contain necessary
contextual information.
Core Principles of Prompt
Engineering
1. Clarity
Prompts should clearly express task requirements and avoid ambiguity.
Compare these two prompts:
❌ Poor: "Analyze this text"
✅ Good:
"Please analyze the sentiment of the following text and provide a judgment of positive, negative, or neutral"
2. Specificity
Provide specific output format requirements so the model knows how to
structure the answer:
1 2 3 4 5 6 7 8 9 10
prompt = """ Please analyze the pros and cons of the following product and output in the following format: Pros: 1. ... 2. ... Cons: 1. ... 2. ... """
3. Context Completeness
Ensure prompts contain all information needed to complete the
task:
1 2 3 4 5 6 7 8 9
# Missing context prompt1 = "Translate this sentence"
# Complete context prompt2 = """ Please translate the following English sentence into Chinese, maintaining the original meaning and tone: English: The quick brown fox jumps over the lazy dog. Chinese: """
4. Role Assignment
Assigning a clear role to the model can significantly improve output
quality:
1 2 3 4 5
prompt = """ You are an experienced Python programming expert with expertise in writing clear and efficient code. Please write a Python function for the following requirement: Requirement: Implement a quicksort algorithm """
defbuild_prompt(instruction, context, input_data, output_format=None, examples=None): prompt_parts = [] # Role assignment (optional) prompt_parts.append("You are a professional data analyst.") # Instruction prompt_parts.append(f"Task: {instruction}") # Context if context: prompt_parts.append(f"Background: {context}") # Examples if examples: prompt_parts.append("Examples:") for ex in examples: prompt_parts.append(f"Input: {ex['input']}") prompt_parts.append(f"Output: {ex['output']}") # Output format if output_format: prompt_parts.append(f"Output format: {output_format}") # Input data prompt_parts.append(f"Please process the following data:\n{input_data}") return"\n\n".join(prompt_parts)
Zero-shot,
Few-shot, and Chain-of-Thought Prompting
Zero-shot Prompting
Zero-shot prompting is the simplest approach: directly provide a task
description without any examples.
1 2 3 4 5
zero_shot_prompt = """ Please determine the sentiment of the following sentence: Sentence: This movie has an excellent plot and outstanding acting. Sentiment: """
Use Cases: - Model has good prior knowledge of the
task - Task is relatively simple and straightforward - Need to quickly
test model capabilities
Limitations: - Models may misunderstand complex
tasks - Output format may not meet expectations - Difficult to handle
tasks requiring multi-step reasoning
Few-shot Prompting
Few-shot prompting provides a small number of examples, allowing the
model to learn task patterns. This is the core manifestation of
In-Context Learning.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
few_shot_prompt = """ Please determine the sentiment of the following sentences (positive/negative/neutral): Example 1: Sentence: The weather is beautiful today, sunny and bright. Sentiment: positive Example 2: Sentence: This product is of poor quality and not worth the price. Sentiment: negative Example 3: Sentence: It will rain tomorrow. Sentiment: neutral Now please determine: Sentence: The service attitude at this restaurant is impressive. Sentiment: """
Advantages of Few-shot Prompting:
Pattern Learning: Models learn task patterns
through examples
Format Alignment: Examples demonstrate expected
output format
Task Adaptation: Models can quickly adapt to new
tasks even without specific training
# Usage example examples = [ {"input": "The weather is beautiful today", "output": "positive"}, {"input": "This product is of poor quality", "output": "negative"}, {"input": "It will rain tomorrow", "output": "neutral"} ]
prompt = create_few_shot_prompt( "Please determine the sentiment of sentences", examples, "The service attitude at this restaurant is impressive" )
Chain-of-Thought (CoT)
Prompting
Chain-of-Thought prompting requires models to show their reasoning
process, thinking step by step. This is particularly effective for
complex reasoning tasks.
Standard CoT Prompt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
cot_prompt = """ Please solve the following math problem and show your reasoning process: Problem: Xiao Ming has 15 apples. He gave 3 to Xiao Hong and 5 to Xiao Hua, then ate 2 himself. How many apples does Xiao Ming have left? Reasoning: 1. Xiao Ming initially has 15 apples 2. After giving 3 to Xiao Hong: 15 - 3 = 12 apples 3. After giving 5 to Xiao Hua: 12 - 5 = 7 apples 4. After eating 2: 7 - 2 = 5 apples Answer: 5 apples Now please solve: Problem: A book has 120 pages. On day 1, 30 pages were read. On day 2, twice as many as day 1 were read. On day 3, half of the remaining pages were read. How many pages were read on day 3? """
Few-shot CoT:
1 2 3 4 5 6 7 8 9 10 11 12 13
few_shot_cot = """ Please solve the following problems, showing reasoning steps: Problem 1: A basket has 8 apples. 3 were taken away, then 2 were put back. How many are there now? Reasoning: Initially 8, after taking 3 there are 5, after putting back 2 there are 7. Answer: 7 Problem 2: A store has 20 items. 12 were sold, then 8 were restocked. How many are there now? Reasoning: Initially 20, after selling 12 there are 8, after restocking 8 there are 16. Answer: 16 Problem 3: A class has 30 students. 5 transferred out, then 7 transferred in. How many students are there now? """
Mathematical Expression of CoT:
For problem , CoT prompting
guides the model to generate a sequence of reasoning steps, ultimately
producing answer:whereis the final answer.
role_prompts = { "expert": """ You are a senior Python engineer with 20 years of experience, skilled in writing efficient and maintainable code. Please write code for the following requirement: """, "teacher": """ You are a patient programming teacher, skilled at explaining complex concepts in simple terms. Please explain the following concept: """, "analyst": """ You are a senior data analyst, skilled at discovering insights from data. Please analyze the following data: """, "creative": """ You are a creative copywriter, skilled at writing engaging copy. Please write copy for the following product: """ }
Effects of Role Assignment:
Professionalism: Expert roles produce more
professional, technical outputs
Style Consistency: Role assignment ensures output
style meets expectations
Domain Adaptation: Different roles adapt to
different domain tasks
Formatting Techniques
1. Structured Output
Use clear format markers to guide models to produce structured
content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
structured_prompt = """ Please analyze the following article and output in the following format: ## Article Summary [Summary content] ## Key Points 1. [Point 1] 2. [Point 2] 3. [Point 3] ## Sentiment Analysis - Overall sentiment: [positive/negative/neutral] - Sentiment intensity: [1-10 score] Article content: [Article content] """
2. JSON Format Output
For programmatic processing, require JSON format:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
json_prompt = """ Please analyze the following text and output results in JSON format: Requirements: - Field names: title, summary, keywords, sentiment - sentiment values: positive, negative, neutral Text: [Text content] Output format: { "title": "...", "summary": "...", "keywords": ["...", "..."], "sentiment": "..." } """
3. Step-by-step Output
For complex tasks, require step-by-step display:
1 2 3 4 5 6 7 8 9 10 11
step_by_step_prompt = """ Please solve the following problem, showing steps: Step 1: [First step] Step 2: [Second step] Step 3: [Third step] ... Final Answer: [Answer] Problem: [Problem content] """
4. Using Delimiters
Use clear delimiters to distinguish different sections:
Prompt templates are reusable prompt frameworks suitable for specific
types of tasks.
Classification Task Template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classification_template = """ You are a professional text classification expert. Task: Classify text into one of the following categories: {categories} Classification rules: {rules} Examples: {examples} Text to classify: {text} Please output: Category: [Category name] Confidence: [Value between 0-1] Reason: [Brief explanation] """
Generation Task Template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
generation_template = """ You are a professional {domain} content creator. Task: {task_description} Requirements: - Length: Approximately {length} words - Style: {style} - Target audience: {audience} Reference information: {reference} Please generate content: """
Q&A Task Template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
qa_template = """ Answer questions based on the following document. Document: {document} Question: {question} Requirements: 1. Answers must be based on document content 2. If no relevant information is found in the document, answer "No relevant information found in the document" 3. Cite specific content from the document to support your answer Answer: """
Code Generation Template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
code_generation_template = """ You are an experienced {language} programmer. Requirement: {requirement} Technical requirements: - Programming language: {language} - Code style: {style} - Must include: {features} Example input/output: {examples} Please write code: ```{language} [Code]
Code explanation: [Brief explanation of code logic] """
# Usage example template = PromptTemplate(classification_template) prompt = template.format( categories="positive, negative, neutral", rules="Classify based on text sentiment", examples="Example 1: The weather is beautiful today → positive", text="This movie is really great" )
Self-Consistency:
Consistency Sampling
Self-Consistency is a technique to improve CoT reasoning accuracy.
The core idea is: generate multiple reasoning paths for the same
problem, then select the most consistent answer.
Self-Consistency Principle
Traditional CoT generates only one reasoning path, while
Self-Consistency generatespaths
and selects the final answer through voting.
Algorithm Flow:
Use CoT prompting to generatedifferent reasoning paths
Extract answers from each path
Select the most frequently occurring answer (majority voting)
defself_consistency_sample(model, prompt, k=5, temperature=0.7): """ Sample multiple reasoning paths using Self-Consistency Args: model: Language model prompt: CoT prompt k: Number of samples temperature: Sampling temperature (higher temperature increases diversity) Returns: Final answer """ answers = [] for _ inrange(k): # Use higher temperature sampling to increase diversity response = model.generate( prompt, temperature=temperature, max_tokens=500 ) answer = extract_answer(response) answers.append(answer) # Majority voting answer_counts = Counter(answers) final_answer = answer_counts.most_common(1)[0][0] return final_answer, answer_counts
defextract_answer(response): """Extract answer from response""" # Simple implementation: find content after "Answer:" if"Answer:"in response: return response.split("Answer:")[-1].strip() # Or find the last number import re numbers = re.findall(r'\d+', response) return numbers[-1] if numbers else response
Mathematical
Expression of Self-Consistency
For problem, generatereasoning paths, each corresponding
to answer.
The final answer is selected through majority voting:whereis the indicator
function.
classSelfConsistency: def__init__(self, model, k=5, temperature=0.7): self.model = model self.k = k self.temperature = temperature defsolve(self, question, cot_prompt_template): """Solve problem using Self-Consistency""" prompt = cot_prompt_template.format(question=question) answers = [] reasoning_paths = [] for i inrange(self.k): response = self.model.generate( prompt, temperature=self.temperature, max_tokens=500 ) answer = self._extract_answer(response) answers.append(answer) reasoning_paths.append(response) # Count answer distribution answer_counts = Counter(answers) final_answer = answer_counts.most_common(1)[0][0] confidence = answer_counts[final_answer] / self.k return { "answer": final_answer, "confidence": confidence, "answer_distribution": dict(answer_counts), "reasoning_paths": reasoning_paths } def_extract_answer(self, response): """Extract answer (needs customization for specific tasks)""" # Example: extract last number import re numbers = re.findall(r'\d+', response) return numbers[-1] if numbers else response.split()[-1]
# Usage example sc = SelfConsistency(model, k=5) result = sc.solve( "Xiao Ming has 15 apples, gave 3 to Xiao Hong and 5 to Xiao Hua. How many are left?", cot_prompt_template ) print(f"Answer: {result['answer']}") print(f"Confidence: {result['confidence']:.2%}")
Advantages of
Self-Consistency
Improved Accuracy: Reduces errors through majority
voting
Robustness: Insensitive to single sampling
errors
Confidence Estimation: Answer distribution provides
confidence information
ReAct: Combining Reasoning
and Acting
ReAct (Reasoning + Acting) is a method that combines reasoning and
action, particularly suitable for tasks requiring tool usage.
ReAct Framework
The core idea of ReAct is: models can call external tools
during reasoning, guiding next-step reasoning through tool
observations.
Basic Loop:
Thought: Analyze current situation, decide next
action
Action: Call tool or execute operation
Observation: Get action result
Repeat until final answer is obtained
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
react_prompt = """ You can use the following tools: - search(query): Search for information - calculator(expression): Calculate mathematical expressions - get_weather(city): Get weather information Please answer in the following format: Thought: [Your thought process] Action: [tool_name(parameters)] Observation: [Tool return result] ... (repeat thought-action-observation loop) Thought: [Final thought] Answer: [Final answer] Question: {question} """
classReActAgent: def__init__(self, model, tools): self.model = model self.tools = tools # Tool dictionary defsolve(self, question): """Solve problem using ReAct method""" prompt = self._build_initial_prompt(question) max_iterations = 10 for i inrange(max_iterations): # Generate thought response = self.model.generate(prompt, max_tokens=200) # Parse response thought, action = self._parse_response(response) if action isNone: # No action, might be final answer answer = self._extract_answer(response) return answer # Execute action observation = self._execute_action(action) # Update prompt prompt += f"\nThought: {thought}\nAction: {action}\nObservation: {observation}\n" return"Reached maximum iterations" def_build_initial_prompt(self, question): """Build initial prompt""" tool_descriptions = "\n".join([ f"- {name}: {desc}" for name, desc in self.tools.items() ]) returnf""" You can use the following tools: {tool_descriptions} Please answer in the following format: Thought: [Your thought process] Action: [tool_name(parameters)] Observation: [Tool return result] ... (repeat thought-action-observation loop) Thought: [Final thought] Answer: [Final answer] Question: {question} """ def_parse_response(self, response): """Parse response, extract thought and action""" import re thought_match = re.search(r'Thought: (.*?)(?=Action: |Answer: |$)', response, re.DOTALL) action_match = re.search(r'Action: (\w+)\((.*?)\)', response) thought = thought_match.group(1).strip() if thought_match else"" action = None if action_match: tool_name = action_match.group(1) tool_args = action_match.group(2).strip() action = (tool_name, tool_args) return thought, action def_execute_action(self, action): """Execute action""" tool_name, tool_args = action if tool_name notin self.tools: returnf"Error: Tool {tool_name} does not exist" tool_func = self.tools[tool_name] try: result = tool_func(tool_args) returnstr(result) except Exception as e: returnf"Error: {str(e)}" def_extract_answer(self, response): """Extract final answer""" import re answer_match = re.search(r'Answer: (.*?)$', response, re.DOTALL) return answer_match.group(1).strip() if answer_match else response
# Tool definitions defsearch_tool(query): """Simulate search tool""" # In actual implementation, would call real search API returnf"Search results: Information about '{query}'..."
defcalculator_tool(expression): """Calculator tool""" try: result = eval(expression) return result except: return"Calculation error"
defbuild_advanced_prompt(question, examples, use_cot=True, use_role=True): """Build advanced prompt, combining multiple techniques""" prompt_parts = [] # Role assignment if use_role: prompt_parts.append("You are a professional problem-solving expert.") # Task description prompt_parts.append("Please solve the following problem:") # Few-shot examples if examples: prompt_parts.append("Examples:") for ex in examples: prompt_parts.append(f"Problem: {ex['question']}") if use_cot: prompt_parts.append(f"Reasoning: {ex['reasoning']}") prompt_parts.append(f"Answer: {ex['answer']}") # CoT requirement if use_cot: prompt_parts.append("\nPlease show your reasoning process, then provide the answer.") # Current problem prompt_parts.append(f"\nProblem: {question}") return"\n".join(prompt_parts)
classSentimentAnalyzer: def__init__(self, model): self.model = model self.prompt_template = """ You are a professional sentiment analysis expert. Task: Analyze text sentiment Classification criteria: - Positive: Expresses positive emotions, satisfaction, praise, etc. - Negative: Expresses negative emotions, dissatisfaction, criticism, etc. - Neutral: No clear emotional tendency Examples: Text 1: This movie is really great, with outstanding acting and a tight plot. Sentiment: positive Reason: Uses positive words like "great" and "outstanding" Text 2: The product quality is too poor and not worth the price. Sentiment: negative Reason: Uses negative words like "too poor" and "not worth" Text 3: It will rain tomorrow. Sentiment: neutral Reason: Just states a fact, no emotional color Please analyze the following text: Text: {text} Output format: Sentiment: [positive/negative/neutral] Confidence: [Value between 0-1] Reason: [Brief explanation] """ defanalyze(self, text): """Analyze text sentiment""" prompt = self.prompt_template.format(text=text) response = self.model.generate(prompt) return self._parse_response(response) def_parse_response(self, response): """Parse response""" import re sentiment_match = re.search(r'Sentiment: (\w+)', response) confidence_match = re.search(r'Confidence: ([\d.]+)', response) reason_match = re.search(r'Reason: (.*?)(?=\n|$)', response, re.DOTALL) return { 'sentiment': sentiment_match.group(1) if sentiment_match elseNone, 'confidence': float(confidence_match.group(1)) if confidence_match elseNone, 'reason': reason_match.group(1).strip() if reason_match elseNone }
classCodeGenerator: def__init__(self, model): self.model = model self.prompt_template = """ You are an experienced Python programmer, skilled in writing clear, efficient, and maintainable code. Task: Generate Python code based on requirements Requirements: 1. Code must be directly runnable 2. Include necessary comments 3. Follow PEP 8 code standards 4. Handle edge cases Example: Requirement: Implement a function to calculate the sum of all even numbers in a list Code: ```python def sum_even_numbers(numbers): \"\"\" Calculate the sum of all even numbers in a list Args: numbers: List of numbers Returns: Sum of even numbers \"\"\" return sum(num for num in numbers if num % 2 == 0)
Please generate code for the following requirement: Requirement:
{requirement}
```python class QASystem: def __init__(self, model): self.model = model self.knowledge_base = {} # Knowledge base def add_knowledge(self, doc_id, content): """Add knowledge""" self.knowledge_base[doc_id] = content def answer(self, question, doc_ids=None): """Answer question""" if doc_ids is None: doc_ids = list(self.knowledge_base.keys()) # Retrieve relevant documents relevant_docs = self._retrieve_docs(question, doc_ids) # Build prompt prompt = self._build_qa_prompt(question, relevant_docs) # Generate answer response = self.model.generate(prompt) return self._extract_answer(response) def _retrieve_docs(self, question, doc_ids, top_k=3): """Retrieve relevant documents (simplified implementation)""" # In actual implementation, could use vector retrieval return [self.knowledge_base[did] for did in doc_ids[:top_k]] def _build_qa_prompt(self, question, docs): """Build QA prompt""" doc_text = "\n\n".join([ f"Document {i+1}: {doc}" for i, doc in enumerate(docs) ]) return f""" Answer questions based on the following documents.
Documents: {doc_text}
Question: {question}
Requirements: 1. Answers must be based on document content 2. If no relevant information is found in the documents, answer "No relevant information found in the documents" 3. Cite specific content from the documents to support your answer 4. If there are conflicts between documents, please explain
Answer: """ def _extract_answer(self, response): """Extract answer""" if "Answer:" in response: return response.split("Answer:")[-1].strip() return response.strip()
❓ Q&A: Common
Questions About Prompt Engineering
Q1: Is longer prompt always better?
Not necessarily. Prompts should contain all information needed to
complete the task, but excessive length may: - Increase computational
cost - Distract model attention - Exceed context window limits
Best practice: Start with a concise version, then gradually
add details if results are unsatisfactory.
Q2: How many examples are needed for few-shot
prompting?
Usually 2-5 examples work well. Too few may fail to learn patterns,
too many may: - Waste tokens - Increase confusion - Reduce
efficiency
Recommendation: Start with 2-3 examples, adjust based on
results.