Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

LLM Comparison WebApp

This Blazor web application allows you to compare responses from multiple Large Language Models (LLMs) across different providers including OpenAI, Google Gemini, Anthropic Claude, Amazon Bedrock, and locally hosted models via Ollama.

I wanted an easy way to iterate on instruction driven prompts for crafting agents and other specialist personas.

Uses and limitations

At the moment the system allows for a system prompt and one user prompt in order to set the persona and LLM instruction. This is ideal for building text and image driven personas

It will only take a single shot prompt at the moment.

It doesn't have a way to handle media generation.

🚀 Supported Providers & Models

The models here are just the ones I was interested in testing. Adding new models is trivial. Adding new providers is not hard but will require code modifications.

OpenAI

  • GPT-4o
  • GPT-3.5-Turbo

Google Gemini

  • Gemini 2.5 Pro
  • Gemini 2.5 Flash
  • Gemini 2.5 Flash Lite
  • Gemini 1.5 Pro
  • Gemini 1.5 Flash

Anthropic Claude (Direct API)

  • Claude 4 Opus
  • Claude 4 Sonnet
  • Claude 3 Opus
  • Claude 3 Sonnet
  • Claude 3 Haiku

Amazon Bedrock

  • Anthropic Models: Claude Opus 4, Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet v2, Claude 3.5 Sonnet, Claude 3.5 Haiku, Claude 3 series
  • Amazon Nova: Nova Pro, Nova Lite, Nova Micro, Nova Canvas (image generation), Nova Reel (video generation)
  • Cross-Region Support: US inference profiles for better availability

Ollama (Local Models)

  • Llava (Vision-Language Model)
  • Any other models you have installed locally

📋 Prerequisites

  • .NET 8 SDK
  • Docker (optional, for running local models with Ollama)
  • Internet connection for cloud-based models
  • API keys for the providers you want to use

⚙️ Configuration

The application uses a scalable configuration system where providers and models are defined separately. You can enable/disable providers and their models will automatically appear in the UI.

A concrete example for the Ollama provider is included in appsettings.json. For development, you should copy the LlmSettings section to appsettings.Development.json and enable the providers you want to use, adding your API keys.

Configuration Structure

Open appsettings.Development.json and configure the providers you want to use. Models are now nested under each provider.

{
"LlmSettings": {
"Providers": {
"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
}
]
}
}
}
}

Provider-Specific Setup

🔑 OpenAI

  1. Get API key from OpenAI Platform
  2. Set OpenAI.ApiKey in configuration
  3. Set OpenAI.Enabled to true

🔑 Google Gemini

  1. Get API key from Google AI Studio
  2. Set Google.ApiKey in configuration
  3. Set Google.Enabled to true

🔑 Anthropic Claude

  1. Get API key from Anthropic Console
  2. Set Anthropic.ApiKey in configuration
  3. Set Anthropic.Enabled to true

🔑 Amazon Bedrock

  1. Configure AWS credentials:
    aws configure
    # OR set environment variables:# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
  2. Enable model access in AWS Bedrock Console
  3. Set Bedrock.Region to your preferred region (e.g., "us-east-1")
  4. Set Bedrock.Enabled to true

🔑 Ollama (Local Models)

  1. Install and run Ollama:
    # Using Docker
    docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
    # Pull a vision model
    docker exec ollama ollama pull llava
  2. Verify Ollama is running at http://localhost:11434
  3. Set Ollama.Enabled to true

Adding providers

Where possible I have tried to use the Microsoft Semantic Kernel. It's early days for this project but I suspect it will mature and become a useful abstraction over all providers. Most connectors were in alpha at the time of writing this so I expect some things to be sub-optimal.

I've had to use more direct integrations for OpenAI and Bedrock.

When adding a new provider do try to use the semantic kernel first. The code is fairly straight forward right now but it might be nice to further abstract the provider/model architecture to allow for drop-in registration.

