Skip to content

Commit 6db942e

Browse files
author
Michał Żarnecki
committed
add customize section to documentation
1 parent 136df6b commit 6db942e

File tree

3 files changed

+123
-3
lines changed

3 files changed

+123
-3
lines changed

README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@ A Retrieval Augmented Generation application that combines the power of Large La
44

55
![Application Demo](img/app_running.gif)
66

7+
## Table of Contents
8+
9+
1. [Overview](#-overview)
10+
2. [Features](#-features)
11+
3. [Prerequisites](#-prerequisites)
12+
4. [Installation](#️-installation)
13+
5. [Usage](#-usage)
14+
- [Web Interface](#web-interface)
15+
- [API Endpoint](#api-endpoint)
16+
- [CLI Interface](#cli-interface)
17+
6. [Example Outputs](#-example-outputs)
18+
- [Basic Arithmetic](#basic-arithmetic)
19+
- [Complex Context Analysis](#complex-context-analysis)
20+
7. [Architecture](#-architecture)
21+
- [Basic Concept](#basic-concept)
22+
- [Detailed Architecture](#detailed-architecture)
23+
8. [Debugging](#-debugging)
24+
9. [Customize](#-customize)
25+
10. [Resources](#-resources)
26+
11. [Local Ollama Setup](#-local-ollama-setup)
27+
12. [Contributing](#-contributing)
28+
729
## 🎯 Overview
830

931
This application leverages OpenAI's GPT-4 and other LLMs to generate contextually relevant responses based on user input. It searches through a database of over 1,000 websites to provide accurate information, with special handling for disambiguating between entities with identical names. It can be used for semantic search and context aware question-answering for any text dataset.
@@ -136,6 +158,56 @@ docker rmi -f ankane/pgvector
136158
docker-compose up
137159
```
138160

161+
## 🎚 Customize
162+
- Use different LLMs. \
163+
You can pick from available LLMs: `GPT-4o, Claude-3.5, Llama3.2, Mixtral, Gemini2` \
164+
For using other ones you can just modify model name in LLM client class for model provider, for example `app/src/service/openai/GeneratedTextFromGPTProvider.php:13`
165+
```php
166+
final class GeneratedTextFromGPTProvider extends AbstractGPTAPIClient
167+
implements StageInterface, GeneratedTextProviderInterface
168+
{
169+
private string $model = 'gpt-4o';
170+
```
171+
- Use different embeddings model. \
172+
Modify `app/src/loadDocuments.php:13` and `app/src/process.php:20`. \
173+
Put there one of classes that implement `TextEncoderInterface` or create yours that satisfies interface.\
174+
Embedding size can have impact on text matching precision.
175+
- Modify system prompt. \
176+
Modify system prompt text in `\service\PromptResolver::getSystemPrompt()`. \
177+
You can add there additional instructions, example solutions (one-shot/few-shot) or some patterns of reasoning (chain of thought).
178+
```php
179+
private function getSystemPrompt(): string
180+
{
181+
return 'You are a helpful assistant that answers questions based on source documents.' . PHP_EOL;
182+
}
183+
```
184+
- Use different number of retrieved documents. \
185+
Change `$limit` in `DocumentProvider::getSimilarDocuments()`
186+
```php
187+
public function getSimilarDocuments(
188+
string $prompt,
189+
string $embeddingPrompt,
190+
bool $useReranking = false,
191+
int $limit = 10,
192+
string $distanceFunction = 'l2'
193+
) {
194+
```
195+
- Use reranking. \
196+
If too many documents are passed to LLM it may focus on wrong information. If number is too small on the other hand it's possible to miss most important sources.\
197+
Set `Payload::$useReranking` to `True` in `app/src/process.php:25`.
198+
- Use different text matching algorithm. \
199+
Change `$distanceFunction` in `DocumentProvider::getSimilarDocuments()`. \
200+
Pick one from l2|cosine|innerProduct or support other one (see https://github.com/pgvector/pgvector, section "Quering").
201+
```php
202+
public function getSimilarDocuments(
203+
string $prompt,
204+
string $embeddingPrompt,
205+
bool $useReranking = false,
206+
int $limit = 10,
207+
string $distanceFunction = 'l2'
208+
) {
209+
```
210+
139211
## 📚 Resources
140212

141213
- Dataset: "Website Classification" by Hetul Mehta on [Kaggle](https://www.kaggle.com/datasets/hetulmehta/website-classification)

app/src/service/DocumentProvider.php

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,23 @@
88

99
final class DocumentProvider extends AbstractDocumentRepository implements StageInterface
1010
{
11+
/**
12+
* @param string $prompt
13+
* @param string $embeddingPrompt
14+
* @param bool $useReranking
15+
* @param int $limit
16+
* @param string $distanceFunction l2|cosine|innerProduct
17+
* @return array
18+
*/
1119
public function getSimilarDocuments(
1220
string $prompt,
1321
string $embeddingPrompt,
14-
bool $useReranking = false
22+
bool $useReranking = false,
23+
int $limit = 10,
24+
string $distanceFunction = 'l2'
1525
): array {
16-
$stmt = $this->connection->prepare("SELECT name, text from document order by embedding <-> :embeddingPrompt limit 10;");
26+
$query = $this->getQueryForDistanceFunction($distanceFunction, $limit);
27+
$stmt = $this->connection->prepare($query);
1728
$stmt->execute(['embeddingPrompt' => $embeddingPrompt]);
1829
$documents = $stmt->fetchAll();
1930
error_log('RETRIEVED DOCUMENTS:'. PHP_EOL);
@@ -51,6 +62,37 @@ public function rerank(string $prompt, array $documents): array
5162
return $documentsReranked;
5263
}
5364

65+
private function getQueryForDistanceFunction(
66+
string $distanceFunction,
67+
int $limit = 10
68+
): string {
69+
switch ($distanceFunction) {
70+
case 'l2':
71+
return $this->getQueryForL2Distance($limit);
72+
case 'cosine':
73+
return $this->getQueryForCosineDistance($limit);
74+
case 'innerProduct':
75+
return $this->getQueryForInnerProduct($limit);
76+
default:
77+
throw new \LogicException('Unknown distance function: ' . $distanceFunction);
78+
}
79+
}
80+
81+
private function getQueryForL2Distance(int $limit = 10): string
82+
{
83+
return "SELECT name, text from document order by embedding <-> :embeddingPrompt limit {$limit};";
84+
}
85+
86+
private function getQueryForCosineDistance(int $limit = 10): string
87+
{
88+
return "SELECT name, text from document order by 1 - (embedding <=> :embeddingPrompt) limit {$limit};";
89+
}
90+
91+
private function getQueryForInnerProduct(int $limit = 10): string
92+
{
93+
return "SELECT name, text from document order by (embedding <#> :embeddingPrompt) * -1 limit {$limit};";
94+
}
95+
5496
/**
5597
* @param Payload $payload
5698
* @return Payload

app/src/service/PromptResolver.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ final class PromptResolver implements StageInterface
1010
{
1111
public function getPromptFromInput(): string
1212
{
13-
$prompt = $_POST['prompt'] ?? null;
13+
$prompt = $this->getSystemPrompt();
14+
$prompt .= $_POST['prompt'] ?? null;
1415
if (! $prompt) {
1516
$prompt = $argv[0] ?? null;
1617
}
@@ -28,4 +29,9 @@ public function __invoke($payload)
2829
{
2930
return $payload->setPrompt($this->getPromptFromInput());
3031
}
32+
33+
private function getSystemPrompt(): string
34+
{
35+
return 'You are a helpful assistant that answers questions based on source documents.' . PHP_EOL;
36+
}
3137
}

0 commit comments

Comments
 (0)