115 lines
4.4 KiB
C#
115 lines
4.4 KiB
C#
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/");
|
||
}
|
||
private const int MaxCodeLength = 1500;
|
||
|
||
private string BuildSafeContext(CodeChunk chunk)
|
||
{
|
||
// Метаданные (оставляем всегда целиком)
|
||
string metadata = $"File: {chunk.FilePath}\nEntity: {chunk.EntityName}\nCode:\n";
|
||
|
||
// Вычисляем, сколько символов у нас осталось для самого кода
|
||
int remainingLength = MaxCodeLength - metadata.Length;
|
||
|
||
string code = chunk.Content;
|
||
|
||
// Если код слишком длинный — аккуратно отрезаем хвост
|
||
if (code.Length > remainingLength && remainingLength > 0)
|
||
{
|
||
code = code.Substring(0, remainingLength) + "\n...[TRUNCATED]";
|
||
Console.WriteLine($"[ВЕКТОРИЗАЦИЯ] Метод {chunk.EntityName} слишком длинный. Обрезан до {MaxCodeLength} символов.");
|
||
}
|
||
|
||
return metadata + code;
|
||
}
|
||
|
||
|
||
|
||
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 = BuildSafeContext(chunk);
|
||
|
||
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.Embedding = result.vector;
|
||
Console.WriteLine($"[+] Векторизована сущность: {chunk.EntityName}");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"[-] Ошибка API для {chunk.EntityName}: {response.StatusCode}");
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[-] Ошибка подключения к Python-сервису: {ex.Message}");
|
||
}
|
||
}
|
||
return chunks;
|
||
}
|
||
}
|
||
}
|