From 65f9fa9cd5fa0c09128b3326d535e268b95245c9 Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Fri, 13 Dec 2024 00:52:54 +0100 Subject: [PATCH] chore: clean up after bundle 0.9 release --- assets/styles/app.css | 8 +++ composer.json | 4 +- composer.lock | 24 ++++---- config/packages/llm_chain.yaml | 35 ++++++++++-- src/Blog/Embedder.php | 50 +++------------- tests/Blog/EmbedderTest.php | 101 --------------------------------- 6 files changed, 59 insertions(+), 163 deletions(-) delete mode 100644 tests/Blog/EmbedderTest.php diff --git a/assets/styles/app.css b/assets/styles/app.css index a3a7dcd..a546e8d 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -72,10 +72,18 @@ body { .rag & { background: #dc8b6e; + + a { + color: #f4e973; + } } .youtube & { background: #df3535; + + a { + color: #3e2926; + } } .wikipedia & { diff --git a/composer.json b/composer.json index 40b14ca..bb07f87 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "codewithkyrian/chromadb-php": "^0.3.0", "league/commonmark": "^2.6", "php-llm/llm-chain": "^0.9.3", - "php-llm/llm-chain-bundle": "dev-feat-prepare-0.8", + "php-llm/llm-chain-bundle": "^0.9", "phpdocumentor/reflection-docblock": "^5.5", "phpstan/phpdoc-parser": "^1.33", "runtime/frankenphp-symfony": "^0.2.0", @@ -93,8 +93,6 @@ "App\\Tests\\": "tests/" } }, - "minimum-stability": "stable", - "prefer-stable": true, "scripts": { "post-install-cmd": [ "@auto-scripts" diff --git a/composer.lock b/composer.lock index 2021d23..2a2d67d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b3492f124ff5c8349f283273cd9e42fc", + "content-hash": "18c7e48ce770bdde7cc49cde13bb84d2", "packages": [ { "name": "codewithkyrian/chromadb-php", @@ -1177,16 +1177,16 @@ }, { "name": "php-llm/llm-chain-bundle", - "version": "dev-feat-prepare-0.8", + "version": "0.9", "source": { "type": "git", "url": "https://github.com/php-llm/llm-chain-bundle.git", - "reference": "5db2d4643339e7dce884a6caea61e39b55ebc23a" + "reference": "ca77abb0bf1fab8d551408a6c95bd8ad2b69a982" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-llm/llm-chain-bundle/zipball/5db2d4643339e7dce884a6caea61e39b55ebc23a", - "reference": "5db2d4643339e7dce884a6caea61e39b55ebc23a", + "url": "https://api.github.com/repos/php-llm/llm-chain-bundle/zipball/ca77abb0bf1fab8d551408a6c95bd8ad2b69a982", + "reference": "ca77abb0bf1fab8d551408a6c95bd8ad2b69a982", "shasum": "" }, "require": { @@ -1197,9 +1197,9 @@ "symfony/framework-bundle": "^6.4 || ^7.0" }, "require-dev": { - "php-cs-fixer/shim": "^3.64", + "php-cs-fixer/shim": "^3.65", "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^11.5" }, "type": "symfony-bundle", "autoload": { @@ -1220,9 +1220,9 @@ "description": "Symfony integration bundle for php-llm/llm-chain", "support": { "issues": "https://github.com/php-llm/llm-chain-bundle/issues", - "source": "https://github.com/php-llm/llm-chain-bundle/tree/feat-prepare-0.8" + "source": "https://github.com/php-llm/llm-chain-bundle/tree/0.9" }, - "time": "2024-12-08T16:49:35+00:00" + "time": "2024-12-12T23:47:19+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -8376,10 +8376,8 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "php-llm/llm-chain-bundle": 20 - }, - "prefer-stable": true, + "stability-flags": {}, + "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=8.4", diff --git a/config/packages/llm_chain.yaml b/config/packages/llm_chain.yaml index 70a193f..8b5bdc6 100644 --- a/config/packages/llm_chain.yaml +++ b/config/packages/llm_chain.yaml @@ -1,9 +1,23 @@ llm_chain: platform: + # anthropic: + # api_key: '%env(ANTHROPIC_API_KEY)%' + # azure: + # gpt_deployment: + # base_url: '%env(AZURE_GPT_BASE_URL)%' + # deployment: '%env(AZURE_GPT_DEPLOYMENT)%' + # api_key: '%env(AZURE_GPT_API_KEY)%' + # api_version: '%env(AZURE_GPT_VERSION)%' + # embeddings_deployment: + # base_url: '%env(AZURE_EMBEDDINGS_BASE_URL)%' + # deployment: '%env(AZURE_EMBEDDINGS_DEPLOYMENT)%' + # api_key: '%env(AZURE_EMBEDDINGS_API_KEY)%' + # api_version: '%env(AZURE_EMBEDDINGS_VERSION)%' openai: api_key: '%env(OPENAI_API_KEY)%' chain: rag: + # platform: 'llm_chain.platform.anthropic' model: name: 'GPT' version: 'gpt-4o-mini' @@ -18,23 +32,34 @@ llm_chain: model: name: 'GPT' version: 'gpt-4o-mini' + options: + temperature: 0.5 tools: - 'PhpLlm\LlmChain\Chain\ToolBox\Tool\Wikipedia' store: chroma_db: symfonycon: - host: '%env(CHROMADB_HOST)%' collection: 'symfony_blog' + # web_summer_camp: + # host: '%env(CHROMADB_HOST)%' + # collection: 'wsc_program' + embedder: + default: + # platform: 'llm_chain.platform.anthropic' + # store: 'llm_chain.store.chroma_db.symfonycon' + model: + name: 'Embeddings' + version: 'text-embedding-ada-002' services: _defaults: autowire: true autoconfigure: true + # PhpLlm\LlmChain\Chain\ToolBox\Tool\Clock: ~ + # PhpLlm\LlmChain\Chain\ToolBox\Tool\OpenMeteo: ~ + # PhpLlm\LlmChain\Chain\ToolBox\Tool\SerpApi: + # $apiKey: '%env(SERP_API_KEY)%' PhpLlm\LlmChain\Chain\ToolBox\Tool\Wikipedia: ~ PhpLlm\LlmChain\Chain\ToolBox\Tool\SimilaritySearch: ~ - # TODO: move to configuration - PhpLlm\LlmChain\Bridge\OpenAI\Embeddings: ~ - PhpLlm\LlmChain\Model\EmbeddingsModel: '@PhpLlm\LlmChain\Bridge\OpenAI\Embeddings' - diff --git a/src/Blog/Embedder.php b/src/Blog/Embedder.php index 8cb8eec..86343fd 100644 --- a/src/Blog/Embedder.php +++ b/src/Blog/Embedder.php @@ -4,57 +4,25 @@ namespace App\Blog; -use Codewithkyrian\ChromaDB\Client; -use PhpLlm\LlmChain\Bridge\OpenAI\Embeddings; -use PhpLlm\LlmChain\Document\Vector; -use PhpLlm\LlmChain\Model\Response\AsyncResponse; -use PhpLlm\LlmChain\Model\Response\VectorResponse; -use PhpLlm\LlmChain\PlatformInterface; +use PhpLlm\LlmChain\Document\Metadata; +use PhpLlm\LlmChain\Document\TextDocument; +use PhpLlm\LlmChain\Embedder as LlmChainEmbedder; final readonly class Embedder { public function __construct( private Loader $loader, - private PlatformInterface $platform, - private Client $chromaClient, + private LlmChainEmbedder $embedder, ) { } public function embedBlog(): void { - $posts = $this->loader->load(); - $vectors = $this->createEmbeddings($posts); - $this->pushToChromaDB($posts, $vectors); - } - - /** - * @param Post[] $posts - * - * @return Vector[] - */ - private function createEmbeddings(array $posts): array - { - $texts = array_map(fn (Post $post) => $post->toString(), $posts); - $response = $this->platform->request(new Embeddings(), $texts); - - assert($response instanceof AsyncResponse); - $response = $response->unwrap(); - assert($response instanceof VectorResponse); - - return $response->getContent(); - } - - /** - * @param Post[] $posts - * @param Vector[] $vectors - */ - private function pushToChromaDB(array $posts, array $vectors): void - { - $collection = $this->chromaClient->getOrCreateCollection('symfony_blog'); - - $ids = array_map(fn (Post $post) => $post->id, $posts); - $vectors = array_map(fn (Vector $vector) => $vector->getData(), $vectors); + $documents = []; + foreach ($this->loader->load() as $post) { + $documents[] = new TextDocument($post->id, $post->toString(), new Metadata($post->toArray())); + } - $collection->upsert($ids, $vectors, $posts); + $this->embedder->embed($documents); } } diff --git a/tests/Blog/EmbedderTest.php b/tests/Blog/EmbedderTest.php deleted file mode 100644 index 51652be..0000000 --- a/tests/Blog/EmbedderTest.php +++ /dev/null @@ -1,101 +0,0 @@ -createMock(PlatformInterface::class); - $chromaClient = $this->createMock(Client::class); - $posts = $loader->load(); - $vectors = [ - new Vector([0.1, 0.2, 0.3]), - new Vector([0.4, 0.5, 0.6]), - new Vector([0.7, 0.8, 0.9]), - new Vector([1.0, 1.1, 1.2]), - new Vector([1.3, 1.4, 1.5]), - new Vector([1.6, 1.7, 1.8]), - new Vector([1.9, 2.0, 2.1]), - new Vector([2.2, 2.3, 2.4]), - new Vector([2.5, 2.6, 2.7]), - new Vector([2.8, 2.9, 3.0]), - ]; - $platform - ->method('request') - ->willReturn($this->createAsyncResponse($vectors)); - - $collection = $this->createMock(CollectionResource::class); - $chromaClient - ->expects($this->once()) - ->method('getOrCreateCollection') - ->with('symfony_blog') - ->willReturn($collection); - - $collection - ->expects($this->once()) - ->method('upsert') - ->with( - array_map(fn (Post $post) => $post->id, $posts), - array_map(fn (Vector $vector) => $vector->getData(), $vectors), - $posts, - ); - - $embedder = new Embedder($loader, $platform, $chromaClient); - $embedder->embedBlog(); - } - - /** - * @param Vector[] $vectors - */ - private function createAsyncResponse(array $vectors): AsyncResponse - { - $converter = new class($vectors) implements ResponseConverter { - /** - * @param Vector[] $vectors - */ - public function __construct(private readonly array $vectors) - { - } - - public function supports(Model $model, object|array|string $input): bool - { - return true; - } - - public function convert(HttpResponse $response, array $options = []): LlmResponse - { - return new VectorResponse(...$this->vectors); - } - }; - - return new AsyncResponse($converter, new MockResponse()); - } -}