Skip to content

Creating a custom scanner

INFERENCE DEFEND

This article is meant for Inference Defend users.

ROLES AND PERMISSIONS

To complete the tasks described in this section, make sure you have the required permissions.

In addition to the scanners provided with CalypsoAI, you may want to create your own custom scanners with specific configurations depending on your particular requirements.

You can create three types of custom scanners:

Create a GenAI scanner

A GenAI scanner uses generative artificial intelligence to scan and flag text based on an input you can configure.

In this scenario, we are going to set our input as Political figures. The scanner will scan and flag any text that contains a political figure.

To create a GenAI scanner:

  1. Edit the following sample.

    python
    from calypsoai import CalypsoAI
    from calypsoai.datatypes import GenAIScannerConfig, ScanContext, ScannerDirection,
    ScannerVersionInputModel
    
    # Define the URL and token for CalypsoAI
    CALYPSOAI_URL = "https://www.us1.calypsoai.app"
    CALYPSOAI_TOKEN = "ADD-YOUR-TOKEN-HERE"
    
    # Initialize the CalypsoAI client
    cai = CalypsoAI(url=CALYPSOAI_URL, token=CALYPSOAI_TOKEN)
    
    # Configure the scanner
    config = GenAIScannerConfig(input="Political figures", type="custom",
    scanContext=ScanContext.DIRECTIONAL)
    
    # Configure the scanner version
    version = ScannerVersionInputModel(name="ADD-YOUR-VERSION-NAME-HERE", description="ADD-YOUR-VERSION-DESCRIPTION-HERE", published=False)
    
    # Create the scanner
    response = cai.scanners.create(name='ADD-YOUR-SCANNER-NAME-HERE', config=config,
    direction=ScannerDirection.BOTH, published=False, version=version)
    
    # Print the response
    print(response.model_dump_json(indent=2))
    • Add your token value.
    • In GenAIScannerConfig > input, provide the input that you want the scanner to scan for and flag.
      In this scenario, the input is Political figures.
    • In ScannerVersionInputModel, do the following:

      SCANNER VERSIONS

      When creating a custom scanner, setting a scanner version is optional. If you don't set a version, the system creates a version for you and automatically assigns a version name, with the following additional configuration:

      • description left empty.
      • published set to False.

      For more information, see Working with scanner versions.

      • In name, provide a name for the scanner version.
      • In description, provide a description for the scanner version.
        This is an optional parameter. You can include it to add context and describe the changes made in each new scanner version.
      • In published, enter either True or False.
        If set to True, the scanner version is published and made available for use.
        The default value for this property is False.
    • In cai.scanners.create, do the following:
      • In name, provide a name for the scanner.
      • In direction, define the direction of the scan.
        The direction property defines if the scan analyzes the request, the response, or both. You can choose one of the following three options:
        • REQUEST: Only the request (prompt) is scanned. This is the default selection.
        • RESPONSE: Only the LLM response is scanned.
        • BOTH: Both the request and response are scanned.
      • In published, enter either True or False.

        PUBLISHING SCANNER VERSIONS

        The Python request sample includes two instances of the published property.

        • ScannerVersionInputModel > published
        • cai.scanners.create > published

        Both instances of the published property have the same function - they define if the scanner version is published. The published property in cai.scanners.create is a legacy feature to allow for backwards compatibility.

        • If you don't set a version, or ScannerVersionInputModel is invalid, the value in cai.scanners.create > published is used.
        • If ScannerVersionInputModel includes the published property, this value is used.
        • If the published property is included in both ScannerVersionInputModel and cai.scanners.create, the value in ScannerVersionInputModel > published is used.

        For more information, see Working with scanner versions.

  2. Run the script.

  3. Analyze the response.
    The following response sample is a simplified version of a successful request, focusing only on the main details relevant to this specific request.

    json
    {
      "config": {
        "type": "custom",
        "input": "Political figures"
      },
      "direction": "both",
      "id": "01973b46-3d66-70b8-94f8-aab4b01d0684",
      "name": "ADD-YOUR-SCANNER-NAME-HERE",
      "versionMeta": {
        "id": "01985680-6fb7-70b7-a684-960344ebd18b",
        "name": "ADD-YOUR-VERSION-NAME-HERE",
        "published": false
      }
    }

    The response includes the following key parameters:

    • config > type: The scanner type.
      In this example, custom defines the GenAI scanner.
    • config > input: The input the scanner scans for.
      In this example, the scanner is scanning for political figures.
    • direction: The scanning direction of the scanner.
    • name: The name of the scanner.
    • versionMeta > name: The name of the scanner version.
    • versionMeta > published: Defines if the scanner version is published.
    To view the full response, click here.
    json
    {
        "availability": {
            "global_": true,
            "projectIds": []
        },
        "availableUpdate": null,
        "config": {
            "input": "Political figures",
            "scanContext": "directional",
            "type": "custom"
        },
        "direction": "both",
        "files": [],
        "id": "01973b46-3d66-70b8-94f8-aab4b01d0684",
        "name": "ADD-YOUR-SCANNER-NAME-HERE",
        "packageId": null,
        "projectId": null,
        "scannerTemplateId": "0192afb2-466f-703e-929e-e465d697e653",
        "shared": false,
        "source": {
            "type": "internal"
        },
        "tags": [],
        "vendored": false,
        "versionMeta": {
            "createdAt": "2025-07-29T14:05:14.551745Z",
            "createdBy": null,
            "description": "ADD-YOUR-VERSION-DESCRIPTION-HERE",
            "id": "01985680-6fb7-70b7-a684-960344ebd18b",
            "name": "ADD-YOUR-VERSION-NAME-HERE",
            "published": false
        },
        "published": false
    }

