Skip to content

Commit 6260f73

Browse files
author
Alexander Cherednikov
committed
Rector is installed
1 parent 0aab424 commit 6260f73

19 files changed

Lines changed: 168 additions & 445 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
### Что нужно установить
4545

4646
- Docker и Docker Compose
47-
- PHP 8.2+ с Composer
47+
- PHP 8.3+ с Composer
4848
- Make (опционально, для удобных команд)
4949

5050
### Запуск в одну команду

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"require-dev": {
8787
"friendsofphp/php-cs-fixer": "^3.87.2",
8888
"phpstan/phpstan": "^1.12.28",
89-
"rector/rector": "^1.2",
89+
"rector/rector": "^1.2.10",
9090
"symfony/maker-bundle": "^1.64"
9191
}
9292
}

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/services.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ services:
5454
App\Contract\ResponseGeneratorInterface:
5555
class: App\Service\Generation\LlamaResponseGenerator
5656

57-
# Main RAG Service - uses refactored implementation
57+
# Main RAG Service implementation
5858
App\Service\RAGServiceInterface:
59-
class: App\Service\RefactoredRAGService
59+
class: App\Service\RAGService
6060

6161
# LlamaService configuration
6262
App\Service\LlamaService:
@@ -65,4 +65,4 @@ services:
6565

6666
# HTTP Client for external services
6767
Symfony\Contracts\HttpClient\HttpClientInterface:
68-
class: Symfony\Component\HttpClient\HttpClient
68+
factory: ['Symfony\Component\HttpClient\HttpClient', 'create']

src/Command/ProductsChatCommand.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace App\Command;
66

7-
use App\Service\ImprovedRAGService;
7+
use App\Service\RAGService;
88
use Symfony\Component\Console\Attribute\AsCommand;
99
use Symfony\Component\Console\Command\Command;
1010
use Symfony\Component\Console\Input\InputInterface;
@@ -17,10 +17,10 @@
1717
)]
1818
final class ProductsChatCommand extends Command
1919
{
20-
private const SESSION_ID = 'chat_session';
20+
private const string SESSION_ID = 'chat_session';
2121

2222
public function __construct(
23-
private readonly ImprovedRAGService $ragService,
23+
private readonly RAGService $ragService,
2424
) {
2525
parent::__construct();
2626
}
@@ -82,7 +82,6 @@ private function displayChatResults(array $results, string $aiResponse, SymfonyS
8282
{
8383
$io->section('Рекомендации');
8484

85-
// Очищаем markdown и форматируем для консоли
8685
$cleanResponse = strip_tags(str_replace(['**', '*', '#', '`'], '', $aiResponse));
8786
$io->text($cleanResponse);
8887

src/Command/ProductsSearchCommand.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44

55
namespace App\Command;
66

7-
use Codewithkyrian\Transformers\Pipelines\Pipeline;
8-
9-
use function Codewithkyrian\Transformers\Pipelines\pipeline;
10-
11-
use Codewithkyrian\Transformers\Pipelines\Task;
12-
use Codewithkyrian\Transformers\Tensor\Tensor;
7+
use App\Service\EmbeddingConfigService;
138
use Qdrant\Config;
149
use Qdrant\Http\Transport;
1510
use Qdrant\Models\Request\SearchRequest;
@@ -29,10 +24,11 @@
2924
)]
3025
final class ProductsSearchCommand extends Command
3126
{
32-
private const COLLECTION_NAME = 'products';
27+
private const string COLLECTION_NAME = 'products';
3328

3429
private Qdrant $qdrantClient;
35-
private Pipeline $embedder;
30+
31+
private EmbeddingConfigService $embeddingService;
3632

3733
protected function configure(): void
3834
{
@@ -66,22 +62,15 @@ private function initializeServices(): void
6662
$config = new Config('http://localhost', 6333);
6763
$transport = new Transport(new Psr18Client(), $config);
6864
$this->qdrantClient = new Qdrant($transport);
69-
$this->embedder = pipeline(Task::Embeddings, 'onnx-community/Qwen3-Embedding-0.6B-ONNX');
65+
$this->embeddingService = new EmbeddingConfigService();
7066
}
7167

7268
/**
7369
* @return array<int, array<string, mixed>>
7470
*/
7571
private function searchProducts(string $query): array
7672
{
77-
$embedding = ($this->embedder)($query, pooling: 'mean', normalize: true);
78-
79-
if (is_array($embedding)) {
80-
$vector = $embedding[0];
81-
} else {
82-
$vector = $embedding instanceof Tensor ? $embedding[0] : [];
83-
}
84-
73+
$vector = $this->embeddingService->createEmbedding($query);
8574
$searchVector = new VectorStruct($vector, 'default');
8675
$searchRequest = new SearchRequest($searchVector);
8776
$searchRequest->setLimit(5)->setWithPayload(true)->setScoreThreshold(0.5);

src/Command/ProductsVectorizeCommand.php

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44

55
namespace App\Command;
66

7-
use Codewithkyrian\Transformers\Pipelines\Pipeline;
8-
9-
use function Codewithkyrian\Transformers\Pipelines\pipeline;
10-
11-
use Codewithkyrian\Transformers\Pipelines\Task;
12-
use Codewithkyrian\Transformers\Tensor\Tensor;
7+
use App\Service\EmbeddingConfigService;
138
use Qdrant\Config;
149
use Qdrant\Http\Transport;
1510
use Qdrant\Models\PointsStruct;
@@ -31,11 +26,12 @@
3126
)]
3227
final class ProductsVectorizeCommand extends Command
3328
{
34-
private const COLLECTION_NAME = 'products';
35-
private const DATA_FILE = __DIR__.'/../../data/products.json';
29+
private const string COLLECTION_NAME = 'products';
30+
private const string DATA_FILE = __DIR__.'/../../data/products.json';
3631

3732
private Qdrant $qdrantClient;
38-
private Pipeline $embedder;
33+
34+
private EmbeddingConfigService $embeddingService;
3935

4036
protected function configure(): void
4137
{
@@ -66,7 +62,7 @@ private function initializeServices(): void
6662
$config = new Config('http://localhost', 6333);
6763
$transport = new Transport(new Psr18Client(), $config);
6864
$this->qdrantClient = new Qdrant($transport);
69-
$this->embedder = pipeline(Task::Embeddings, 'onnx-community/Qwen3-Embedding-0.6B-ONNX');
65+
$this->embeddingService = new EmbeddingConfigService();
7066
}
7167

7268
private function loadProductData(): \Generator
@@ -99,7 +95,8 @@ private function prepareCollection(): void
9995
}
10096

10197
$createCollection = new CreateCollection();
102-
$createCollection->addVector(new VectorParams(1024, VectorParams::DISTANCE_COSINE), 'default');
98+
$vectorSize = $this->embeddingService->getVectorSize();
99+
$createCollection->addVector(new VectorParams($vectorSize, VectorParams::DISTANCE_COSINE), 'default');
103100
$this->qdrantClient->collections(self::COLLECTION_NAME)->create($createCollection);
104101
}
105102

