diff --git a/03.0-CoreGenerativeAITechniques-Overview/README.md b/03.0-CoreGenerativeAITechniques-Overview/README.md new file mode 100644 index 0000000..8592f02 --- /dev/null +++ b/03.0-CoreGenerativeAITechniques-Overview/README.md @@ -0,0 +1,163 @@ +# Core Generative AI Techniques - Overview + +Welcome to the **Core Generative AI Techniques** learning path! This comprehensive series teaches you practical skills for building AI-enabled .NET applications through hands-on examples and real-world scenarios. + +--- + +## šŸ“š Course Structure + +We've organized the Core Generative AI content into focused lessons that build upon each other: + +### **Lesson 03.0 – Core Generative AI Techniques (Overview)** +*šŸŽÆ You are here! High-level introduction and learning path guide.* + +This overview provides the roadmap for all Core Generative AI lessons and helps you choose the best starting point based on your experience and needs. + +--- + +### **Lesson 03.1 – Text-based Techniques (with `.NET run app.cs`)** +*šŸš€ Modern single-file demos using .NET 10* + +**New!** Modernized version featuring simplified single-file C# programs: +- **LLM Completions** - Basic text generation and analysis +- **Chat Flows** - Interactive conversations with memory +- **Prompt Engineering Patterns** - Effective AI communication + +**Perfect for:** Developers who want to get started quickly with minimal setup + +šŸ‘‰ **[Start with Lesson 03.1](../03.1-CoreGenerativeAITechniques-runapp/readme.md)** + +--- + +### **Lesson 03.2 – Extending Models with Context** +*šŸ”§ Advanced AI capabilities and integrations* + +- **Functions and Plugins** - Extending AI with custom tools +- **Retrieval Augmented Generation (RAG)** - AI + knowledge bases +- **Structured Outputs / JSON Mode** - Type-safe AI responses + +**Perfect for:** Building production applications with complex requirements + +šŸ‘‰ **[Start with Lesson 03.2](../03-CoreGenerativeAITechniques/01-lm-completions-functions.md)** + +--- + +### **Lesson 03.3 – Beyond Text** +*šŸŽØ Multimodal AI capabilities* + +- **Multi-modal Generative AI** - Text + vision analysis +- **Image Generation** - DALL-E and gpt-image-1 models +- **Video Generation** - Azure OpenAI Sora integration +- **Speech-to-text-to-LLM** - Audio processing workflows + +**Perfect for:** Creating rich, multimedia AI experiences + +šŸ‘‰ **[Start with Lesson 03.3](../03-CoreGenerativeAITechniques/03-vision-audio.md)** + +--- + +### **Lesson 03.4 – Intro to Agents** +*šŸ¤– Autonomous AI systems* + +- **Basic Agent Loop** - Reasoning and action cycles +- **Agent Planning** - Multi-step problem solving +- **Tool Integration** - Agents with external capabilities +- **Teaser for Lesson 04** - Full agent frameworks + +**Perfect for:** Building intelligent, autonomous applications + +šŸ‘‰ **[Start with Lesson 03.4](../03-CoreGenerativeAITechniques/04-agents.md)** + +--- + +## šŸŽÆ Choose Your Learning Path + +### **šŸš€ Quick Start Path** *(Recommended for beginners)* +1. **Lesson 03.1** - Get hands-on with single-file demos +2. **Lesson 03.2** - Add advanced capabilities +3. **Lesson 04** - See it all in action with [Practical Samples](../04-PracticalSamples/readme.md) + +### **šŸ”¬ Comprehensive Path** *(For thorough understanding)* +1. **Lesson 03.1** - Modern development patterns +2. **Lesson 03.2** - Production-ready features +3. **Lesson 03.3** - Multimodal capabilities +4. **Lesson 03.4** - Agent fundamentals +5. **Lesson 04** - Real-world applications + +### **šŸŽØ Multimodal Focus Path** *(For multimedia applications)* +1. **Lesson 03.1** - Core concepts +2. **Lesson 03.3** - Vision, audio, and video +3. **Lesson 05** - [App Creation Examples](../05-AppCreatedWithGenAI/readme.md) + +### **šŸ¤– Agent Development Path** *(For autonomous systems)* +1. **Lesson 03.1** - Foundation skills +2. **Lesson 03.2** - Tools and functions +3. **Lesson 03.4** - Agent patterns +4. **Lesson 04** - [Practical Agent Examples](../04-PracticalSamples/readme.md) + +--- + +## šŸ› ļø Prerequisites + +### **For All Lessons:** +- Basic C# and .NET knowledge +- GitHub account with access to GitHub Models +- Development environment (VS Code, Visual Studio, or GitHub Codespaces) + +### **Lesson-Specific Requirements:** +- **Lesson 03.1**: .NET 10 SDK (for single-file execution) +- **Lesson 03.2+**: .NET 9+ SDK (for full project examples) +- **Lesson 03.3**: Additional packages for vision/audio (installed automatically) + +### **Setup Guides:** +- šŸ“– [Development Environment Setup](../02-SetupDevEnvironment/readme.md) +- šŸ”‘ [GitHub Models Access](../02-SetupDevEnvironment/getting-started-github-models.md) +- ā˜ļø [Azure OpenAI Setup](../02-SetupDevEnvironment/getting-started-azure-openai.md) (optional) +- šŸ  [Local Models with Ollama](../02-SetupDevEnvironment/getting-started-ollama.md) (optional) + +--- + +## šŸŽ“ Learning Outcomes + +By completing the Core Generative AI Techniques lessons, you'll be able to: + +āœ… **Build AI-powered .NET applications** from concept to deployment +āœ… **Integrate multiple AI providers** (GitHub Models, Azure OpenAI, Ollama) +āœ… **Implement RAG systems** for knowledge-based applications +āœ… **Create multimodal experiences** with text, vision, and audio +āœ… **Develop AI agents** with reasoning and tool capabilities +āœ… **Apply best practices** for production AI applications + +--- + +## šŸš€ Quick Start + +**Ready to dive in?** Start with the modernized single-file demos: + +```bash +# Clone the repository +git clone https://github.com/microsoft/Generative-AI-for-beginners-dotnet +cd Generative-AI-for-beginners-dotnet + +# Set up your GitHub token +export GITHUB_TOKEN="your_token_here" + +# Run your first AI demo +cd 03.1-CoreGenerativeAITechniques-runapp/src +dotnet run 01-llm-completion.cs +``` + +--- + +## šŸ“š Additional Resources + +- **[What's New](../10-WhatsNew/readme.md)** - Latest features and updates +- **[Practical Samples](../04-PracticalSamples/readme.md)** - Complete applications +- **[App Creation Examples](../05-AppCreatedWithGenAI/readme.md)** - Full-stack AI apps +- **[Responsible AI](../09-ResponsibleGenAI/readme.md)** - Ethics and best practices + +--- + +> šŸ™‹ **Questions?** Open an issue in the repository or check out our [community discussions](https://github.com/microsoft/Generative-AI-for-beginners-dotnet/discussions). + +**Happy learning! šŸŽ‰** \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/QUICKSTART.md b/03.1-CoreGenerativeAITechniques-runapp/QUICKSTART.md new file mode 100644 index 0000000..d7e1d38 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/QUICKSTART.md @@ -0,0 +1,69 @@ +# Quick Start Instructions + +## šŸš€ Running Single-File AI Demos + +### Prerequisites +1. **.NET 9+ SDK** installed +2. **GitHub Token** with access to GitHub Models + +### Setup +```bash +# Set your GitHub token (choose one method): + +# Option 1: Environment variable (recommended) +export GITHUB_TOKEN="your_github_token_here" + +# Option 2: User secrets (for development) +dotnet user-secrets set "GITHUB_TOKEN" "your_github_token_here" +``` + +### Run Demos +```bash +# Make script executable (first time only) +chmod +x run-demo.sh + +# Run any demo +./run-demo.sh 01-llm-completion.cs +./run-demo.sh 02-chat-flow.cs +./run-demo.sh 03-functions-and-plugins.cs +./run-demo.sh 04-retrieval-augmented-generation.cs +./run-demo.sh 05-structured-output.cs +./run-demo.sh 06-multimodal.cs + +# List available demos +./run-demo.sh +``` + +### What These Demos Show + +| Demo | Concept | Key Learning | +|------|---------|--------------| +| `01-llm-completion.cs` | Text completions | Basic AI prompting and responses | +| `02-chat-flow.cs` | Interactive chat | Conversation memory and streaming | +| `03-functions-and-plugins.cs` | Tool calling | Extending AI with custom functions | +| `04-retrieval-augmented-generation.cs` | RAG patterns | AI + knowledge bases | +| `05-structured-output.cs` | JSON responses | Type-safe AI data extraction | +| `06-multimodal.cs` | Vision AI | Image analysis capabilities | + +### Troubleshooting + +**Authentication Error?** +- Ensure your `GITHUB_TOKEN` has access to GitHub Models +- Check that the token is properly set in environment variables + +**Build Issues?** +- Make sure .NET 9+ SDK is installed +- The helper script automatically manages dependencies + +**No .NET 10?** +- These demos work on .NET 9+ using the provided script +- When .NET 10 is released, you can use `dotnet run file.cs` directly + +### Next Steps +- Experiment with different prompts and parameters +- Combine techniques from multiple demos +- Check out full applications in [Lesson 04 - Practical Samples](../../04-PracticalSamples/readme.md) + +--- + +Happy coding with .NET and AI! šŸŽ‰ \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/readme.md b/03.1-CoreGenerativeAITechniques-runapp/readme.md new file mode 100644 index 0000000..f71865a --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/readme.md @@ -0,0 +1,408 @@ +# Core Generative AI Techniques - Single-File Demos + +> šŸ’” *This lesson uses .NET 10's `dotnet run .cs` feature for ultra-simple AI demos. Each file is self-contained and runnable! Don't have .NET 10 yet? Use the provided fallback scripts (`run-demo.sh` or `run-demo.ps1`) that work with .NET 9.* + +Welcome to the modernized version of Core Generative AI Techniques! This lesson demonstrates the same powerful AI concepts as the full [Lesson 03](../03-CoreGenerativeAITechniques/readme.md), but with simplified **single-file C# demos** that showcase the elegance of .NET 10's direct file execution. + +--- + +## What you'll learn + +- 🌟 **LLM Completions** - Text generation and analysis +- šŸ’¬ **Interactive Chat** - Conversational AI with memory +- šŸ”§ **Function Calling** - Extending AI with custom tools +- šŸ” **RAG (Retrieval-Augmented Generation)** - AI + knowledge bases +- šŸ“Š **Structured Output** - Getting consistent JSON responses +- šŸ‘ļø **Multimodal AI** - Vision and image analysis +- šŸ–¼ļø **Image Generation** - Creating images with AI +- šŸ¤– **Local Models** - Running AI locally with Ollama +- ā˜ļø **Cloud Providers** - Azure OpenAI integration +- 🧠 **Vector Search** - Advanced semantic search + +## Prerequisites + +- **.NET 10 SDK** - Required for `dotnet run file.cs` functionality +- **GitHub Token** with access to GitHub Models (for most demos) +- **Azure OpenAI** (optional, for Azure-specific demos) +- **Ollama** (optional, for local AI demos) + +## Quick Setup + +1. **Set your GitHub Token** (for GitHub Models demos): + ```bash + # Environment variable (recommended) + export GITHUB_TOKEN="your_github_token_here" + + # OR user secrets for development + dotnet user-secrets set "GITHUB_TOKEN" "your_github_token_here" + ``` + +2. **Navigate to the demo directory**: + ```bash + cd 03.1-CoreGenerativeAITechniques-runapp/src + ``` + +3. **Run any demo**: + ```bash + dotnet run 01-llm-completion.cs + ``` + +## Single-File Demos + +### Core AI Techniques + +#### 1. LLM Text Completion šŸ“ +**File**: `01-llm-completion.cs` +**Concept**: Basic text completions with GitHub Models + +```bash +dotnet run 01-llm-completion.cs +``` + +Learn: +- Setting up GitHub Models client +- Creating effective prompts for sentiment analysis +- Processing single-turn AI responses +- Handling authentication and errors + +#### 2. Interactive Chat Flow šŸ’¬ +**File**: `02-chat-flow.cs` +**Concept**: Stateful conversations with memory + +```bash +dotnet run 02-chat-flow.cs +``` + +Discover: +- Maintaining conversation history +- Interactive chat experiences with streaming +- Building context-aware conversations +- User input handling and response formatting + +#### 3. Functions and Plugins šŸ”§ +**File**: `03-functions-and-plugins.cs` +**Concept**: Extending AI with custom tools + +```bash +dotnet run 03-functions-and-plugins.cs +``` + +Master: +- Function calling with Microsoft.Extensions.AI +- Creating custom AI tools/plugins +- Automatic function invocation +- Tool descriptions and parameters + +#### 4. Retrieval-Augmented Generation (RAG) šŸ” +**File**: `04-retrieval-augmented-generation.cs` +**Concept**: Simple RAG with keyword search + +```bash +dotnet run 04-retrieval-augmented-generation.cs +``` + +Explore: +- In-memory knowledge stores +- Context injection for AI responses +- Building knowledge-aware applications +- Simple search and retrieval patterns + +#### 5. Structured Output šŸ“Š +**File**: `05-structured-output.cs` +**Concept**: Getting consistent JSON responses + +```bash +dotnet run 05-structured-output.cs +``` + +Learn: +- Structured data extraction +- JSON schema compliance +- Type-safe AI responses +- Business data processing patterns + +#### 6. Multimodal AI (Vision) šŸ‘ļø +**File**: `06-multimodal.cs` +**Concept**: Analyzing images with AI + +```bash +dotnet run 06-multimodal.cs +``` + +Discover: +- Vision-enabled AI models +- Image analysis and description +- URL and local file processing +- Multimodal conversation flows + +### Provider-Specific Demos + +#### 7. Local AI with Ollama šŸ  +**File**: `07-ollama-local-models.cs` +**Concept**: Running AI models locally + +```bash +dotnet run 07-ollama-local-models.cs +``` + +Features: +- No API keys required +- Privacy-focused local processing +- Phi4-mini model integration +- Connection troubleshooting + +#### 8. Azure Image Generation šŸŽØ +**File**: `08-azure-image-generation.cs` +**Concept**: Creating images with DALL-E + +```bash +dotnet run 08-azure-image-generation.cs +``` + +Learn: +- Azure OpenAI DALL-E integration +- Image generation parameters +- Saving and displaying generated images +- Cross-platform file handling + +#### 9. Semantic Kernel Chat 🧠 +**File**: `09-semantic-kernel-chat.cs` +**Concept**: Interactive chat with SK framework + +```bash +dotnet run 09-semantic-kernel-chat.cs +``` + +Explore: +- Semantic Kernel framework +- Streaming conversation experiences +- Advanced chat capabilities +- Framework comparison with MEAI + +#### 10. Azure Functions šŸ”§ +**File**: `10-azure-functions.cs` +**Concept**: Function calling with Azure OpenAI + +```bash +dotnet run 10-azure-functions.cs +``` + +Master: +- Azure OpenAI function calling +- Multiple function definitions +- Weather, time, and calculation tools +- Enterprise-grade AI integration + +#### 11. Advanced RAG with Vectors šŸ” +**File**: `11-advanced-rag-vectors.cs` +**Concept**: Vector-based semantic search + +```bash +dotnet run 11-advanced-rag-vectors.cs +``` + +Advanced topics: +- Vector embeddings and similarity +- Semantic search capabilities +- Local embedding generation +- Movie recommendation system + +## Key Features of These Demos + +### ✨ Simplified Architecture +- **Direct file execution** with .NET 10's `dotnet run file.cs` +- **Top-level statements** - Minimal boilerplate code +- **Self-contained** - Each demo focuses on one core concept + +### šŸš€ Modern .NET 10 Features +- **Single-file execution** - No project files needed +- **Implicit global usings** - Cleaner, more focused code +- **Latest AI libraries** - Microsoft.Extensions.AI integration + +### šŸŽÆ Educational Progressive Learning +- **11 comprehensive demos** covering all major AI techniques +- **Multiple provider examples** - GitHub Models, Azure OpenAI, Ollama +- **Real-world scenarios** - Practical applications you can build upon +- **Best practices** - Error handling, authentication, logging + +### šŸ”§ Provider Flexibility +- **GitHub Models** - Free tier for learning and experimentation +- **Azure OpenAI** - Enterprise-grade cloud AI services +- **Ollama** - Privacy-focused local AI processing +- **Easy switching** - Similar patterns across providers + +## Setup Instructions by Provider + +### GitHub Models (Recommended for Learning) +```bash +# Set your GitHub token +export GITHUB_TOKEN="your_github_token_here" + +# Works with demos: 01, 02, 03, 04, 05, 06, 09 +dotnet run 01-llm-completion.cs +``` + +### Azure OpenAI (Enterprise/Production) +```bash +# Set Azure configuration +dotnet user-secrets set "AZURE_OPENAI_ENDPOINT" "https://your-resource.openai.azure.com/" +dotnet user-secrets set "AZURE_OPENAI_APIKEY" "your-api-key" +dotnet user-secrets set "AZURE_OPENAI_MODEL" "gpt-4o-mini" + +# Works with demos: 08, 10 +dotnet run 08-azure-image-generation.cs +``` + +### Ollama (Local/Privacy) +```bash +# Start Ollama and pull required models +ollama serve +ollama pull phi4-mini +ollama pull all-minilm + +# Works with demos: 07, 11 +dotnet run 07-ollama-local-models.cs +``` + +## Running the Demos + +### Option 1: .NET 10 Direct Execution (Recommended) + +With .NET 10 installed, running demos is incredibly simple: + +```bash +# Navigate to the demos folder +cd 03.1-CoreGenerativeAITechniques-runapp/src + +# Run any demo directly +dotnet run 01-llm-completion.cs +dotnet run 02-chat-flow.cs +dotnet run 03-functions-and-plugins.cs +dotnet run 04-retrieval-augmented-generation.cs +dotnet run 05-structured-output.cs +dotnet run 06-multimodal.cs +dotnet run 07-ollama-local-models.cs +dotnet run 08-azure-image-generation.cs +dotnet run 09-semantic-kernel-chat.cs +dotnet run 10-azure-functions.cs +dotnet run 11-advanced-rag-vectors.cs +``` + +### Option 2: Fallback Scripts (If .NET 10 Not Available) + +If you don't have .NET 10 yet, use the provided scripts that simulate the single-file execution: + +**Linux/macOS (Bash):** +```bash +# Navigate to the demos folder +cd 03.1-CoreGenerativeAITechniques-runapp/src + +# Make script executable (first time only) +chmod +x run-demo.sh + +# Run any demo +./run-demo.sh 01-llm-completion.cs +./run-demo.sh 02-chat-flow.cs +./run-demo.sh 06-multimodal.cs +``` + +**Windows (PowerShell):** +```powershell +# Navigate to the demos folder +cd 03.1-CoreGenerativeAITechniques-runapp/src + +# Run any demo +.\run-demo.ps1 01-llm-completion.cs +.\run-demo.ps1 02-chat-flow.cs +.\run-demo.ps1 06-multimodal.cs +``` + +> šŸ’” **How the scripts work**: They create a temporary .NET project, copy your demo file as `Program.cs`, include all necessary NuGet packages, run the demo, and clean up automatically. + +Each demo is completely self-contained and demonstrates different aspects of Generative AI development with .NET. + +## Learning Paths + +Choose your learning journey based on your goals: + +### šŸš€ Quick Start Path (1-2 hours) +Perfect for getting started quickly: +1. **01-llm-completion.cs** - Basic AI text generation +2. **02-chat-flow.cs** - Interactive conversations +3. **03-functions-and-plugins.cs** - AI with custom tools + +### šŸŽ“ Comprehensive Learning Path (3-4 hours) +Complete understanding of all techniques: +1. Start with Quick Start demos (1-3) +2. **04-retrieval-augmented-generation.cs** - Knowledge integration +3. **05-structured-output.cs** - Reliable data extraction +4. **06-multimodal.cs** - Vision and image analysis +5. **09-semantic-kernel-chat.cs** - Advanced framework features + +### šŸ–¼ļø Multimodal AI Focus Path (2-3 hours) +For image and visual AI applications: +1. **06-multimodal.cs** - Vision analysis fundamentals +2. **08-azure-image-generation.cs** - Creating images with AI +3. **05-structured-output.cs** - Extracting data from visual content + +### šŸ  Privacy & Local AI Path (2 hours) +For local, privacy-focused development: +1. **07-ollama-local-models.cs** - Local text generation +2. **11-advanced-rag-vectors.cs** - Local vector search +3. **04-retrieval-augmented-generation.cs** - Simple RAG patterns + +### ā˜ļø Enterprise & Cloud Path (2-3 hours) +For production Azure deployments: +1. **08-azure-image-generation.cs** - Azure DALL-E integration +2. **10-azure-functions.cs** - Azure OpenAI function calling +3. **09-semantic-kernel-chat.cs** - Advanced framework patterns + +## Common Issues & Solutions + +### .NET 10 Not Available? +- **.NET 10 is preferred** for the modern `dotnet run file.cs` syntax +- **Fallback option available**: Use the provided scripts in the `src/` folder: + - **Linux/macOS**: `./run-demo.sh ` + - **Windows**: `.\run-demo.ps1 ` +- **Alternative**: Use the project-based examples in [Lesson 03](../03-CoreGenerativeAITechniques/readme.md) +- Download the latest .NET 10 SDK from [dotnet.microsoft.com](https://dotnet.microsoft.com) + +### Authentication Errors +- **GitHub Models**: Ensure your `GITHUB_TOKEN` has GitHub Models access +- **Azure OpenAI**: Verify endpoint URL and API key in user secrets +- **Ollama**: Check that `ollama serve` is running and models are pulled + +### Missing Dependencies +Each demo is self-contained but relies on these NuGet packages being available: +- `Microsoft.Extensions.AI` (9.7.1+) +- `Microsoft.Extensions.AI.AzureAIInference` (9.6.0-preview.1+) +- `Microsoft.SemanticKernel.Connectors.InMemory` (1.62.0-preview+) + +### Model Availability +- **GitHub Models**: Free tier has rate limits, consider upgrading for production +- **Azure OpenAI**: Ensure your subscription has the required model deployments +- **Ollama**: Pull required models: `ollama pull phi4-mini` and `ollama pull all-minilm` + +## Next Steps + +### šŸ› ļø Build Your Own +- **Experiment** with different prompts and parameters +- **Combine** techniques from multiple demos +- **Create** your own single-file AI applications +- **Adapt** examples for your specific use cases + +### šŸ“š Continue Learning +- **[Lesson 04 - Practical Samples](../04-PracticalSamples/readme.md)** - Complete AI applications +- **[Lesson 05 - SpaceAINet](../05-AppCreatedWithGenAI/SpaceAINet/README.md)** - Full-scale AI-powered game +- **Original [Lesson 03](../03-CoreGenerativeAITechniques/readme.md)** - Detailed project-based examples + +### šŸ¤ Contribute +- **Share** your own single-file AI demos +- **Report** issues or suggest improvements +- **Extend** examples with new AI capabilities + +--- + +> šŸŽ‰ **Congratulations!** You've learned the core techniques of Generative AI with .NET. These patterns form the foundation for building sophisticated AI-powered applications. + +**Happy coding with .NET 10 and AI! šŸš€** \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/01-llm-completion.cs b/03.1-CoreGenerativeAITechniques-runapp/src/01-llm-completion.cs new file mode 100644 index 0000000..5b678d6 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/01-llm-completion.cs @@ -0,0 +1,66 @@ +// LLM Text Completion Demo +// This demo shows how to use Microsoft.Extensions.AI for basic text completions +// +// Prerequisites: Set GITHUB_TOKEN environment variable or user secret +// Run with: dotnet run 01-llm-completion.cs (requires .NET 10) + +using Azure; +using Azure.AI.Inference; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; +using System.Text; + +// Get GitHub token from environment or user secrets +var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); +if (string.IsNullOrEmpty(githubToken)) +{ + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; +} + +if (string.IsNullOrEmpty(githubToken)) +{ + Console.WriteLine("Error: GITHUB_TOKEN not found. Please set it as an environment variable or user secret."); + return; +} + +// Create chat client using GitHub Models +IChatClient client = new ChatCompletionsClient( + endpoint: new Uri("https://models.inference.ai.azure.com"), + new AzureKeyCredential(githubToken)) + .AsIChatClient("Phi-3.5-MoE-instruct"); + +// Build the sentiment analysis prompt +StringBuilder prompt = new StringBuilder(); +prompt.AppendLine("You will analyze the sentiment of the following product reviews. Each line is its own review. Output the sentiment of each review in a bulleted list and then provide a general sentiment of all reviews."); +prompt.AppendLine("I bought this product and it's amazing. I love it!"); +prompt.AppendLine("This product is terrible. I hate it."); +prompt.AppendLine("I'm not sure about this product. It's okay."); +prompt.AppendLine("I found this product based on the other reviews. It worked for a bit, and then it didn't."); + +Console.WriteLine("šŸ¤– Analyzing product review sentiments...\n"); +Console.WriteLine("šŸ“ Reviews to analyze:"); +var reviewLines = prompt.ToString().Split('\n').Skip(1).Take(4); +foreach (var review in reviewLines) +{ + if (!string.IsNullOrWhiteSpace(review)) + Console.WriteLine($" • {review}"); +} + +Console.WriteLine("\nšŸ”„ Sending to AI model...\n"); + +try +{ + // Send the prompt to the model and wait for the text completion + var response = await client.GetResponseAsync(prompt.ToString()); + + // Display the response + Console.WriteLine("šŸŽÆ AI Analysis Result:"); + Console.WriteLine(new string('=', 50)); + Console.WriteLine(response.Text); +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine("Make sure your GITHUB_TOKEN is valid and has access to GitHub Models."); +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/02-chat-flow.cs b/03.1-CoreGenerativeAITechniques-runapp/src/02-chat-flow.cs new file mode 100644 index 0000000..dc9c33c --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/02-chat-flow.cs @@ -0,0 +1,78 @@ +// Interactive Chat Flow Demo +// This demo shows how to create an interactive chat conversation using Microsoft.Extensions.AI +// +// Prerequisites: Set GITHUB_TOKEN environment variable or user secret +// Run with: dotnet run 02-chat-flow.cs (requires .NET 10) + +using Azure; +using Azure.AI.Inference; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; + +// Get GitHub token from environment or user secrets +var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); +if (string.IsNullOrEmpty(githubToken)) +{ + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; +} + +if (string.IsNullOrEmpty(githubToken)) +{ + Console.WriteLine("Error: GITHUB_TOKEN not found. Please set it as an environment variable or user secret."); + return; +} + +// Create chat client using GitHub Models +IChatClient client = new ChatCompletionsClient( + endpoint: new Uri("https://models.inference.ai.azure.com"), + new AzureKeyCredential(githubToken)) + .AsIChatClient("Phi-3.5-MoE-instruct"); + +// Initialize conversation history +var chatHistory = new List +{ + new ChatMessage(ChatRole.System, "You are a helpful AI assistant specializing in .NET development and programming best practices. Keep your responses concise and practical.") +}; + +Console.WriteLine("šŸ’¬ Interactive .NET Programming Assistant"); +Console.WriteLine("========================================="); +Console.WriteLine("Ask me anything about .NET development! Type 'quit' to exit.\n"); + +try +{ + while (true) + { + // Get user input + Console.Write("šŸ‘¤ You: "); + var userInput = Console.ReadLine(); + + if (string.IsNullOrWhiteSpace(userInput) || userInput.ToLower() == "quit") + { + Console.WriteLine("šŸ‘‹ Goodbye! Happy coding!"); + break; + } + + // Add user message to conversation history + chatHistory.Add(new ChatMessage(ChatRole.User, userInput)); + + Console.Write("šŸ¤– Assistant: "); + + // Get streaming response from the AI + await foreach (var update in client.CompleteStreamingAsync(chatHistory)) + { + Console.Write(update.Text); + } + + // Add the complete response to conversation history + var response = await client.CompleteAsync(chatHistory); + chatHistory.Add(new ChatMessage(ChatRole.Assistant, response.Message.Text)); + + Console.WriteLine("\n"); + } +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine("Make sure your GITHUB_TOKEN is valid and has access to GitHub Models."); +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/03-functions-and-plugins.cs b/03.1-CoreGenerativeAITechniques-runapp/src/03-functions-and-plugins.cs new file mode 100644 index 0000000..bc5ad74 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/03-functions-and-plugins.cs @@ -0,0 +1,109 @@ +// Functions and Plugins Demo +// This demo shows how to use AI functions/tools with Microsoft.Extensions.AI +// +// Prerequisites: Set GITHUB_TOKEN environment variable or user secret +// Run with: dotnet run 03-functions-and-plugins.cs (requires .NET 10) + +using Azure; +using Azure.AI.Inference; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; +using System.ComponentModel; + +// Get GitHub token from environment or user secrets +var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); +if (string.IsNullOrEmpty(githubToken)) +{ + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; +} + +if (string.IsNullOrEmpty(githubToken)) +{ + Console.WriteLine("Error: GITHUB_TOKEN not found. Please set it as an environment variable or user secret."); + return; +} + +// Create chat options with function tools +ChatOptions options = new ChatOptions +{ + Tools = [ + AIFunctionFactory.Create(GetWeather), + AIFunctionFactory.Create(GetDateTime), + AIFunctionFactory.Create(CalculateSum) + ] +}; + +// Create chat client with function invocation capability +IChatClient client = new ChatCompletionsClient( + endpoint: new Uri("https://models.inference.ai.azure.com"), + new AzureKeyCredential(githubToken)) + .AsIChatClient("gpt-4o-mini") + .AsBuilder() + .UseFunctionInvocation() + .Build(); + +Console.WriteLine("šŸ”§ AI Functions & Plugins Demo"); +Console.WriteLine("==============================="); +Console.WriteLine("Ask questions that might require tool usage!"); +Console.WriteLine("Try: 'What's the weather like?' or 'What time is it?' or 'What's 15 + 27?'"); +Console.WriteLine("Type 'quit' to exit.\n"); + +try +{ + while (true) + { + Console.Write("šŸ‘¤ You: "); + var question = Console.ReadLine(); + + if (string.IsNullOrWhiteSpace(question) || question.ToLower() == "quit") + { + Console.WriteLine("šŸ‘‹ Goodbye!"); + break; + } + + Console.WriteLine($"\nšŸ¤– Processing: {question}"); + Console.WriteLine("─" + new string('─', 49)); + + var response = await client.CompleteAsync(question, options); + Console.WriteLine($"šŸ’¬ Response: {response.Message.Text}\n"); + } +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine("Make sure your GITHUB_TOKEN is valid and has access to GitHub Models."); +} + +// Function definitions +[Description("Get the current weather information")] +static string GetWeather([Description("The location to get weather for")] string location = "your area") +{ + var temperature = Random.Shared.Next(-5, 35); + var conditions = Random.Shared.Next(0, 3) switch + { + 0 => "sunny", + 1 => "rainy", + _ => "cloudy" + }; + var weatherInfo = $"The weather in {location} is {temperature}°C and {conditions}."; + Console.WriteLine($" šŸŒ¤ļø Function Call - Weather: {weatherInfo}"); + return weatherInfo; +} + +[Description("Get the current date and time")] +static string GetDateTime() +{ + var now = DateTime.Now; + var dateTimeInfo = $"Current date and time: {now:yyyy-MM-dd HH:mm:ss}"; + Console.WriteLine($" šŸ•’ Function Call - DateTime: {dateTimeInfo}"); + return dateTimeInfo; +} + +[Description("Calculate the sum of two numbers")] +static int CalculateSum([Description("First number")] int a, [Description("Second number")] int b) +{ + var result = a + b; + Console.WriteLine($" 🧮 Function Call - Math: {a} + {b} = {result}"); + return result; +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/04-retrieval-augmented-generation.cs b/03.1-CoreGenerativeAITechniques-runapp/src/04-retrieval-augmented-generation.cs new file mode 100644 index 0000000..4f9fa96 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/04-retrieval-augmented-generation.cs @@ -0,0 +1,162 @@ +// Retrieval-Augmented Generation (RAG) Demo +// This demo shows how to implement basic RAG using Microsoft.Extensions.AI with in-memory vector storage +// +// Prerequisites: Set GITHUB_TOKEN environment variable or user secret +// Run with: dotnet run 04-retrieval-augmented-generation.cs (requires .NET 10) + +using Azure; +using Azure.AI.Inference; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; +using System.Text; + +// Get GitHub token from environment or user secrets +var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); +if (string.IsNullOrEmpty(githubToken)) +{ + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; +} + +if (string.IsNullOrEmpty(githubToken)) +{ + Console.WriteLine("Error: GITHUB_TOKEN not found. Please set it as an environment variable or user secret."); + return; +} + +Console.WriteLine("šŸ” Retrieval-Augmented Generation (RAG) Demo"); +Console.WriteLine("==========================================="); +Console.WriteLine("Setting up movie database with simple similarity search...\n"); + +// Sample movie data with embedded descriptions +var movieData = new List +{ + new() { Id = 1, Title = "The Lion King", Year = 1994, Category = "Animation, Family, Adventure", + Description = "A young lion named Simba embarks on a journey to reclaim his throne as the king of the Pride Lands after his father's death.", + Keywords = new[] { "lion", "family", "adventure", "animals", "kingdom", "young", "journey" } }, + new() { Id = 2, Title = "Inception", Year = 2010, Category = "Science Fiction, Action, Thriller", + Description = "A group of thieves enter the dreams of their targets to steal information in this mind-bending sci-fi thriller.", + Keywords = new[] { "dreams", "sci-fi", "thriller", "mind-bending", "thieves", "technology" } }, + new() { Id = 3, Title = "Shrek", Year = 2001, Category = "Animation, Comedy, Family", + Description = "An ogre named Shrek goes on a quest to rescue Princess Fiona from a dragon-guarded castle.", + Keywords = new[] { "ogre", "dragon", "princess", "quest", "comedy", "family", "fairy tale" } }, + new() { Id = 4, Title = "Finding Nemo", Year = 2003, Category = "Animation, Family, Adventure", + Description = "A clownfish named Marlin searches for his lost son Nemo across the ocean with help from a forgetful fish named Dory.", + Keywords = new[] { "fish", "ocean", "family", "adventure", "lost", "search", "underwater" } }, + new() { Id = 5, Title = "The Matrix", Year = 1999, Category = "Science Fiction, Action", + Description = "A computer hacker discovers that reality is a simulation and joins a rebellion against the machines.", + Keywords = new[] { "hacker", "simulation", "reality", "machines", "rebellion", "technology" } } +}; + +// Create chat client +IChatClient chatClient = new ChatCompletionsClient( + endpoint: new Uri("https://models.inference.ai.azure.com"), + new AzureKeyCredential(githubToken)) + .AsIChatClient("gpt-4o-mini"); + +Console.WriteLine("šŸ“š Movie database loaded:"); +foreach (var movie in movieData) +{ + Console.WriteLine($" āœ“ {movie.Title} ({movie.Year})"); +} + +Console.WriteLine("\nšŸŽ¬ Movie Recommendation System Ready!"); +Console.WriteLine("Ask for movie recommendations and I'll search our database!"); +Console.WriteLine("Type 'quit' to exit.\n"); + +try +{ + while (true) + { + Console.Write("šŸ‘¤ What kind of movie are you looking for? "); + var query = Console.ReadLine(); + + if (string.IsNullOrWhiteSpace(query) || query.ToLower() == "quit") + { + Console.WriteLine("šŸ‘‹ Goodbye! Enjoy your movies!"); + break; + } + + Console.WriteLine($"\nšŸ” Searching for movies matching: '{query}'"); + + // Simple keyword-based similarity search + var searchResults = FindSimilarMovies(query.ToLower(), movieData); + + if (searchResults.Any()) + { + // Create context from search results + var context = new StringBuilder(); + context.AppendLine("Based on your request, here are some relevant movies from our database:"); + foreach (var movie in searchResults.Take(3)) + { + context.AppendLine($"- {movie.Title} ({movie.Year}): {movie.Description}"); + } + + // Generate AI response with context + var prompt = $@"User Query: {query} + +Movie Database Context: +{context} + +Please provide a helpful recommendation based on the user's request and the movies found in our database. +Explain why these movies match what they're looking for."; + + Console.WriteLine("šŸ¤– AI Recommendation:"); + Console.WriteLine(new string('─', 50)); + var response = await chatClient.CompleteAsync(prompt); + Console.WriteLine(response.Message.Text); + Console.WriteLine(); + } + else + { + Console.WriteLine("āŒ No matching movies found in our database."); + Console.WriteLine(); + } + } +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine("Make sure your GITHUB_TOKEN is valid and has access to GitHub Models."); +} + +// Simple similarity search based on keywords and description +static List FindSimilarMovies(string query, List movies) +{ + var queryWords = query.Split(' ', StringSplitOptions.RemoveEmptyEntries); + var results = new List<(Movie movie, int score)>(); + + foreach (var movie in movies) + { + int score = 0; + + // Check keywords + foreach (var word in queryWords) + { + if (movie.Keywords.Any(k => k.Contains(word, StringComparison.OrdinalIgnoreCase))) + score += 3; + if (movie.Description.Contains(word, StringComparison.OrdinalIgnoreCase)) + score += 2; + if (movie.Title.Contains(word, StringComparison.OrdinalIgnoreCase)) + score += 4; + if (movie.Category.Contains(word, StringComparison.OrdinalIgnoreCase)) + score += 2; + } + + if (score > 0) + results.Add((movie, score)); + } + + return results.OrderByDescending(r => r.score).Select(r => r.movie).ToList(); +} + +// Simplified movie data class +public class Movie +{ + public int Id { get; set; } + public string Title { get; set; } = ""; + public int Year { get; set; } + public string Category { get; set; } = ""; + public string Description { get; set; } = ""; + public string[] Keywords { get; set; } = []; +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/05-structured-output.cs b/03.1-CoreGenerativeAITechniques-runapp/src/05-structured-output.cs new file mode 100644 index 0000000..7dfe7d7 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/05-structured-output.cs @@ -0,0 +1,321 @@ +// Structured Output Demo +// This demo shows how to get structured JSON responses from AI models +// +// Prerequisites: Set GITHUB_TOKEN environment variable or user secret +// Run with: dotnet run 05-structured-output.cs (requires .NET 10) + +using Azure; +using Azure.AI.Inference; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; +using System.Text.Json; +using System.Text.Json.Serialization; + +// Get GitHub token from environment or user secrets +var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); +if (string.IsNullOrEmpty(githubToken)) +{ + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; +} + +if (string.IsNullOrEmpty(githubToken)) +{ + Console.WriteLine("Error: GITHUB_TOKEN not found. Please set it as an environment variable or user secret."); + return; +} + +// Create chat client +IChatClient client = new ChatCompletionsClient( + endpoint: new Uri("https://models.inference.ai.azure.com"), + new AzureKeyCredential(githubToken)) + .AsIChatClient("gpt-4o-mini"); + +Console.WriteLine("šŸ“Š Structured Output Demo"); +Console.WriteLine("========================="); +Console.WriteLine("This demo shows how to get structured JSON responses from AI models.\n"); + +// Demo 1: Product Analysis +await DemoProductAnalysis(client); + +// Demo 2: Recipe Generation +await DemoRecipeGeneration(client); + +// Demo 3: Meeting Summary +await DemoMeetingSummary(client); + +Console.WriteLine("✨ Demo completed! All responses were structured JSON objects."); + +static async Task DemoProductAnalysis(IChatClient client) +{ + Console.WriteLine("šŸ›ļø Demo 1: Product Review Analysis"); + Console.WriteLine("──────────────────────────────────"); + + var productReviews = """ + "This laptop is amazing! Super fast processor and great battery life. Worth every penny." + "The screen is a bit dim and the keyboard feels cheap. Not impressed." + "Excellent build quality and performance. Highly recommended for developers." + "Overpriced for what you get. There are better alternatives." + """; + + var prompt = $@"Analyze these product reviews and return the results in the following JSON format: + {{{{ + ""overall_sentiment"": ""positive|negative|neutral"", + ""sentiment_score"": 0.0-1.0, + ""key_themes"": [""theme1"", ""theme2""], + ""summary"": ""brief summary"", + ""recommendation"": ""buy|avoid|consider"" + }}}} + + Reviews: + {productReviews} + + Respond only with valid JSON, no additional text."; + + try + { + var response = await client.CompleteAsync(prompt); + var analysis = JsonSerializer.Deserialize(response.Message.Text); + + Console.WriteLine("šŸ“ˆ Analysis Result:"); + Console.WriteLine($" Overall Sentiment: {analysis.OverallSentiment}"); + Console.WriteLine($" Sentiment Score: {analysis.SentimentScore:F2}"); + Console.WriteLine($" Key Themes: {string.Join(", ", analysis.KeyThemes)}"); + Console.WriteLine($" Summary: {analysis.Summary}"); + Console.WriteLine($" Recommendation: {analysis.Recommendation}"); + Console.WriteLine(); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error parsing product analysis: {ex.Message}"); + Console.WriteLine(); + } +} + +static async Task DemoRecipeGeneration(IChatClient client) +{ + Console.WriteLine("šŸ‘Øā€šŸ³ Demo 2: Recipe Generation"); + Console.WriteLine("─────────────────────────────"); + + var prompt = @"Create a simple pasta recipe and return it in the following JSON format: + { + ""name"": ""recipe name"", + ""prep_time_minutes"": 15, + ""cook_time_minutes"": 20, + ""servings"": 4, + ""difficulty"": ""easy|medium|hard"", + ""ingredients"": [ + {""item"": ""ingredient name"", ""amount"": ""2 cups"", ""notes"": ""optional notes""} + ], + ""steps"": [ + {""step_number"": 1, ""instruction"": ""detailed instruction"", ""time_minutes"": 5} + ], + ""tips"": [""tip1"", ""tip2""] + } + + Respond only with valid JSON, no additional text."; + + try + { + var response = await client.CompleteAsync(prompt); + var recipe = JsonSerializer.Deserialize(response.Message.Text); + + Console.WriteLine("šŸ Generated Recipe:"); + Console.WriteLine($" Name: {recipe.Name}"); + Console.WriteLine($" Prep: {recipe.PrepTimeMinutes}min | Cook: {recipe.CookTimeMinutes}min | Serves: {recipe.Servings}"); + Console.WriteLine($" Difficulty: {recipe.Difficulty}"); + Console.WriteLine(" Ingredients:"); + foreach (var ingredient in recipe.Ingredients) + { + Console.WriteLine($" • {ingredient.Amount} {ingredient.Item}"); + } + Console.WriteLine(" Steps:"); + foreach (var step in recipe.Steps) + { + Console.WriteLine($" {step.StepNumber}. {step.Instruction} ({step.TimeMinutes}min)"); + } + Console.WriteLine(); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error parsing recipe: {ex.Message}"); + Console.WriteLine(); + } +} + +static async Task DemoMeetingSummary(IChatClient client) +{ + Console.WriteLine("šŸ“ Demo 3: Meeting Summary"); + Console.WriteLine("─────────────────────────"); + + var meetingTranscript = """ + John: Thanks everyone for joining. Let's start with the quarterly review. + Sarah: The sales numbers look good. We're up 15% from last quarter. + Mike: That's great! The new marketing campaign is really paying off. + John: What about the development timeline for the new features? + Sarah: We're slightly behind on the mobile app, but the web version is on track. + Mike: I think we need to hire two more developers to meet our Q4 goals. + John: Agreed. I'll work on the budget approval. Any other concerns? + Sarah: The customer support team needs better tools for handling tickets. + """; + + var prompt = $@"Summarize this meeting transcript and return the results in the following JSON format: + {{{{ + ""meeting_type"": ""type of meeting"", + ""key_topics"": [""topic1"", ""topic2""], + ""decisions_made"": [""decision1"", ""decision2""], + ""action_items"": [ + {{{{""assignee"": ""person"", ""task"": ""task description"", ""priority"": ""high|medium|low""}}}} + ], + ""metrics_mentioned"": [ + {{{{""metric"": ""metric name"", ""value"": ""value"", ""context"": ""context""}}}} + ], + ""next_steps"": [""step1"", ""step2""] + }}}} + + Meeting Transcript: + {meetingTranscript} + + Respond only with valid JSON, no additional text."; + + try + { + var response = await client.CompleteAsync(prompt); + var summary = JsonSerializer.Deserialize(response.Message.Text); + + Console.WriteLine("šŸ“‹ Meeting Summary:"); + Console.WriteLine($" Type: {summary.MeetingType}"); + Console.WriteLine($" Key Topics: {string.Join(", ", summary.KeyTopics)}"); + Console.WriteLine(" Decisions Made:"); + foreach (var decision in summary.DecisionsMade) + { + Console.WriteLine($" • {decision}"); + } + Console.WriteLine(" Action Items:"); + foreach (var item in summary.ActionItems) + { + Console.WriteLine($" • {item.Assignee}: {item.Task} ({item.Priority} priority)"); + } + Console.WriteLine(); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error parsing meeting summary: {ex.Message}"); + Console.WriteLine(); + } +} + +// Data classes for structured outputs +public class ProductAnalysis +{ + [JsonPropertyName("overall_sentiment")] + public string OverallSentiment { get; set; } = ""; + + [JsonPropertyName("sentiment_score")] + public double SentimentScore { get; set; } + + [JsonPropertyName("key_themes")] + public string[] KeyThemes { get; set; } = []; + + [JsonPropertyName("summary")] + public string Summary { get; set; } = ""; + + [JsonPropertyName("recommendation")] + public string Recommendation { get; set; } = ""; +} + +public class Recipe +{ + [JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonPropertyName("prep_time_minutes")] + public int PrepTimeMinutes { get; set; } + + [JsonPropertyName("cook_time_minutes")] + public int CookTimeMinutes { get; set; } + + [JsonPropertyName("servings")] + public int Servings { get; set; } + + [JsonPropertyName("difficulty")] + public string Difficulty { get; set; } = ""; + + [JsonPropertyName("ingredients")] + public Ingredient[] Ingredients { get; set; } = []; + + [JsonPropertyName("steps")] + public RecipeStep[] Steps { get; set; } = []; + + [JsonPropertyName("tips")] + public string[] Tips { get; set; } = []; +} + +public class Ingredient +{ + [JsonPropertyName("item")] + public string Item { get; set; } = ""; + + [JsonPropertyName("amount")] + public string Amount { get; set; } = ""; + + [JsonPropertyName("notes")] + public string Notes { get; set; } = ""; +} + +public class RecipeStep +{ + [JsonPropertyName("step_number")] + public int StepNumber { get; set; } + + [JsonPropertyName("instruction")] + public string Instruction { get; set; } = ""; + + [JsonPropertyName("time_minutes")] + public int TimeMinutes { get; set; } +} + +public class MeetingSummary +{ + [JsonPropertyName("meeting_type")] + public string MeetingType { get; set; } = ""; + + [JsonPropertyName("key_topics")] + public string[] KeyTopics { get; set; } = []; + + [JsonPropertyName("decisions_made")] + public string[] DecisionsMade { get; set; } = []; + + [JsonPropertyName("action_items")] + public ActionItem[] ActionItems { get; set; } = []; + + [JsonPropertyName("metrics_mentioned")] + public Metric[] MetricsMentioned { get; set; } = []; + + [JsonPropertyName("next_steps")] + public string[] NextSteps { get; set; } = []; +} + +public class ActionItem +{ + [JsonPropertyName("assignee")] + public string Assignee { get; set; } = ""; + + [JsonPropertyName("task")] + public string Task { get; set; } = ""; + + [JsonPropertyName("priority")] + public string Priority { get; set; } = ""; +} + +public class Metric +{ + [JsonPropertyName("metric")] + public string MetricName { get; set; } = ""; + + [JsonPropertyName("value")] + public string Value { get; set; } = ""; + + [JsonPropertyName("context")] + public string Context { get; set; } = ""; +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/06-multimodal.cs b/03.1-CoreGenerativeAITechniques-runapp/src/06-multimodal.cs new file mode 100644 index 0000000..19bb86a --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/06-multimodal.cs @@ -0,0 +1,191 @@ +// Multimodal AI Demo (Vision) +// This demo shows how to analyze images using vision-capable AI models +// +// Prerequisites: Set GITHUB_TOKEN environment variable or user secret +// Run with: dotnet run 06-multimodal.cs (requires .NET 10) + +using Azure; +using Azure.AI.Inference; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; +using System.Text; + +// Get GitHub token from environment or user secrets +var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); +if (string.IsNullOrEmpty(githubToken)) +{ + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; +} + +if (string.IsNullOrEmpty(githubToken)) +{ + Console.WriteLine("Error: GITHUB_TOKEN not found. Please set it as an environment variable or user secret."); + return; +} + +// Create chat client with vision capabilities +IChatClient client = new ChatCompletionsClient( + endpoint: new Uri("https://models.inference.ai.azure.com"), + new AzureKeyCredential(githubToken)) + .AsIChatClient("gpt-4o-mini"); + +Console.WriteLine("šŸ‘ļø Multimodal AI Demo - Vision Analysis"); +Console.WriteLine("========================================"); +Console.WriteLine("This demo analyzes images using AI vision capabilities.\n"); + +// Demo 1: Analyze a sample image from URL +await AnalyzeImageFromUrl(client); + +// Demo 2: Analyze a local image (if available) +await AnalyzeLocalImage(client); + +Console.WriteLine("✨ Vision analysis demo completed!"); + +static async Task AnalyzeImageFromUrl(IChatClient client) +{ + Console.WriteLine("šŸ–¼ļø Demo 1: Analyzing Image from URL"); + Console.WriteLine("───────────────────────────────────"); + + // Using a sample image from the web + var imageUrl = "https://raw.githubusercontent.com/microsoft/Generative-AI-for-beginners-dotnet/main/03-CoreGenerativeAITechniques/images/vision-sample.jpg"; + + try + { + var messages = new List + { + new ChatMessage(ChatRole.System, "You are a helpful AI assistant that can analyze images. Provide detailed, accurate descriptions of what you see."), + new ChatMessage(ChatRole.User, [ + new TextContent("Please analyze this image and describe what you see. Include details about:"), + new TextContent("- Main subjects or objects"), + new TextContent("- Setting/environment"), + new TextContent("- Colors and lighting"), + new TextContent("- Any text or signs visible"), + new TextContent("- Overall mood or atmosphere"), + new ImageContent(new Uri(imageUrl)) + ]) + }; + + Console.WriteLine($"šŸ”— Analyzing image: {imageUrl}"); + Console.WriteLine("šŸ¤– AI Analysis:"); + Console.WriteLine(new string('─', 50)); + + var response = await client.CompleteAsync(messages); + Console.WriteLine(response.Message.Text); + Console.WriteLine(); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error analyzing image from URL: {ex.Message}"); + Console.WriteLine("Note: The image URL might not be accessible or the model might not support vision."); + Console.WriteLine(); + } +} + +static async Task AnalyzeLocalImage(IChatClient client) +{ + Console.WriteLine("šŸ“ Demo 2: Analyzing Local Image"); + Console.WriteLine("────────────────────────────────"); + + // Check for common image file types in current directory + var imageExtensions = new[] { "*.jpg", "*.jpeg", "*.png", "*.gif", "*.bmp" }; + var currentDir = Directory.GetCurrentDirectory(); + + string? imageFile = null; + foreach (var extension in imageExtensions) + { + var files = Directory.GetFiles(currentDir, extension, SearchOption.TopDirectoryOnly); + if (files.Length > 0) + { + imageFile = files[0]; + break; + } + } + + if (imageFile == null) + { + Console.WriteLine("šŸ’” No local image files found in current directory."); + Console.WriteLine(" To test with a local image, place a .jpg, .png, or other image file in this directory."); + Console.WriteLine(); + return; + } + + try + { + // Read image as base64 + var imageBytes = await File.ReadAllBytesAsync(imageFile); + var base64Image = Convert.ToBase64String(imageBytes); + var mimeType = GetMimeType(Path.GetExtension(imageFile)); + + var messages = new List + { + new ChatMessage(ChatRole.System, "You are a helpful AI assistant that can analyze images. Be specific and detailed in your analysis."), + new ChatMessage(ChatRole.User, [ + new TextContent("Please analyze this local image and provide:"), + new TextContent("1. A general description of what you see"), + new TextContent("2. Technical details (resolution, format if visible)"), + new TextContent("3. Suggestions for improvement if it's a photo"), + new TextContent("4. Any interesting details you notice"), + new ImageContent(Convert.FromBase64String(base64Image), mimeType) + ]) + }; + + Console.WriteLine($"šŸ“ø Analyzing local image: {Path.GetFileName(imageFile)}"); + Console.WriteLine("šŸ¤– AI Analysis:"); + Console.WriteLine(new string('─', 50)); + + var response = await client.CompleteAsync(messages); + Console.WriteLine(response.Message.Text); + Console.WriteLine(); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error analyzing local image: {ex.Message}"); + Console.WriteLine("Note: The model might not support vision or the image format might not be supported."); + Console.WriteLine(); + } +} + +static string GetMimeType(string extension) +{ + return extension.ToLower() switch + { + ".jpg" or ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".gif" => "image/gif", + ".bmp" => "image/bmp", + ".webp" => "image/webp", + _ => "image/jpeg" + }; +} + +// Helper method to create a simple test image if none exists +static async Task CreateSampleImageIfNeeded() +{ + var sampleImagePath = "sample-image.txt"; + if (!File.Exists(sampleImagePath)) + { + var sampleImageInfo = """ + šŸ“ Sample Image Instructions + ═══════════════════════════ + + To test the multimodal demo with a local image: + + 1. Place any image file (.jpg, .png, .gif, .bmp) in this directory + 2. Run the demo again + 3. The AI will analyze your image and provide detailed insights + + Suggested test images: + • Screenshots of applications + • Photos of objects or scenes + • Charts or diagrams + • Artwork or designs + • Documents with text + + The AI can describe content, read text, analyze composition, + and provide detailed observations about what it sees. + """; + + await File.WriteAllTextAsync(sampleImagePath, sampleImageInfo); + } +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/07-ollama-local-models.cs b/03.1-CoreGenerativeAITechniques-runapp/src/07-ollama-local-models.cs new file mode 100644 index 0000000..5f1ae17 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/07-ollama-local-models.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.AI; +using System.Text; + +// Local AI with Ollama - no API keys needed! +// Make sure Ollama is running with: ollama serve +// And the model is pulled: ollama pull phi4-mini + +Console.WriteLine("šŸ”§ Local AI Demo with Ollama"); +Console.WriteLine("Using phi4-mini model locally via Ollama"); +Console.WriteLine(); + +try +{ + // Create Ollama client pointing to local server + IChatClient client = new OllamaChatClient(new Uri("http://localhost:11434/"), "phi4-mini"); + + // Build a comprehensive prompt for sentiment analysis + StringBuilder prompt = new StringBuilder(); + prompt.AppendLine("You will analyze the sentiment of the following product reviews. Each line is its own review. Output the sentiment of each review in a bulleted list including the original text and the sentiment, and then provide a general sentiment of all reviews."); + prompt.AppendLine(); + prompt.AppendLine("Reviews:"); + prompt.AppendLine("I bought this product and it's amazing. I love it!"); + prompt.AppendLine("This product is terrible. I hate it."); + prompt.AppendLine("I'm not sure about this product. It's okay."); + prompt.AppendLine("I found this product based on the other reviews. It worked for a bit, and then it didn't."); + + Console.WriteLine("šŸ“ Prompt sent to Ollama:"); + Console.WriteLine(prompt.ToString()); + Console.WriteLine("šŸ¤– Ollama Response:"); + Console.WriteLine(); + + // Send prompt to local model + var response = await client.GetResponseAsync(prompt.ToString()); + Console.WriteLine(response.Text); + + Console.WriteLine(); + Console.WriteLine("āœ… Local AI demo completed successfully!"); + Console.WriteLine("šŸ’” Try modifying the reviews or prompt to experiment with different scenarios"); +} +catch (HttpRequestException ex) when (ex.Message.Contains("Connection refused")) +{ + Console.WriteLine("āŒ Error: Could not connect to Ollama server"); + Console.WriteLine("Please ensure Ollama is running:"); + Console.WriteLine(" 1. Start Ollama: ollama serve"); + Console.WriteLine(" 2. Pull the model: ollama pull phi4-mini"); + Console.WriteLine(" 3. Try again"); +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine("Make sure Ollama is properly installed and the phi4-mini model is available"); +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/08-azure-image-generation.cs b/03.1-CoreGenerativeAITechniques-runapp/src/08-azure-image-generation.cs new file mode 100644 index 0000000..1f16e9d --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/08-azure-image-generation.cs @@ -0,0 +1,102 @@ +using Microsoft.Extensions.Configuration; +using Azure.AI.OpenAI; +using OpenAI.Images; + +// Azure OpenAI Image Generation Demo +// This demo shows how to generate images using Azure OpenAI DALL-E models + +Console.WriteLine("šŸŽØ Azure OpenAI Image Generation Demo"); +Console.WriteLine(); + +try +{ + // Load configuration from user secrets + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + + var endpoint = config["AZURE_OPENAI_ENDPOINT"]; + var apiKey = config["AZURE_OPENAI_APIKEY"]; + var model = config["AZURE_OPENAI_IMAGE_MODEL"] ?? "dall-e-3"; // Default to DALL-E 3 + + if (string.IsNullOrEmpty(endpoint) || string.IsNullOrEmpty(apiKey)) + { + Console.WriteLine("āŒ Missing Azure OpenAI configuration"); + Console.WriteLine("Please set the following user secrets:"); + Console.WriteLine(" dotnet user-secrets set 'AZURE_OPENAI_ENDPOINT' 'https://your-resource.openai.azure.com/'"); + Console.WriteLine(" dotnet user-secrets set 'AZURE_OPENAI_APIKEY' 'your-api-key'"); + Console.WriteLine(" dotnet user-secrets set 'AZURE_OPENAI_IMAGE_MODEL' 'dall-e-3' (optional)"); + return; + } + + // Create Azure OpenAI client + var azureClient = new AzureOpenAIClient(new Uri(endpoint), new System.ClientModel.ApiKeyCredential(apiKey)); + var imageClient = azureClient.GetImageClient(model); + + // Define the image prompt + string prompt = "A futuristic robot coding on a laptop in a coffee shop, digital art style with warm lighting"; + + Console.WriteLine($"šŸ–¼ļø Generating image with prompt: {prompt}"); + Console.WriteLine($"šŸ¤– Using model: {model}"); + Console.WriteLine(); + + // Configure image generation options + var options = new ImageGenerationOptions() + { + Size = GeneratedImageSize.W1024xH1024, + Quality = GeneratedImageQuality.Standard, + Style = GeneratedImageStyle.Vivid, + ResponseFormat = GeneratedImageFormat.Bytes + }; + + // Generate the image + Console.WriteLine("ā³ Generating image... This may take a few seconds"); + var generatedImage = await imageClient.GenerateImageAsync(prompt, options); + + // Save the image to a file + string fileName = $"generated-image-{DateTimeOffset.Now:yyyyMMdd-HHmmss}.png"; + string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + string fullPath = Path.Combine(desktopPath, fileName); + + await File.WriteAllBytesAsync(fullPath, generatedImage.ImageBytes.ToArray()); + + Console.WriteLine($"āœ… Image generated successfully!"); + Console.WriteLine($"šŸ“ Saved to: {fullPath}"); + Console.WriteLine(); + + // Attempt to open the image with the default viewer + try + { + if (OperatingSystem.IsWindows()) + { + System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(fullPath) { UseShellExecute = true }); + } + else if (OperatingSystem.IsLinux()) + { + System.Diagnostics.Process.Start("xdg-open", fullPath); + } + else if (OperatingSystem.IsMacOS()) + { + System.Diagnostics.Process.Start("open", fullPath); + } + + Console.WriteLine("šŸ–¼ļø Image opened in default viewer"); + } + catch + { + Console.WriteLine("šŸ“ Please manually open the image file to view it"); + } + + Console.WriteLine(); + Console.WriteLine("šŸ’” Try experimenting with different prompts:"); + Console.WriteLine(" - 'A serene mountain landscape at sunset, oil painting style'"); + Console.WriteLine(" - 'A cute cartoon cat wearing glasses reading a book'"); + Console.WriteLine(" - 'Abstract geometric patterns in blue and gold, modern art style'"); +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error generating image: {ex.Message}"); + Console.WriteLine(); + Console.WriteLine("šŸ”§ Troubleshooting:"); + Console.WriteLine("• Verify your Azure OpenAI endpoint and API key are correct"); + Console.WriteLine("• Ensure your Azure resource has DALL-E models deployed"); + Console.WriteLine("• Check that you have sufficient quota for image generation"); +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/09-semantic-kernel-chat.cs b/03.1-CoreGenerativeAITechniques-runapp/src/09-semantic-kernel-chat.cs new file mode 100644 index 0000000..9d09a77 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/09-semantic-kernel-chat.cs @@ -0,0 +1,115 @@ +using Microsoft.SemanticKernel.ChatCompletion; +using Microsoft.SemanticKernel; +using OpenAI; +using System.ClientModel; +using Microsoft.Extensions.Configuration; +using System.Text; + +// Interactive Chat with Semantic Kernel +// This demo shows streaming chat with conversation memory using SK + +Console.WriteLine("šŸ’¬ Interactive Chat with Semantic Kernel"); +Console.WriteLine("Type 'exit' or 'quit' to end the conversation"); +Console.WriteLine(); + +try +{ + // Get GitHub token for GitHub Models + var githubToken = Environment.GetEnvironmentVariable("GITHUB_TOKEN"); + if (string.IsNullOrEmpty(githubToken)) + { + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + githubToken = config["GITHUB_TOKEN"]; + } + + if (string.IsNullOrEmpty(githubToken)) + { + Console.WriteLine("āŒ Missing GitHub token"); + Console.WriteLine("Please set your GitHub token:"); + Console.WriteLine(" export GITHUB_TOKEN='your_token_here'"); + Console.WriteLine(" OR"); + Console.WriteLine(" dotnet user-secrets set 'GITHUB_TOKEN' 'your_token_here'"); + return; + } + + // Configure GitHub Models with Semantic Kernel + var modelId = "Phi-3.5-mini-instruct"; + var uri = "https://models.github.ai/inference"; + + var client = new OpenAIClient(new ApiKeyCredential(githubToken), + new OpenAIClientOptions { Endpoint = new Uri(uri) }); + + var builder = Kernel.CreateBuilder(); + builder.AddOpenAIChatCompletion(modelId, client); + + var kernel = builder.Build(); + var chat = kernel.GetRequiredService(); + + // Initialize chat history with system message + var history = new ChatHistory(); + history.AddSystemMessage("You are a helpful, creative, and friendly AI assistant. You explain things clearly and ask follow-up questions when helpful. Use emojis occasionally to make the conversation more engaging. If you don't know something, say so honestly."); + + Console.WriteLine("šŸ¤– AI Assistant ready! How can I help you today?"); + Console.WriteLine(); + + // Main chat loop + while (true) + { + Console.Write("šŸ‘¤ You: "); + var userInput = Console.ReadLine(); + + if (string.IsNullOrWhiteSpace(userInput) || + userInput.Equals("exit", StringComparison.OrdinalIgnoreCase) || + userInput.Equals("quit", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine("šŸ‘‹ Goodbye! Thanks for chatting!"); + break; + } + + // Add user message to history + history.AddUserMessage(userInput); + + // Get streaming response from AI + Console.Write("šŸ¤– AI: "); + var responseBuilder = new StringBuilder(); + + try + { + var streamingResponse = chat.GetStreamingChatMessageContentsAsync(history); + + await foreach (var chunk in streamingResponse) + { + var content = chunk.Content; + if (!string.IsNullOrEmpty(content)) + { + Console.Write(content); + responseBuilder.Append(content); + } + } + + Console.WriteLine(); + Console.WriteLine(); + + // Add AI response to history + history.AddAssistantMessage(responseBuilder.ToString()); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error getting response: {ex.Message}"); + Console.WriteLine("Let's try again!"); + Console.WriteLine(); + } + } + + // Display conversation summary + Console.WriteLine($"šŸ“Š Conversation ended. Total messages: {history.Count}"); +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Startup error: {ex.Message}"); + Console.WriteLine(); + Console.WriteLine("šŸ”§ Troubleshooting:"); + Console.WriteLine("• Make sure your GitHub token has access to GitHub Models"); + Console.WriteLine("• Check your internet connection"); + Console.WriteLine("• Verify the GitHub Models service is available"); +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/10-azure-functions.cs b/03.1-CoreGenerativeAITechniques-runapp/src/10-azure-functions.cs new file mode 100644 index 0000000..9e2439c --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/10-azure-functions.cs @@ -0,0 +1,149 @@ +using Azure.AI.OpenAI; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; +using System.ClientModel; +using System.ComponentModel; + +// Azure OpenAI Function Calling Demo +// This shows how to use AI function calling with Azure OpenAI + +Console.WriteLine("šŸ”§ Azure OpenAI Function Calling Demo"); +Console.WriteLine(); + +try +{ + // Load Azure OpenAI configuration + var config = new ConfigurationBuilder().AddUserSecrets().Build(); + + var endpoint = config["AZURE_OPENAI_ENDPOINT"]; + var apiKey = config["AZURE_OPENAI_APIKEY"]; + var deploymentName = config["AZURE_OPENAI_MODEL"] ?? "gpt-4o-mini"; + + if (string.IsNullOrEmpty(endpoint) || string.IsNullOrEmpty(apiKey)) + { + Console.WriteLine("āŒ Missing Azure OpenAI configuration"); + Console.WriteLine("Please set the following user secrets:"); + Console.WriteLine(" dotnet user-secrets set 'AZURE_OPENAI_ENDPOINT' 'https://your-resource.openai.azure.com/'"); + Console.WriteLine(" dotnet user-secrets set 'AZURE_OPENAI_APIKEY' 'your-api-key'"); + Console.WriteLine(" dotnet user-secrets set 'AZURE_OPENAI_MODEL' 'gpt-4o-mini' (optional)"); + return; + } + + // Create Azure OpenAI client with function calling + var client = new AzureOpenAIClient(new Uri(endpoint), new ApiKeyCredential(apiKey)) + .GetChatClient(deploymentName) + .AsIChatClient() + .AsBuilder() + .UseFunctionInvocation() + .Build(); + + // Define chat options with functions + var chatOptions = new ChatOptions + { + Tools = [ + AIFunctionFactory.Create(GetWeather), + AIFunctionFactory.Create(GetCurrentTime), + AIFunctionFactory.Create(CalculateDistance) + ] + }; + + Console.WriteLine($"šŸ¤– Using Azure OpenAI model: {deploymentName}"); + Console.WriteLine("šŸ”§ Available functions: GetWeather, GetCurrentTime, CalculateDistance"); + Console.WriteLine(); + + // Test various function calling scenarios + var questions = new[] + { + "What time is it right now?", + "What's the weather like today?", + "Should I bring an umbrella?", + "How far is it between New York and Los Angeles?", + "What's the current time and weather? Should I go for a walk?" + }; + + foreach (var question in questions) + { + Console.WriteLine($"ā“ Question: {question}"); + Console.Write("šŸ¤– Response: "); + + try + { + var response = await client.GetResponseAsync(question, chatOptions); + Console.WriteLine(response.Text); + } + catch (Exception ex) + { + Console.WriteLine($"āŒ Error: {ex.Message}"); + } + + Console.WriteLine(); + } + + Console.WriteLine("āœ… Function calling demo completed!"); + Console.WriteLine("šŸ’” Notice how the AI automatically called the appropriate functions to answer your questions"); +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine(); + Console.WriteLine("šŸ”§ Troubleshooting:"); + Console.WriteLine("• Verify your Azure OpenAI endpoint and API key"); + Console.WriteLine("• Ensure your model deployment supports function calling"); + Console.WriteLine("• Check that your Azure resource is properly configured"); +} + +// Function implementations + +[Description("Get the current weather conditions")] +static string GetWeather() +{ + // Simulate weather data + var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy", "windy" }; + var temperature = Random.Shared.Next(-5, 35); + var condition = conditions[Random.Shared.Next(conditions.Length)]; + var humidity = Random.Shared.Next(30, 90); + + var weather = $"Temperature: {temperature}°C, Conditions: {condition}, Humidity: {humidity}%"; + Console.WriteLine($" šŸŒ¤ļø [Function Call] Getting weather: {weather}"); + return weather; +} + +[Description("Get the current date and time")] +static string GetCurrentTime() +{ + var currentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + Console.WriteLine($" šŸ• [Function Call] Getting current time: {currentTime}"); + return $"Current date and time: {currentTime}"; +} + +[Description("Calculate the distance between two cities")] +static string CalculateDistance( + [Description("The first city")] string city1 = "New York", + [Description("The second city")] string city2 = "Los Angeles") +{ + // Simulate distance calculation (in reality, you'd use a mapping service) + var distances = new Dictionary<(string, string), int> + { + { ("New York", "Los Angeles"), 2445 }, + { ("New York", "Chicago"), 790 }, + { ("Los Angeles", "San Francisco"), 380 }, + { ("Chicago", "Detroit"), 280 }, + { ("Miami", "New York"), 1090 } + }; + + var key1 = (city1, city2); + var key2 = (city2, city1); + + if (distances.TryGetValue(key1, out var distance) || distances.TryGetValue(key2, out distance)) + { + var result = $"Distance between {city1} and {city2}: {distance} miles"; + Console.WriteLine($" šŸ—ŗļø [Function Call] Calculating distance: {result}"); + return result; + } + + // Default calculation for unknown cities + var estimatedDistance = Random.Shared.Next(100, 3000); + var result2 = $"Estimated distance between {city1} and {city2}: {estimatedDistance} miles"; + Console.WriteLine($" šŸ—ŗļø [Function Call] Estimating distance: {result2}"); + return result2; +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/11-advanced-rag-vectors.cs b/03.1-CoreGenerativeAITechniques-runapp/src/11-advanced-rag-vectors.cs new file mode 100644 index 0000000..cabb21f --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/11-advanced-rag-vectors.cs @@ -0,0 +1,133 @@ +using Microsoft.Extensions.AI; +using Microsoft.SemanticKernel.Connectors.InMemory; + +// Advanced RAG with Vector Search +// This demo shows how to implement Retrieval-Augmented Generation with embeddings + +Console.WriteLine("šŸ” Advanced RAG with Vector Search Demo"); +Console.WriteLine(); + +try +{ + // Setup in-memory vector store + var vectorStore = new InMemoryVectorStore(); + var moviesCollection = vectorStore.GetCollection>("movies"); + await moviesCollection.EnsureCollectionExistsAsync(); + + Console.WriteLine("šŸ“š Setting up knowledge base with movie information..."); + + // Create embeddings generator (using Ollama locally) + IEmbeddingGenerator> embeddingGenerator; + + try + { + embeddingGenerator = new OllamaEmbeddingGenerator(new Uri("http://localhost:11434/"), "all-minilm"); + Console.WriteLine("āœ… Connected to Ollama for embeddings (all-minilm model)"); + } + catch + { + Console.WriteLine("āŒ Could not connect to Ollama. Please ensure:"); + Console.WriteLine(" 1. Ollama is running: ollama serve"); + Console.WriteLine(" 2. The embedding model is available: ollama pull all-minilm"); + return; + } + + // Load movie data and generate embeddings + var movieData = MovieFactory.GetMovieVectorList(); + Console.WriteLine($"šŸ“½ļø Processing {movieData.Count} movies..."); + + foreach (var movie in movieData) + { + Console.WriteLine($" Embedding: {movie.Title}"); + movie.Vector = await embeddingGenerator.GenerateVectorAsync(movie.Description); + await moviesCollection.UpsertAsync(movie); + } + + Console.WriteLine(); + Console.WriteLine("šŸ” Vector store ready! Let's search for movies..."); + Console.WriteLine(); + + // Interactive search loop + var searchQueries = new[] + { + "A family friendly movie that includes ogres and dragons", + "Science fiction with space battles and robots", + "A romantic comedy with time travel", + "Action movie with superheroes saving the world", + "Animated movie about talking toys" + }; + + foreach (var query in searchQueries) + { + Console.WriteLine($"šŸ”Ž Query: \"{query}\""); + Console.WriteLine("šŸ“Š Top matches:"); + + // Generate embedding for the search query + var queryEmbedding = await embeddingGenerator.GenerateVectorAsync(query); + + // Search the vector store + var results = new List<(MovieVector Movie, double Score)>(); + await foreach (var result in moviesCollection.SearchAsync(queryEmbedding, top: 3)) + { + results.Add((result.Record, result.Score)); + } + + // Display results + for (int i = 0; i < results.Count; i++) + { + var (movie, score) = results[i]; + Console.WriteLine($" {i + 1}. {movie.Title} (Score: {score:F3})"); + Console.WriteLine($" {movie.Description}"); + Console.WriteLine(); + } + + Console.WriteLine("---"); + Console.WriteLine(); + } + + Console.WriteLine("āœ… RAG Vector Search demo completed!"); + Console.WriteLine(); + Console.WriteLine("šŸ’” Key concepts demonstrated:"); + Console.WriteLine(" • Vector embeddings for semantic search"); + Console.WriteLine(" • In-memory vector storage"); + Console.WriteLine(" • Similarity scoring and ranking"); + Console.WriteLine(" • Knowledge retrieval for AI enhancement"); +} +catch (Exception ex) +{ + Console.WriteLine($"āŒ Error: {ex.Message}"); + Console.WriteLine(); + Console.WriteLine("šŸ”§ Troubleshooting:"); + Console.WriteLine("• Ensure Ollama is running with the all-minilm model"); + Console.WriteLine("• Check that the semantic kernel packages are properly installed"); +} + +// Movie data factory (simplified version) +public static class MovieFactory +{ + public static List> GetMovieVectorList() + { + return new List> + { + new() { Key = (T)(object)1, Title = "Shrek", Description = "An ogre embarks on a quest to rescue a princess from a dragon-guarded tower, discovering friendship and love along the way. Family-friendly animated comedy with fairy tale characters." }, + new() { Key = (T)(object)2, Title = "Star Wars", Description = "Epic space opera featuring rebels fighting against an evil galactic empire, with Jedi knights, lightsabers, and the Force. Classic science fiction adventure." }, + new() { Key = (T)(object)3, Title = "The Matrix", Description = "A hacker discovers reality is a simulation and joins a rebellion against machines that have enslaved humanity. Cyberpunk action with philosophical themes." }, + new() { Key = (T)(object)4, Title = "Toy Story", Description = "Animated tale of toys that come to life when humans aren't around, focusing on friendship and loyalty. Pixar's groundbreaking computer-animated family film." }, + new() { Key = (T)(object)5, Title = "Groundhog Day", Description = "A weatherman gets trapped in a time loop, reliving the same day repeatedly until he learns to become a better person. Romantic comedy with fantasy elements." }, + new() { Key = (T)(object)6, Title = "The Avengers", Description = "Superheroes team up to save Earth from an alien invasion, featuring Iron Man, Captain America, Thor, and Hulk. Action-packed Marvel superhero ensemble." }, + new() { Key = (T)(object)7, Title = "Finding Nemo", Description = "A clownfish searches the ocean for his lost son with the help of a forgetful blue tang fish. Heartwarming Pixar animated adventure about family." }, + new() { Key = (T)(object)8, Title = "Inception", Description = "A thief who steals secrets from dreams is tasked with planting an idea instead. Mind-bending science fiction thriller about reality and dreams." }, + new() { Key = (T)(object)9, Title = "The Lion King", Description = "A young lion prince flees his kingdom after his father's death, later returning to reclaim his throne. Disney animated musical about courage and responsibility." }, + new() { Key = (T)(object)10, Title = "Back to the Future", Description = "A teenager accidentally travels back in time and must ensure his parents fall in love to secure his existence. Science fiction comedy about time travel." } + }; + } +} + +// Movie vector model +public class MovieVector +{ + public T Key { get; set; } = default!; + public string Title { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public Embedding? Vector { get; set; } +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/run-demo.ps1 b/03.1-CoreGenerativeAITechniques-runapp/src/run-demo.ps1 new file mode 100644 index 0000000..bd85646 --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/run-demo.ps1 @@ -0,0 +1,70 @@ +# Single-file .NET demo runner for Windows +# This script simulates .NET 10's "dotnet run file.cs" functionality +# Usage: .\run-demo.ps1 01-llm-completion.cs + +param( + [Parameter(Mandatory=$false)] + [string]$DemoFile +) + +if (-not $DemoFile) { + Write-Host "Usage: .\run-demo.ps1 " + Write-Host "" + Write-Host "Available demos:" + Get-ChildItem -Filter "*.cs" | Sort-Object Name | ForEach-Object { Write-Host " $($_.Name)" } + exit 1 +} + +if (-not (Test-Path $DemoFile)) { + Write-Host "Error: File '$DemoFile' not found" -ForegroundColor Red + exit 1 +} + +$DemoName = [System.IO.Path]::GetFileNameWithoutExtension($DemoFile) + +Write-Host "šŸš€ Running $DemoFile (simulating 'dotnet run $DemoFile')" -ForegroundColor Green +Write-Host "Note: When .NET 10 is available, use: dotnet run $DemoFile" -ForegroundColor Yellow +Write-Host "" + +# Create temporary project directory +$TempDir = Join-Path $env:TEMP "dotnet-run-$DemoName-$(Get-Random)" +New-Item -ItemType Directory -Path $TempDir -Force | Out-Null + +try { + # Copy the demo file as Program.cs + Copy-Item $DemoFile (Join-Path $TempDir "Program.cs") + + # Create project file + $ProjectContent = @" + + + Exe + net9.0 + enable + enable + 03-1-core-generative-ai-runapp + + + + + + + + + + +"@ + + $ProjectContent | Out-File -FilePath (Join-Path $TempDir "TempDemo.csproj") -Encoding UTF8 + + # Build and run in the temp directory + Push-Location $TempDir + dotnet run +} +finally { + # Cleanup + Pop-Location + if (Test-Path $TempDir) { + Remove-Item -Path $TempDir -Recurse -Force + } +} \ No newline at end of file diff --git a/03.1-CoreGenerativeAITechniques-runapp/src/run-demo.sh b/03.1-CoreGenerativeAITechniques-runapp/src/run-demo.sh new file mode 100755 index 0000000..181f62f --- /dev/null +++ b/03.1-CoreGenerativeAITechniques-runapp/src/run-demo.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Single-file .NET demo runner +# This script simulates .NET 10's "dotnet run file.cs" functionality +# Usage: ./run-demo.sh 01-llm-completion.cs + +if [ $# -eq 0 ]; then + echo "Usage: ./run-demo.sh " + echo "" + echo "Available demos:" + ls *.cs 2>/dev/null | sort + exit 1 +fi + +DEMO_FILE=$1 +DEMO_NAME=$(basename "$DEMO_FILE" .cs) + +if [ ! -f "$DEMO_FILE" ]; then + echo "Error: File '$DEMO_FILE' not found" + exit 1 +fi + +echo "šŸš€ Running $DEMO_FILE (simulating 'dotnet run $DEMO_FILE')" +echo "Note: When .NET 10 is available, use: dotnet run $DEMO_FILE" +echo "" + +# Create temporary project directory +TEMP_DIR="/tmp/dotnet-run-$DEMO_NAME-$$" +mkdir -p "$TEMP_DIR" + +# Copy the demo file as Program.cs +cp "$DEMO_FILE" "$TEMP_DIR/Program.cs" + +# Create project file +cat > "$TEMP_DIR/TempDemo.csproj" << EOF + + + Exe + net9.0 + enable + enable + 03-1-core-generative-ai-runapp + + + + + + + + + + +EOF + +# Build and run in the temp directory +cd "$TEMP_DIR" +dotnet run + +# Cleanup +cd - > /dev/null +rm -rf "$TEMP_DIR" \ No newline at end of file