Skip to main content

langchain-cisco-aidefense

PyPI version License Python 3.10+

LangChain agent middleware for Cisco AI Defense, providing runtime security inspection of LLM inputs/outputs and tool/MCP calls.

Detects prompt injection, jailbreaks, PII leakage, toxic content, and unsafe tool usage — directly within the LangChain agent loop.

Installation

pip install langchain-cisco-aidefense

Middleware Overview

create_agent (LangChain LCEL) — four middleware classes

LLM Inspection (before_model / after_model)

Middleware Built on Best for
AIDefenseMiddleware ChatInspectionClient New integrations — lightweight, no global state
AIDefenseAgentsecMiddleware agentsec LLMInspector When you need agentsec's retry/backoff machinery

Tool / MCP Inspection (wrap_tool_call)

Middleware Built on Best for
AIDefenseToolMiddleware MCPInspectionClient New integrations — tool/MCP call inspection
AIDefenseAgentsecToolMiddleware agentsec MCPInspector When you need agentsec's retry/backoff machinery

create_react_agent (LangGraph prebuilt) — added in v1.1.0

Symbol Purpose
AIDefenseHooks Provides pre_model_hook / post_model_hook for LLM inspection
AIDefenseToolNode ToolNode subclass for tool call inspection
create_aidefense_react_agent Drop-in replacement for create_react_agent

Quick Start

pip install langchain-cisco-aidefense langchain-openai
from aidefense_langchain import AIDefenseMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model="openai:gpt-4.1",
    tools=[get_weather],
    middleware=[
        AIDefenseMiddleware(
            api_key="your-cisco-ai-defense-api-key",
            region="us-west-2",
            mode="enforce",
        ),
    ],
)

result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})

LLM Inspection

Uses ChatInspectionClient directly. Self-contained configuration, no global state, no monkey-patching.

from aidefense_langchain import AIDefenseMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model="openai:gpt-4.1",
    tools=[get_weather],
    middleware=[
        AIDefenseMiddleware(
            api_key="your-api-key",
            region="us-west-2",
            mode="enforce",       # "enforce" | "monitor" | "off"
            fail_open=True,
        ),
    ],
)

Parameters

Parameter Type Default Description
api_key str required Cisco AI Defense API key
region str "us-west-2" AI Defense region ("us-west-2", "eu-central-1", "ap-northeast-1")
mode str "enforce" "enforce" (block), "monitor" (log only), "off"
fail_open bool True Allow on inspection API errors
timeout int 30 Inspection timeout in seconds
rules list None Rules to enable (e.g. ["PII", "Prompt Injection"])
user str None User identity for audit
src_app str None Source application name
on_violation callable None (InspectResponse, direction) -> None callback

How it works

User message
    |
    v
+--------------------------------------------------+
|  before_model hook                               |
|  -> ChatInspectionClient.inspect_conversation()  |
|  -> if not safe and mode="enforce": jump_to=end  |
+--------------------------------------------------+
    |
    v
  LLM call
    |
    v
+--------------------------------------------------+
|  after_model hook                                |
|  -> ChatInspectionClient.inspect_conversation()  |
|  -> if not safe and mode="enforce": jump_to=end  |
+--------------------------------------------------+
    |
    v
Agent response

AIDefenseAgentsecMiddleware

Uses agentsec's LLMInspector — gets retry with exponential backoff and fail-open semantics.

from aidefense_langchain import AIDefenseAgentsecMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model="openai:gpt-4.1",
    tools=[get_weather],
    middleware=[
        AIDefenseAgentsecMiddleware(
            mode="enforce",
            api_key="your-api-key",
            endpoint="https://us.api.inspect.aidefense.security.cisco.com",
            retry_total=3,
            retry_backoff=1.0,
        ),
    ],
)

Do not call agentsec.protect() when using middleware. The middleware handles all inspection directly. Calling protect() would activate monkey-patching on the underlying LLM SDK, causing every request to be inspected twice — once by the patched SDK and once by the middleware — doubling latency and API calls with no security benefit.

Parameters

Parameter Type Default Description
mode str "enforce" "enforce", "monitor", or "off"
api_key str from state/env AI Defense API key
endpoint str from state/env AI Defense API endpoint
fail_open bool True Allow on inspection errors
timeout_ms int from state Timeout in milliseconds
retry_total int 1 Retry attempts
retry_backoff float 0.0 Backoff factor in seconds
rules list None Inspection rules
user str None User identity
src_app str None Source application name
on_violation callable None (Decision, direction) -> None callback

