Rulesets#
Overview#
A Ruleset can be used to define Ruleset s for Structures and add_tasks(*tasks) . Gen AI Builder places Rules into the LLM’s system prompt for strong control over the output.
Types of Rules#
Rule#
Ruleset s shape the LLM’s behavior by defining specific guidelines or instructions for how it should interpret and respond to inputs. Rules can be used to modify language style, tone, or even behavior based on what you define.
Tip
Avoid writing large amounts of text in a single Rule. Breaking down your Rules generally helps the LLM follow them more effectively. Additionally, it makes it easier to evaluate the Rule's effectiveness using tools like the Eval Engine . If you have an existing system prompt, consider overriding the default system prompt instead.
from griptape.rules import Rule, Ruleset
from griptape.structures import Agent
pipeline = Agent(
rulesets=[
Ruleset(
name="Personality",
rules=[Rule("Talk like a pirate.")],
),
]
)
pipeline.run("Hi there! How are you?")
Json Schema#
Tip
Structured Output provides a more robust solution for having the LLM generate structured output.
JsonSchemaRule s defines a structured format for the LLM’s output by providing a JSON schema. This is particularly useful when you need the LLM to return well-formed data, such as JSON objects, with specific fields and data types.
import json
import schema
from griptape.rules.json_schema_rule import JsonSchemaRule
from griptape.structures import Agent
agent = Agent(
rules=[
JsonSchemaRule(
schema.Schema({"answer": str, "relevant_emojis": schema.Schema(["str"])}).json_schema("Output Format")
)
]
)
output = agent.run("What is the sentiment of this message?: I am so happy!").output
print(json.dumps(json.loads(output.value), indent=2))
Although Gen AI Builder leverages the schema library, you’re free to
use any JSON schema generation library to define your schema!
For example, using pydantic :
from __future__ import annotations
import pydantic
from griptape.rules.json_schema_rule import JsonSchemaRule
from griptape.structures import Agent
class SentimentModel(pydantic.BaseModel):
answer: str
relevant_emojis: list[str]
agent = Agent(rules=[JsonSchemaRule(SentimentModel.model_json_schema())])
output = agent.run("What is the sentiment of this message?: I am so happy!").output
sentiment_analysis = SentimentModel.model_validate_json(output.value)
# Autocomplete via dot notation 🤩
print(sentiment_analysis.answer)
print(sentiment_analysis.relevant_emojis)
Structure#
Rulesets#
You can define a Ruleset at the Structure level if you need to have certain behaviors across all Tasks.
from griptape.rules import Rule, Ruleset
from griptape.structures import Pipeline
from griptape.tasks import PromptTask
pipeline = Pipeline(
rulesets=[
Ruleset(
name="Employment",
rules=[
Rule("Behave like a polite customer support agent"),
Rule("Act like you work for company SkaterWorld, Inc."),
Rule("Discuss only topics related to skateboarding"),
Rule("Limit your response to fewer than 5 sentences."),
],
),
Ruleset(
name="Background",
rules=[
Rule("Your name is Todd"),
],
),
]
)
pipeline.add_tasks(
PromptTask(input="Respond to this users question: {{ args[0] }}"),
PromptTask(input="Extract keywords from this response: {{ parent_output }}"),
)
pipeline.run("How do I do a kickflip?")
Rules#
You can pass Ruleset directly to the Structure to have a Ruleset created for you.
from griptape.rules import Rule
from griptape.structures import Pipeline
from griptape.tasks import PromptTask
pipeline = Pipeline(
rules=[
Rule("Respond only using emojis"),
],
)
pipeline.add_tasks(
PromptTask("Respond to this question from the user: {{ args[0] }}"),
PromptTask("How would you rate your response (1-5)? 1 being bad, 5 being good. Response: {{parent_output}}"),
)
pipeline.run("How do I bake a cake?")
Task#
Rulesets#
You can define a Ruleset at the Task level if you need to have different behaviors per Task.
from griptape.rules import Rule, Ruleset
from griptape.structures import Pipeline
from griptape.tasks import PromptTask
pipeline = Pipeline()
pipeline.add_tasks(
PromptTask(
input="Respond to the following prompt: {{ args[0] }}",
rulesets=[
Ruleset(
name="Emojis",
rules=[
Rule("Respond using uppercase characters only."),
],
)
],
),
PromptTask(
input="Determine the sentiment of the following text: {{ parent_output }}",
rulesets=[
Ruleset(
name="Diacritic",
rules=[
Rule("Respond using diacritic characters only."),
],
)
],
),
)
pipeline.run("I love skateboarding!")
Rules#
You can pass Ruleset directly to the Task to have a Ruleset created for you.
from griptape.rules import Rule
from griptape.structures import Pipeline
from griptape.tasks import PromptTask
pipeline = Pipeline()
pipeline.add_tasks(
PromptTask(
rules=[
Rule("Write your answer in json with a single key emoji_response"),
Rule("Respond only using emojis"),
],
),
)
pipeline.run("How are you?")
Overriding System Prompts#
While Rulesets are the preferred way to steer LLM output, sometimes you may want to fully override the system prompt.
from textwrap import dedent
from griptape.rules import Rule
from griptape.structures import Pipeline
from griptape.tasks.prompt_task import PromptTask
pipeline = Pipeline(
tasks=[
PromptTask(
rules=[Rule("Your favorite color is blue")], # Will be ignored!
generate_system_template=lambda _: dedent("""
Employment:
- Behave like a polite customer support agent
- Act like you work for company SkaterWorld, Inc.
- Discuss only topics related to skateboarding
- Limit your response to fewer than 5 sentences.
Background:
- Your name is Todd
"""),
)
]
)
pipeline.run("What is your name and favorite color?")
Note that when overriding the system prompt, it is your responsibility to integrate anything that goes in by default . You can achieve this by appending the default system prompt to your custom prompt like so:
from textwrap import dedent
from griptape.rules import Rule
from griptape.structures import Pipeline
from griptape.tasks.prompt_task import PromptTask
pipeline = Pipeline(
tasks=[
PromptTask(
rules=[Rule("Your favorite color is blue")],
generate_system_template=lambda task: dedent(
"""
Employment:
- Behave like a polite customer support agent
- Act like you work for company SkaterWorld, Inc.
- Discuss only topics related to skateboarding
- Limit your response to fewer than 5 sentences.
Background:
- Your name is Todd
"""
+ task.default_generate_system_template(task)
),
)
]
)
pipeline.run("What is your name and favorite color?")