عنوان:

‫ساخت یک دستیار کدنویسی مبتنی بر مدل زبانی محلی با استفاده از #C و NET.


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۵/۱۸ ۱۰:۰۷
آدرس: www.dntips.ir
ابزارهای هوش مصنوعی مانند GitHub Copilot و Amazon CodeWhisperer به توسعه‌دهندگان کمک می‌کنند تا کدهای بهتری بنویسند و بهره‌وری خود را افزایش دهند. با این حال، این ابزارها معمولاً مبتنی بر ابر هستند، منبع بسته دارند و به محیط‌های توسعه خاص وابسته‌اند. در این مقاله، ما یک دستیار کدنویسی مبتنی بر مدل زبانی محلی (Local LLM) را با استفاده از #C و پلتفرم NET Core. طراحی می‌کنیم. این دستیار نه تنها قابلیت تحلیل کد و ارائه پیشنهادات عملی را دارد، بلکه به صورت کاملاً محلی، خصوصی و قابل تنظیم عمل می‌کند. هدف این است که توسعه‌دهندگان بتوانند ابزاری قدرتمند و انعطاف‌پذیر برای تحلیل کد و بهبود کیفیت پروژه‌های خود در اختیار داشته باشند.
این مقاله شما را با فرآیند گام‌به‌گام ساخت یک عامل هوشمند کدنویسی (Code Agent) آشنا می‌کند که از فناوری‌های مدرن .NET، از جمله Roslyn برای تحلیل سینتکس و مدل‌های زبانی محلی از طریق Ollama، بهره می‌برد. چه یک توسعه‌دهنده تازه‌کار باشید و چه حرفه‌ای، این راهنما به شما کمک می‌کند تا با مفاهیم کلیدی و کاربردهای عملی آن‌ها آشنا شوید.

چرا یک دستیار کدنویسی محلی بسازیم؟
ابزارهای هوش مصنوعی تجاری معمولاً به زیرساخت‌های ابری وابسته‌اند، که ممکن است نگرانی‌هایی در مورد حریم خصوصی داده‌ها، هزینه‌های اشتراک و محدودیت‌های یکپارچگی با محیط‌های خاص ایجاد کند. ساخت یک دستیار کدنویسی محلی با استفاده از #C و NET. مزایای متعددی دارد. این ابزار نه تنها امکان تحلیل کدهای پروژه را به صورت آفلاین فراهم می‌کند، بلکه کاملاً متن‌باز و قابل تنظیم است. از آنجا که از فناوری Roslyn (تحلیلگر سینتکس مایکروسافت) و مدل‌های زبانی محلی مانند CodeLlama استفاده می‌کند، می‌توانید آن را برای نیازهای خاص خود، از جمله تحلیل کدهای قدیمی، بهبود کیفیت کد یا حتی آموزش توسعه‌دهندگان، بهینه کنید.
این دستیار می‌تواند فایل‌های کد محلی را بخواند، سینتکس آن‌ها را تحلیل کند، پیشنهادات بهبود ارائه دهد و حتی در محیط‌های خط فرمان (CLI) یا رابط کاربری گرافیکی (UI) عمل کند. در ادامه، مراحل ساخت این ابزار را به صورت گام‌به‌گام بررسی می‌کنیم.

مرحله اول: راه‌اندازی مدل زبانی محلی با Ollama
اولین گام برای ساخت دستیار کدنویسی، راه‌اندازی یک مدل زبانی محلی است. در اینجا از Ollama، یک پلتفرم متن‌باز برای اجرای مدل‌های زبانی، استفاده می‌کنیم. این ابزار به شما امکان می‌دهد مدل‌های پیشرفته‌ای مانند CodeLlama را روی سیستم خود اجرا کنید.
برای نصب Ollama، دستور زیر را در ترمینال اجرا کنید:
curl -fsSL https://ollama.com/install.sh | sh
سپس مدل CodeLlama را دانلود کنید:
ollama pull codellama:latest
در نهایت، سرور Ollama را اجرا کنید:
ollama run codellama
با اجرای این دستور، سرور مدل زبانی روی آدرس http://localhost:11434 فعال می‌شود و آماده دریافت درخواست‌ها خواهد بود. این سرور به عنوان هسته اصلی برای پردازش درخواست‌های هوش مصنوعی عمل می‌کند.

مرحله دوم: ایجاد پروژه .NET
برای شروع، یک پروژه کنسول ساده در .NET ایجاد می‌کنیم. این پروژه به عنوان بستر اصلی برای دستیار کدنویسی ما عمل خواهد کرد. دستورات زیر را در ترمینال اجرا کنید:
dotnet new console -n CodeAgent
cd CodeAgent
سپس بسته‌های مورد نیاز را اضافه کنید:
dotnet add package Microsoft.CodeAnalysis.CSharp
dotnet add package Spectre.Console
dotnet add package Newtonsoft.Json
این بسته‌ها به ترتیب برای تحلیل سینتکس (Roslyn)، رابط کاربری خط فرمان پیشرفته (Spectre.Console) و پردازش داده‌های JSON (Newtonsoft.Json) استفاده می‌شوند.

مرحله سوم: پیاده‌سازی منطق اصلی عامل
کلاس CodeAgent هسته اصلی منطق دستیار کدنویسی است. این کلاس فایل‌های کد را می‌خواند، آن‌ها را با استفاده از Roslyn تحلیل می‌کند و پیشنهادات بهبود را از مدل زبانی دریافت می‌کند.
public class CodeAgent
{
    private readonly LLMClient _llm;

    public CodeAgent(LLMClient llm)
    {
        _llm = llm;
    }

