🧠 Prompt Reasoning Patterns Playground (LAB-05)¶
Estimated time to read: 7 minutes
Welcome to the interactive playground for LAB-05: Prompt Reasoning Patterns.
This notebook allows you to interactively explore and run:
- PromptTemplate & ChatPromptTemplate: Safe formatting and static variable checking.
- Few-Shot In-Context Learning (ICL): Static and dynamic exemplar selection.
- Chain-of-Thought (CoT): Zero-shot trigger induction and answer extraction.
- Self-Consistency with Majority Voting: Stochastic sampling and Shannon Entropy metrics.
- ReAct Autonomous Agent: Execution loop with registered custom tools.
0. Environment Setup¶
If you are running in Google Colab, this cell will automatically clone the repository and configure dependencies.
In [1]:
Copied!
import os
import sys
import sys
from pathlib import Path
try:
import google.colab
IN_COLAB = True
except ImportError:
IN_COLAB = False
if IN_COLAB:
print("🤖 Running in Google Colab. Setting up environment...")
!pip install -q numpy scikit-learn matplotlib loguru
# Clone repository to access custom local source modules
if not os.path.exists("production-ai-systems"):
!git clone https://github.com/RogerioLS/production-ai-systems.git
sys.path.append("production-ai-systems")
print("🎉 Colab environment successfully initialized!")
# Ensure project root is in the path when running locally
if not IN_COLAB:
# Localiza dinamicamente a raiz do repositório procurando por 'pyproject.toml'
current_dir = Path.cwd()
root_dir = current_dir
for parent in [current_dir] + list(current_dir.parents):
if (parent / "pyproject.toml").exists() or (parent / "projects").exists():
root_dir = parent
break
if str(root_dir) not in sys.path:
sys.path.insert(0, str(root_dir))
print(f"📁 Project root added to sys.path: {root_dir}")
import os
import sys
import sys
from pathlib import Path
try:
import google.colab
IN_COLAB = True
except ImportError:
IN_COLAB = False
if IN_COLAB:
print("🤖 Running in Google Colab. Setting up environment...")
!pip install -q numpy scikit-learn matplotlib loguru
# Clone repository to access custom local source modules
if not os.path.exists("production-ai-systems"):
!git clone https://github.com/RogerioLS/production-ai-systems.git
sys.path.append("production-ai-systems")
print("🎉 Colab environment successfully initialized!")
# Ensure project root is in the path when running locally
if not IN_COLAB:
# Localiza dinamicamente a raiz do repositório procurando por 'pyproject.toml'
current_dir = Path.cwd()
root_dir = current_dir
for parent in [current_dir] + list(current_dir.parents):
if (parent / "pyproject.toml").exists() or (parent / "projects").exists():
root_dir = parent
break
if str(root_dir) not in sys.path:
sys.path.insert(0, str(root_dir))
print(f"📁 Project root added to sys.path: {root_dir}")
📁 Project root added to sys.path: /home/runner/work/production-ai-systems/production-ai-systems
1. Safe Prompt Templating¶
Verify that required variables cannot be omitted, preventing production leakage.
In [2]:
Copied!
from projects.b_prompt_engineering.src.lab_05_reasoning.templates import PromptTemplate, ChatPromptTemplate
from projects.b_prompt_engineering.src.lab_05_reasoning.types import PromptRole
template = PromptTemplate(
"Analyze stock {ticker} for fiscal year {year}. Focus on {metric}.",
role=PromptRole.USER
)
print("Required variables:", template.variables)
formatted = template.format(ticker="PETR4", year="2024", metric="EBITDA Margin")
print("\nFormatted Prompt:")
print(formatted)
from projects.b_prompt_engineering.src.lab_05_reasoning.templates import PromptTemplate, ChatPromptTemplate
from projects.b_prompt_engineering.src.lab_05_reasoning.types import PromptRole
template = PromptTemplate(
"Analyze stock {ticker} for fiscal year {year}. Focus on {metric}.",
role=PromptRole.USER
)
print("Required variables:", template.variables)
formatted = template.format(ticker="PETR4", year="2024", metric="EBITDA Margin")
print("\nFormatted Prompt:")
print(formatted)
2026-09-30 21:12:19.680 | DEBUG | projects.b_prompt_engineering.src.lab_05_reasoning.templates:__init__:25 - Initialized PromptTemplate (Role: user) with variables: ['metric', 'ticker', 'year']
Required variables: {'metric', 'year', 'ticker'}
Formatted Prompt:
Analyze stock PETR4 for fiscal year 2024. Focus on EBITDA Margin.
2. Few-Shot In-Context Learning (Dynamic Selector)¶
Demonstrating dynamic selection of exemplars based on query domain.
In [3]:
Copied!
from projects.b_prompt_engineering.src.lab_05_reasoning.few_shot import FewShotPromptEngine
from projects.b_prompt_engineering.src.lab_05_reasoning.types import Exemplar
engine = FewShotPromptEngine()
engine.register_exemplar(Exemplar(
input_text="What is the P/E ratio if Price=100 and EPS=10?",
output_text="10.0",
reasoning="P/E = Price / EPS = 100 / 10 = 10.0",
metadata={"domain": "finance"}
))
engine.register_exemplar(Exemplar(
input_text="Classify sentiment: 'The quarterly revenue exceeded all guidance.'",
output_text="Positive",
reasoning="Words like 'exceeded all guidance' express strong positive performance.",
metadata={"domain": "nlp"}
))
# Dynamic selector based on keyword
def domain_selector(query, pool, k):
domain = "finance" if any(w in query.lower() for w in ["ratio", "eps", "price", "ebitda"]) else "nlp"
return [ex for ex in pool if ex.metadata.get("domain") == domain][:k]
prompt = engine.build_prompt("Calculate P/E with Price=50 and EPS=5.", selector=domain_selector)
print(prompt)
from projects.b_prompt_engineering.src.lab_05_reasoning.few_shot import FewShotPromptEngine
from projects.b_prompt_engineering.src.lab_05_reasoning.types import Exemplar
engine = FewShotPromptEngine()
engine.register_exemplar(Exemplar(
input_text="What is the P/E ratio if Price=100 and EPS=10?",
output_text="10.0",
reasoning="P/E = Price / EPS = 100 / 10 = 10.0",
metadata={"domain": "finance"}
))
engine.register_exemplar(Exemplar(
input_text="Classify sentiment: 'The quarterly revenue exceeded all guidance.'",
output_text="Positive",
reasoning="Words like 'exceeded all guidance' express strong positive performance.",
metadata={"domain": "nlp"}
))
# Dynamic selector based on keyword
def domain_selector(query, pool, k):
domain = "finance" if any(w in query.lower() for w in ["ratio", "eps", "price", "ebitda"]) else "nlp"
return [ex for ex in pool if ex.metadata.get("domain") == domain][:k]
prompt = engine.build_prompt("Calculate P/E with Price=50 and EPS=5.", selector=domain_selector)
print(prompt)
2026-09-30 21:12:19.688 | DEBUG | projects.b_prompt_engineering.src.lab_05_reasoning.few_shot:build_prompt:92 - Constructed few-shot prompt with 1 exemplars.
Here are a few examples to follow: Input: What is the P/E ratio if Price=100 and EPS=10? Reasoning: P/E = Price / EPS = 100 / 10 = 10.0 Output: 10.0 Now solve the following problem: Input: Calculate P/E with Price=50 and EPS=5. Output:
3. Self-Consistency: Majority Voting & Shannon Entropy¶
Simulating stochastic reasoning paths and evaluating consensus confidence vs. information entropy.
In [4]:
Copied!
from projects.b_prompt_engineering.src.lab_05_reasoning.chain_of_thought import SelfConsistencyEngine
sc = SelfConsistencyEngine()
# Scenario A: Unanimous agreement (zero entropy)
samples_a = ["$42M", "$42M", "$42M", "$42M", "$42M"]
res_a = sc.evaluate_consensus(samples_a)
print(f"Scenario A -> Winner: {res_a.winning_answer} | Confidence: {res_a.confidence_score*100}% | Entropy: {res_a.shannon_entropy}")
# Scenario B: High uncertainty (divergent paths)
samples_b = ["$42M", "$45M", "$40M", "$42M", "$50M"]
res_b = sc.evaluate_consensus(samples_b)
print(f"Scenario B -> Winner: {res_b.winning_answer} | Confidence: {res_b.confidence_score*100}% | Entropy: {res_b.shannon_entropy}")
from projects.b_prompt_engineering.src.lab_05_reasoning.chain_of_thought import SelfConsistencyEngine
sc = SelfConsistencyEngine()
# Scenario A: Unanimous agreement (zero entropy)
samples_a = ["$42M", "$42M", "$42M", "$42M", "$42M"]
res_a = sc.evaluate_consensus(samples_a)
print(f"Scenario A -> Winner: {res_a.winning_answer} | Confidence: {res_a.confidence_score*100}% | Entropy: {res_a.shannon_entropy}")
# Scenario B: High uncertainty (divergent paths)
samples_b = ["$42M", "$45M", "$40M", "$42M", "$50M"]
res_b = sc.evaluate_consensus(samples_b)
print(f"Scenario B -> Winner: {res_b.winning_answer} | Confidence: {res_b.confidence_score*100}% | Entropy: {res_b.shannon_entropy}")
2026-09-30 21:12:19.694 | INFO | projects.b_prompt_engineering.src.lab_05_reasoning.chain_of_thought:evaluate_consensus:98 - Consensus evaluated: Winner='$42m' (Confidence: 100.0%, Samples: 5, Entropy: 0.0000)
2026-09-30 21:12:19.695 | INFO | projects.b_prompt_engineering.src.lab_05_reasoning.chain_of_thought:evaluate_consensus:98 - Consensus evaluated: Winner='$42m' (Confidence: 40.0%, Samples: 5, Entropy: 1.9219)
Scenario A -> Winner: $42m | Confidence: 100.0% | Entropy: 0.0 Scenario B -> Winner: $42m | Confidence: 40.0% | Entropy: 1.9219
4. Autonomous ReAct Agent Loop¶
Testing an autonomous reasoning cycle with tool execution.
In [5]:
Copied!
from projects.b_prompt_engineering.src.lab_05_reasoning.react import ReActEngine
agent = ReActEngine(max_iterations=5)
# Register financial lookup tool
def financial_database(ticker: str):
db = {"VALE3": "R$ 280 Billion Market Cap", "ITUB4": "R$ 310 Billion Market Cap"}
return db.get(ticker.upper(), "Ticker not found")
agent.register_tool(
name="financial_database",
description="Returns market cap given a Brazilian stock ticker (e.g. VALE3, ITUB4)",
handler=financial_database
)
# Mock LLM that reasons and calls the tool
def mock_llm_step(trajectory: str):
if "Observation: R$ 280 Billion Market Cap" in trajectory:
return "Thought: I have retrieved the market cap.\nFinal Answer: The market cap of VALE3 is R$ 280 Billion."
return "Thought: I need to query the database for VALE3.\nAction: financial_database\nAction Input: {\"ticker\": \"VALE3\"}\n"
result = agent.run("What is the market cap of VALE3?", llm_responder=mock_llm_step)
print(f"Success: {result.success}")
print(f"Total Steps: {result.total_steps}")
print(f"Final Answer: {result.final_answer}")
for step in result.steps:
print(f" Step {step.step_number}: Tool={step.action_tool} -> Obs={step.observation}")
from projects.b_prompt_engineering.src.lab_05_reasoning.react import ReActEngine
agent = ReActEngine(max_iterations=5)
# Register financial lookup tool
def financial_database(ticker: str):
db = {"VALE3": "R$ 280 Billion Market Cap", "ITUB4": "R$ 310 Billion Market Cap"}
return db.get(ticker.upper(), "Ticker not found")
agent.register_tool(
name="financial_database",
description="Returns market cap given a Brazilian stock ticker (e.g. VALE3, ITUB4)",
handler=financial_database
)
# Mock LLM that reasons and calls the tool
def mock_llm_step(trajectory: str):
if "Observation: R$ 280 Billion Market Cap" in trajectory:
return "Thought: I have retrieved the market cap.\nFinal Answer: The market cap of VALE3 is R$ 280 Billion."
return "Thought: I need to query the database for VALE3.\nAction: financial_database\nAction Input: {\"ticker\": \"VALE3\"}\n"
result = agent.run("What is the market cap of VALE3?", llm_responder=mock_llm_step)
print(f"Success: {result.success}")
print(f"Total Steps: {result.total_steps}")
print(f"Final Answer: {result.final_answer}")
for step in result.steps:
print(f" Step {step.step_number}: Tool={step.action_tool} -> Obs={step.observation}")
2026-09-30 21:12:19.702 | DEBUG | projects.b_prompt_engineering.src.lab_05_reasoning.react:register_tool:53 - Registered tool: 'financial_database' (Returns market cap given a Brazilian stock ticker (e.g. VALE3, ITUB4))
2026-09-30 21:12:19.702 | DEBUG | projects.b_prompt_engineering.src.lab_05_reasoning.react:run:141 - ReAct Step 1/5
2026-09-30 21:12:19.704 | INFO | projects.b_prompt_engineering.src.lab_05_reasoning.react:execute_tool:88 - ReAct invoking tool 'financial_database' with args: {'ticker': 'VALE3'}
2026-09-30 21:12:19.704 | DEBUG | projects.b_prompt_engineering.src.lab_05_reasoning.react:run:141 - ReAct Step 2/5
Success: True Total Steps: 2 Final Answer: The market cap of VALE3 is R$ 280 Billion. Step 1: Tool=financial_database -> Obs=R$ 280 Billion Market Cap Step 2: Tool=None -> Obs=None