How to Use @zero_shot and @few_shot Decorators in SymbolicAI: A Complete Guide
The @zero_shot and @few_shot decorators in SymbolicAI transform regular Python functions into neuro-symbolic engine calls, automatically routing prompts and examples to configured LLM backends like OpenAI, Anthropic, or Gemini.
SymbolicAI is a neuro-symbolic framework that bridges classical programming with large language models (LLMs). The @zero_shot and @few_shot decorators are core abstractions that eliminate boilerplate when integrating LLM capabilities into Python applications. They wrap standard methods, package arguments into structured payloads, and delegate execution to the configured neuro-symbolic engine.
What Are @zero_shot and @few_shot Decorators?
@zero_shot and @few_shot are general-purpose decorators defined in symai/core.py that convert static Python methods into dynamic LLM queries.
- Zero-shot inference sends only a prompt to the model without demonstration examples. The
@zero_shotdecorator is implemented as a thin wrapper that invokes@few_shotwith an emptyexampleslist. - Few-shot inference includes a list of example prompts that demonstrate the desired input-output pattern, improving reliability for complex or structured tasks.
Both decorators handle argument serialization, engine selection, constraint validation, and result post-processing automatically.
Architecture Overview
When a decorated method is invoked, the following pipeline executes:
- Argument Packaging: The runtime positional and keyword arguments are captured into an
Argumentobject along with static decorator metadata (prompt, examples, constraints). - Engine Routing: The payload is forwarded to
EngineRepository.queryinsymai/functional.py, which routes to the configured"neurosymbolic"engine (e.g., OpenAI GPT-4, Anthropic Claude). - Pre-processing: Input data passes through optional pre-processors (e.g., tokenization, formatting) before reaching the LLM.
- Constraint Validation: If the engine returns a result, optional constraint functions validate the output. If validation fails, the system can retry or return a default value.
- Post-processing: The output flows through post-processors (e.g.,
StripPostProcessorto clean whitespace) before being returned to the caller.
How the Decorators Work Under the Hood
The implementation resides primarily in symai/core.py.
Decorator Definition and Wrapping
The few_shot function (lines 33-70) returns a decorator that wraps the target method:
# Conceptual flow from symai/core.py:33-70
def few_shot(*decorator_args, **decorator_kwargs):
def decorator(func):
def wrapper(*signature_args, **signature_kwargs):
# Build Argument object from runtime + static metadata
argument = Argument(
args=signature_args,
kwargs=signature_kwargs,
prompt=decorator_kwargs.get('prompt'),
examples=decorator_kwargs.get('examples', []),
# ... constraints, processors, etc.
)
# Delegate to engine repository
return EngineRepository.query(
'neurosymbolic',
argument,
# ... additional parameters
)
return wrapper
return decorator
Zero-Shot Shortcut
The zero_shot decorator (lines 73-94) is implemented as a convenience wrapper that calls few_shot with examples=[]:
# From symai/core.py:73-94
def zero_shot(*args, **kwargs):
# Force examples to empty list for zero-shot behavior
kwargs['examples'] = []
return few_shot(*args, **kwargs)
Engine Repository and Processing
The EngineRepository singleton in symai/functional.py manages backend instances. When query is invoked, it:
- Selects the engine instance registered under the
"neurosymbolic"key. - Passes the
Argumentobject through the processing pipeline defined bysymai/pre_processors.pyandsymai/post_processors.py. - Applies constraints defined in the decorator (e.g.,
constraints=[is_nonempty]) to validate outputs. - Returns the final value, or the
defaultparameter if validation fails or the engine returnsNone.
Practical Code Examples
Basic Zero-Shot Translation
Use @zero_shot for simple tasks that require only a prompt and input text:
from symai import zero_shot
@zero_shot(prompt="Translate the following English text to French:\n")
def translate_to_french(text: str) -> str:
...
result = translate_to_french("Hello, world!")
print(result) # → « Bonjour, le monde ! »
The decorator automatically injects the prompt prefix, sends the concatenated string to the configured LLM, and returns the generated translation.
Few-Shot Summarization with Examples
Use @few_shot when you need to demonstrate the desired output format to improve reliability:
from symai import few_shot, prompts as prm
example_prompt = prm.Prompt(
"""
Input: The quick brown fox jumps over the lazy dog.
Summary: A fox jumps over a dog.
Input: Climate change leads to rising sea levels.
Summary: Climate change raises sea levels.
""".strip()
)
@few_shot(
prompt="Summarise the following text in one sentence:\n",
examples=example_prompt,
limit=1,
)
def summarise(text: str) -> str:
...
print(summarise("Artificial intelligence enables new ways of solving problems."))
# → "AI enables novel problem‑solving approaches."
The examples parameter accepts a Prompt object containing demonstration pairs that prime the LLM for the specific summarization style.
Adding Constraints and Post-Processors
Enhance reliability by validating outputs and cleaning formatting:
from symai import few_shot, post_processors as post
def is_nonempty(s: str) -> bool:
return bool(s.strip())
@few_shot(
prompt="Give a short, one‑word answer to the yes/no question: Is the sky blue?\n",
post_processors=[post.StripPostProcessor()],
constraints=[is_nonempty],
default="unknown",
)
def answer_yes_no(question: str) -> str:
...
print(answer_yes_no("Is the sky blue?")) # → "yes"
Here, post_processors applies StripPostProcessor() to remove whitespace, while constraints ensures non-empty results. If the constraint fails, the function returns "unknown".
Key Implementation Files
| File | Role |
|---|---|
symai/core.py |
Defines few_shot and zero_shot decorators, Argument class, and metadata handling. |
symai/functional.py |
Implements EngineRepository singleton for engine registration and query routing. |
symai/symbol.py |
Provides the base Expression class that underpins decorated functions. |
symai/pre_processors.py |
Input transformation pipelines applied before LLM calls. |
symai/post_processors.py |
Output cleaning and formatting applied after LLM responses. |
symai/prompts.py |
Prompt class and utilities for constructing few-shot example sets. |
These files collectively implement the decorator-driven neuro-symbolic workflow that powers SymbolicAI's seamless LLM integration.
Summary
@zero_shotand@few_shotare decorators in SymbolicAI that convert Python methods into LLM-powered neuro-symbolic engine calls.@zero_shot(defined insymai/core.py:73-94) invokes the engine with a single prompt and no examples, while@few_shot(symai/core.py:33-70) supports demonstration examples via theexamplesparameter.- Both decorators package arguments into an
Argumentobject and route requests throughEngineRepository.queryinsymai/functional.pyto the configured"neurosymbolic"backend. - Advanced features include pre/post-processors for data transformation, constraints for output validation, and default values for fallback behavior when LLM calls fail.
Frequently Asked Questions
What is the difference between @zero_shot and @few_shot?
@zero_shot is designed for tasks that require only a prompt with no prior examples, making it ideal for simple transformations or queries. According to the source code in symai/core.py, it is implemented as a wrapper that calls @few_shot with an empty examples list. @few_shot, conversely, accepts a examples parameter (typically a Prompt object) that contains demonstration input-output pairs, which helps guide the LLM toward the desired response format for more complex or structured tasks.
How do I configure which LLM backend @zero_shot uses?
The decorators do not specify the backend directly; instead, they route queries through EngineRepository.query with the engine key "neurosymbolic". To configure the actual LLM (e.g., OpenAI GPT-4, Anthropic Claude, or Gemini), you must register the desired engine instance with EngineRepository in your application initialization, typically in symai/functional.py or via the framework's configuration API. The decorator will then automatically use whichever engine is registered under the "neurosymbolic" namespace.
Can I use @few_shot without examples?
Technically, yes, but it defeats the purpose of the decorator. If you pass an empty list or empty Prompt object to the examples parameter, @few_shot behaves identically to @zero_shot. However, the SymbolicAI source code provides @zero_shot specifically for this use case to make your intent explicit. For clarity and maintainability, use @zero_shot when you have no examples and @few_shot when you have demonstration data to provide.
What happens if the LLM returns an invalid response?
The decorators include a constraint and default value system to handle invalid or failed responses. You can pass a list of constraint functions (callables that return boolean) to the constraints parameter; if the LLM output fails validation, the decorator can retry or return the value specified in the default parameter. Additionally, post_processors (such as StripPostProcessor) clean the output before validation occurs. If all constraints fail and no default is provided, the system may return None or raise an exception depending on the engine configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →