AI Agents  

Part 2 — Building an AI Agent with Skills for Code Review and Auto-Fix in C#

AI Code Review Image

In Part 1, we built a simple AI-powered code review system using Git diff and an LLM.

That approach works well for basic automation, but modern AI systems are evolving into something much more powerful: AI Agents.

Instead of sending one large prompt to an LLM, AI Agents:

  • Collect Context

  • Invoke Tools

  • Execute Specialized Skills

  • Generate Fixes

  • Validate Outputs

  • Orchestrate Workflows Dynamically

In this article, we’ll build a modular AI Agent in C# capable of:

  • Reviewing Code

  • Analyzing Security Issues

  • Generating Fixes

  • Coordinating Multiple Skills

What Is an AI Agent?

Traditional LLM workflow:

Prompt → LLM → Response

AI Agent workflow:

Task
  ↓
Planner
  ↓
Skills / Tools
  ↓
LLM Reasoning
  ↓
Actions
  ↓
Validation
  ↓
Final Output

This makes the system far more intelligent and extensible.

What Are Skills?

Skills are modular capabilities an AI Agent can execute.

Examples:

SkillPurpose
Git Diff SkillExtract code changes
Security Review SkillDetect vulnerabilities
Performance Review SkillFind inefficient code
Fix Generator SkillGenerate fixes
Unit Test SkillCreate test cases
Validation SkillVerify generated code

Instead of one giant prompt, the agent orchestrates multiple focused operations.

Agent Architecture

Developer Request
        ↓
AI Agent
        ↓
Skill Orchestrator
   ┌──────────────┐
   │ Git Diff     │
   │ Code Review  │
   │ Fix Generator│
   │ Validation   │
   └──────────────┘
        ↓
LLM
        ↓
Review + Fix Output

Step 1 — Define a Skill Contract

public interface IAiSkill
{
    string Name { get; }

    Task<string> ExecuteAsync(AiContext context);
}

Every skill follows a standard contract.

Step 2 — Create Shared Context

public class AiContext
{
    public string GitDiff { get; set; }

    public List<string> Findings { get; set; }
        = new();
}

This shared context acts like agent memory.

Step 3 — Implement Git Diff Skill

public class GitDiffSkill : IAiSkill
{
    public string Name => "GitDiff";

    public async Task<string> ExecuteAsync(AiContext context)
    {
        string diff = await GitHelper.GetDiffAsync();

        context.GitDiff = diff;

        return diff;
    }
}

Step 4 — Implement Review Skill

public class CodeReviewSkill : IAiSkill
{
    private readonly IChatClient _chatClient;

    public string Name => "CodeReview";

    public CodeReviewSkill(IChatClient chatClient)
    {
        _chatClient = chatClient;
    }

    public async Task<string> ExecuteAsync(AiContext context)
    {
        string prompt = $@"
Review this C# git diff.

Focus on:
- Bugs
- Security
- Performance

Diff:
{context.GitDiff}
";

        string result =
            await _chatClient.GetResponseAsync(prompt);

        context.Findings.Add(result);

        return result;
    }
}

Step 5 — Add Fix Generation Skill

public class FixSuggestionSkill : IAiSkill
{
    private readonly IChatClient _chatClient;

    public string Name => "FixSuggestion";

    public FixSuggestionSkill(IChatClient chatClient)
    {
        _chatClient = chatClient;
    }

    public async Task<string> ExecuteAsync(AiContext context)
    {
        string findings =
            string.Join("\n", context.Findings);

        string prompt = $@"
Generate corrected C# code fixes
for these findings:

{findings}
";

        return await _chatClient.GetResponseAsync(prompt);
    }
}

Step 6 — Build Agent Orchestrator

public class CodeReviewAgent
{
    private readonly List<IAiSkill> _skills;

    public CodeReviewAgent(List<IAiSkill> skills)
    {
        _skills = skills;
    }

    public async Task RunAsync()
    {
        var context = new AiContext();

        foreach (var skill in _skills)
        {
            Console.WriteLine(
                $"Running: {skill.Name}");

            var result =
                await skill.ExecuteAsync(context);

            Console.WriteLine(result);
        }
    }
}

Final Thoughts

Part 2 introduced a modular AI Agent architecture.

Instead of:

  • One large prompt

we now have:

  • Reusable skills

  • Shared memory

  • Orchestrated workflows

  • Auto-fix generation

However, prompts are still embedded inside C# code.

In Part 3, we’ll externalize intelligence into reusable markdown-based skills.md files and dynamically load them into the agent.