Tool / MCP Inspection

Uses MCPInspectionClient to inspect tool call requests (name + arguments) and tool call results.

from aidefense_langchain import AIDefenseMiddleware, AIDefenseToolMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model="openai:gpt-4.1",
    tools=[search_db, send_email],
    middleware=[
        AIDefenseMiddleware(api_key="your-key", mode="enforce"),
        AIDefenseToolMiddleware(api_key="your-key", mode="enforce"),
    ],
)

AIDefenseAgentsecToolMiddleware

Uses agentsec's MCPInspector with retry, backoff, and fail-open support.

from aidefense_langchain import AIDefenseAgentsecMiddleware, AIDefenseAgentsecToolMiddleware

agent = create_agent(
    model="openai:gpt-4.1",
    tools=[read_file, execute_query],
    middleware=[
        AIDefenseAgentsecMiddleware(mode="enforce", api_key="your-key"),
        AIDefenseAgentsecToolMiddleware(mode="enforce", api_key="your-key"),
    ],
)

Tool Middleware Parameters

Parameter Type Default Description
api_key str required / from env Cisco AI Defense API key
region str "us-west-2" AI Defense region (ChatClient variant only)
mode str "enforce" "enforce", "monitor", or "off"
fail_open bool True Allow on inspection API errors
inspect_requests bool True Inspect tool call requests before execution
inspect_responses bool True Inspect tool results after execution
on_violation callable None Violation callback

How tool inspection works

Tool call (from LLM)
    |
    v
+--------------------------------------------------+
|  wrap_tool_call -- PRE-CALL inspection           |
|  -> MCPInspectionClient.inspect_tool_call()      |
|  -> if not safe and mode="enforce": return block |
+--------------------------------------------------+
    |
    v
  Tool executes
    |
    v
+--------------------------------------------------+
|  wrap_tool_call -- POST-CALL inspection          |
|  -> MCPInspectionClient.inspect_response()       |
|  -> if not safe and mode="enforce": return block |
+--------------------------------------------------+
    |
    v
Tool result returned to agent

This covers all tool types:

  • LangChain tools (@tool decorated functions)
  • MCP tools registered via LangChain's MCP integration
  • Any tool executed through the agent's tool node

Environment Variables

The middleware can also be configured via environment variables (used by from_env() class methods):

export AIDEFENSE_API_KEY=your-api-key
export AIDEFENSE_REGION=us-west-2
export AIDEFENSE_MODE=enforce
export AIDEFENSE_FAIL_OPEN=true
export AIDEFENSE_TIMEOUT=30
from aidefense_langchain import AIDefenseMiddleware

middleware = AIDefenseMiddleware.from_env()

Comparison

Criteria AIDefenseMiddleware AIDefenseAgentsecMiddleware
No global state / side effects Yes No (uses _state)
Self-contained config Yes Yes (pass explicitly)
Built-in retry + backoff Via Config Custom
Built-in fail-open In middleware In inspector
inspect_prompt / inspect_response Yes No (inspect_conversation only)
Dependency footprint Lighter (aidefense.runtime) Heavier (aidefense.runtime.agentsec)

Recommendation: Use AIDefenseMiddleware for new projects. Use AIDefenseAgentsecMiddleware when you need agentsec's retry/backoff machinery.

Enforcement Modes

Mode Behavior
enforce Block violations — agent returns a "blocked" message via jump_to: "end"
monitor Log violations and invoke on_violation callback; never blocks
off Skip inspection entirely

Fail-Open Behavior

When fail_open=True (default) and the AI Defense inspection API is unreachable:

  • The request is allowed to proceed
  • A warning is logged

When fail_open=False:

  • The request is blocked (or an exception is raised)

Examples