@@ -141,7 +138,7 @@ private function processBatch(array $batch): void
141138
}
142139

143140
$text .= ' '.$product['brand'].' '.$product['category'];
144-
$embedding = ($this->embedder)($text, pooling: 'mean', normalize: true);
141+
$vector = $this->embeddingService->createEmbedding($text);
145142

146143
$payload = [
147144
'name' => $product['name'],
@@ -151,12 +148,6 @@ private function processBatch(array $batch): void
151148
'description' => $product['description'],
152149
];
153150

154-
if (is_array($embedding)) {
155-
$vector = $embedding[0];
156-
} else {
157-
$vector = $embedding instanceof Tensor ? $embedding[0] : [];
158-
}
159-
160151
$pointsStruct->addPoint(
161152
new PointStruct(
162153
$product['id'],

src/Command/RAGDemoCommand.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace App\Command;
66

77
use App\DTO\RAGSearchResult;
8-
use App\Service\ImprovedRAGService;
8+
use App\Service\RAGService;
99
use Symfony\Component\Console\Attribute\AsCommand;
1010
use Symfony\Component\Console\Command\Command;
1111
use Symfony\Component\Console\Input\InputInterface;
@@ -15,12 +15,12 @@
1515

1616
#[AsCommand(
1717
name: 'rag:demo',
18-
description: 'Демонстрация улучшенной RAG архитектуры с четким разделением этапов'
18+
description: 'Демонстрация RAG архитектуры с четким разделением этапов'
1919
)]
2020
final class RAGDemoCommand extends Command
2121
{
2222
public function __construct(
23-
private readonly ImprovedRAGService $ragService,
23+
private readonly RAGService $ragService,
2424
) {
2525
parent::__construct();
2626
}
@@ -111,11 +111,11 @@ private function displayRAGSteps(RAGSearchResult $result, SymfonyStyle $io): voi
111111

112112
$io->section('Retrieval');
113113
if ($result->hasResults()) {
114-
$io->text("Найдено товаров: {$result->getDocumentCount()}");
114+
$io->text("Найдено товаров: {$result->getResultCount()}");
115115

116116
$io->table(
117117
['#', 'Товар', 'Бренд', 'Цена', 'Релевантность'],
118-
array_map(function ($doc, $i) {
118+
array_map(function (array $doc, int $i): array {
119119
$payload = $doc['payload'];
120120
$price = number_format($payload['price'] / 100, 0, '.', ' ').'';
121121
$relevance = round($doc['score'] * 100, 1).'%';

0 commit comments

Comments
 (0)