    public async Task AnalyzeAsync(string path)
    {
        string code = File.ReadAllText(path);
        var syntaxTree = CSharpSyntaxTree.ParseText(code);
        var root = syntaxTree.GetRoot();
        string summary = RoslynAnalyzer.Analyze(root);
        string prompt = PromptBuilder.BuildPrompt(code, summary);
        string llmResponse = await _llm.SendAsync(prompt);
        AnsiConsole.MarkupLine($"[green]Suggestion from AI:[/]\n{llmResponse}");
    }
}
در این کد، فایل ورودی خوانده می‌شود و به یک درخت سینتکسی (Syntax Tree) تبدیل می‌شود. سپس تحلیلگر Roslyn خلاصه‌ای از ساختار کد تولید می‌کند و این اطلاعات به همراه کد اصلی به مدل زبانی ارسال می‌شود تا پیشنهادات بهبود ارائه شود.

مرحله چهارم: ارتباط با مدل زبانی
کلاس LLMClient وظیفه برقراری ارتباط با سرور Ollama را بر عهده دارد. این کلاس درخواست‌های HTTP را به سرور مدل زبانی ارسال کرده و پاسخ‌ها را دریافت می‌کند.
public class LLMClient
{
    private readonly HttpClient _http = new();

    public async Task<string> SendAsync(string prompt)
    {
        var body = new
        {
            model = "codellama",
            prompt = prompt,
            stream = false
        };
        var response = await _http.PostAsync(
            "http://localhost:11434/api/generate",
            new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"));
        string json = await response.Content.ReadAsStringAsync();
        var parsed = JObject.Parse(json);
        return parsed["response"]?.ToString() ?? "No response";
    }
}
این کد یک درخواست POST به سرور Ollama ارسال می‌کند و پاسخ مدل زبانی را به صورت رشته بازمی‌گرداند. استفاده از Newtonsoft.Json برای سریال‌سازی و تحلیل پاسخ‌های JSON ضروری است.

مرحله پنجم: تحلیل کد با Roslyn
تحلیلگر Roslyn به ما امکان می‌دهد ساختار کد را به صورت عمیق بررسی کنیم. در این مثال، یک تحلیل ساده برای شمارش تعداد کلاس‌ها و متدها ارائه شده است:
public static class RoslynAnalyzer
{
    public static string Analyze(SyntaxNode root)
    {
        var methodCount = root.DescendantNodes().OfType<MethodDeclarationSyntax>().Count();
        var classCount = root.DescendantNodes().OfType<ClassDeclarationSyntax>().Count();
        return $"This file contains {classCount} class(es) and {methodCount} method(s).";
    }
}
این تحلیلگر می‌تواند گسترش یابد تا ویژگی‌های پیچیده‌تری مانند شناسایی الگوهای ناکارآمد یا مشکلات احتمالی در کد را بررسی کند.

مرحله ششم: ساخت پرامپت برای مدل زبانی
پرامپت (Prompt) ورودی اصلی برای مدل زبانی است. کلاس PromptBuilder یک پرامپت ساختارمند ایجاد می‌کند که شامل خلاصه تحلیل Roslyn و کد اصلی است.
public static class PromptBuilder
{
    public static string BuildPrompt(string code, string summary)
    {
        return $"""
        You are an expert C# developer AI assistant.
        Here is a summary of the file:
        {summary}
        Analyze the following code for potential improvements, bugs, or best practices:
        ```
        {code}
        ```
        Provide concrete suggestions and explain why.
        """;
    }
}
این پرامپت به مدل زبانی دستور می‌دهد که کد را تحلیل کرده و پیشنهادات مشخصی ارائه دهد.

مرحله هفتم: نقطه ورودی برنامه
نقطه ورودی برنامه در فایل Program.cs تعریف می‌شود که مسیر فایل ورودی را از آرگومان‌های خط فرمان دریافت کرده و فرآیند تحلیل را آغاز می‌کند.
class Program
{
    static async Task Main(string[] args)
    {
        if (args.Length == 0)
        {
            AnsiConsole.MarkupLine("[red]Usage:[/] dotnet run <path-to-cs-file>");
            return;
        }
        var llm = new LLMClient();
        var agent = new CodeAgent(llm);
        await agent.AnalyzeAsync(args[0]);
    }
}
برای اجرای برنامه، کافی است دستور زیر را اجرا کنید:
dotnet run ./Example.cs
خروجی نمونه ممکن است شامل پیشنهاداتی مانند بررسی خالی بودن رشته‌ها یا اجتناب از اعداد جادویی (Magic Numbers) باشد.

نتیجه‌گیری
ساخت یک دستیار کدنویسی محلی با استفاده از #C و .NET نه تنها امکان تحلیل کد و بهبود کیفیت آن را فراهم می‌کند، بلکه به توسعه‌دهندگان اجازه می‌دهد تا ابزاری کاملاً قابل تنظیم و خصوصی داشته باشند. با ترکیب فناوری‌های قدرتمندی مانند Roslyn برای تحلیل سینتکس، Ollama برای اجرای مدل‌های زبانی محلی و Spectre.Console برای رابط کاربری جذاب، می‌توانید ابزاری بسازید که هم برای پروژه‌های کوچک و هم برای سیستم‌های پیچیده مناسب باشد. این رویکرد نه تنها به کاهش اشکالات و بهبود عملکرد کد کمک می‌کند، بلکه می‌تواند به عنوان پایه‌ای برای توسعه ابزارهای پیشرفته‌تر در آینده مورد استفاده قرار گیرد.


مشاهده مطلب اصلی