Use a built-in check
This guide puts one of Kindgi's built-in checks on an agent, instead of a check you write, and lists the settings each one reads.
Kindgi has seven built-in checks for common rules: words an answer must or mustn't contain, a pattern it must match, citations, and which tools a turn may call, how many and in what order. A guardrail can name one instead of shipping a check you write yourself.
Before you start
Section titled “Before you start”- A TypeScript pack, with Kindgi 0.1's SDK, on a runtime such as
kindgi dev. A Python, Java or Scala pack can't name a built-in. - An agent to put the guardrail on.
Name a built-in
Section titled “Name a built-in”A built-in check needs no code of yours. The guardrail names the built-in as
its check, gives its config, and ships no check implementation. Ask your
coding agent: "I want a guardrail, with a built-in check, that stops an
answer promising a guarantee." Kindgi's skills in your pack tell it how
(How it knows Kindgi). For reference, the
guardrail looks like this:
export default { id: 'my-pack.no-guarantees', name: 'Never promise a guarantee', kind: 'zero-llm', check: 'forbidden-substring', config: { patterns: ['guaranteed', 'we promise'] }, action: { 'on-violation': 'halt' }, severity: 'error',};Put it on an agent by its id, as with any guardrail, as
Put it on an agent shows. With
halt, an answer containing "guaranteed" stops the turn, as
A halted turn describes. The failure
gives the check's reason. For a must-cite guardrail on an answer without a
citation:
Error [guardrail-violation]: Turn blocked by guardrail 'acme.cite-or-halt': expected >= 1 citations, found 0A Python, Java or Scala pack can't name a built-in: a guardrail there is
always defined with its own check. Python's @guardrail decorates a check
function. Write the rule as your own check, and use
The built-in checks for what each built-in checks.
The built-in checks
Section titled “The built-in checks”A tool list holds tool ids, as <pack>.<tool>. A setting in bold is
required.
| Check | Fails when | config |
|---|---|---|
must-cite |
the answer is empty, or has fewer than minCitations matches of sourcePattern |
minCitations: a whole number, 1 or more (1 by default); sourcePattern: a regular expression (by default, citations in square brackets, such as [ord_1003]) |
never-call-tool |
the turn called any tool in tools |
tools: a list of one or more tool ids |
max-tool-calls |
the turn made more than max tool calls |
max: a whole number, 0 or more (10 by default) |
output-matches |
the answer doesn't match pattern, or, with negate: true, it does |
pattern: a regular expression; flags: regular-expression flags (d, g, i, m, s, u, v, y), such as "i"; negate: true or false |
tool-order |
the tools in sequence weren't called in that order (other calls may come between) |
sequence: a list of one or more tool ids |
required-substring |
the answer is empty, or lacks any of patterns |
patterns: a list of one or more plain-text strings; caseSensitive (false by default) |
forbidden-substring |
the answer contains any of patterns |
patterns: a list of one or more plain-text strings; caseSensitive (false by default) |
A config the check doesn't take is refused: a required setting left out, a
setting of the wrong type, one the check doesn't know, or a regular expression
that doesn't compile, or is longer than 8,192 characters with its flags.
Registering such a guardrail answers 422 guardrail-config-invalid, with each
problem in details.issues. Deploying a pack with one fails with
deployment-validation-failed. If one
reaches a turn anyway, its check can't run, so with halt the turn stops, as
When the check can't run
describes.
Your own check under a built-in's name
Section titled “Your own check under a built-in's name”The built-in ids are reserved. A pack that ships its own check under one, such
as a defineCheck({ id: 'must-cite', … }), is refused when you build it, with
reserved-check-id, or DefinitionError in Python. Give your check a name of
its own, such as my-pack.checks.must-cite. Or, to use the built-in, name it
and drop your implementation.
A current CLI marks a guardrail that only names a built-in. A pack built with an older CLI may lack that mark. A guardrail that names a built-in, comes with its pack's code, and lacks the mark gets one warning in the runtime's log each time the runtime loads the guardrail. The built-in runs either way. If the guardrail only names the built-in, rebuild the pack with a current CLI and the warning goes. If its module is your own check, give that check a name of its own: the built-in has been running in its place.