# File Description
1 01_chat_client_enforce.py ChatClient middleware — enforce mode (block violations)
2 02_chat_client_monitor.py ChatClient middleware — monitor mode with violation callback
3 03_chat_client_with_rules.py ChatClient middleware — specific rules (PII, Prompt Injection)
4 04_agentsec_enforce.py Agentsec middleware — enforce mode with retry config
5 05_composed_middleware.py AI Defense + custom logging middleware composed together
6 06_side_by_side.py Same request through both middleware — side-by-side comparison
7 07_tool_inspection_enforce.py Tool inspection — LLM + tool call inspection combined
8 08_tool_inspection_agentsec.py Agentsec tool inspection — MCPInspector with retry
9 09_callback_handler_create_react_agent.py create_react_agent with OpenAI — Options A & B
10 10_azure_openai_create_react_agent.py create_react_agent with Azure OpenAI + macOS SSL fix

create_react_agent Integration (v1.1.0)

LangGraph's create_react_agent does not expose before_model / after_model hooks, so the middleware classes above cannot be used with it directly. v1.1.0 adds native support via LangGraph's pre_model_hook, post_model_hook, and ToolNode.wrap_tool_call.

Requires langgraph >= 0.2.27.

Option A — Primitives (maximum control)

from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from aidefense_langchain import AIDefenseHooks, AIDefenseToolNode, AIDefenseViolationError

@tool
def get_weather(city: str) -> str:
    """Return current weather for a city."""
    return f"It's 72°F and sunny in {city}!"

hooks = AIDefenseHooks(api_key="<AIDEFENSE_API_KEY>", mode="enforce")
tool_node = AIDefenseToolNode([get_weather], api_key="<AIDEFENSE_API_KEY>", mode="enforce")

agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o-mini"),
    tools=tool_node,
    pre_model_hook=hooks.pre_model_hook,
    post_model_hook=hooks.post_model_hook,
)

try:
    result = agent.invoke({"messages": [("user", "What's the weather in Seattle?")]})
    print(result["messages"][-1].content)
except AIDefenseViolationError as e:
    print(f"Blocked at '{e.direction}': {e}")

Option B — Convenience wrapper (minimum changes)

from aidefense_langchain import create_aidefense_react_agent, AIDefenseViolationError

agent = create_aidefense_react_agent(
    model=ChatOpenAI(model="gpt-4o-mini"),
    tools=[get_weather],
    api_key="<AIDEFENSE_API_KEY>",
    mode="enforce",
)

Violation handling

AIDefenseViolationError carries:

  • .direction — "input", "output", "tool '<name>' input", or "tool '<name>' output"
  • .response — the full InspectResponse from the SDK (includes event_id, severity, explanation)

In "monitor" mode, violations are logged and the optional on_violation callback is invoked, but the agent continues:

violations = []
agent = create_aidefense_react_agent(
    model=llm, tools=[get_weather],
    api_key="<AIDEFENSE_API_KEY>",
    mode="monitor",
    on_violation=lambda resp, direction: violations.append(direction),
)

LangGraph V2.0 note: create_react_agent is deprecated in langgraph.prebuilt (LangGraph V1.0) and will move to langchain.agents in V2.0. Update your import when you upgrade.

Development

git clone https://github.com/cisco-ai-defense/ai-defense-langchain-middleware.git
cd ai-defense-langchain-middleware
pip install -e ".[dev,examples]"
pytest

License

Apache-2.0 — see LICENSE for details.

Metadata

Release files for langchain-cisco-aidefense 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchain-cisco-aidefense 1.1.1
File Size Uploaded
langchain_cisco_aidefense-1.1.1.tar.gz 33.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchain-cisco-aidefense 1.1.1
File Interpreter ABI Platform
langchain_cisco_aidefense-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 66.1 kB

Release files / langchain_cisco_aidefense-1.1.1.tar.gz

Download URL langchain_cisco_aidefense-1.1.1.tar.gz
Size 33.1 kB
Tags Source
SHA-256 checksum
How to use checksums
16a89db04c8160a756a65816f26e86a78c1e4930b65b3fe9997be4aced81eb8a
BLAKE2b-256 checksum
How to use checksums
1429b00c40272ec45f92764595fa3bdb0d4ee411c7dac5065ae3058f638c50c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 14, 2026.

Transparency log

Release files / langchain_cisco_aidefense-1.1.1-py3-none-any.whl

Download URL langchain_cisco_aidefense-1.1.1-py3-none-any.whl
Size 33.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd8480ffe8c30a8134ecfe7b2deae976e63009dc906538897bfa9d5c0b977128
BLAKE2b-256 checksum
How to use checksums
8caff4484dcf26cc091a7223bdd002d83c9bd3607b22a6070765fe531bb72086
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page