Corridor Sync
Overview
Section titled “Overview”The GenGuardX Corridor Sync system enables you to programmatically manage and version-control your AI assets (Prompts, Models, RAGs, Pipelines, Global Functions, and Reports) directly from your development environment. Using Python decorators and a simple sync command, you can declare and synchronize your components to the GenGuardX platform.
What Can Be Synced?
Section titled “What Can Be Synced?”GenGuardX Corridor Sync supports six core component types:
| Component | Purpose | Example Use Case |
|---|---|---|
| Prompt | System instructions, templates, and persona definitions | Customer service chatbot instructions |
| Model | LLM configurations and API integrations | Gemini, GPT, Claude model wrappers |
| RAG | Retrieval-Augmented Generation systems | Database query systems, knowledge base retrieval |
| Pipeline | End-to-end workflows combining multiple components | Complete chatbot with intent classification and response generation |
| Global Function | Reusable utility functions | Data preprocessing, validation, formatting functions |
| Report | Evaluation and monitoring reports with visualizations | Model performance dashboards, bias analysis reports |
Getting Started
Section titled “Getting Started”Step 1: Installation
Section titled “Step 1: Installation”pip install genguardxStep 2: Initialize Connection
Section titled “Step 2: Initialize Connection”Before syncing any components, you need to authenticate with your GenGuardX instance.
Obtaining Your API Key
Section titled “Obtaining Your API Key”- Log into your GenGuardX platform
- Navigate to Profile Section → Account Security
- Locate your API Key (format:
eyJI-XXXX-XXXX-XXXX-XXXX-XXXX-3fe3) - Click “How to use this key” to view the initialization code
Initialize in Your Code
Section titled “Initialize in Your Code”import genguardx as ggx
# Initialize connection to your GenGuardX instanceggx.init( api_url="https://devaisandbox.corridorplatforms.com", # Change for your instance api_key="your-api-key-here",)Important: Replace the api_url if you’re using a different GenGuardX instance (e.g., production, staging). The URL should point to your specific deployment.
Component Declaration & Sync
Section titled “Component Declaration & Sync”Each component type uses a specific decorator pattern. Components can be declared and synced independently or used together in pipelines.
1. Prompts
Section titled “1. Prompts”Prompts define system instructions, templates, or conversation guidelines.
Decorator Syntax
Section titled “Decorator Syntax”import genguardx as ggx@ggx.Prompt.declare( name='My Prompt Name', # Optional: defaults to function name group='My Group', # Optional: organizational grouping task_type='Question Answering', # Optional: Classification | Summarization | etc. prompt_type='System Instruction', # Optional: User Prompt | Others prompt_elements=['Persona + Goal', 'Tone', 'Constraints'], # Optional: list of components)def my_prompt_function(*, cache: dict = {}, prompt: str = "Your prompt text here"): """Docstring describing the prompt purpose.""" # -- BEGIN DEFINITION -- return prompt
# Sync to platformggx.sync(my_prompt_function)2. Models
Section titled “2. Models”Models wrap LLM API calls with consistent interfaces and cost tracking.
Decorator Syntax
Section titled “Decorator Syntax”import genguardx as ggx@ggx.Model.declare( name='My Model Name', # Optional: defaults to function name group='My Group', # Optional: organizational grouping ownership_type='Proprietary', # Optional: Proprietary | Open Source model_type='LLM', # Optional: LLM | Text Embedding | Guardrail | Judge Model | Others provider='openai', # Optional: openai | google | anthropic | etc. (for API-based models) model='gpt-4', # Optional: specific model identifier (required if provider is set))def my_model_function(text: str, temperature: float = 0.7, *, cache: dict = {}): """Docstring describing the model configuration.""" # -- BEGIN DEFINITION -- # Your model implementation return {"response": "...", "cost": "..."}
# Sync to platformggx.sync(my_model_function)3. RAGs (Retrieval-Augmented Generation)
Section titled “3. RAGs (Retrieval-Augmented Generation)”RAGs connect to knowledge bases, databases, or document stores to retrieve relevant context.
Decorator Syntax
Section titled “Decorator Syntax”import pathlibimport genguardx as ggx@ggx.Rag.declare( name='My RAG System', # Optional: defaults to function name group='My Group', # Optional: organizational grouping knowledge_base_format='Relational Database', # Optional: Vector Database | Graph Database | etc. provider=None, # Optional: provider identifier for API-based RAG systems)def my_rag_function( query: str, *, cache: dict = {}, knowledge: pathlib.Path = pathlib.Path('data.db')): """Docstring describing the RAG system.""" # -- BEGIN DEFINITION -- # Your RAG implementation return {"retrieved_data": "...", "query_used": "..."}
# Sync to platformggx.sync(my_rag_function)4. Pipelines
Section titled “4. Pipelines”Pipelines orchestrate multiple components into complete workflows.
Decorator Syntax
Section titled “Decorator Syntax”import typing as timport genguardx as ggx@ggx.Pipeline.declare( name='My Pipeline', # Optional: defaults to function name group='My Group', # Optional: organizational grouping usecase_type='Question Answering', # Optional: Summarization | Translation task_type='Generative Responses', # Optional: Classification | Templated Responses | etc. impact='External Facing', # Optional: Internal Only | Internal - with external implications data_usage=['Customer Specific Data'], # Optional: list of data types pipeline_type='Chat based - OpenAI Spec', # Required: or 'Custom Return Type')def my_pipeline_function( user_message: str, history: list[t.TypedDict("T", {'role': str, 'content': str}, total=False)] = (), context: t.Optional[dict[str, str]] = None, *, cache: dict = {},): """Docstring describing the pipeline workflow.""" # -- BEGIN DEFINITION -- # Your pipeline implementation return {"output": "...", "context": "..."}
# Sync to platformggx.sync(my_pipeline_function)5. Global Functions
Section titled “5. Global Functions”Global Functions are reusable utility functions that can be referenced by other components.
Decorator Syntax
Section titled “Decorator Syntax”import genguardx as ggx@ggx.GlobalFunction.declare( name='My Utility Function', # Optional: defaults to function name group='My Group', # Optional: organizational grouping)def my_utility_function(input_text: str, max_length: int = 100, *, cache: dict = {}) -> str: """Docstring describing the utility function.""" # -- BEGIN DEFINITION -- # Your utility function implementation return input_text[:max_length]
# Sync to platformggx.sync(my_utility_function)Key Points:
- Global Functions can be called by other components (Pipelines, RAGs, Models, etc.)
6. Reports
Section titled “6. Reports”Reports generate evaluation dashboards with metrics and visualizations for monitoring AI systems.
Decorator Syntax
Section titled “Decorator Syntax”import typing as timport genguardx as ggx@ggx.Report.declare( name='My Evaluation Report', # Optional: defaults to function name object_types=['PIPELINE', 'FOUNDATION_MODEL'], # Required: list of object types this report evaluates group='My Group', # Optional: organizational grouping risk_type='Accuracy', # Optional: Accuracy | Stability | Bias | Vulnerability | Toxicity | Others task_type='Classification', # Optional: Classification | Templated Responses | etc. risk_domain='Model Risk Management', # Optional: Model Risk Management | Fair Lending | Technology | Infosec | Others evaluation_methodology='Statistical / ML Algorithms', # Optional: LLM-as-a-Judge | Rule-based | Statistical / ML Algorithms | Others report_methodology='Custom methodology', # Optional: free text description parameters=[], # Optional: list of report parameters)def my_evaluation_report(job: t.Any, data: t.Any, *, cache: dict = {}) -> t.Any: """Docstring describing the report purpose.""" # -- BEGIN DEFINITION -- # Your report logic here # Process data and return metrics return metrics_dict, processed_data
# Sync to platformggx.sync(my_evaluation_report)Key Points:
- Reports typically work with ReportOutput, DataLogicExample, and AdditionalReportFigure helper components
- Helper components use the
reportparameter to associate with their parent report (e.g.,report='My Evaluation Report') - Report functions typically receive
jobanddataparameters and return processed results - ReportOutput functions generate visualizations (Plotly figures, Pandas DataFrames, or HTML/Markdown strings)
Key Concepts
Section titled “Key Concepts”The # -- BEGIN DEFINITION -- Anchor
Section titled “The # -- BEGIN DEFINITION -- Anchor”Every component function must include this special comment. Only code after this anchor is synced to the platform.
def my_function(): # Imports and setup code here (NOT synced) import os
# -- BEGIN DEFINITION -- # Everything after this line IS synced result = process_data() return resultWhy? This ensures only the core logic is synced, keeping your platform definitions clean and portable.
The cache Parameter
Section titled “The cache Parameter”All component functions include a cache: dict = {} parameter. This is a reserved keyword that is:
- Automatically removed from function inputs during sync (not exposed to end users)
- Commonly used for storing database connections in RAG implementations
Example from RAG:
if "sql_cursor_obj" not in cache: conn = sqlite3.connect(...) cache["sql_cursor_obj"] = conn.cursor()cursor = cache["sql_cursor_obj"]Dependency Resolution
Section titled “Dependency Resolution”When you sync a Pipeline, the system:
- Inspects the function bytecode to find referenced objects
- Checks if those objects have
_corridor_metadata - Recursively syncs those dependencies by calling their respective sync handlers
- Collects the version IDs returned from each sync operation
- Includes those version IDs in the pipeline payload (e.g.,
promptVersionIds,foundationModelVersionIds)
Example:
# Define componentsimport genguardx as ggx@ggx.Prompt.declare(name='System Prompt')def system_prompt(*, cache: dict = {}, prompt: str = "You are a helpful assistant."): """System instruction for the assistant.""" # -- BEGIN DEFINITION -- return prompt
@ggx.Model.declare(name='GPT-4', provider='openai', model='gpt-4', ownership_type='Proprietary', model_type='LLM')def gpt4(text: str, *, cache: dict = {}): """GPT-4 model wrapper.""" # -- BEGIN DEFINITION -- # Implementation return {"response": "..."}
@ggx.Pipeline.declare(name='Q&A Pipeline', pipeline_type='Chat based - OpenAI Spec')def qa_pipeline( user_message: str, history: list[t.TypedDict("T", {'role': str, 'content': str}, total=False)] = (), context: t.Optional[dict[str, str]] = None, *, cache: dict = {}): """Q&A pipeline combining prompt and model.""" # -- BEGIN DEFINITION -- prompt = system_prompt() response = gpt4(f"{prompt}\n{user_message}") return {"output": response["response"]}
# Sync only the pipeline - dependencies sync automaticallyggx.sync(qa_pipeline)Independent vs. Pipeline Usage
Section titled “Independent vs. Pipeline Usage”Independent Sync
Section titled “Independent Sync”You can declare and sync components without using them in a pipeline:
# Declare a standalone prompt@ggx.Prompt.declare(name='Greeting Prompt', group='Standalone')def greeting_prompt(*, cache: dict = {}, prompt: str = "Hello! How can I help you today?"): """Greeting message prompt.""" # -- BEGIN DEFINITION -- return prompt
# Sync it independentlyggx.sync(greeting_prompt)Pipeline Integration
Section titled “Pipeline Integration”Or use components together in a pipeline (they’ll sync automatically):
@ggx.Pipeline.declare(name='Greeter Bot', pipeline_type='Chat based - OpenAI Spec')def greeter_pipeline( user_message: str, history: list[t.TypedDict("T", {'role': str, 'content': str}, total=False)] = (), context: t.Optional[dict[str, str]] = None, *, cache: dict = {}): """Simple greeter pipeline.""" # -- BEGIN DEFINITION -- prompt = greeting_prompt() # References the prompt return {"output": prompt}
ggx.sync(greeter_pipeline) # Syncs both prompt and pipelineMetadata Parameters Reference
Section titled “Metadata Parameters Reference”Common Parameters (All Components)
Section titled “Common Parameters (All Components)”name(str, optional): Display name on platform. Defaults to function name.group(str, optional): Organizational grouping. Must exist on platform.
Prompt-Specific Parameters
Section titled “Prompt-Specific Parameters”task_type(str, optional):'Classification'|'Question Answering'|'Information Extraction'|'Summarization'|'Code Generation'|'Transformation'|'Generation'|'Others'prompt_type(str, optional):'System Instruction'|'User Prompt'|'Others'prompt_elements(list, optional): List of components:['Persona + Goal', 'Tone', 'Task', 'Constraints', 'Context', 'Examples', 'Reasoning Steps', 'Output Format', 'Recap']
Model-Specific Parameters
Section titled “Model-Specific Parameters”ownership_type(str, optional):'Open Source'|'Proprietary'model_type(str, optional):'LLM'|'Text Embedding'|'Guardrail'|'Judge Model'|'Others'provider(str, optional): Provider identifier (e.g.,'openai','google','anthropic'). If provided, model is treated as API-based.model(str, optional): Specific model identifier (e.g.,'gpt-4','gemini-pro','claude-3-opus'). Required if provider is specified.
RAG-Specific Parameters
Section titled “RAG-Specific Parameters”knowledge_base_format(str, optional):'Vector Database'|'Graph Database'|'Relational Database'|'External Web-Search APIs'|'NoSQL'|'Document'|'Others'provider(str, optional): Provider identifier for API-based RAG systems.
Pipeline-Specific Parameters
Section titled “Pipeline-Specific Parameters”usecase_type(str, optional):'Question Answering'|'Summarization'|'Translation'task_type(str, optional):'Classification'|'Templated Responses'|'Generative Responses'|'Summarization'|'Others'impact(str, optional):'External Facing'|'Internal Only'|'Internal - with external implications'data_usage(list, optional): List of data types:['No Additional Data', 'General Public Data', 'Internal Policies/Data', 'Customer Specific Data']pipeline_type(str, required):'Chat based - OpenAI Spec'|'Custom Return Type'
Global Function Parameters
Section titled “Global Function Parameters”name(str, optional): Display name on platform. Defaults to function name.group(str, optional): Organizational grouping. Must exist on platform.
Report-Specific Parameters
Section titled “Report-Specific Parameters”object_types(list, required): List of object types the report evaluates (e.g.,['PIPELINE', 'FOUNDATION_MODEL', 'PROMPT'])name(str, optional): Display name on platform. Defaults to function name.group(str, optional): Organizational grouping. Must exist on platform.risk_type(str, optional):'Accuracy'|'Stability'|'Bias'|'Vulnerability'|'Toxicity'|'Others'task_type(str, optional):'Classification'|'Templated Responses'|'Generative Responses'|'Summarization'|'Others'risk_domain(str, optional):'Model Risk Management'|'Fair Lending'|'Technology'|'Infosec'|'Others'evaluation_methodology(str, optional):'LLM-as-a-Judge'|'Rule-based'|'Statistical / ML Algorithms'|'Others'report_methodology(str, optional): Free-text description of the methodologyparameters(list, optional): List of parameter dictionaries for report execution
Complete Workflow Example
Section titled “Complete Workflow Example”import genguardx as ggximport typing as t
# Step 1: Initializeggx.init( api_url="https://devaisandbox.corridorplatforms.com", api_key="your-api-key-here",)
# Step 2: Declare components@ggx.Prompt.declare( name='FAQ Prompt', group='Support', task_type='Question Answering', prompt_type='System Instruction',)def faq_prompt(*, cache: dict = {}, prompt: str = "Answer FAQs concisely and professionally."): """System prompt for FAQ bot.""" # -- BEGIN DEFINITION -- return prompt
@ggx.Model.declare( name='GPT-3.5', group='Models', ownership_type='Proprietary', model_type='LLM', provider='openai', model='gpt-3.5-turbo',)def gpt35(text: str, *, cache: dict = {}): """GPT-3.5 Turbo model wrapper.""" # -- BEGIN DEFINITION -- # Implementation here return {"response": "..."}
@ggx.Pipeline.declare( name='FAQ Bot', group='Support', usecase_type='Question Answering', task_type='Templated Responses', impact='External Facing', data_usage=['General Public Data'], pipeline_type='Chat based - OpenAI Spec',)def faq_pipeline( user_message: str, history: list[t.TypedDict("T", {'role': str, 'content': str}, total=False)] = (), context: t.Optional[dict[str, str]] = None, *, cache: dict = {}): """Complete FAQ pipeline.""" # -- BEGIN DEFINITION -- prompt = faq_prompt() response = gpt35(f"{prompt}\n\nQuestion: {user_message}") return {"output": response["response"]}
# Step 3: Sync (syncs all dependencies automatically)ggx.sync(faq_pipeline)Best Practices
Section titled “Best Practices”✅ Do’s
Section titled “✅ Do’s”- Always use the anchor comment:
# -- BEGIN DEFINITION -- - Validate groups exist: Check your platform for valid group names before declaring
- Use type annotations: Help the platform understand your data types
- Test locally first: Run your functions before syncing to catch errors
- Use meaningful names: Choose descriptive names for components
- Include the cache parameter: Even if unused, include
cache: dict = {} - Write clear docstrings: Document what each component does
❌ Don’ts
Section titled “❌ Don’ts”- Don’t hardcode secrets: Use environment variables for API keys and passwords
- Don’t skip the cache parameter: Required for all component functions
- Don’t sync without testing: Ensure functions work locally first
- Don’t use undefined groups: Verify group names exist on your platform instance
- Don’t forget the anchor comment: Missing anchor will cause sync errors
Troubleshooting
Section titled “Troubleshooting””Group not found” Warning
Section titled “”Group not found” Warning”Problem: Warning message: ├ [WARN] Group "YourGroupName" not found: Ignoring the group
Cause: The group specified in your declaration doesn’t exist on the platform.
Solution:
- Check available groups in your platform UI
- Create the group in platform settings first
- Or remove the
groupparameter (it will default to None or the existing component’s group)
Note: This is a warning, not an error - the sync will still complete successfully.
”Expected anchor comment” Error
Section titled “”Expected anchor comment” Error”Problem: Error message: AssertionError: Expected anchor comment # -- BEGIN DEFINITION -- to be present in source. Found None
Cause: Your function is missing the required # -- BEGIN DEFINITION -- anchor comment.
Solution: Add the anchor comment before your function’s core logic:
import genguardx as ggx@ggx.Prompt.declare(name='My Prompt')def my_prompt(*, cache: dict = {}, prompt: str = "Hello"): """Docstring here""" # -- BEGIN DEFINITION -- # <-- Add this line return prompt“Skipping X - not declared as a Corridor object” Warning
Section titled ““Skipping X - not declared as a Corridor object” Warning”Problem: Warning message: [WARN] Skipping "function_name" - as it is not declared as a Corridor object
Cause: Your pipeline references a function that doesn’t have a @declare() decorator.
Solution: Add the appropriate decorator to the referenced function:
import genguardx as ggx# Before (causes warning)def helper_function(): return "result"
# After (no warning)@ggx.Prompt.declare(name='Helper')def helper_function(*, cache: dict = {}, prompt: str = "result"): # -- BEGIN DEFINITION -- return promptNote: This is a warning - the sync completes, but the dependency won’t be tracked or synced.
Invalid Metadata Values Warning
Section titled “Invalid Metadata Values Warning”Problem: Warning messages like:
├ [WARN] Task Type "YourTaskType" is invalid: Ignoring the Task Type├ [WARN] Prompt Type "YourPromptType" is invalid: Ignoring the Prompt Type
Cause: The value provided for a metadata parameter doesn’t match the allowed values.
Solution: Check the Metadata Parameters Reference section above for the exact valid values. For example:
- Task Type must be one of:
'Classification','Question Answering','Information Extraction', etc. - Prompt Type must be one of:
'System Instruction','User Prompt','Others'
Note: This is a warning - the sync completes, but the invalid metadata field is ignored.
”Prompt must be a kwarg named ‘prompt’” Error
Section titled “”Prompt must be a kwarg named ‘prompt’” Error”Problem: Error message: ValueError: Prompt "your_prompt_name" must be a kwarg names: "prompt" which contains the prompt template as the default value
Cause: Prompt functions require a specific parameter format.
Solution: Add prompt: str = "your template" as a keyword-only parameter:
import genguardx as ggx@ggx.Prompt.declare(name='My Prompt')def my_prompt(*, cache: dict = {}, prompt: str = "Your prompt text here"): """Docstring""" # -- BEGIN DEFINITION -- return promptType Hint Error for dict/list
Section titled “Type Hint Error for dict/list”Problem: Error message: Unable to process type hint: '<class 'dict'>' as the dict has no inner type
Cause: Using bare dict or list types without specifying inner types.
Solution: Use proper type hints with inner types:
# Badcontext: dict = None
# Goodcontext: dict[str, str] = Nonecontext: t.Optional[dict[str, str]] = None
# For listshistory: list = () # Badhistory: list[dict[str, str]] = () # GoodAdditional Resources
Section titled “Additional Resources”- Platform Documentation: Contact your platform administrator for instance-specific docs
- API Reference: Available in your GenGuardX instance
- Support: Contact your platform administrator or support team