Create a regex scanner

A regex scanner uses regular expressions to scan and flag text based on a regex pattern you can configure.

Regex scanners are most useful for finding input that follows a predictable pattern. For example:

  • Email addresses
  • Phone numbers
  • URLs

In this scenario, we are going to create a regex scanner that scans for and flags any text that contains an email address.

To create a regex scanner:

  1. Edit the following sample.

    python
    from calypsoai import CalypsoAI
    from calypsoai.datatypes import RegexScannerConfig, ScannerDirection, ScannerVersionInputModel
    
    # Define the URL and token for CalypsoAI
    CALYPSOAI_URL = "https://www.us1.calypsoai.app"
    CALYPSOAI_TOKEN = "ADD-YOUR-TOKEN-HERE"
    
    # Initialize the CalypsoAI client
    cai = CalypsoAI(url=CALYPSOAI_URL, token=CALYPSOAI_TOKEN)
    
    # Configure the scanner
    config = RegexScannerConfig(pattern=r"\b[\w.-]+@[\w.-]+\.\w+\b", type="regex")
    
    # Configure the scanner version
    version = ScannerVersionInputModel(name="ADD-YOUR-VERSION-NAME-HERE", description="ADD-YOUR-VERSION-DESCRIPTION-HERE", published=False)
    
    # Create the scanner
    response = cai.scanners.create(name='ADD-YOUR-SCANNER-NAME-HERE', config=config,
    direction=ScannerDirection.BOTH, published=False, version=version)
    
    # Print the response
    print(response.model_dump_json(indent=2))
    • Add your token value.
    • In RegexScannerConfig > pattern, provide the regex pattern that you want the scanner to scan for and flag.
      In this scenario, the pattern is scanning for email addresses.
    • In ScannerVersionInputModel, do the following:

      SCANNER VERSIONS

      When creating a custom scanner, setting a scanner version is optional. If you don't set a version, the system creates a version for you and automatically assigns a version name, with the following additional configuration:

      • description left empty.
      • published set to False.

      For more information, see Working with scanner versions.

      • In name, provide a name for the scanner version.
      • In description, provide a description for the scanner version.
        This is an optional parameter. You can include it to add context and describe the changes made in each new scanner version.
      • In published, enter either True or False.
        If set to True, the scanner version is published and made available for use.
        The default value for this property is False.
    • In cai.scanners.create, do the following:
      • In name, provide a name for the scanner.
      • In direction, define the direction of the scan.
        The direction property defines if the scan analyzes the request, the response, or both. You can choose one of the following three options:
        • REQUEST: Only the request (prompt) is scanned. This is the default selection.
        • RESPONSE: Only the LLM response is scanned.
        • BOTH: Both the request and response are scanned.
      • In published, enter either True or False.

        PUBLISHING SCANNER VERSIONS

        The Python request sample includes two instances of the published property.

        • ScannerVersionInputModel > published
        • cai.scanners.create > published

        Both instances of the published property have the same function - they define if the scanner version is published. The published property in cai.scanners.create is a legacy feature to allow for backwards compatibility.

        • If you don't set a version, or ScannerVersionInputModel is invalid, the value in cai.scanners.create > published is used.
        • If ScannerVersionInputModel includes the published property, this value is used.
        • If the published property is included in both ScannerVersionInputModel and cai.scanners.create, the value in ScannerVersionInputModel > published is used.

        For more information, see Working with scanner versions.

  2. Run the script.

  3. Analyze the response.
    The following response sample is a simplified version of a successful request, focusing only on the main details relevant to this specific request.

    json
    {
      "config": {
        "type": "regex",
        "pattern": "\\b[\\w.-]+@[\\w.-]+\\.\\w+\\b",
      },
      "direction": "both",
      "id": "01973b4a-2623-700b-8f59-38f55352124b",
      "name": "ADD-YOUR-SCANNER-NAME-HERE",
      "versionMeta": {
        "id": "01985687-88f1-7054-9fbb-f97bd76bf8f9",
        "name": "ADD-YOUR-VERSION-NAME-HERE",
        "published": false
      }
    }

    The response includes the following key parameters:

    • config > type: The scanner type.
      In this example, regex defines the regex scanner.
    • config > pattern: The regex pattern the scanner scans for.
      In this example, the scanner is scanning for emails.
    • direction: The scanning direction of the scanner.
    • name: The name of the scanner.
    • versionMeta > name: The name of the scanner version.
    • versionMeta > published: Defines if the scanner version is published.
    To view the full response, click here.
    json
    {
        "availability": {
            "global_": true,
            "projectIds": []
        },
        "availableUpdate": null,
        "config": {
            "pattern": "\\b[\\w.-]+@[\\w.-]+\\.\\w+\\b",
            "type": "regex"
        },
        "direction": "both",
        "files": [],
        "id": "01973b4a-2623-700b-8f59-38f55352124b",
        "name": "ADD-YOUR-SCANNER-NAME-HERE",
        "packageId": null,
        "projectId": null,
        "scannerTemplateId": null,
        "shared": false,
        "source": {
            "type": "internal"
        },
        "tags": [],
        "vendored": false,
        "versionMeta": {
            "createdAt": "2025-07-29T14:12:59.761349Z",
            "createdBy": null,
            "description": "ADD-YOUR-VERSION-DESCRIPTION-HERE",
            "id": "01985687-88f1-7054-9fbb-f97bd76bf8f9",
            "name": "ADD-YOUR-VERSION-NAME-HERE",
            "published": false
        },
        "published": false
    }

