Добавьте файлы проекта.
This commit is contained in:
16
CodeBase/CodeBase.csproj
Normal file
16
CodeBase/CodeBase.csproj
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.6" />
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.6.0" />
|
||||||
|
<PackageReference Include="OpenAI" Version="2.12.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
CodeBase/CodeBase.http
Normal file
6
CodeBase/CodeBase.http
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@CodeBase_HostAddress = http://localhost:5236
|
||||||
|
|
||||||
|
GET {{CodeBase_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
3
CodeBase/CodeBase.slnx
Normal file
3
CodeBase/CodeBase.slnx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<Solution>
|
||||||
|
<Project Path="CodeBase.csproj" />
|
||||||
|
</Solution>
|
||||||
26
CodeBase/Controllers/CodeController.cs
Normal file
26
CodeBase/Controllers/CodeController.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
using CodeBase.Services;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace CodeBase.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class CodeController(CodeService service) : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpPost("analyze")]
|
||||||
|
public async Task<CodeChunk> AnalyzeRepository(string path, string name)
|
||||||
|
{
|
||||||
|
var chunks = await service.GetCodeChunksAsync(path, name);
|
||||||
|
return chunks[0];
|
||||||
|
}
|
||||||
|
[HttpPost("answer")]
|
||||||
|
public async Task<string> GetAnswer(string question, string name)
|
||||||
|
{
|
||||||
|
var answer = await service.GetAnswerAsync(name, question);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
CodeBase/Models/CodeChunk.cs
Normal file
12
CodeBase/Models/CodeChunk.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace CodeBase.Models
|
||||||
|
{
|
||||||
|
public class CodeChunk
|
||||||
|
{
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
public string ClassName { get; set; }
|
||||||
|
public string MethodName { get; set; }
|
||||||
|
public string Documentation { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
public float[] Vector { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
33
CodeBase/Program.cs
Normal file
33
CodeBase/Program.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using CodeBase.Services;
|
||||||
|
using CodeBase.Warehouse;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<ChunkWarehouse>();
|
||||||
|
builder.Services.AddTransient<VectorizationService>();
|
||||||
|
builder.Services.AddTransient<LlmService>();
|
||||||
|
builder.Services.AddScoped<LlmPromptBuilder>();
|
||||||
|
builder.Services.AddTransient<ChunkService>();
|
||||||
|
builder.Services.AddTransient<CodeService>();
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
23
CodeBase/Properties/launchSettings.json
Normal file
23
CodeBase/Properties/launchSettings.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": false,
|
||||||
|
"applicationUrl": "http://localhost:5236",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": false,
|
||||||
|
"applicationUrl": "https://localhost:7218;http://localhost:5236",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
CodeBase/Services/ChunkService.cs
Normal file
62
CodeBase/Services/ChunkService.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
|
namespace CodeBase.Services
|
||||||
|
{
|
||||||
|
public class ChunkService(VectorizationService vectorizationService)
|
||||||
|
{
|
||||||
|
public List<CodeChunk> ChunkCSharpFile(string filePath, string fileContent)
|
||||||
|
{
|
||||||
|
var chunks = new List<CodeChunk>();
|
||||||
|
var syntaxTree = CSharpSyntaxTree.ParseText(fileContent);
|
||||||
|
var root = syntaxTree.GetRoot();
|
||||||
|
|
||||||
|
// 1. Собираем методы (как и раньше)
|
||||||
|
var methods = root.DescendantNodes().OfType<MethodDeclarationSyntax>();
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
chunks.Add(new CodeChunk
|
||||||
|
{
|
||||||
|
FilePath = filePath,
|
||||||
|
MethodName = method.Identifier.Text,
|
||||||
|
Content = method.ToFullString().Trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. ДОБАВЛЯЕМ СБОР ENUM (Перечислений)
|
||||||
|
var enums = root.DescendantNodes().OfType<EnumDeclarationSyntax>();
|
||||||
|
foreach (var enumSyntax in enums)
|
||||||
|
{
|
||||||
|
chunks.Add(new CodeChunk
|
||||||
|
{
|
||||||
|
FilePath = filePath,
|
||||||
|
MethodName = enumSyntax.Identifier.Text, // Сохраняем имя енама
|
||||||
|
Content = enumSyntax.ToFullString().Trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. ДОБАВЛЯЕМ СБОР КЛАССОВ-МОДЕЛЕЙ (без методов)
|
||||||
|
var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
|
||||||
|
foreach (var classSyntax in classes)
|
||||||
|
{
|
||||||
|
// Берем только свойства, чтобы понимать структуру модели
|
||||||
|
var properties = classSyntax.Members.OfType<PropertyDeclarationSyntax>();
|
||||||
|
if (properties.Any())
|
||||||
|
{
|
||||||
|
chunks.Add(new CodeChunk
|
||||||
|
{
|
||||||
|
FilePath = filePath,
|
||||||
|
MethodName = classSyntax.Identifier.Text,
|
||||||
|
// Сохраняем объявление класса и его свойства
|
||||||
|
Content = $"class {classSyntax.Identifier.Text} {{\n" +
|
||||||
|
string.Join("\n", properties.Select(p => p.ToFullString().Trim())) +
|
||||||
|
"\n}"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
102
CodeBase/Services/CodeService.cs
Normal file
102
CodeBase/Services/CodeService.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
using CodeBase.Warehouse;
|
||||||
|
|
||||||
|
namespace CodeBase.Services
|
||||||
|
{
|
||||||
|
public class CodeService(ChunkService service,
|
||||||
|
ChunkWarehouse warehouse,
|
||||||
|
VectorizationService vectorizationService,
|
||||||
|
LlmService llmService)
|
||||||
|
{
|
||||||
|
public async Task<List<CodeChunk>> GetCodeChunksAsync(string path, string name)
|
||||||
|
{
|
||||||
|
if (!Path.Exists(path))
|
||||||
|
{
|
||||||
|
throw new Exception("Путь не найден");
|
||||||
|
}
|
||||||
|
|
||||||
|
var allChunks = new List<CodeChunk>();
|
||||||
|
|
||||||
|
// Находим все .cs файлы во всех вложенных папках
|
||||||
|
var csFiles = Directory.GetFiles(path, "*.cs", SearchOption.AllDirectories);
|
||||||
|
|
||||||
|
foreach (var filePath in csFiles)
|
||||||
|
{
|
||||||
|
var content = File.ReadAllText(filePath);
|
||||||
|
|
||||||
|
// Парсим каждый файл отдельно, сохраняя его оригинальный путь
|
||||||
|
var fileChunks = service.ChunkCSharpFile(filePath, content);
|
||||||
|
|
||||||
|
allChunks.AddRange(fileChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
var chunks = await vectorizationService.EnrichChunksWithVectorsAsync(allChunks);
|
||||||
|
|
||||||
|
warehouse.UpsertDictionary(name, allChunks);
|
||||||
|
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetAnswerAsync(string name, string question)
|
||||||
|
{
|
||||||
|
var query = await vectorizationService.GetVectorAsync(question);
|
||||||
|
|
||||||
|
var answerVectors = Search(query, name, 15);
|
||||||
|
|
||||||
|
var answer = await llmService.AskQuestionAsync(question, answerVectors.Select(s => s.Chunk).ToList());
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Главный метод поиска
|
||||||
|
public List<(CodeChunk Chunk, float Score)> Search(
|
||||||
|
float[] queryVector,
|
||||||
|
string name,
|
||||||
|
int topK = 3) // Возвращаем топ-3 результата
|
||||||
|
{
|
||||||
|
var memoryBase = warehouse.GetChunks(name);
|
||||||
|
|
||||||
|
var results = new List<(CodeChunk, float)>();
|
||||||
|
|
||||||
|
foreach (var chunk in memoryBase)
|
||||||
|
{
|
||||||
|
if (chunk.Vector == null || chunk.Vector.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Считаем близость вектора вопроса к вектору кода
|
||||||
|
float similarity = CalculateCosineSimilarity(queryVector, chunk.Vector);
|
||||||
|
results.Add((chunk, similarity));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сортируем по убыванию сходства (чем ближе к 1, тем лучше)
|
||||||
|
return results
|
||||||
|
.OrderByDescending(x => x.Item2)
|
||||||
|
.Take(topK)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Математика косинусного сходства
|
||||||
|
private float CalculateCosineSimilarity(float[] vectorA, float[] vectorB)
|
||||||
|
{
|
||||||
|
if (vectorA.Length != vectorB.Length)
|
||||||
|
throw new ArgumentException("Векторы должны быть одинаковой длины (например, 768).");
|
||||||
|
|
||||||
|
float dotProduct = 0;
|
||||||
|
float magnitudeA = 0;
|
||||||
|
float magnitudeB = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < vectorA.Length; i++)
|
||||||
|
{
|
||||||
|
dotProduct += vectorA[i] * vectorB[i];
|
||||||
|
magnitudeA += vectorA[i] * vectorA[i];
|
||||||
|
magnitudeB += vectorB[i] * vectorB[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Защита от деления на ноль
|
||||||
|
if (magnitudeA == 0 || magnitudeB == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (float)(dotProduct / (Math.Sqrt(magnitudeA) * Math.Sqrt(magnitudeB)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
CodeBase/Services/LlmPromptBuilder.cs
Normal file
41
CodeBase/Services/LlmPromptBuilder.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
public class LlmPromptBuilder
|
||||||
|
{
|
||||||
|
public string BuildPrompt(string userQuestion, List<CodeChunk> foundChunks)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
// 1. Задаем жесткую роль и ограничения
|
||||||
|
sb.AppendLine("Ты — опытный разработчик и архитектор. Твоя задача — ответить на вопрос пользователя.");
|
||||||
|
sb.AppendLine("ОТВЕЧАЙ СТРОГО НА ОСНОВЕ ПРЕДОСТАВЛЕННОГО КОДА НИЖЕ.");
|
||||||
|
sb.AppendLine("Если в коде нет ответа на вопрос, честно скажи: «В данном фрагменте кода нет этой информации». Не придумывай функции, которых нет в тексте.");
|
||||||
|
|
||||||
|
sb.AppendLine("\n================ ПРЕДОСТАВЛЕННЫЙ КОД ================");
|
||||||
|
|
||||||
|
// 2. Вклеиваем найденные чанки с контекстом
|
||||||
|
foreach (var chunk in foundChunks)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"Файл: {chunk.FilePath}");
|
||||||
|
sb.AppendLine($"Класс: {chunk.ClassName}");
|
||||||
|
sb.AppendLine($"Метод: {chunk.MethodName}");
|
||||||
|
if (!string.IsNullOrEmpty(chunk.Documentation))
|
||||||
|
{
|
||||||
|
sb.AppendLine($"Документация: {chunk.Documentation}");
|
||||||
|
}
|
||||||
|
sb.AppendLine("Код:");
|
||||||
|
sb.AppendLine("```csharp");
|
||||||
|
sb.AppendLine(chunk.Content);
|
||||||
|
sb.AppendLine("```");
|
||||||
|
sb.AppendLine("--------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Добавляем сам вопрос
|
||||||
|
sb.AppendLine("\n================ ВОПРОС ПОЛЬЗОВАТЕЛЯ ================");
|
||||||
|
sb.AppendLine(userQuestion);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
62
CodeBase/Services/LlmService.cs
Normal file
62
CodeBase/Services/LlmService.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
using OpenAI;
|
||||||
|
using OpenAI.Chat;
|
||||||
|
using System;
|
||||||
|
using System.ClientModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class LlmService
|
||||||
|
{
|
||||||
|
private readonly ChatClient _chatClient;
|
||||||
|
private readonly LlmPromptBuilder _builder;
|
||||||
|
|
||||||
|
public LlmService(LlmPromptBuilder llmPromptBuilder)
|
||||||
|
{
|
||||||
|
// 1. Указываем адрес Ollama (обязательно с /v1 на конце для совместимости с OpenAI)
|
||||||
|
var options = new OpenAIClientOptions
|
||||||
|
{
|
||||||
|
Endpoint = new Uri("http://localhost:11434/v1")
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Ключ не нужен, но пакет просит хоть какую-то строку
|
||||||
|
var credential = new ApiKeyCredential("ollama");
|
||||||
|
|
||||||
|
// 3. ВАЖНО: Имя модели должно ТОЧНО совпадать с тем, что ты скачала в Ollama.
|
||||||
|
// Например, "llama3", "llama3.1", "qwen2.5-coder" или "phi3".
|
||||||
|
string modelName = "qwen2.5-coder:7b";
|
||||||
|
|
||||||
|
_chatClient = new ChatClient(modelName, credential, options);
|
||||||
|
|
||||||
|
_builder = llmPromptBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<String> AskQuestionAsync(string userQuestion, List<CodeChunk> foundChunks)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var finalPrompt = _builder.BuildPrompt(userQuestion, foundChunks);
|
||||||
|
// Формируем сообщение. Поскольку мы уже зашили роль и инструкции
|
||||||
|
// внутрь finalPrompt с помощью LlmPromptBuilder,
|
||||||
|
// передаем все это как UserMessage.
|
||||||
|
var messages = new ChatMessage[]
|
||||||
|
{
|
||||||
|
new UserChatMessage(finalPrompt)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Отправляем запрос (настройки опциональны)
|
||||||
|
var completionOptions = new ChatCompletionOptions
|
||||||
|
{
|
||||||
|
Temperature = 0.2f, // Делаем ответы менее креативными и более точными
|
||||||
|
};
|
||||||
|
|
||||||
|
ChatCompletion completion = await _chatClient.CompleteChatAsync(messages, completionOptions);
|
||||||
|
|
||||||
|
// Возвращаем сгенерированный текст
|
||||||
|
return completion.Content[0].Text;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return $"[-] Ошибка при обращении к LLM: {ex.Message}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
92
CodeBase/Services/VectorizationService.cs
Normal file
92
CodeBase/Services/VectorizationService.cs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
|
||||||
|
namespace CodeBase.Services
|
||||||
|
{
|
||||||
|
public class VectorizeRequest
|
||||||
|
{
|
||||||
|
public string text { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VectorizeResponse
|
||||||
|
{
|
||||||
|
public float[] vector { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VectorizationService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
|
public VectorizationService()
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient();
|
||||||
|
// Адрес нашего локального Python-сервиса
|
||||||
|
_httpClient.BaseAddress = new Uri("http://localhost:8000/");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<float[]> GetVectorAsync(string text)
|
||||||
|
{
|
||||||
|
var requestBody = new VectorizeRequest { text = text };
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Стучимся на наш Python-сервер (порт 8000)
|
||||||
|
var response = await _httpClient.PostAsJsonAsync("vectorize", requestBody);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var result = await response.Content.ReadFromJsonAsync<VectorizeResponse>();
|
||||||
|
return result?.vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"[-] Ошибка API при векторизации вопроса: {response.StatusCode}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[-] Ошибка подключения к Python-сервису: {ex.Message}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<CodeChunk>> EnrichChunksWithVectorsAsync(List<CodeChunk> chunks)
|
||||||
|
{
|
||||||
|
foreach (var chunk in chunks)
|
||||||
|
{
|
||||||
|
// 1. Склеиваем контекст
|
||||||
|
// Мы даем нейросети подсказку о том, где именно лежит этот код
|
||||||
|
string contextText = $"File: {chunk.FilePath}\nClass: {chunk.ClassName}\nMethod: {chunk.MethodName}\nCode:\n{chunk.Content}";
|
||||||
|
|
||||||
|
var requestBody = new VectorizeRequest { text = contextText };
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 2. Стучимся в Python
|
||||||
|
var response = await _httpClient.PostAsJsonAsync("vectorize", requestBody);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
// 3. Достаем массив чисел (обычно 768 элементов для GraphCodeBERT)
|
||||||
|
var result = await response.Content.ReadFromJsonAsync<VectorizeResponse>();
|
||||||
|
if (result != null && result.vector != null)
|
||||||
|
{
|
||||||
|
// 4. Сохраняем вектор прямо в наш объект в памяти
|
||||||
|
chunk.Vector = result.vector;
|
||||||
|
Console.WriteLine($"[+] Векторизован метод: {chunk.MethodName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[-] Ошибка API для {chunk.MethodName}: {response.StatusCode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[-] Ошибка подключения к Python-сервису: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
CodeBase/Warehouse/ChunkWarehouse.cs
Normal file
42
CodeBase/Warehouse/ChunkWarehouse.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using CodeBase.Models;
|
||||||
|
|
||||||
|
namespace CodeBase.Warehouse
|
||||||
|
{
|
||||||
|
public class ChunkWarehouse
|
||||||
|
{
|
||||||
|
public Dictionary<string, List<CodeChunk>> dictionary;
|
||||||
|
|
||||||
|
public ChunkWarehouse()
|
||||||
|
{
|
||||||
|
this.dictionary = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpsertDictionary(string name, List<CodeChunk> chunks)
|
||||||
|
{
|
||||||
|
if (dictionary.ContainsKey(name))
|
||||||
|
{
|
||||||
|
dictionary[name] = chunks;
|
||||||
|
}
|
||||||
|
else dictionary.TryAdd(name, chunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteElement(string name)
|
||||||
|
{
|
||||||
|
dictionary.Remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CodeChunk> GetChunks(string name)
|
||||||
|
{
|
||||||
|
if(dictionary.TryGetValue(name, out var chunks))
|
||||||
|
{
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
throw new Exception("Такого проекта нет");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearDictionary()
|
||||||
|
{
|
||||||
|
dictionary.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
CodeBase/appsettings.Development.json
Normal file
8
CodeBase/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
CodeBase/appsettings.json
Normal file
9
CodeBase/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
3
PythonProject/.idea/.gitignore
generated
vendored
Normal file
3
PythonProject/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
10
PythonProject/.idea/PythonProject.iml
generated
Normal file
10
PythonProject/.idea/PythonProject.iml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
PythonProject/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
PythonProject/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
7
PythonProject/.idea/misc.xml
generated
Normal file
7
PythonProject/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.11 (PythonProject)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (PythonProject)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
PythonProject/.idea/modules.xml
generated
Normal file
8
PythonProject/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/PythonProject.iml" filepath="$PROJECT_DIR$/.idea/PythonProject.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
30
PythonProject/main.py
Normal file
30
PythonProject/main.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from transformers import AutoTokenizer, AutoModel
|
||||||
|
import torch
|
||||||
|
import uvicorn # <-- Добавили импорт
|
||||||
|
|
||||||
|
app = FastAPI(title="GraphCodeBERT Vectorizer")
|
||||||
|
|
||||||
|
# Загружаем модель глобально при старте приложения
|
||||||
|
model_name = "microsoft/graphcodebert-base"
|
||||||
|
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
||||||
|
model = AutoModel.from_pretrained(model_name)
|
||||||
|
|
||||||
|
class ChunkRequest(BaseModel):
|
||||||
|
text: str
|
||||||
|
|
||||||
|
@app.post("/vectorize")
|
||||||
|
def vectorize(request: ChunkRequest):
|
||||||
|
inputs = tokenizer(request.text, return_tensors="pt", truncation=True, max_length=512)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
outputs = model(**inputs)
|
||||||
|
|
||||||
|
vector = outputs.last_hidden_state[:, 0, :].squeeze().tolist()
|
||||||
|
return {"vector": vector}
|
||||||
|
|
||||||
|
# <-- Добавили блок запуска
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("Запускаем сервер на порту 8000...")
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||||
5
PythonProject/requirements.txt
Normal file
5
PythonProject/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
fastapi
|
||||||
|
uvicorn
|
||||||
|
transformers
|
||||||
|
torch
|
||||||
|
pydantic
|
||||||
Reference in New Issue
Block a user