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

AIDefenseMiddleware (Recommended)

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

AIDefenseToolMiddleware (Recommended for tools)

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

langchain_cisco_aidefense-1.1.1.tar.gz (33.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langchain_cisco_aidefense-1.1.1-py3-none-any.whl (33.0 kB view details)

Uploaded Python 3

File details

Details for the file langchain_cisco_aidefense-1.1.1.tar.gz.

File metadata

File hashes

Hashes for langchain_cisco_aidefense-1.1.1.tar.gz
Algorithm Hash digest
SHA256 16a89db04c8160a756a65816f26e86a78c1e4930b65b3fe9997be4aced81eb8a
MD5 cddb1fc17ee02cbfec81306c7f56555f
BLAKE2b-256 1429b00c40272ec45f92764595fa3bdb0d4ee411c7dac5065ae3058f638c50c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for langchain_cisco_aidefense-1.1.1.tar.gz:

Publisher: release.yml on cisco-ai-defense/ai-defense-langchain-middleware

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file langchain_cisco_aidefense-1.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for langchain_cisco_aidefense-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cd8480ffe8c30a8134ecfe7b2deae976e63009dc906538897bfa9d5c0b977128
MD5 63be86d5dd90f03559ceb99eb36e92bc
BLAKE2b-256 8caff4484dcf26cc091a7223bdd002d83c9bd3607b22a6070765fe531bb72086

See more details on using hashes here.

Provenance

The following attestation bundles were made for langchain_cisco_aidefense-1.1.1-py3-none-any.whl:

Publisher: release.yml on cisco-ai-defense/ai-defense-langchain-middleware

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page