Complete reference for agent_config.yaml and prompts.yaml configuration files.
Perpendicularity uses two main configuration files:
config/agent_config.yaml- Models, agents, MCP servers, loggingconfig/prompts.yaml- System prompts for different reasoning strategies
Both are YAML files with a hierarchical structure supporting defaults and inheritance.
# config/agent_config.yaml
default_model: "model_name" # Which model to use by default
models: # Model configurations
defaults: {...} # Class-level defaults
model_name: {...} # Specific model instances
agent: # Agent behavior
type: "langgraph" # Agent type
max_steps: 5 # Reasoning steps
verbose: true # Show reasoning
recursion_limit: 25 # LangGraph limit
system_prompt: "default" # Prompt name
mcp_servers: # MCP server connections
server_name:
url: "http://..."
transport: "streamable-http"
logging: # Logging configuration
level: "INFO"Location: Top-level default_model key
Purpose: Model used when --model flag not specified
Example:
# Use cloud model by default
default_model: "gemini"
# Or use local model by default
default_model: "ollama_qwen14b"Recommendation:
- Development: Use local model (
ollama_qwen14b) - Production: Use reliable cloud model (
geminiorclaude)
Location: models.defaults
Purpose: Define common settings for all models of a type
Available Model Classes:
gemini- Google Gemini modelsanthropic- Anthropic Claude modelsopenai- OpenAI-compatible API (Ollama, vLLM, etc.)transformers- HuggingFace Transformers (direct loading)
Example:
models:
defaults:
# Gemini class defaults
gemini:
api_key_env: "GOOGLE_API_KEY" # Environment variable for API key
temperature: 0.4 # Randomness (0.0-1.0)
max_tokens: 8192 # Maximum response length
top_p: 0.95 # Nucleus sampling
# Anthropic (Claude) class defaults
anthropic:
api_key_env: "ANTHROPIC_API_KEY"
temperature: 0.4
max_tokens: 8192
top_p: 0.95
# OpenAI-compatible (Ollama) class defaults
openai:
base_url: "http://localhost:11434/v1" # API endpoint
temperature: 0.4
max_tokens: 4096
top_p: 0.95
# HuggingFace Transformers class defaults
transformers:
device: "auto" # "auto", "cuda", "cpu"
dtype: "auto" # "auto", "float16", "float32"
load_in_4bit: false # 4-bit quantization
load_in_8bit: true # 8-bit quantization
trust_remote_code: true # Allow custom code
low_cpu_mem_usage: true # Optimize memory
temperature: 0.4
max_tokens: 4096
top_p: 0.95Parameters Explained:
| Parameter | Type | Range | Description |
|---|---|---|---|
temperature |
float | 0.0-2.0 | Controls randomness. 0.0=deterministic, 1.0=creative |
max_tokens |
int | 1-32768 | Maximum response length in tokens |
top_p |
float | 0.0-1.0 | Nucleus sampling threshold |
api_key_env |
string | - | Environment variable containing API key |
base_url |
string | - | API endpoint URL |
device |
string | - | Computing device: "auto", "cuda", "cpu" |
dtype |
string | - | Data type: "auto", "float16", "float32" |
load_in_4bit |
bool | - | Use 4-bit quantization (saves VRAM) |
load_in_8bit |
bool | - | Use 8-bit quantization (saves VRAM) |
Location: models.<model_name>
Purpose: Define specific models, inheriting from class defaults
Required Fields:
type- Model class (gemini,anthropic,openai,transformers)name- Model identifier (varies by type)
Optional Fields: Any parameter from class defaults can be overridden
Cloud Model Examples:
# Gemini models (Google AI)
gemini:
type: "gemini"
name: "gemini-2.5-flash"
# Inherits everything from defaults.gemini
# Can override: temperature, max_tokens, etc.
gemini_pro:
type: "gemini"
name: "gemini-2.0-pro"
temperature: 0.3 # Override: more deterministic
# Claude models (Anthropic)
claude:
type: "anthropic"
name: "claude-sonnet-4-20250514"
claude_opus:
type: "anthropic"
name: "claude-opus-4-20250514"
max_tokens: 16384 # Override: longer responsesOllama Model Examples:
# Ollama models (via OpenAI-compatible API)
ollama_qwen14b:
type: "openai"
name: "qwen2.5:14b-instruct"
# Inherits base_url from defaults.openai
ollama_qwen32b:
type: "openai"
name: "qwen2.5:32b-instruct"
ollama_deepseek:
type: "openai"
name: "deepseek-r1:8b"
# Custom Ollama endpoint
ollama_remote:
type: "openai"
name: "qwen2.5:14b-instruct"
base_url: "http://remote-server:11434/v1" # OverrideHuggingFace Model Examples:
# HuggingFace models (direct loading)
hf_qwen14b:
type: "transformers"
model_name: "Qwen/Qwen2.5-14B-Instruct"
load_in_8bit: true # ~14GB VRAM
hf_qwen32b:
type: "transformers"
model_name: "Qwen/Qwen2.5-32B-Instruct"
load_in_4bit: true # ~18GB VRAM
dtype: "float16" # Override: explicit dtype
hf_deepseek:
type: "transformers"
model_name: "deepseek-ai/DeepSeek-R1-Distill-Llama-8B"
load_in_8bit: true
# Custom quantization
hf_custom:
type: "transformers"
model_name: "my-org/my-model"
load_in_4bit: true
device: "cuda:1" # Specific GPU
trust_remote_code: false # Security: disable custom codeLocation: agent section
Controls: Agent behavior, reasoning, and execution
Full Example:
agent:
# Agent type: "langgraph" (production) or "react" (educational)
type: "langgraph"
# Maximum reasoning steps (ReAct) or recursion depth (LangGraph)
max_steps: 5
# Show step-by-step reasoning
verbose: true
# LangGraph-specific: Maximum recursion depth before stopping
recursion_limit: 25
# Maximum concurrent tool executions
max_concurrent_tools: 5
# Tool execution timeout in seconds
tool_timeout_seconds: 180
# System prompt name from prompts.yaml
system_prompt: "default"Parameter Details:
Values: "langgraph" or "react"
Default: "langgraph"
Purpose: Choose agent implementation
# Production (recommended)
type: "langgraph"
# Educational/debugging
type: "react"See Agents Guide for detailed comparison.
Type: Integer
Default: 5
Purpose:
- ReAct: Maximum number of reasoning steps
- LangGraph: Used for UI display only (not limiting)
# For simple queries
max_steps: 3
# For complex analyses
max_steps: 10
# For very complex multi-stage tasks
max_steps: 20Type: Boolean
Default: true
Purpose: Show step-by-step reasoning in output
# Show reasoning (recommended for development)
verbose: true
# Hide reasoning (only final answer)
verbose: falseType: Integer
Default: 25
Purpose: Maximum graph recursions before stopping
# Standard limit
recursion_limit: 25
# For very complex tasks
recursion_limit: 50
# Tight limit (for testing)
recursion_limit: 10Type: Integer
Default: 5
Purpose: Maximum parallel tool executions
# Conservative (sequential)
max_concurrent_tools: 1
# Balanced
max_concurrent_tools: 5
# Aggressive (faster but more resource-intensive)
max_concurrent_tools: 10Type: Integer
Default: 180 (3 minutes)
Purpose: Maximum time to wait for tool execution
# Short timeout (for fast tools)
tool_timeout_seconds: 60
# Standard timeout
tool_timeout_seconds: 180
# Long timeout (for slow external APIs)
tool_timeout_seconds: 300Type: String (prompt name from prompts.yaml)
Default: "default"
Purpose: Which system prompt to use
# Balanced (default)
system_prompt: "default"
# Safety-focused
system_prompt: "conservative"
# Creative exploration
system_prompt: "exploratory"
# Genomics specialist
system_prompt: "genomics"Location: mcp_servers section
Purpose: Configure connections to Model Context Protocol servers
Structure:
mcp_servers:
server_name:
url: "http://server:port/mcp"
transport: "streamable-http" # or "sse", "stdio"
headers: # Optional
Authorization: "Bearer token"
X-Custom: "value"
env: # Optional (for stdio transport)
API_KEY: "key"Transport Types:
Use: Modern MCP servers with bidirectional HTTP streaming
genomic_ops:
url: "http://ec2-instance:8000/mcp"
transport: "streamable-http"Use: Legacy servers with unidirectional streaming
legacy_server:
url: "http://server:3000/sse"
transport: "sse"
headers:
Authorization: "Bearer token"Use: Local processes
local_tool:
command: ["python", "/path/to/server.py"]
transport: "stdio"
env:
SOME_KEY: "value"Complete Example:
mcp_servers:
# GenomicOps-MCP (genomic analysis)
genomic_ops:
url: "http://ec2-3-78-244-11.eu-central-1.compute.amazonaws.com:8000/mcp"
transport: "streamable-http"
# TxGemma-MCP (therapeutics evaluation)
txgemma:
url: "http://ec2-3-122-119-69.eu-central-1.compute.amazonaws.com:8000/mcp"
transport: "streamable-http"
# Custom server with authentication
custom_server:
url: "https://api.example.com/mcp"
transport: "streamable-http"
headers:
Authorization: "Bearer your-token-here"
X-API-Version: "v1"
# Local stdio server
local_processor:
command: ["python", "-m", "my_mcp_server"]
transport: "stdio"
env:
DATABASE_URL: "postgresql://..."Setting Up MCP Servers:
- GenomicOps-MCP: Setup Guide
- TxGemma-MCP: Setup Guide
See MCP Servers Guide for detailed integration.
Location: logging section
Purpose: Control logging verbosity and format
Example:
logging:
level: "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"Log Levels:
| Level | When to Use | What You See |
|---|---|---|
DEBUG |
Development, debugging | Everything including internal details |
INFO |
Normal operation | Important events and agent steps |
WARNING |
Production | Warnings and errors only |
ERROR |
Production (quiet) | Errors only |
CRITICAL |
Production (very quiet) | Critical errors only |
Examples:
# Development
logging:
level: "DEBUG"
# Production
logging:
level: "WARNING"
# Custom format
logging:
level: "INFO"
format: "[%(levelname)s] %(message)s"Location: config/prompts.yaml
Purpose: System prompts for different reasoning strategies
Structure:
# config/prompts.yaml
prompt_name: |
System prompt text goes here.
Can be multi-line.
Provides context and instructions to the LLM.Name: default
Use: General drug discovery and therapeutic research
default: |
You are an expert therapeutic agent specializing in drug discovery and genomics.
You have access to specialized tools that are listed at the start of each task.
Your goals:
1. Provide accurate, evidence-based answers
2. Prioritize drug safety in all recommendations
3. USE YOUR AVAILABLE TOOLS to gather information - don't just theorize
4. Think step-by-step through complex problems
5. Clearly explain your reasoning and cite tool outputs
Critical: You have tools available - USE THEM actively to answer questions.
Don't describe what you would do - actually do it by calling the appropriate tools.
When approaching a question:
- Review the available tools and identify which ones can help
- Use tools to gather data before drawing conclusions
- If a tool can answer part of your question, call it
- Synthesize tool outputs into comprehensive answersName: conservative
Use: Safety-critical decisions, regulatory work, high-stakes evaluations
conservative: |
You are a highly cautious therapeutic agent focused on drug safety and regulatory compliance.
Your primary directive is to ensure patient safety above all else.
Safety-first approach:
1. Use ALL available toxicity and safety assessment tools before making recommendations
2. Flag any safety concerns prominently
3. Require strong evidence for recommendations - use tools to gather it
4. When uncertain, recommend additional testing
5. Never recommend drugs with known toxicity issues
CRITICAL: Do not just think about running safety tests - ACTUALLY RUN THEM.
Look at your available tools and use every relevant toxicity/safety tool you have.
Workflow:
- Step 1: Identify all toxicity/safety assessment tools in your toolkit
- Step 2: Run comprehensive screening using those tools
- Step 3: Only after establishing safety profile, discuss efficacy
- Step 4: Make conservative, evidence-based recommendationsWhen to use:
perpendicularity ask "Which of the following drugs is preferred for further development? 1. CC(=O)OC1=CC=CC=C1C(=O)O (Aspirin) or 2. O=C(CCCCCCC(=O)Nc1ccccc1)NO?" \
--prompt conservativeName: exploratory
Use: Hypothesis generation, creative research, discovering new connections
exploratory: |
You are a creative drug discovery agent focused on finding novel therapeutic approaches.
You combine available data with pharmacological knowledge to generate hypotheses.
Your innovative approach:
1. Use your tools creatively to explore new possibilities
2. Look for unexpected patterns and connections in tool outputs
3. Consider repurposing and novel mechanisms
4. Generate testable hypotheses backed by tool-based evidence
5. Balance innovation with safety considerations
Exploration strategy:
- Use available tools to gather diverse data points
- Look for connections between genomic, molecular, and pharmacological data
- Think creatively about what different tool combinations can reveal
- Don't be afraid to use tools in novel ways to test hypotheses
Remember: Bold hypotheses should be supported by actual tool-based analysis!When to use:
perpendicularity ask "Evaluate alternative modes of action for O=C(CCCCCCC(=O)Nc1ccccc1)NO" \
--prompt exploratoryName: genomics
Use: Translational genomics, cross-species analysis, target identification
genomics: |
You are a genomics expert specializing in translational medicine.
You excel at connecting genomic findings to therapeutic opportunities.
Your systematic workflow:
1. Use genomic analysis tools to understand loci and genes
2. Use knowledge tools to understand gene functions and pathways
3. Connect genomic findings to disease mechanisms
4. Identify druggable targets and therapeutic opportunities
5. Translate findings across species when relevant
Tool usage strategy:
- Start with genomic location/annotation tools to identify genes
- Use knowledge query tools to understand gene function and relevance
- If cross-species tools are available, use them to assess conservation
- Connect genomic insights to therapeutic strategies
Execute the full genomic-to-therapeutic pipeline using your available tools.
Don't just plan - actually use each tool to build the complete picture.When to use:
perpendicularity ask "AFor genomic locus chr15:61857240-61862199, get gene annotations in humans, evaluate therapeutic relevance, and suggest any drugs that may act on these genes." \
--prompt genomicsAdd your own prompts for specific workflows:
# Custom prompt for specific disease area
oncology: |
You are an oncology-focused therapeutic agent.
Specialized in cancer drug discovery and precision oncology.
Always consider:
1. Tumor heterogeneity
2. Resistance mechanisms
3. Combination therapy potential
4. Biomarker-driven approaches
# Custom prompt for specific methodology
structure_based: |
You are a structure-based drug design specialist.
Focus on molecular interactions and binding affinity.
Prioritize:
1. Protein-ligand interactions
2. Binding pocket analysis
3. Structure-activity relationships
4. Optimization of lead compoundsInstead of:
models:
ollama_model1:
type: "openai"
base_url: "http://localhost:11434/v1"
temperature: 0.4
ollama_model2:
type: "openai"
base_url: "http://localhost:11434/v1" # Repeated!
temperature: 0.4 # Repeated!Do:
models:
defaults:
openai:
base_url: "http://localhost:11434/v1"
temperature: 0.4
ollama_model1:
type: "openai"
name: "qwen2.5:14b-instruct"
ollama_model2:
type: "openai"
name: "mistral:7b-instruct"Never hardcode API keys:
# ❌ Bad - hardcoded key
gemini:
type: "gemini"
api_key: "AIza..." # Never do this!Use environment variables:
# ✅ Good - environment variable
models:
defaults:
gemini:
api_key_env: "GOOGLE_API_KEY" # References $GOOGLE_API_KEY# Development
config/agent_config.dev.yaml
default_model: "ollama_qwen14b"
# Production
config/agent_config.prod.yaml
default_model: "gemini"Usage:
perpendicularity ask "question" --config config/agent_config.dev.yaml
perpendicularity ask "question" --config config/agent_config.prod.yaml# config/agent_config.yaml
# Custom configuration for oncology research project
# Last updated: 2025-02-22
# Contact: researcher@institution.edu
default_model: "ollama_qwen32b" # High quality local model
models:
# Development model (fast iteration)
ollama_qwen14b:
type: "openai"
name: "qwen2.5:14b-instruct"
# Fast, good quality, 8GB VRAM
# Production model (best quality)
ollama_qwen32b:
type: "openai"
name: "qwen2.5:32b-instruct"
# Slower but higher quality, 18GB VRAM
# ... rest of config with comments# Python validation
python -c "import yaml; yaml.safe_load(open('config/agent_config.yaml'))"
# If no output, config is valid
# If error, shows line number and issue# Dry run (validates without executing)
perpendicularity ask "test" --dry-run
# List configured models
perpendicularity list-models
# List configured prompts
perpendicularity list-prompts- Getting Started - Basic configuration
- Models Guide - Model options and recommendations
- Agents Guide - Agent types and settings
- MCP Servers Guide - MCP server integration
- CLI Guide - Using
--configflag
Configure Perpendicularity for your specific needs! ⚙️
For questions, see Troubleshooting or open an issue.