Skip to content

Commit 602c7bf

Browse files
committed
testing with IP
1 parent 5de10bd commit 602c7bf

File tree

5 files changed

+64
-14
lines changed

5 files changed

+64
-14
lines changed

services/video-search/src/config.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,29 @@ let {
1010
LOG_STREAM,
1111
NODE_ENV,
1212
YOUTUBE_VIDEOS,
13+
YOUTUBE_TRANSCRIPT_PREFIX,
14+
YOUTUBE_VIDEO_INFO_PREFIX,
1315
REDIS_URL,
1416
SEARCHAPI_API_KEY,
1517
GOOGLE_VIDEO_INDEX_NAME,
1618
GOOGLE_VIDEO_PREFIX,
19+
GOOGLE_ANSWER_INDEX_NAME,
20+
GOOGLE_ANSWER_PREFIX,
1721
GOOGLE_API_KEY,
1822
GOOGLE_EMBEDDING_MODEL,
1923
GOOGLE_SUMMARY_MODEL,
2024
GOOGLE_VECTOR_SET,
2125
GOOGLE_SUMMARY_PREFIX,
22-
GOOGLE_ANSWER_PREFIX,
2326
OPENAI_VIDEO_INDEX_NAME,
2427
OPENAI_VIDEO_PREFIX,
28+
OPENAI_ANSWER_INDEX_NAME,
29+
OPENAI_ANSWER_PREFIX,
2530
OPENAI_API_KEY,
2631
OPENAI_ORGANIZATION,
2732
OPENAI_EMBEDDING_MODEL,
2833
OPENAI_SUMMARY_MODEL,
2934
OPENAI_VECTOR_SET,
3035
OPENAI_SUMMARY_PREFIX,
31-
OPENAI_ANSWER_PREFIX,
3236
USE,
3337
} = process.env;
3438

@@ -41,6 +45,9 @@ const DEFAULT_VIDEO_PREFIX = 'video:';
4145
const DEFAULT_VECTOR_SET = 'video-vectors';
4246
const DEFAULT_SUMMARY_PREFIX = 'video-summary:';
4347
const DEFAULT_ANSWER_PREFIX = 'video-answer:';
48+
const DEFAULT_ANSWER_INDEX_NAME = 'idx-answers';
49+
const DEFAULT_YOUTUBE_TRANSCRIPT_PREFIX = 'transcripts:';
50+
const DEFAULT_YOUTUBE_VIDEO_INFO_PREFIX = 'yt-videos:';
4451