Create a keyword scanner

A keyword scanner scans for and flags text that contains specific keywords you can configure.

In this scenario, we are going to create a keyword scanner that scans for and flags any text that contains the words hello and world.

To create a keyword scanner:

  1. Edit the following sample.

    python
    from calypsoai import CalypsoAI
    from calypsoai.datatypes import KeywordScannerConfig, ScannerDirection,
    ScannerVersionInputModel
    
    # Define the URL and token for CalypsoAI
    CALYPSOAI_URL = "https://www.us1.calypsoai.app"
    CALYPSOAI_TOKEN = "ADD-YOUR-TOKEN-HERE"
    
    # Initialize the CalypsoAI client
    cai = CalypsoAI(url=CALYPSOAI_URL, token=CALYPSOAI_TOKEN)
    
    # Configure the scanner
    config = KeywordScannerConfig(words=["hello", "world"], type="keyword")
    
    # Configure the scanner version
    version = ScannerVersionInputModel(name="ADD-YOUR-VERSION-NAME-HERE", description="ADD-YOUR-VERSION-DESCRIPTION-HERE", published=False)
    
    # Create the scanner
    response = cai.scanners.create(name='ADD-YOUR-SCANNER-NAME-HERE', config=config,
    direction=ScannerDirection.BOTH, published=False, version=version)
    
    # Print the response
    print(response.model_dump_json(indent=2))
    • Add your token value.
    • In KeywordScannerConfig > words, provide the keywords that you want the scanner to scan for and flag.
      In this scenario, the keywords are hello and world.
    • In ScannerVersionInputModel, do the following:

      SCANNER VERSIONS

      When creating a custom scanner, setting a scanner version is optional. If you don't set a version, the system creates a version for you and automatically assigns a version name, with the following additional configuration:

      • description left empty.
      • published set to False.

      For more information, see Working with scanner versions.

      • In name, provide a name for the scanner version.
      • In description, provide a description for the scanner version.
        This is an optional parameter. You can include it to add context and describe the changes made in each new scanner version.
      • In published, enter either True or False.
        If set to True, the scanner version is published and made available for use.
        The default value for this property is False.
    • In cai.scanners.create, do the following:
      • In name, provide a name for the scanner.
      • In direction, define the direction of the scan.
        The direction property defines if the scan analyzes the request, the response, or both. You can choose one of the following three options:
        • REQUEST: Only the request (prompt) is scanned. This is the default selection.
        • RESPONSE: Only the LLM response is scanned.
        • BOTH: Both the request and response are scanned.
      • In published, enter either True or False.

        PUBLISHING SCANNER VERSIONS

        The Python request sample includes two instances of the published property.

        • ScannerVersionInputModel > published
        • cai.scanners.create > published

        Both instances of the published property have the same function - they define if the scanner version is published. The published property in cai.scanners.create is a legacy feature to allow for backwards compatibility.

        • If you don't set a version, or ScannerVersionInputModel is invalid, the value in cai.scanners.create > published is used.
        • If ScannerVersionInputModel includes the published property, this value is used.
        • If the published property is included in both ScannerVersionInputModel and cai.scanners.create, the value in ScannerVersionInputModel > published is used.

        For more information, see Working with scanner versions.

  2. Run the script.

  3. Analyze the response.
    The following response sample is a simplified version of a successful request, focusing only on the main details relevant to this specific request.

    json
    {
      "config": {
        "type": "keyword",
        "words": [
          "hello",
          "world"
        ]
      },
      "direction": "both",
      "id": "01973b52-e9c8-7029-8487-3b52a61d28d6",
      "name": "ADD-YOUR-SCANNER-NAME-HERE",
      "versionMeta": {
        "id": "0198568b-25fe-7052-9ef5-2a31d3415a94",
        "name": "ADD-YOUR-VERSION-NAME-HERE",
        "published": false
      }
    }

    The response includes the following key parameters:

    • config > type: The scanner type.
      In this example, keyword defines the keyword scanner.
    • config > words: A list of the words the scanner scans for.
      In this example, the scanner is scanning for the words hello and world.
    • direction: The scanning direction of the scanner.
    • name: The name of the scanner.
    • versionMeta > name: The name of the scanner version.
    • versionMeta > published: Defines if the scanner version is published.
    To view the full response, click here.
    json
    {
        "availability": {
            "global_": true,
            "projectIds": []
        },
        "availableUpdate": null,
        "config": {
            "type": "keyword",
            "words": [
                "hello",
                "world"
            ]
        },
        "direction": "both",
        "files": [],
        "id": "01973b52-e9c8-7029-8487-3b52a61d28d6",
        "name": "ADD-YOUR-SCANNER-NAME-HERE",
        "packageId": null,
        "projectId": null,
        "scannerTemplateId": null,
        "shared": false,
        "source": {
            "type": "internal"
        },
        "tags": [],
        "vendored": false,
        "versionMeta": {
            "createdAt": "2025-07-29T14:16:56.574340Z",
            "createdBy": null,
            "description": "ADD-YOUR-VERSION-DESCRIPTION-HERE",
            "id": "0198568b-25fe-7052-9ef5-2a31d3415a94",
            "name": "ADD-YOUR-VERSION-NAME-HERE",
            "published": false
        },
        "published": false
    }

Updated at: