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_shot decorator is implemented as a thin wrapper that invokes @few_shot with an empty examples list.
  • 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:

  1. Argument Packaging: The runtime positional and keyword arguments are captured into an Argument object along with static decorator metadata (prompt, examples, constraints).
  2. Engine Routing: The payload is forwarded to EngineRepository.query in symai/functional.py, which routes to the configured "neurosymbolic" engine (e.g., OpenAI GPT-4, Anthropic Claude).
  3. Pre-processing: Input data passes through optional pre-processors (e.g., tokenization, formatting) before reaching the LLM.
  4. 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.
  5. Post-processing: The output flows through post-processors (e.g., StripPostProcessor to 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:

  1. Selects the engine instance registered under the "neurosymbolic" key.
  2. Passes the Argument object through the processing pipeline defined by symai/pre_processors.py and symai/post_processors.py.
  3. Applies constraints defined in the decorator (e.g., constraints=[is_nonempty]) to validate outputs.
  4. Returns the final value, or the default parameter if validation fails or the engine returns None.

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_shot and @few_shot are decorators in SymbolicAI that convert Python methods into LLM-powered neuro-symbolic engine calls.
  • @zero_shot (defined in symai/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 the examples parameter.
  • Both decorators package arguments into an Argument object and route requests through EngineRepository.query in symai/functional.py to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →