Files
CodeAnalizer/CodeBase/Services/CodeService.cs

73 lines
2.4 KiB
C#

using CodeBase.Models;
namespace CodeBase.Services
{
public class CodeService(ChunkService service,
GraphRepository repository,
VectorizationService vectorizationService,
LlmService llmService)
{
public async Task<List<CodeChunk>> GetCodeChunksAsync(string path, string name)
{
if (!Path.Exists(path))
{
throw new Exception("Путь не найден");
}
var allChunks = await service.ParseProjectAsync(path);
var chunks = await vectorizationService.EnrichChunksWithVectorsAsync(allChunks);
await repository.SaveChunksAsync(name, chunks);
return chunks;
}
public async Task<string> GetAnswerAsync(string name, string question)
{
var query = await vectorizationService.GetVectorAsync(question);
var answerVectors = await SearchAsync(query, name, 15);
var answer = await llmService.AskQuestionAsync(question, answerVectors);
return answer;
}
// Главный метод поиска
public async Task<List<GraphNodeContext>> SearchAsync(
float[] queryVector,
string name,
int topK = 3) // Возвращаем топ-3 результата
{
var results = await repository.SearchAsync(name, queryVector, topK);
return results;
}
// Математика косинусного сходства
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)));
}
}
}