4552
export default {
4653
app: {
@@ -68,8 +75,10 @@ export default {
6875
YOUTUBE_VIDEOS ??
6976
'AJhTduDOVCs,c9Rr--1r6pk,FQzlq91g7mg,I-ohlZXXaxs,KUfufrwpBkM,LaiQFZ5bXaM,SzcpwtLRgyk,Z8qcpXyMAiA'
7077
).split(','),
71-
TRANSCRIPT_PREFIX: 'transcripts:',
72-
VIDEO_INFO_PREFIX: 'yt-videos:',
78+
TRANSCRIPT_PREFIX:
79+
YOUTUBE_TRANSCRIPT_PREFIX ?? DEFAULT_YOUTUBE_TRANSCRIPT_PREFIX,
80+
VIDEO_INFO_PREFIX:
81+
YOUTUBE_VIDEO_INFO_PREFIX ?? DEFAULT_YOUTUBE_VIDEO_INFO_PREFIX,
7382
},
7483
redis: {
7584
REDIS_URL: REDIS_URL ?? 'redis://localhost:6379',
@@ -87,6 +96,8 @@ export default {
8796
VECTOR_SET: GOOGLE_VECTOR_SET ?? `google-${DEFAULT_VECTOR_SET}`,
8897
SUMMARY_PREFIX:
8998
GOOGLE_SUMMARY_PREFIX ?? `google-${DEFAULT_SUMMARY_PREFIX}`,
99+
ANSWER_INDEX_NAME:
100+
GOOGLE_ANSWER_INDEX_NAME ?? `google-${DEFAULT_ANSWER_INDEX_NAME}`,
90101
ANSWER_PREFIX:
91102
GOOGLE_ANSWER_PREFIX ?? `google-${DEFAULT_ANSWER_PREFIX}`,
92103
},
@@ -101,6 +112,8 @@ export default {
101112
VECTOR_SET: OPENAI_VECTOR_SET ?? `openai-${DEFAULT_VECTOR_SET}`,
102113
SUMMARY_PREFIX:
103114
OPENAI_SUMMARY_PREFIX ?? `openai-${DEFAULT_SUMMARY_PREFIX}`,
115+
ANSWER_INDEX_NAME:
116+
OPENAI_ANSWER_INDEX_NAME ?? `openai-${DEFAULT_ANSWER_INDEX_NAME}`,
104117
ANSWER_PREFIX:
105118
OPENAI_ANSWER_PREFIX ?? `openai-${DEFAULT_ANSWER_PREFIX}`,
106119
},

services/video-search/src/google/config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
GoogleGenerativeAIEmbeddings,
77
} from '@langchain/google-genai';
88
import { TaskType } from '@google/generative-ai';
9+
import { VectorAlgorithms } from 'redis';
910

1011
export const llm = new ChatGoogleGenerativeAI({
1112
apiKey: config.google.API_KEY,
@@ -25,4 +26,18 @@ export const vectorStore = new RedisVectorStore(getEmbeddings(), {
2526
redisClient: client,
2627
indexName: config.google.VIDEO_INDEX_NAME,
2728
keyPrefix: config.google.VIDEO_PREFIX,
29+
indexOptions: {
30+
ALGORITHM: VectorAlgorithms.HNSW,
31+
DISTANCE_METRIC: 'COSINE',
32+
},
33+
});
34+
35+
export const answerVectorStore = new RedisVectorStore(getEmbeddings(), {
36+
redisClient: client,
37+
indexName: config.google.ANSWER_INDEX_NAME,
38+
keyPrefix: config.google.ANSWER_PREFIX,
39+
indexOptions: {
40+
ALGORITHM: VectorAlgorithms.HNSW,
41+
DISTANCE_METRIC: 'L2',
42+
},
2843
});

services/video-search/src/google/search.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import { Document } from 'langchain/document';
12
import * as summarize from './summarize.js';
23
import { type VideoDocument } from '../transcripts/index.js';
3-
import { llm, vectorStore } from './config.js';
4+
import { llm, vectorStore, answerVectorStore } from './config.js';
45
import log from '../log.js';
56
import config from '../config.js';
67
import { ANSWER_PROMPT } from '../templates/answers.js';
78
import { StringOutputParser } from 'langchain/schema/output_parser';
8-
import { cacheAside } from '../db.js';
99

1010
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1111
const questionAnswerChain = ANSWER_PROMPT.pipe(llm as any).pipe(
@@ -29,29 +29,45 @@ async function getVideos(question: string) {
2929
>);
3030
}
3131

32-
const answerCache = cacheAside(config.google.ANSWER_PREFIX);
33-
3432
async function getAnswer(question: string, videos: VideoDocument[]) {
3533
log.debug(`Getting answer for question: ${question}`, {
3634
location: 'google.search.getAnswer',
3735
});
3836

39-
const cachedAnswer = await answerCache.get(question);
37+
const haveAnswers = await answerVectorStore.checkIndexExists();
4038

41-
if (typeof cachedAnswer === 'string') {
42-
log.debug(`Found cached answer for question: ${question}`, {
39+
if (haveAnswers) {
40+
log.debug(`Searching for closest answer to question: ${question}`, {
4341
location: 'google.search.getAnswer',
42+
question,
4443
});
4544

46-
return cachedAnswer;
45+
const [result] = await answerVectorStore.similaritySearchWithScore(
46+
question,
47+
1,
48+
);
49+
50+
log.debug(`Found closest answer with score: ${String(result[1])}`, {
51+
location: 'google.search.getAnswer',
52+
answer: result[0],
53+
score: result[1],
54+
});
4755
}
4856

4957
const answer = (await questionAnswerChain.invoke({
5058
question,
5159
data: JSON.stringify(videos),
5260
})) as string;
5361

54-
await answerCache.set(question, answer);
62+
await answerVectorStore.addDocuments([
63+
new Document({
64+
metadata: {
65+
videos,
66+
answer,
67+
},
68+
pageContent: question,
69+
}),
70+
]);
5571

5672
return answer;
5773
}

services/video-search/src/openai/config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ export const vectorStore = new RedisVectorStore(getEmbeddings(), {
2727
indexName: config.openai.VIDEO_INDEX_NAME,
2828
keyPrefix: config.openai.VIDEO_PREFIX,
2929
});
30+
31+
export const answerVectorStore = new RedisVectorStore(getEmbeddings(), {
32+
redisClient: client,
33+
indexName: config.openai.ANSWER_INDEX_NAME,
34+
keyPrefix: config.openai.ANSWER_PREFIX,
35+
});

services/video-search/src/templates/questions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { PromptTemplate } from 'langchain/prompts';
22

33
const questionTemplate = `
44
You are an expert in summarizing questions.
5-
Your goal is to reduce a question down to its simplest form while still retaining the semantic meaning.
5+
Your goal is to reduce a question down to its simplest form while still retaining the semantic meaning. Try to be as deterministic as possible.
66
Below you find the question:
77
--------
88
{question}

0 commit comments

Comments
 (0)