Docs Frameworks

LlamaIndex Agents

New to KIFF? Start with the quickstart or connect an existing agent — this page is the framework-specific attach for that same journey. The model behind it: how the guard works.

Status: verified. The adapter ships in kiff-guard (kiff_guard.adapters.llama_index) and was source-verified against llama-index-core and passes the conformance suite.

Shape: middleware. LlamaIndex’s AgentWorkflow runs each tool in its call_tool step. The guard sits inside that step — you subclass AgentWorkflow as GuardedAgentWorkflow and the guard runs the tool via its continuation, the same middleware shape as Agno. See how the guard works for what that means.

Install

pip install "git+https://github.com/kiff/kiff-guard.git#subdirectory=packages/python/kiff-guard"
# plus LlamaIndex itself, the framework you're guarding:
pip install "kiff-guard[llama-index]"

Observe — audit with zero config

from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
from kiff_guard import Guard
from kiff_guard.adapters.llama_index import GuardedAgentWorkflow

guard = Guard(mode="observe")     # no client, no tenant needed

workflow = GuardedAgentWorkflow(
    agents=[FunctionAgent(tools=[refund_order], llm=OpenAI(model="gpt-4o-mini"))],
    guard=guard,
)

Run the workflow as usual, then read the trail:

for r in guard.receipts:
    print(r.state, r.tool, r.outcome)

Activate

Derive a starter domain from what you observed, review it, and activate it in the dashboard:

from kiff_guard import export_yaml
print(export_yaml("my-domain", guard.catalog))

Enforce — govern at runtime

Once you have a tenant and an active domain, point the guard at KIFF and switch to enforce. Nothing about the workflow wiring changes — only the guard:

from kiff_guard import Guard, HTTPClient, ToolMap
from kiff_guard.adapters.llama_index import GuardedAgentWorkflow

client = HTTPClient(
    api_key="kiff_live_...",                       # mint in the dashboard
    tool_map=ToolMap().bind(
        "refund_order", action="REFUND_ORDER",
        entity_type="Order", entity_arg="order_id"),
)
guard = Guard(client=client, tenant="<tenant>", agent="support", mode="enforce")

workflow = GuardedAgentWorkflow(
    agents=[FunctionAgent(tools=[refund_order], llm=OpenAI(model="gpt-4o-mini"))],
    guard=guard,
)

In enforce mode a withheld decision raises kiff_guard.Hold from inside the call_tool step; the tool body never runs and the exception propagates up through the workflow handler (the fail-safe path — an unknown outcome withholds rather than proceeds).

The seam (verified)

LlamaIndex’s AgentWorkflow exposes a call_tool workflow step that resolves and runs each tool. GuardedAgentWorkflow overrides that step and runs the tool body through the guard’s continuation — block by raising Hold, proceed by calling through. The adapter is fully async to match the workflow, and lazily imports LlamaIndex so import kiff_guard works without llama-index-core installed.