🚀 Getting Started

  1. Clone and Build

    git clone <repository-url>cd LLMComparison.WebApp
    dotnet restore
    dotnet build
  2. Configure Providers

    • Copy the LlmSettings section from appsettings.json to appsettings.Development.json.
    • In appsettings.Development.json, enable the providers you want to use and add your API keys.
  3. Run the Application

    dotnet run
  4. Access the Application

    • Open your browser and navigate to the URL shown in the console.
    • By default, the application runs on https://localhost:7084 and http://localhost:5214. You can find the exact ports in Properties/launchSettings.json.
    • The Home page will show available models from your enabled providers
    • Select a model and enter your prompt to compare responses

🔧 Adding New Models

The application uses a dynamic configuration system. To add new models, add them to the Models list under the desired provider in appsettings.Development.json. The model will automatically appear in the UI if its provider is enabled.

Example model configuration for OpenAI:

"OpenAI": {
"ApiKey": "YOUR_OPENAI_API_KEY",
"BaseUrl": "https://api.openai.com/v1",
"Enabled": true,
"Models": [
{
"Id": "gpt-4o",
"DisplayName": "GPT-4o",
"MaxTokens": 128000,
"SupportsImages": true,
"Category": "Chat"
},
{
"Id": "gpt-3.5-turbo",
"DisplayName": "GPT-3.5-Turbo",
"MaxTokens": 16000,
"SupportsImages": false,
"Category": "Chat"
}
]
}

📱 Features

  • Multi-Provider Support: Compare responses across different AI providers
  • Vision Models: Upload and analyze images with vision-capable models
  • Real-time Comparison: Side-by-side response comparison
  • Flexible Configuration: Easy provider and model management
  • Local Model Support: Run models locally with Ollama
  • Enterprise Ready: Support for AWS Bedrock and other enterprise solutions

📝 Default Prompts

You can create a default-prompts.json file in the project root to set up prompt templates that will appear in a dropdown in the UI. This file should not be committed to version control as it contains your personal prompt preferences.

Setup

  1. Copy default-prompts.example.json to default-prompts.json
  2. Customize the prompts to suit your needs
  3. The first prompt in the file will be loaded as the default

Structured Prompts for Better Agent Building

The prompt system supports structured JSON prompts which are superior for building reliable AI agents. Instead of plain text instructions, you can provide detailed JSON structures that give the AI clear, unambiguous guidance.

Example: Simple Text Prompt

{
"simpleAssistant": {
"name": "General AI Assistant",
"description": "Basic conversational AI",
"systemPrompt": "You are a helpful AI assistant.",
"userPrompt": "Hello! How can I help you today?"
}
}

Example: Structured JSON Prompt (Recommended for Agents)

{
"documentAnalysis": {
"name": "Document Analysis Agent",
"systemPrompt": "You are a document validation expert. Never deviate from instructions.",
"userPrompt": {
"instructions": {
"task": "Analyze documents and extract information in JSON format",
"responseFormat": [
{
"documentValidation": {
"docType": "Document type",
"confidence": "High/Medium/Low",
"reason": "Reasoning for confidence"
}
}
],
"requirements": ["Only respond in JSON", "One object per document"]
}
}
}
}

Supported Prompt Formats

  • JSON Structure: For complex agents with detailed instructions
  • Plain Text: For simple conversational prompts
  • XML Structure: For hierarchical task breakdown
  • Markdown: For documentation and formatting-heavy tasks

The example file (default-prompts.example.json) includes examples of all these formats to help you build effective prompts for your specific use cases.

If no default-prompts.json file exists, the UI will show blank text boxes with helpful placeholder text.## 🎯 How to Use

  1. Select the model you want to test from the dropdown menu.
  2. (Optional) Choose a prompt template from the dropdown, or enter custom prompts directly.
  3. Enter or modify the system prompt and user prompt in the text areas.
  4. Optionally, attach any images or documents you want to include in the prompt.
  5. Click the "Submit" button to send the prompt to the selected model.
  6. The response will appear in the "Comparison Results" table below the input form.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Simple webapp to compare one-shot prompt responses from various providers/models

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages