lingyit1108 commited on
Commit
ac8a60b
1 Parent(s): bd54294

finishing QnA and functions calling plus pydantic

Browse files
notebooks/persisted-embedding-model.ipynb → archive/notebooks/002_persisted-embedding-model.ipynb RENAMED
@@ -8,14 +8,14 @@
8
  "outputs": [],
9
  "source": [
10
  "import openai\n",
11
- "from llama_index import SimpleDirectoryReader\n",
12
- "from llama_index import Document\n",
13
- "from llama_index import VectorStoreIndex\n",
14
- "from llama_index import ServiceContext\n",
15
- "from llama_index.llms import OpenAI\n",
16
  "\n",
17
- "from llama_index.embeddings import HuggingFaceEmbedding\n",
18
- "from llama_index import StorageContext, load_index_from_storage\n",
19
  "\n",
20
  "import time"
21
  ]
@@ -298,12 +298,123 @@
298
  "outputs": [],
299
  "source": []
300
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  {
302
  "cell_type": "markdown",
303
  "id": "8acae3ed-2953-45a3-aba9-0327b6ae3679",
304
  "metadata": {},
305
  "source": [
306
- "### ChromaDB method - create vectorstore"
307
  ]
308
  },
309
  {
@@ -314,13 +425,19 @@
314
  "outputs": [],
315
  "source": [
316
  "import chromadb\n",
317
- "from llama_index import VectorStoreIndex, SimpleDirectoryReader\n",
318
- "from llama_index.vector_stores import ChromaVectorStore\n",
319
- "from llama_index.storage.storage_context import StorageContext\n",
320
- "from llama_index import ServiceContext\n",
321
- "from llama_index import Document\n",
 
 
 
 
 
 
 
322
  "\n",
323
- "from llama_index.embeddings import HuggingFaceEmbedding\n",
324
  "\n",
325
  "import time"
326
  ]
@@ -333,7 +450,11 @@
333
  "outputs": [],
334
  "source": [
335
  "# load some documents\n",
336
- "documents = SimpleDirectoryReader(input_files=[\"../raw_documents/HI_Knowledge_Base.pdf\"]).load_data()\n",
 
 
 
 
337
  "document = Document(text=\"\\n\\n\".join([doc.text for doc in documents]))"
338
  ]
339
  },
@@ -385,19 +506,40 @@
385
  "metadata": {},
386
  "outputs": [],
387
  "source": [
388
- "embed_model = HuggingFaceEmbedding(model_name=\"BAAI/bge-small-en-v1.5\")"
 
389
  ]
390
  },
391
  {
392
  "cell_type": "code",
393
  "execution_count": null,
394
- "id": "5289f0f9-bce2-4a2f-9428-b99906b78622",
395
  "metadata": {},
396
  "outputs": [],
397
  "source": [
398
- "service_context = ServiceContext.from_defaults(llm=None, embed_model=embed_model)"
 
 
399
  ]
400
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  {
402
  "cell_type": "code",
403
  "execution_count": null,
@@ -408,6 +550,24 @@
408
  "storage_context = StorageContext.from_defaults(vector_store=vector_store)"
409
  ]
410
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  {
412
  "cell_type": "code",
413
  "execution_count": null,
@@ -418,6 +578,67 @@
418
  "start_time = time.time()"
419
  ]
420
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  {
422
  "cell_type": "code",
423
  "execution_count": null,
@@ -426,6 +647,8 @@
426
  "outputs": [],
427
  "source": [
428
  "# create your index\n",
 
 
429
  "index = VectorStoreIndex.from_documents(\n",
430
  " documents, service_context=service_context, storage_context=storage_context\n",
431
  ")"
@@ -471,7 +694,7 @@
471
  "metadata": {},
472
  "outputs": [],
473
  "source": [
474
- "r_list = retriever.retrieve(\"What is the meaning of life?\")"
475
  ]
476
  },
477
  {
@@ -493,7 +716,7 @@
493
  "metadata": {},
494
  "outputs": [],
495
  "source": [
496
- "response = query_engine.query(\"What is the meaning of life?\")"
497
  ]
498
  },
499
  {
@@ -519,7 +742,7 @@
519
  "id": "a7fc01f6-4738-415b-a96b-afd6cf8d789a",
520
  "metadata": {},
521
  "source": [
522
- "### ChromaDB method - load vectorstore"
523
  ]
524
  },
525
  {
 
8
  "outputs": [],
9
  "source": [
10
  "import openai\n",
11
+ "from llama_index.core import SimpleDirectoryReader\n",
12
+ "from llama_index.core import Document\n",
13
+ "from llama_index.core import VectorStoreIndex\n",
14
+ "from llama_index.core import ServiceContext\n",
15
+ "from llama_index.llms.openai import OpenAI\n",
16
  "\n",
17
+ "from llama_index.legacy.embeddings import HuggingFaceEmbedding\n",
18
+ "from llama_index.core import StorageContext, load_index_from_storage\n",
19
  "\n",
20
  "import time"
21
  ]
 
298
  "outputs": [],
299
  "source": []
300
  },
301
+ {
302
+ "cell_type": "markdown",
303
+ "id": "4730d2e7-dfa9-452d-ae20-95a24b6fd8bd",
304
+ "metadata": {},
305
+ "source": [
306
+ "### Create vectorstore based on default storage"
307
+ ]
308
+ },
309
+ {
310
+ "cell_type": "code",
311
+ "execution_count": null,
312
+ "id": "67e3e5ea-8b6d-4493-91ca-f0ced02971e1",
313
+ "metadata": {},
314
+ "outputs": [],
315
+ "source": [
316
+ "from llama_index.core import (\n",
317
+ " SimpleDirectoryReader,\n",
318
+ " VectorStoreIndex,\n",
319
+ " StorageContext,\n",
320
+ " load_index_from_storage,\n",
321
+ ")\n",
322
+ "\n",
323
+ "from llama_index.core.tools import QueryEngineTool, ToolMetadata"
324
+ ]
325
+ },
326
+ {
327
+ "cell_type": "code",
328
+ "execution_count": null,
329
+ "id": "d8d4ee04-37be-4014-8403-27ef467462b1",
330
+ "metadata": {},
331
+ "outputs": [],
332
+ "source": [
333
+ "documents = SimpleDirectoryReader(input_files=[\n",
334
+ " \"../raw_documents/HI Chapter Summary Version 1.3.pdf\",\n",
335
+ " \"../raw_documents/qna.txt\"\n",
336
+ " ]).load_data()"
337
+ ]
338
+ },
339
+ {
340
+ "cell_type": "code",
341
+ "execution_count": null,
342
+ "id": "d5f6a8b0-0798-42ab-9741-caf52a0bae0c",
343
+ "metadata": {},
344
+ "outputs": [],
345
+ "source": [
346
+ "hi_index = VectorStoreIndex.from_documents(documents)"
347
+ ]
348
+ },
349
+ {
350
+ "cell_type": "code",
351
+ "execution_count": null,
352
+ "id": "3e9f4da3-32af-4e1a-9b28-bfe2c51cc7e1",
353
+ "metadata": {},
354
+ "outputs": [],
355
+ "source": [
356
+ "hi_index.storage_context.persist(persist_dir=\"../models/default_storage\")"
357
+ ]
358
+ },
359
+ {
360
+ "cell_type": "code",
361
+ "execution_count": null,
362
+ "id": "6f032e21-7f98-4752-ad55-3607fd40b7d5",
363
+ "metadata": {},
364
+ "outputs": [],
365
+ "source": [
366
+ "hi_engine = hi_index.as_query_engine(similarity_top_k=3)"
367
+ ]
368
+ },
369
+ {
370
+ "cell_type": "code",
371
+ "execution_count": null,
372
+ "id": "3c599039-8cdf-449c-b3d8-f0d41bffdffc",
373
+ "metadata": {},
374
+ "outputs": [],
375
+ "source": [
376
+ "response = hi_engine.query(\"what is the healthcare philosophy in singapore\")\n",
377
+ "response"
378
+ ]
379
+ },
380
+ {
381
+ "cell_type": "code",
382
+ "execution_count": null,
383
+ "id": "0757962c-235b-49b7-a92d-49c474b79731",
384
+ "metadata": {},
385
+ "outputs": [],
386
+ "source": []
387
+ },
388
+ {
389
+ "cell_type": "code",
390
+ "execution_count": null,
391
+ "id": "b77caa5b-16eb-48ec-8f74-0fc6ca03efbd",
392
+ "metadata": {},
393
+ "outputs": [],
394
+ "source": []
395
+ },
396
+ {
397
+ "cell_type": "code",
398
+ "execution_count": null,
399
+ "id": "f0c97e94-5dc5-443e-94a2-ce28aad99a3c",
400
+ "metadata": {},
401
+ "outputs": [],
402
+ "source": []
403
+ },
404
+ {
405
+ "cell_type": "code",
406
+ "execution_count": null,
407
+ "id": "c19cc1b2-4669-4019-9fea-8e8aa3c74c6f",
408
+ "metadata": {},
409
+ "outputs": [],
410
+ "source": []
411
+ },
412
  {
413
  "cell_type": "markdown",
414
  "id": "8acae3ed-2953-45a3-aba9-0327b6ae3679",
415
  "metadata": {},
416
  "source": [
417
+ "### ChromaDB method - create vectorstore based on Chroma"
418
  ]
419
  },
420
  {
 
425
  "outputs": [],
426
  "source": [
427
  "import chromadb\n",
428
+ "from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
429
+ "from llama_index.vector_stores.chroma.base import ChromaVectorStore\n",
430
+ "from llama_index.core import StorageContext\n",
431
+ "from llama_index.core import ServiceContext\n",
432
+ "from llama_index.core import Document\n",
433
+ "\n",
434
+ "from llama_index.embeddings.huggingface.base import HuggingFaceEmbedding\n",
435
+ "from llama_index.core import Settings\n",
436
+ "\n",
437
+ "import nest_asyncio\n",
438
+ "\n",
439
+ "nest_asyncio.apply()\n",
440
  "\n",
 
441
  "\n",
442
  "import time"
443
  ]
 
450
  "outputs": [],
451
  "source": [
452
  "# load some documents\n",
453
+ "documents = SimpleDirectoryReader(input_files=[\n",
454
+ " \"../raw_documents/HI_Knowledge_Base.pdf\",\n",
455
+ " \"../raw_documents/HI Chapter Summary Version 1.3.pdf\",\n",
456
+ " \"../raw_documents/qna.txt\"\n",
457
+ " ]).load_data()\n",
458
  "document = Document(text=\"\\n\\n\".join([doc.text for doc in documents]))"
459
  ]
460
  },
 
506
  "metadata": {},
507
  "outputs": [],
508
  "source": [
509
+ "# embed_model = HuggingFaceEmbedding(model_name=\"BAAI/bge-small-en-v1.5\")\n",
510
+ "# embed_model = HuggingFaceEmbedding(model_name=\"local:../models/fine-tuned-embeddings\")"
511
  ]
512
  },
513
  {
514
  "cell_type": "code",
515
  "execution_count": null,
516
+ "id": "0946b6ce-96ab-44de-ad75-e424a8429f67",
517
  "metadata": {},
518
  "outputs": [],
519
  "source": [
520
+ "Settings.llm = None\n",
521
+ "Settings.chunk_size = 1024\n",
522
+ "Settings.embed_model = \"local:../models/fine-tuned-embeddings\""
523
  ]
524
  },
525
+ {
526
+ "cell_type": "code",
527
+ "execution_count": null,
528
+ "id": "b8c73a2c-1129-406a-8046-085afcaf9cbb",
529
+ "metadata": {},
530
+ "outputs": [],
531
+ "source": [
532
+ "nodes = Settings.node_parser.get_nodes_from_documents(documents)"
533
+ ]
534
+ },
535
+ {
536
+ "cell_type": "code",
537
+ "execution_count": null,
538
+ "id": "adfe688f-95c0-477c-a9de-e9e77541a1d7",
539
+ "metadata": {},
540
+ "outputs": [],
541
+ "source": []
542
+ },
543
  {
544
  "cell_type": "code",
545
  "execution_count": null,
 
550
  "storage_context = StorageContext.from_defaults(vector_store=vector_store)"
551
  ]
552
  },
553
+ {
554
+ "cell_type": "code",
555
+ "execution_count": null,
556
+ "id": "6a764113-ad7e-4674-aa57-ebbf405902a8",
557
+ "metadata": {},
558
+ "outputs": [],
559
+ "source": [
560
+ "storage_context.docstore.add_documents(nodes)"
561
+ ]
562
+ },
563
+ {
564
+ "cell_type": "code",
565
+ "execution_count": null,
566
+ "id": "38e7c88d-6c45-4275-8293-d09b4b85a7cf",
567
+ "metadata": {},
568
+ "outputs": [],
569
+ "source": []
570
+ },
571
  {
572
  "cell_type": "code",
573
  "execution_count": null,
 
578
  "start_time = time.time()"
579
  ]
580
  },
581
+ {
582
+ "cell_type": "code",
583
+ "execution_count": null,
584
+ "id": "cbd11b89-9b83-4f08-bb30-160f750f2ffb",
585
+ "metadata": {},
586
+ "outputs": [],
587
+ "source": [
588
+ "vector_index = VectorStoreIndex(nodes, storage_context=storage_context)"
589
+ ]
590
+ },
591
+ {
592
+ "cell_type": "code",
593
+ "execution_count": null,
594
+ "id": "082a0d7e-b025-4db1-be2a-7a0b7bc453b9",
595
+ "metadata": {},
596
+ "outputs": [],
597
+ "source": [
598
+ "vector_query_engine = vector_index.as_query_engine()"
599
+ ]
600
+ },
601
+ {
602
+ "cell_type": "code",
603
+ "execution_count": null,
604
+ "id": "d3bd848d-9985-4a3d-bdc4-ec340cc69ef3",
605
+ "metadata": {},
606
+ "outputs": [],
607
+ "source": [
608
+ "indexing_cost = time.time() - start_time\n",
609
+ "indexing_cost = indexing_cost / 60\n",
610
+ "print(f\"Indexing time: {indexing_cost:.1f} mins\")"
611
+ ]
612
+ },
613
+ {
614
+ "cell_type": "code",
615
+ "execution_count": null,
616
+ "id": "3290e870-41d7-49c4-9c4f-cb16bd1f469e",
617
+ "metadata": {},
618
+ "outputs": [],
619
+ "source": [
620
+ "response = vector_query_engine.query(\"what is the healthcare philosophy in singapore\")\n",
621
+ "response"
622
+ ]
623
+ },
624
+ {
625
+ "cell_type": "code",
626
+ "execution_count": null,
627
+ "id": "131d907a-0677-4ad8-b3f7-6fc9b9c5d0a5",
628
+ "metadata": {},
629
+ "outputs": [],
630
+ "source": []
631
+ },
632
+ {
633
+ "cell_type": "code",
634
+ "execution_count": null,
635
+ "id": "f95e42ff-374b-4c57-8333-137a6205a6ad",
636
+ "metadata": {},
637
+ "outputs": [],
638
+ "source": [
639
+ "start_time = time.time()"
640
+ ]
641
+ },
642
  {
643
  "cell_type": "code",
644
  "execution_count": null,
 
647
  "outputs": [],
648
  "source": [
649
  "# create your index\n",
650
+ "service_context = ServiceContext.from_defaults(llm=None, embed_model=\"local:../models/fine-tuned-embeddings\")\n",
651
+ "storage_context = StorageContext.from_defaults(vector_store=vector_store)\n",
652
  "index = VectorStoreIndex.from_documents(\n",
653
  " documents, service_context=service_context, storage_context=storage_context\n",
654
  ")"
 
694
  "metadata": {},
695
  "outputs": [],
696
  "source": [
697
+ "r_list = retriever.retrieve(\"what is the healthcare philosophy in singapore\")"
698
  ]
699
  },
700
  {
 
716
  "metadata": {},
717
  "outputs": [],
718
  "source": [
719
+ "response = query_engine.query(\"what is the healthcare philosophy in singapore\")"
720
  ]
721
  },
722
  {
 
742
  "id": "a7fc01f6-4738-415b-a96b-afd6cf8d789a",
743
  "metadata": {},
744
  "source": [
745
+ "### ChromaDB method - load vectorstore based on Chroma"
746
  ]
747
  },
748
  {
archive/notebooks/005_qna_prompting_with_pydantic_embeddings.ipynb ADDED
@@ -0,0 +1,528 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "4cf3ca7c-2c43-495b-a1ee-24c770f0ad1e",
6
+ "metadata": {},
7
+ "source": [
8
+ "### Simple OpenAI agent with tool"
9
+ ]
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": null,
14
+ "id": "a9d74b11-4049-4e3c-839e-7d13d7c0dadc",
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "import json\n",
19
+ "from typing import Sequence, List\n",
20
+ "from pydantic import BaseModel\n",
21
+ "\n",
22
+ "from llama_index.core.llms import ChatMessage\n",
23
+ "from llama_index.core.tools import BaseTool, FunctionTool\n",
24
+ "from llama_index.llms.openai import OpenAI\n",
25
+ "from llama_index.agent.openai import OpenAIAgent\n",
26
+ "\n",
27
+ "import nest_asyncio\n",
28
+ "\n",
29
+ "nest_asyncio.apply()"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": null,
35
+ "id": "39ca840b-0ec7-4279-9654-e4ddfda6137f",
36
+ "metadata": {},
37
+ "outputs": [],
38
+ "source": [
39
+ "# define sample Tool\n",
40
+ "def multiply(a: int, b: int) -> int:\n",
41
+ " \"\"\"Multiply two integers and returns the result integer\"\"\"\n",
42
+ " return a * b\n",
43
+ "\n",
44
+ "multiply_tool = FunctionTool.from_defaults(fn=multiply)\n",
45
+ "\n",
46
+ "def add(a: int, b: int) -> int:\n",
47
+ " \"\"\"Add two integers and returns the result integer\"\"\"\n",
48
+ " return a + b\n",
49
+ "\n",
50
+ "add_tool = FunctionTool.from_defaults(fn=add)\n",
51
+ "\n",
52
+ "class Song(BaseModel):\n",
53
+ " \"\"\"A song with name and artist\"\"\"\n",
54
+ "\n",
55
+ " name: str\n",
56
+ " artist: str\n",
57
+ "\n",
58
+ "song_fn = FunctionTool.from_defaults(fn=Song)"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "id": "4df3e9f2-4a32-4449-b203-929dff9e7963",
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": []
68
+ },
69
+ {
70
+ "cell_type": "code",
71
+ "execution_count": null,
72
+ "id": "bbeeea36-0bb0-4edb-9b8c-adb7c64c4cd3",
73
+ "metadata": {},
74
+ "outputs": [],
75
+ "source": [
76
+ "# initialize openai agent\n",
77
+ "llm = OpenAI(model=\"gpt-3.5-turbo-0613\")\n",
78
+ "agent = OpenAIAgent.from_tools([multiply_tool, add_tool, song_fn], llm=llm, verbose=True)"
79
+ ]
80
+ },
81
+ {
82
+ "cell_type": "code",
83
+ "execution_count": null,
84
+ "id": "65158ede-b99f-477d-9d17-3be40e57a629",
85
+ "metadata": {},
86
+ "outputs": [],
87
+ "source": [
88
+ "res = agent.chat(message=\"3 x 2 equals?\")\n",
89
+ "res"
90
+ ]
91
+ },
92
+ {
93
+ "cell_type": "code",
94
+ "execution_count": null,
95
+ "id": "d74b0e5c-47a2-4de4-acd2-d39a94941f2d",
96
+ "metadata": {},
97
+ "outputs": [],
98
+ "source": []
99
+ },
100
+ {
101
+ "cell_type": "code",
102
+ "execution_count": null,
103
+ "id": "d9787ed4-46a2-46aa-80e6-b317d9280b9e",
104
+ "metadata": {},
105
+ "outputs": [],
106
+ "source": [
107
+ "res = agent.chat(message=\"3 plus 2 equals?\")\n",
108
+ "res"
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "code",
113
+ "execution_count": null,
114
+ "id": "dd3358c6-e0e4-4354-8a4e-97d70254f648",
115
+ "metadata": {},
116
+ "outputs": [],
117
+ "source": []
118
+ },
119
+ {
120
+ "cell_type": "code",
121
+ "execution_count": null,
122
+ "id": "16e1db2c-dca3-4dc6-9cc5-c10644d5927c",
123
+ "metadata": {},
124
+ "outputs": [],
125
+ "source": [
126
+ "res = agent.chat(message=\"give me the lyrics of taylor swift's `you belong with me`\")\n",
127
+ "res"
128
+ ]
129
+ },
130
+ {
131
+ "cell_type": "code",
132
+ "execution_count": null,
133
+ "id": "97a021f4-4701-4914-9ab8-0683b396f096",
134
+ "metadata": {},
135
+ "outputs": [],
136
+ "source": []
137
+ },
138
+ {
139
+ "cell_type": "code",
140
+ "execution_count": null,
141
+ "id": "1f0b352d-8510-4b2a-a495-9f2e1fbfcddb",
142
+ "metadata": {},
143
+ "outputs": [],
144
+ "source": [
145
+ "# res_stream = agent.stream_chat(message=\"3 x 2 equals?\")\n",
146
+ "# for r in res_stream.response_gen:\n",
147
+ "# print(r, end=\"\")"
148
+ ]
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "execution_count": null,
153
+ "id": "ea0a6cd4-f204-4997-bdfb-cb9b5a9e1266",
154
+ "metadata": {},
155
+ "outputs": [],
156
+ "source": []
157
+ },
158
+ {
159
+ "cell_type": "markdown",
160
+ "id": "96c978e6-62e2-46e6-ae63-76841487f618",
161
+ "metadata": {},
162
+ "source": [
163
+ "### OpenAI agent with embeddings, and function calling"
164
+ ]
165
+ },
166
+ {
167
+ "cell_type": "code",
168
+ "execution_count": null,
169
+ "id": "6f0f5f02-c8e9-43a9-853d-12bb3c19dbe8",
170
+ "metadata": {},
171
+ "outputs": [],
172
+ "source": [
173
+ "import os\n",
174
+ "import chromadb\n",
175
+ "\n",
176
+ "from llama_index.core import (\n",
177
+ " SimpleDirectoryReader,\n",
178
+ " VectorStoreIndex,\n",
179
+ " ServiceContext,\n",
180
+ " StorageContext,\n",
181
+ " load_index_from_storage,\n",
182
+ ")\n",
183
+ "from llama_index.core.memory import ChatMemoryBuffer\n",
184
+ "from llama_index.vector_stores.chroma.base import ChromaVectorStore\n",
185
+ "from llama_index.core.tools import QueryEngineTool, ToolMetadata\n",
186
+ "from llama_index.llms.openai import OpenAI\n",
187
+ "from llama_index.agent.openai import OpenAIAgent\n",
188
+ "from llama_index.core.tools import BaseTool, FunctionTool\n",
189
+ "from llama_index.core import Settings\n",
190
+ "\n",
191
+ "from pydantic import BaseModel\n",
192
+ "import nest_asyncio\n",
193
+ "\n",
194
+ "nest_asyncio.apply()"
195
+ ]
196
+ },
197
+ {
198
+ "cell_type": "code",
199
+ "execution_count": null,
200
+ "id": "54855aa4-dcad-404e-843f-c96d61046df3",
201
+ "metadata": {},
202
+ "outputs": [],
203
+ "source": []
204
+ },
205
+ {
206
+ "cell_type": "markdown",
207
+ "id": "4edb89f6-bb2f-46ff-8807-dfb03115fcd5",
208
+ "metadata": {},
209
+ "source": [
210
+ "#### Parameters"
211
+ ]
212
+ },
213
+ {
214
+ "cell_type": "code",
215
+ "execution_count": null,
216
+ "id": "61ad7369-8fd4-434f-b687-0c649940bda1",
217
+ "metadata": {},
218
+ "outputs": [],
219
+ "source": [
220
+ "selected_model = \"gpt-3.5-turbo-1106\"\n",
221
+ "temperature = 0.0\n",
222
+ "\n",
223
+ "persisted_vector_db = \"../models/chroma_db\"\n",
224
+ "input_files = [\"../raw_documents/HI_Knowledge_Base.pdf\",\n",
225
+ " \"../raw_documents/HI Chapter Summary Version 1.3.pdf\",\n",
226
+ " \"../raw_documents/qna.txt\"]\n",
227
+ "fine_tuned_path = \"local:../models/fine-tuned-embeddings\"\n",
228
+ "system_content = (\"You are a helpful study assistant. \"\n",
229
+ " \"You do not respond as 'User' or pretend to be 'User'. \"\n",
230
+ " \"You only respond once as 'Assistant'.\"\n",
231
+ ")"
232
+ ]
233
+ },
234
+ {
235
+ "cell_type": "code",
236
+ "execution_count": null,
237
+ "id": "a18117f5-48a7-4e81-9b46-541f382caf9e",
238
+ "metadata": {},
239
+ "outputs": [],
240
+ "source": []
241
+ },
242
+ {
243
+ "cell_type": "markdown",
244
+ "id": "3210c837-9b40-4cd9-bb00-ead559deff6f",
245
+ "metadata": {},
246
+ "source": [
247
+ "#### Load vector store"
248
+ ]
249
+ },
250
+ {
251
+ "cell_type": "code",
252
+ "execution_count": null,
253
+ "id": "b9dfba0c-f27d-49d1-86c5-a1d95c11b844",
254
+ "metadata": {},
255
+ "outputs": [],
256
+ "source": [
257
+ "if os.path.exists(persisted_vector_db):\n",
258
+ " db = chromadb.PersistentClient(path=persisted_vector_db)\n",
259
+ " chroma_collection = db.get_or_create_collection(\"quickstart\")\n",
260
+ " \n",
261
+ " # assign chroma as the vector_store to the context\n",
262
+ " vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n",
263
+ " storage_context = StorageContext.from_defaults(vector_store=vector_store)\n",
264
+ "\n",
265
+ "else:\n",
266
+ " documents = SimpleDirectoryReader(input_files=input_files).load_data()\n",
267
+ " document = Document(text=\"\\n\\n\".join([doc.text for doc in documents]))\n",
268
+ " \n",
269
+ " # initialize client, setting path to save data\n",
270
+ " db = chromadb.PersistentClient(path=persisted_vector_db)\n",
271
+ " \n",
272
+ " # create collection\n",
273
+ " chroma_collection = db.get_or_create_collection(\"quickstart\")\n",
274
+ "\n",
275
+ " # assign chroma as the vector_store to the context\n",
276
+ " vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n",
277
+ " storage_context = StorageContext.from_defaults(vector_store=vector_store)"
278
+ ]
279
+ },
280
+ {
281
+ "cell_type": "code",
282
+ "execution_count": null,
283
+ "id": "693c9808-efbe-47a6-a49c-7143c63d13e5",
284
+ "metadata": {},
285
+ "outputs": [],
286
+ "source": []
287
+ },
288
+ {
289
+ "cell_type": "code",
290
+ "execution_count": null,
291
+ "id": "c6bfae0b-7c97-4c2b-9996-f5e3ecf7a992",
292
+ "metadata": {},
293
+ "outputs": [],
294
+ "source": [
295
+ "# define sample Tool\n",
296
+ "def multiply(a: int, b: int) -> int:\n",
297
+ " \"\"\"Multiply two integers and returns the result integer\"\"\"\n",
298
+ " return a * b\n",
299
+ "\n",
300
+ "def add(a: int, b: int) -> int:\n",
301
+ " \"\"\"Add two integers and returns the result integer\"\"\"\n",
302
+ " return a + b\n",
303
+ "\n",
304
+ "class Song(BaseModel):\n",
305
+ " \"\"\"A song with name and artist\"\"\"\n",
306
+ "\n",
307
+ " name: str\n",
308
+ " artist: str\n",
309
+ "\n",
310
+ "add_tool = FunctionTool.from_defaults(fn=add)\n",
311
+ "multiply_tool = FunctionTool.from_defaults(fn=multiply)\n",
312
+ "song_fn = FunctionTool.from_defaults(fn=Song)"
313
+ ]
314
+ },
315
+ {
316
+ "cell_type": "code",
317
+ "execution_count": null,
318
+ "id": "16a80b2e-8e5f-462a-8616-042afe18be3a",
319
+ "metadata": {},
320
+ "outputs": [],
321
+ "source": [
322
+ "llm = OpenAI(model=selected_model, temperature=temperature)\n",
323
+ "service_context = ServiceContext.from_defaults(llm=llm, embed_model=fine_tuned_path)\n",
324
+ "\n",
325
+ "Settings.llm = llm\n",
326
+ "Settings.embed_model = fine_tuned_path"
327
+ ]
328
+ },
329
+ {
330
+ "cell_type": "code",
331
+ "execution_count": null,
332
+ "id": "95d3a420-1ee4-45bd-a18b-b398d9531db4",
333
+ "metadata": {},
334
+ "outputs": [],
335
+ "source": [
336
+ "# index = VectorStoreIndex.from_vector_store(\n",
337
+ "# vector_store=vector_store,\n",
338
+ "# service_context=service_context, \n",
339
+ "# storage_context=storage_context\n",
340
+ "# )\n",
341
+ "index = VectorStoreIndex.from_vector_store(\n",
342
+ " vector_store=vector_store,\n",
343
+ " storage_context=storage_context\n",
344
+ ")"
345
+ ]
346
+ },
347
+ {
348
+ "cell_type": "code",
349
+ "execution_count": null,
350
+ "id": "eac6d76d-059b-40e3-b67f-c736f1ce6baa",
351
+ "metadata": {},
352
+ "outputs": [],
353
+ "source": [
354
+ "memory = ChatMemoryBuffer.from_defaults(token_limit=15000)\n",
355
+ "\n",
356
+ "hi_engine = index.as_query_engine(\n",
357
+ " memory=memory,\n",
358
+ " system_prompt=system_content,\n",
359
+ " similarity_top_k=3,\n",
360
+ " streaming=True\n",
361
+ ")"
362
+ ]
363
+ },
364
+ {
365
+ "cell_type": "code",
366
+ "execution_count": null,
367
+ "id": "18e38a8f-9b51-4675-a1d5-8aaa6c21694c",
368
+ "metadata": {},
369
+ "outputs": [],
370
+ "source": [
371
+ "res = hi_engine.query(\"what is the healthcare philosophy in singapore\")\n",
372
+ "print(res)"
373
+ ]
374
+ },
375
+ {
376
+ "cell_type": "code",
377
+ "execution_count": null,
378
+ "id": "70dae6f7-682e-42d6-be59-3b807c10482c",
379
+ "metadata": {},
380
+ "outputs": [],
381
+ "source": []
382
+ },
383
+ {
384
+ "cell_type": "code",
385
+ "execution_count": null,
386
+ "id": "1eb5df65-c926-4b22-8071-449d645b339f",
387
+ "metadata": {},
388
+ "outputs": [],
389
+ "source": [
390
+ "hi_query_tool = QueryEngineTool.from_defaults(\n",
391
+ " query_engine=hi_engine,\n",
392
+ " name=\"vector_tool\",\n",
393
+ " description=(\n",
394
+ " \"Provides information about Health Insurance landscape in Singapore. \"\n",
395
+ " \"Use a detailed plain text question as input to the tool.\"\n",
396
+ " )\n",
397
+ ")\n",
398
+ "\n",
399
+ "# hi_query_tool = QueryEngineTool(\n",
400
+ "# query_engine=hi_engine,\n",
401
+ "# metadata=ToolMetadata(\n",
402
+ "# name=\"health_insurance_mentor\",\n",
403
+ "# description=(\n",
404
+ "# \"Provides information about Health Insurance landscape in Singapore. \"\n",
405
+ "# \"Use a detailed plain text question as input to the tool.\"\n",
406
+ "# )\n",
407
+ "# )\n",
408
+ "# )"
409
+ ]
410
+ },
411
+ {
412
+ "cell_type": "code",
413
+ "execution_count": null,
414
+ "id": "a5822b1d-32ef-4b68-8629-a727ff51cd0a",
415
+ "metadata": {},
416
+ "outputs": [],
417
+ "source": []
418
+ },
419
+ {
420
+ "cell_type": "code",
421
+ "execution_count": null,
422
+ "id": "2a1235da-a379-4055-8bcf-4b21c91c9fb0",
423
+ "metadata": {},
424
+ "outputs": [],
425
+ "source": [
426
+ "agent = OpenAIAgent.from_tools([multiply_tool, add_tool, hi_query_tool], llm=llm, verbose=True)"
427
+ ]
428
+ },
429
+ {
430
+ "cell_type": "code",
431
+ "execution_count": null,
432
+ "id": "05b65cbd-d15c-4909-b383-50b13f64e535",
433
+ "metadata": {},
434
+ "outputs": [],
435
+ "source": []
436
+ },
437
+ {
438
+ "cell_type": "code",
439
+ "execution_count": null,
440
+ "id": "63332a44-9441-4f49-85a2-934e2c55a362",
441
+ "metadata": {},
442
+ "outputs": [],
443
+ "source": [
444
+ "res = agent.chat(\"what is the healthcare philosophy in singapore\", tool_choice=\"auto\")\n",
445
+ "res.response"
446
+ ]
447
+ },
448
+ {
449
+ "cell_type": "code",
450
+ "execution_count": null,
451
+ "id": "81709cbf-9a5e-482f-ae6a-ba361b8219dc",
452
+ "metadata": {},
453
+ "outputs": [],
454
+ "source": []
455
+ },
456
+ {
457
+ "cell_type": "code",
458
+ "execution_count": null,
459
+ "id": "adf26268-e40a-4ebd-a737-6b203ddc4444",
460
+ "metadata": {},
461
+ "outputs": [],
462
+ "source": [
463
+ "res = agent.stream_chat(\"what is the healthcare philosophy in singapore\", tool_choice=\"auto\")\n",
464
+ "for r in res.response_gen:\n",
465
+ " print(r, end=\"\")"
466
+ ]
467
+ },
468
+ {
469
+ "cell_type": "code",
470
+ "execution_count": null,
471
+ "id": "540c0f71-048a-4a64-9818-e2b1cffc0db7",
472
+ "metadata": {},
473
+ "outputs": [],
474
+ "source": []
475
+ },
476
+ {
477
+ "cell_type": "code",
478
+ "execution_count": null,
479
+ "id": "fbeabf28-30f9-4d7f-a4b9-21cd08a9b128",
480
+ "metadata": {},
481
+ "outputs": [],
482
+ "source": [
483
+ "res = agent.stream_chat(\"what is the result of 328123 + 2891230\", tool_choice=\"auto\")\n",
484
+ "for r in res.response_gen:\n",
485
+ " print(r, end=\"\")"
486
+ ]
487
+ },
488
+ {
489
+ "cell_type": "code",
490
+ "execution_count": null,
491
+ "id": "19b7e12c-0729-4181-acce-53a3a95b67b8",
492
+ "metadata": {},
493
+ "outputs": [],
494
+ "source": [
495
+ "328123 + 2891230"
496
+ ]
497
+ },
498
+ {
499
+ "cell_type": "code",
500
+ "execution_count": null,
501
+ "id": "bca4c0b2-5165-4943-af1f-d3168ee88fcd",
502
+ "metadata": {},
503
+ "outputs": [],
504
+ "source": []
505
+ }
506
+ ],
507
+ "metadata": {
508
+ "kernelspec": {
509
+ "display_name": "Python 3 (ipykernel)",
510
+ "language": "python",
511
+ "name": "python3"
512
+ },
513
+ "language_info": {
514
+ "codemirror_mode": {
515
+ "name": "ipython",
516
+ "version": 3
517
+ },
518
+ "file_extension": ".py",
519
+ "mimetype": "text/x-python",
520
+ "name": "python",
521
+ "nbconvert_exporter": "python",
522
+ "pygments_lexer": "ipython3",
523
+ "version": "3.9.18"
524
+ }
525
+ },
526
+ "nbformat": 4,
527
+ "nbformat_minor": 5
528
+ }
archive/requirements.txt ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohttp==3.9.1
2
+ aiosignal==1.3.1
3
+ alembic==1.13.1
4
+ altair==5.2.0
5
+ annotated-types==0.6.0
6
+ anyio==4.2.0
7
+ appnope==0.1.3
8
+ argon2-cffi==23.1.0
9
+ argon2-cffi-bindings==21.2.0
10
+ arrow==1.3.0
11
+ asgiref==3.7.2
12
+ asttokens==2.4.1
13
+ async-lru==2.0.4
14
+ async-timeout==4.0.3
15
+ attrs==23.2.0
16
+ Babel==2.14.0
17
+ backoff==2.2.1
18
+ bcrypt==4.1.2
19
+ beautifulsoup4==4.12.3
20
+ bleach==6.1.0
21
+ blinker==1.7.0
22
+ bs4==0.0.2
23
+ build==1.0.3
24
+ cachetools==5.3.2
25
+ certifi==2023.11.17
26
+ cffi==1.16.0
27
+ charset-normalizer==3.3.2
28
+ chroma-hnswlib==0.7.3
29
+ chromadb==0.4.22
30
+ click==8.1.7
31
+ coloredlogs==15.0.1
32
+ comm==0.2.0
33
+ contourpy==1.2.0
34
+ cycler==0.12.1
35
+ dataclasses-json==0.6.3
36
+ debugpy==1.8.0
37
+ decorator==5.1.1
38
+ defusedxml==0.7.1
39
+ Deprecated==1.2.14
40
+ dill==0.3.7
41
+ dirtyjson==1.0.8
42
+ distro==1.9.0
43
+ entrypoints==0.4
44
+ exceptiongroup==1.2.0
45
+ executing==2.0.1
46
+ Faker==22.0.0
47
+ fastapi==0.109.0
48
+ fastjsonschema==2.19.1
49
+ favicon==0.7.0
50
+ filelock==3.13.1
51
+ flatbuffers==23.5.26
52
+ fonttools==4.47.0
53
+ fqdn==1.5.1
54
+ frozendict==2.4.0
55
+ frozenlist==1.4.1
56
+ fsspec==2023.12.2
57
+ gitdb==4.0.11
58
+ GitPython==3.1.40
59
+ google-auth==2.27.0
60
+ googleapis-common-protos==1.62.0
61
+ greenlet==3.0.3
62
+ grpcio==1.60.0
63
+ h11==0.14.0
64
+ htbuilder==0.6.2
65
+ httpcore==1.0.2
66
+ httptools==0.6.1
67
+ httpx==0.26.0
68
+ huggingface-hub==0.20.1
69
+ humanfriendly==10.0
70
+ humanize==4.9.0
71
+ idna==3.6
72
+ importlib-metadata==6.11.0
73
+ importlib-resources==6.1.1
74
+ ipykernel==6.28.0
75
+ ipython==8.18.1
76
+ ipywidgets==8.1.1
77
+ isoduration==20.11.0
78
+ jedi==0.19.1
79
+ Jinja2==3.1.2
80
+ joblib==1.3.2
81
+ json5==0.9.14
82
+ jsonpatch==1.33
83
+ jsonpointer==2.4
84
+ jsonschema==4.20.0
85
+ jsonschema-specifications==2023.12.1
86
+ jupyter==1.0.0
87
+ jupyter-console==6.6.3
88
+ jupyter-events==0.9.0
89
+ jupyter-lsp==2.2.1
90
+ jupyter_client==8.6.0
91
+ jupyter_core==5.6.1
92
+ jupyter_server==2.12.1
93
+ jupyter_server_terminals==0.5.1
94
+ jupyterlab==4.0.10
95
+ jupyterlab-widgets==3.0.9
96
+ jupyterlab_pygments==0.3.0
97
+ jupyterlab_server==2.25.2
98
+ kiwisolver==1.4.5
99
+ kubernetes==29.0.0
100
+ langchain==0.0.354
101
+ langchain-community==0.0.8
102
+ langchain-core==0.1.5
103
+ langsmith==0.0.77
104
+ llama-index==0.9.39
105
+ Mako==1.3.0
106
+ Markdown==3.5.1
107
+ markdown-it-py==3.0.0
108
+ markdownlit==0.0.7
109
+ MarkupSafe==2.1.3
110
+ marshmallow==3.20.1
111
+ matplotlib==3.8.2
112
+ matplotlib-inline==0.1.6
113
+ mdurl==0.1.2
114
+ merkle-json==1.0.0
115
+ millify==0.1.1
116
+ mistune==3.0.2
117
+ mmh3==4.1.0
118
+ monotonic==1.6
119
+ more-itertools==10.1.0
120
+ mpmath==1.3.0
121
+ multidict==6.0.4
122
+ munch==4.0.0
123
+ mypy-extensions==1.0.0
124
+ nbclient==0.9.0
125
+ nbconvert==7.14.0
126
+ nbformat==5.9.2
127
+ nest-asyncio==1.5.8
128
+ networkx==3.2.1
129
+ nltk==3.8.1
130
+ notebook==7.0.6
131
+ notebook_shim==0.2.3
132
+ numpy==1.26.2
133
+ oauthlib==3.2.2
134
+ onnxruntime==1.16.3
135
+ openai==1.6.1
136
+ opentelemetry-api==1.22.0
137
+ opentelemetry-exporter-otlp-proto-common==1.22.0
138
+ opentelemetry-exporter-otlp-proto-grpc==1.22.0
139
+ opentelemetry-instrumentation==0.43b0
140
+ opentelemetry-instrumentation-asgi==0.43b0
141
+ opentelemetry-instrumentation-fastapi==0.43b0
142
+ opentelemetry-proto==1.22.0
143
+ opentelemetry-sdk==1.22.0
144
+ opentelemetry-semantic-conventions==0.43b0
145
+ opentelemetry-util-http==0.43b0
146
+ overrides==7.4.0
147
+ packaging==23.2
148
+ pandas==2.1.4
149
+ pandocfilters==1.5.0
150
+ parso==0.8.3
151
+ pexpect==4.9.0
152
+ pillow==10.2.0
153
+ platformdirs==4.1.0
154
+ posthog==3.3.3
155
+ prometheus-client==0.19.0
156
+ prompt-toolkit==3.0.43
157
+ protobuf==4.25.1
158
+ psutil==5.9.7
159
+ ptyprocess==0.7.0
160
+ pulsar-client==3.4.0
161
+ pure-eval==0.2.2
162
+ pyarrow==14.0.2
163
+ pyasn1==0.5.1
164
+ pyasn1-modules==0.3.0
165
+ pycparser==2.21
166
+ pydantic==2.5.3
167
+ pydantic_core==2.14.6
168
+ pydeck==0.8.1b0
169
+ Pygments==2.17.2
170
+ pymdown-extensions==10.7
171
+ pyparsing==3.1.1
172
+ pypdf==3.17.4
173
+ PyPika==0.48.9
174
+ pyproject_hooks==1.0.0
175
+ python-dateutil==2.8.2
176
+ python-decouple==3.8
177
+ python-dotenv==1.0.0
178
+ python-json-logger==2.0.7
179
+ pytz==2023.3.post1
180
+ PyYAML==6.0.1
181
+ pyzmq==25.1.2
182
+ qtconsole==5.5.1
183
+ QtPy==2.4.1
184
+ referencing==0.32.0
185
+ regex==2023.12.25
186
+ requests==2.31.0
187
+ requests-oauthlib==1.3.1
188
+ rfc3339-validator==0.1.4
189
+ rfc3986-validator==0.1.1
190
+ rich==13.7.0
191
+ rpds-py==0.16.2
192
+ rsa==4.9
193
+ safetensors==0.4.1
194
+ scikit-learn==1.4.0
195
+ scipy==1.12.0
196
+ Send2Trash==1.8.2
197
+ sentence-transformers==2.3.0
198
+ sentencepiece==0.1.99
199
+ six==1.16.0
200
+ smmap==5.0.1
201
+ sniffio==1.3.0
202
+ soupsieve==2.5
203
+ SQLAlchemy==2.0.24
204
+ st-annotated-text==4.0.1
205
+ stack-data==0.6.3
206
+ starlette==0.35.1
207
+ streamlit==1.29.0
208
+ streamlit-aggrid==0.3.4.post3
209
+ streamlit-camera-input-live==0.2.0
210
+ streamlit-card==1.0.0
211
+ streamlit-embedcode==0.1.2
212
+ streamlit-extras==0.3.6
213
+ streamlit-faker==0.0.3
214
+ streamlit-feedback==0.1.3
215
+ streamlit-image-coordinates==0.1.6
216
+ streamlit-keyup==0.2.2
217
+ streamlit-toggle-switch==1.0.2
218
+ streamlit-vertical-slider==2.5.5
219
+ sympy==1.12
220
+ tenacity==8.2.3
221
+ terminado==0.18.0
222
+ threadpoolctl==3.2.0
223
+ tiktoken==0.5.2
224
+ tinycss2==1.2.1
225
+ tokenizers==0.15.0
226
+ toml==0.10.2
227
+ tomli==2.0.1
228
+ toolz==0.12.0
229
+ torch==2.1.2
230
+ tornado==6.4
231
+ tqdm==4.66.1
232
+ traitlets==5.14.0
233
+ transformers==4.36.2
234
+ trulens==0.13.4
235
+ trulens-eval==0.20.0
236
+ typer==0.9.0
237
+ types-python-dateutil==2.8.19.14
238
+ typing-inspect==0.9.0
239
+ typing_extensions==4.9.0
240
+ tzdata==2023.4
241
+ tzlocal==5.2
242
+ uri-template==1.3.0
243
+ urllib3==2.1.0
244
+ uvicorn==0.27.0
245
+ uvloop==0.19.0
246
+ validators==0.22.0
247
+ watchfiles==0.21.0
248
+ wcwidth==0.2.12
249
+ webcolors==1.13
250
+ webencodings==0.5.1
251
+ websocket-client==1.7.0
252
+ websockets==12.0
253
+ widgetsnbextension==4.0.9
254
+ wrapt==1.16.0
255
+ yarl==1.9.4
256
+ zipp==3.17.0
archive/streamlit_app/streamlit_app_14Feb2024.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from streamlit_feedback import streamlit_feedback
3
+
4
+ import os
5
+ import pandas as pd
6
+ import base64
7
+ from io import BytesIO
8
+ import nest_asyncio
9
+
10
+ import chromadb
11
+ from llama_index.legacy import (
12
+ VectorStoreIndex,
13
+ SimpleDirectoryReader,
14
+ ServiceContext,
15
+ Document
16
+ )
17
+
18
+ from llama_index.legacy.vector_stores.chroma import ChromaVectorStore
19
+ from llama_index.legacy.storage.storage_context import StorageContext
20
+ from llama_index.legacy.embeddings import HuggingFaceEmbedding
21
+ from llama_index.legacy.llms import OpenAI
22
+ from llama_index.legacy.memory import ChatMemoryBuffer
23
+
24
+ from vision_api import get_transcribed_text
25
+
26
+ nest_asyncio.apply()
27
+
28
+ # App title
29
+ st.set_page_config(page_title="💬 Open AI Chatbot")
30
+ openai_api = os.getenv("OPENAI_API_KEY")
31
+
32
+ # "./raw_documents/HI_Knowledge_Base.pdf"
33
+ input_files = ["./raw_documents/HI Chapter Summary Version 1.3.pdf",
34
+ "./raw_documents/qna.txt"]
35
+ embedding_model = "BAAI/bge-small-en-v1.5"
36
+ persisted_vector_db = "./models/chroma_db"
37
+ fine_tuned_path = "local:models/fine-tuned-embeddings"
38
+ system_content = ("You are a helpful study assistant. "
39
+ "You do not respond as 'User' or pretend to be 'User'. "
40
+ "You only respond once as 'Assistant'."
41
+ )
42
+
43
+ data_df = pd.DataFrame(
44
+ {
45
+ "Completion": [30, 40, 100, 10],
46
+ }
47
+ )
48
+ data_df.index = ["Chapter 1", "Chapter 2", "Chapter 3", "Chapter 4"]
49
+
50
+ # Replicate Credentials
51
+ with st.sidebar:
52
+ st.title("💬 Open AI Chatbot")
53
+ st.write("This chatbot is created using the GPT model from Open AI.")
54
+ if openai_api:
55
+ pass
56
+ elif "OPENAI_API_KEY" in st.secrets:
57
+ st.success("API key already provided!", icon="✅")
58
+ openai_api = st.secrets["OPENAI_API_KEY"]
59
+ else:
60
+ openai_api = st.text_input("Enter OpenAI API token:", type="password")
61
+ if not (openai_api.startswith("sk-") and len(openai_api)==51):
62
+ st.warning("Please enter your credentials!", icon="⚠️")
63
+ else:
64
+ st.success("Proceed to entering your prompt message!", icon="👉")
65
+
66
+ ### for streamlit purpose
67
+ os.environ["OPENAI_API_KEY"] = openai_api
68
+
69
+ st.subheader("Models and parameters")
70
+ selected_model = st.sidebar.selectbox("Choose an OpenAI model",
71
+ ["gpt-3.5-turbo-1106", "gpt-4-1106-preview"],
72
+ key="selected_model")
73
+ temperature = st.sidebar.slider("temperature", min_value=0.0, max_value=2.0,
74
+ value=0.0, step=0.01)
75
+ st.data_editor(
76
+ data_df,
77
+ column_config={
78
+ "Completion": st.column_config.ProgressColumn(
79
+ "Completion %",
80
+ help="Percentage of content covered",
81
+ format="%.1f%%",
82
+ min_value=0,
83
+ max_value=100,
84
+ ),
85
+ },
86
+ hide_index=False,
87
+ )
88
+
89
+ st.markdown("📖 Reach out to SakiMilo to learn how to create this app!")
90
+
91
+ if "init" not in st.session_state.keys():
92
+ st.session_state.init = {"warm_started": "No"}
93
+ st.session_state.feedback = False
94
+
95
+ # Store LLM generated responses
96
+ if "messages" not in st.session_state.keys():
97
+ st.session_state.messages = [{"role": "assistant",
98
+ "content": "How may I assist you today?",
99
+ "type": "text"}]
100
+
101
+ if "feedback_key" not in st.session_state:
102
+ st.session_state.feedback_key = 0
103
+
104
+ if "release_file" not in st.session_state:
105
+ st.session_state.release_file = "false"
106
+
107
+ def clear_chat_history():
108
+ st.session_state.messages = [{"role": "assistant",
109
+ "content": "How may I assist you today?",
110
+ "type": "text"}]
111
+ chat_engine = get_query_engine(input_files=input_files,
112
+ llm_model=selected_model,
113
+ temperature=temperature,
114
+ embedding_model=embedding_model,
115
+ fine_tuned_path=fine_tuned_path,
116
+ system_content=system_content,
117
+ persisted_path=persisted_vector_db)
118
+ chat_engine.reset()
119
+
120
+ st.sidebar.button("Clear Chat History", on_click=clear_chat_history)
121
+ if st.sidebar.button("I want to submit a feedback!"):
122
+ st.session_state.feedback = True
123
+ st.session_state.feedback_key += 1 # overwrite feedback component
124
+
125
+ @st.cache_resource
126
+ def get_document_object(input_files):
127
+ documents = SimpleDirectoryReader(input_files=input_files).load_data()
128
+ document = Document(text="\n\n".join([doc.text for doc in documents]))
129
+ return document
130
+
131
+ @st.cache_resource
132
+ def get_llm_object(selected_model, temperature):
133
+ llm = OpenAI(model=selected_model, temperature=temperature)
134
+ return llm
135
+
136
+ @st.cache_resource
137
+ def get_embedding_model(model_name, fine_tuned_path=None):
138
+ if fine_tuned_path is None:
139
+ print(f"loading from `{model_name}` from huggingface")
140
+ embed_model = HuggingFaceEmbedding(model_name=model_name)
141
+ else:
142
+ print(f"loading from local `{fine_tuned_path}`")
143
+ embed_model = fine_tuned_path
144
+ return embed_model
145
+
146
+ @st.cache_resource
147
+ def get_query_engine(input_files, llm_model, temperature,
148
+ embedding_model, fine_tuned_path,
149
+ system_content, persisted_path):
150
+
151
+ llm = get_llm_object(llm_model, temperature)
152
+ embedded_model = get_embedding_model(
153
+ model_name=embedding_model,
154
+ fine_tuned_path=fine_tuned_path
155
+ )
156
+ service_context = ServiceContext.from_defaults(
157
+ llm=llm,
158
+ embed_model=embedded_model
159
+ )
160
+
161
+ if os.path.exists(persisted_path):
162
+ print("loading from vector database - chroma")
163
+ db = chromadb.PersistentClient(path=persisted_path)
164
+ chroma_collection = db.get_or_create_collection("quickstart")
165
+ vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
166
+ storage_context = StorageContext.from_defaults(
167
+ vector_store=vector_store
168
+ )
169
+ index = VectorStoreIndex.from_vector_store(
170
+ vector_store=vector_store,
171
+ service_context=service_context,
172
+ storage_context=storage_context
173
+ )
174
+ else:
175
+ print("create in-memory vector store")
176
+ document = get_document_object(input_files)
177
+ index = VectorStoreIndex.from_documents(
178
+ [document],
179
+ service_context=service_context
180
+ )
181
+
182
+ memory = ChatMemoryBuffer.from_defaults(token_limit=15000)
183
+ chat_engine = index.as_chat_engine(
184
+ chat_mode="context",
185
+ memory=memory,
186
+ system_prompt=system_content
187
+ )
188
+
189
+ return chat_engine
190
+
191
+ def generate_llm_response(prompt_input):
192
+ chat_engine = get_query_engine(input_files=input_files,
193
+ llm_model=selected_model,
194
+ temperature=temperature,
195
+ embedding_model=embedding_model,
196
+ fine_tuned_path=fine_tuned_path,
197
+ system_content=system_content,
198
+ persisted_path=persisted_vector_db)
199
+
200
+ # st.session_state.messages
201
+ response = chat_engine.stream_chat(prompt_input)
202
+ return response
203
+
204
+ def handle_feedback(user_response):
205
+ st.toast("✔️ Feedback received!")
206
+ st.session_state.feedback = False
207
+
208
+ def handle_image_upload():
209
+ st.session_state.release_file = "true"
210
+
211
+ # Warm start
212
+ if st.session_state.init["warm_started"] == "No":
213
+ clear_chat_history()
214
+ st.session_state.init["warm_started"] = "Yes"
215
+
216
+ # Image upload option
217
+ with st.sidebar:
218
+ image_file = st.file_uploader("Upload your image here...",
219
+ type=["png", "jpeg", "jpg"],
220
+ on_change=handle_image_upload)
221
+
222
+ if st.session_state.release_file == "true" and image_file:
223
+ with st.spinner("Uploading..."):
224
+ b64string = base64.b64encode(image_file.read()).decode('utf-8')
225
+ message = {
226
+ "role": "user",
227
+ "content": b64string,
228
+ "type": "image"}
229
+ st.session_state.messages.append(message)
230
+
231
+ transcribed_msg = get_transcribed_text(b64string)
232
+ message = {
233
+ "role": "admin",
234
+ "content": transcribed_msg,
235
+ "type": "text"}
236
+ st.session_state.messages.append(message)
237
+ st.session_state.release_file = "false"
238
+
239
+ # Display or clear chat messages
240
+ for message in st.session_state.messages:
241
+ if message["role"] == "admin":
242
+ continue
243
+ with st.chat_message(message["role"]):
244
+ if message["type"] == "text":
245
+ st.write(message["content"])
246
+ elif message["type"] == "image":
247
+ img_io = BytesIO(base64.b64decode(message["content"].encode("utf-8")))
248
+ st.image(img_io)
249
+
250
+ # User-provided prompt
251
+ if prompt := st.chat_input(disabled=not openai_api):
252
+ client = OpenAI()
253
+ st.session_state.messages.append({"role": "user",
254
+ "content": prompt,
255
+ "type": "text"})
256
+ with st.chat_message("user"):
257
+ st.write(prompt)
258
+
259
+ # Retrieve text prompt from image submission
260
+ if prompt is None and \
261
+ st.session_state.messages[-1]["role"] == "admin":
262
+ prompt = st.session_state.messages[-1]["content"]
263
+
264
+ # Generate a new response if last message is not from assistant
265
+ if st.session_state.messages[-1]["role"] != "assistant":
266
+ with st.chat_message("assistant"):
267
+ with st.spinner("Thinking..."):
268
+ response = generate_llm_response(prompt)
269
+ placeholder = st.empty()
270
+ full_response = ""
271
+ for token in response.response_gen:
272
+ full_response += token
273
+ placeholder.markdown(full_response)
274
+ placeholder.markdown(full_response)
275
+
276
+ message = {"role": "assistant",
277
+ "content": full_response,
278
+ "type": "text"}
279
+ st.session_state.messages.append(message)
280
+
281
+ # Trigger feedback
282
+ if st.session_state.feedback:
283
+ result = streamlit_feedback(
284
+ feedback_type="thumbs",
285
+ optional_text_label="[Optional] Please provide an explanation",
286
+ on_submit=handle_feedback,
287
+ key=f"feedback_{st.session_state.feedback_key}"
288
+ )
archive/{streamlit_app_archive.py → streamlit_app/streamlit_app_15Jan2024.py} RENAMED
File without changes
models/chroma_db/9b83ffa5-f19f-42a5-b97f-969906ca1a4f/data_level0.bin CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d37c44e68139700bd5cfddc1f64e610ae6d974b559548175754eac7df1ac8065
3
- size 1676000
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f6cf8f7e78059a729ff1d88eca662790e198f689fd928b4f862a1aaaf93295e4
3
+ size 25140000
models/chroma_db/9b83ffa5-f19f-42a5-b97f-969906ca1a4f/header.bin CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e
3
  size 100
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0a95628a4a7b1b1b04e3993394511109b03e9060612be3ebc5a8c488e1cada5c
3
  size 100
models/chroma_db/9b83ffa5-f19f-42a5-b97f-969906ca1a4f/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:80795638f4e5e55013e63f7f283e2b3b97b5ad2ac54e10c35cd9564b50c2ba94
3
+ size 868175
models/chroma_db/9b83ffa5-f19f-42a5-b97f-969906ca1a4f/length.bin CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:fc19b1997119425765295aeab72d76faa6927d4f83985d328c26f20468d6cc76
3
- size 4000
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dbcafc88fc032c4c88850545971753cc8c8b24837ee14c55cce0839d49055d89
3
+ size 60000
models/chroma_db/9b83ffa5-f19f-42a5-b97f-969906ca1a4f/link_lists.bin CHANGED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e08b2de8cb48360a38c01ab6cb218345297bfa7bcf83739723d00a74baa8161e
3
+ size 131332
models/chroma_db/chroma.sqlite3 CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:ffe0f3842c7835daddb5c11b8f70bb5dc6352abcb91c11f30c53a49d8c6d540c
3
- size 23486464
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:29a8ddc3f6f6744fe7cce8314b9c7dd60545b66e3bfd25ad7988b47afa93cc94
3
+ size 250535936
notebooks/{fine-tuning-embedding-model.ipynb → 001_fine-tuning-embedding-model.ipynb} RENAMED
File without changes
notebooks/002_persisted-embedding-model.ipynb ADDED
@@ -0,0 +1,476 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "8acae3ed-2953-45a3-aba9-0327b6ae3679",
6
+ "metadata": {},
7
+ "source": [
8
+ "### ChromaDB method - create vectorstore based on Chroma"
9
+ ]
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": null,
14
+ "id": "7de9c591-5a77-4bbe-80f1-4897e15f0b97",
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "import chromadb\n",
19
+ "from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
20
+ "from llama_index.vector_stores.chroma.base import ChromaVectorStore\n",
21
+ "from llama_index.core import StorageContext\n",
22
+ "from llama_index.core import ServiceContext\n",
23
+ "from llama_index.core import Document\n",
24
+ "\n",
25
+ "from llama_index.embeddings.huggingface.base import HuggingFaceEmbedding\n",
26
+ "from llama_index.core import Settings\n",
27
+ "\n",
28
+ "import nest_asyncio\n",
29
+ "nest_asyncio.apply()\n",
30
+ "\n",
31
+ "import time"
32
+ ]
33
+ },
34
+ {
35
+ "cell_type": "code",
36
+ "execution_count": null,
37
+ "id": "3e65dff6-77b6-4be8-8857-5cecf3a035bb",
38
+ "metadata": {},
39
+ "outputs": [],
40
+ "source": [
41
+ "# load some documents\n",
42
+ "documents = SimpleDirectoryReader(input_files=[\n",
43
+ " \"../raw_documents/HI_Knowledge_Base.pdf\",\n",
44
+ " \"../raw_documents/HI Chapter Summary Version 1.3.pdf\",\n",
45
+ " \"../raw_documents/qna.txt\"\n",
46
+ " ]).load_data()\n",
47
+ "document = Document(text=\"\\n\\n\".join([doc.text for doc in documents]))"
48
+ ]
49
+ },
50
+ {
51
+ "cell_type": "code",
52
+ "execution_count": null,
53
+ "id": "bd86b3f5-1dfc-4257-bd9c-86d34f02398d",
54
+ "metadata": {},
55
+ "outputs": [],
56
+ "source": [
57
+ "# initialize client, setting path to save data\n",
58
+ "db = chromadb.PersistentClient(path=\"../models/chroma_db\")"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "id": "f568ce7b-bcbf-455c-acf1-6c2cae129fed",
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": [
68
+ "# create collection\n",
69
+ "chroma_collection = db.get_or_create_collection(\"quickstart\")"
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "code",
74
+ "execution_count": null,
75
+ "id": "ed0b018e-1982-46b2-b1b4-04f5c0ce8672",
76
+ "metadata": {},
77
+ "outputs": [],
78
+ "source": [
79
+ "# assign chroma as the vector_store to the context\n",
80
+ "vector_store = ChromaVectorStore(chroma_collection=chroma_collection)"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": null,
86
+ "id": "eb5edab2-30db-4bf7-96b5-4005d3161988",
87
+ "metadata": {},
88
+ "outputs": [],
89
+ "source": []
90
+ },
91
+ {
92
+ "cell_type": "code",
93
+ "execution_count": null,
94
+ "id": "0946b6ce-96ab-44de-ad75-e424a8429f67",
95
+ "metadata": {},
96
+ "outputs": [],
97
+ "source": [
98
+ "Settings.llm = None\n",
99
+ "Settings.chunk_size = 1024\n",
100
+ "Settings.embed_model = \"local:../models/fine-tuned-embeddings\""
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "code",
105
+ "execution_count": null,
106
+ "id": "b8c73a2c-1129-406a-8046-085afcaf9cbb",
107
+ "metadata": {},
108
+ "outputs": [],
109
+ "source": [
110
+ "nodes = Settings.node_parser.get_nodes_from_documents(documents)"
111
+ ]
112
+ },
113
+ {
114
+ "cell_type": "code",
115
+ "execution_count": null,
116
+ "id": "adfe688f-95c0-477c-a9de-e9e77541a1d7",
117
+ "metadata": {},
118
+ "outputs": [],
119
+ "source": []
120
+ },
121
+ {
122
+ "cell_type": "code",
123
+ "execution_count": null,
124
+ "id": "dab4c6f3-ef67-4d90-b3d5-e290c5d1b6f4",
125
+ "metadata": {},
126
+ "outputs": [],
127
+ "source": [
128
+ "storage_context = StorageContext.from_defaults(vector_store=vector_store)"
129
+ ]
130
+ },
131
+ {
132
+ "cell_type": "code",
133
+ "execution_count": null,
134
+ "id": "6a764113-ad7e-4674-aa57-ebbf405902a8",
135
+ "metadata": {},
136
+ "outputs": [],
137
+ "source": [
138
+ "storage_context.docstore.add_documents(nodes)"
139
+ ]
140
+ },
141
+ {
142
+ "cell_type": "code",
143
+ "execution_count": null,
144
+ "id": "38e7c88d-6c45-4275-8293-d09b4b85a7cf",
145
+ "metadata": {},
146
+ "outputs": [],
147
+ "source": []
148
+ },
149
+ {
150
+ "cell_type": "code",
151
+ "execution_count": null,
152
+ "id": "e492ed4a-23a3-47d6-8b50-51fb48b3aa05",
153
+ "metadata": {},
154
+ "outputs": [],
155
+ "source": [
156
+ "start_time = time.time()"
157
+ ]
158
+ },
159
+ {
160
+ "cell_type": "code",
161
+ "execution_count": null,
162
+ "id": "cbd11b89-9b83-4f08-bb30-160f750f2ffb",
163
+ "metadata": {},
164
+ "outputs": [],
165
+ "source": [
166
+ "vector_index = VectorStoreIndex(nodes, storage_context=storage_context)"
167
+ ]
168
+ },
169
+ {
170
+ "cell_type": "code",
171
+ "execution_count": null,
172
+ "id": "082a0d7e-b025-4db1-be2a-7a0b7bc453b9",
173
+ "metadata": {},
174
+ "outputs": [],
175
+ "source": [
176
+ "vector_query_engine = vector_index.as_query_engine()"
177
+ ]
178
+ },
179
+ {
180
+ "cell_type": "code",
181
+ "execution_count": null,
182
+ "id": "d3bd848d-9985-4a3d-bdc4-ec340cc69ef3",
183
+ "metadata": {},
184
+ "outputs": [],
185
+ "source": [
186
+ "indexing_cost = time.time() - start_time\n",
187
+ "indexing_cost = indexing_cost / 60\n",
188
+ "print(f\"Indexing time: {indexing_cost:.1f} mins\")"
189
+ ]
190
+ },
191
+ {
192
+ "cell_type": "code",
193
+ "execution_count": null,
194
+ "id": "3290e870-41d7-49c4-9c4f-cb16bd1f469e",
195
+ "metadata": {},
196
+ "outputs": [],
197
+ "source": [
198
+ "response = vector_query_engine.query(\"what is the healthcare philosophy in singapore\")\n",
199
+ "response"
200
+ ]
201
+ },
202
+ {
203
+ "cell_type": "code",
204
+ "execution_count": null,
205
+ "id": "131d907a-0677-4ad8-b3f7-6fc9b9c5d0a5",
206
+ "metadata": {},
207
+ "outputs": [],
208
+ "source": []
209
+ },
210
+ {
211
+ "cell_type": "code",
212
+ "execution_count": null,
213
+ "id": "08fb2be5-3a44-4bb8-a9fc-61d7f03b7a35",
214
+ "metadata": {},
215
+ "outputs": [],
216
+ "source": []
217
+ },
218
+ {
219
+ "cell_type": "markdown",
220
+ "id": "a7fc01f6-4738-415b-a96b-afd6cf8d789a",
221
+ "metadata": {},
222
+ "source": [
223
+ "### ChromaDB method - load vectorstore based on Chroma"
224
+ ]
225
+ },
226
+ {
227
+ "cell_type": "code",
228
+ "execution_count": null,
229
+ "id": "c1a42c35-5f57-423c-8fb7-7d18b3b466b5",
230
+ "metadata": {},
231
+ "outputs": [],
232
+ "source": [
233
+ "import chromadb\n",
234
+ "from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
235
+ "from llama_index.vector_stores.chroma.base import ChromaVectorStore\n",
236
+ "from llama_index.core import StorageContext\n",
237
+ "from llama_index.core import ServiceContext\n",
238
+ "from llama_index.core import Document\n",
239
+ "\n",
240
+ "from llama_index.embeddings.huggingface.base import HuggingFaceEmbedding\n",
241
+ "from llama_index.llms.openai import OpenAI\n",
242
+ "from llama_index.core.memory import ChatMemoryBuffer\n",
243
+ "\n",
244
+ "import time"
245
+ ]
246
+ },
247
+ {
248
+ "cell_type": "code",
249
+ "execution_count": null,
250
+ "id": "72dd0ece-c72d-428a-89b4-9494d948c845",
251
+ "metadata": {},
252
+ "outputs": [],
253
+ "source": []
254
+ },
255
+ {
256
+ "cell_type": "code",
257
+ "execution_count": null,
258
+ "id": "d38dc953-b923-4128-86a1-c8c6f69af0ed",
259
+ "metadata": {},
260
+ "outputs": [],
261
+ "source": [
262
+ "fine_tuned_path = \"local:../models/fine-tuned-embeddings\""
263
+ ]
264
+ },
265
+ {
266
+ "cell_type": "code",
267
+ "execution_count": null,
268
+ "id": "4c83c613-2cfc-4871-9d07-c82f77a3bd5e",
269
+ "metadata": {},
270
+ "outputs": [],
271
+ "source": [
272
+ "llm = OpenAI(model=\"gpt-3.5-turbo-1106\", temperature=0.0)"
273
+ ]
274
+ },
275
+ {
276
+ "cell_type": "code",
277
+ "execution_count": null,
278
+ "id": "0583e9b0-d977-488c-8331-46dfa749924c",
279
+ "metadata": {},
280
+ "outputs": [],
281
+ "source": [
282
+ "Settings.llm = llm\n",
283
+ "Settings.embed_model = fine_tuned_path"
284
+ ]
285
+ },
286
+ {
287
+ "cell_type": "code",
288
+ "execution_count": null,
289
+ "id": "f994f440-f647-48b4-a517-46a79f7561e5",
290
+ "metadata": {},
291
+ "outputs": [],
292
+ "source": []
293
+ },
294
+ {
295
+ "cell_type": "code",
296
+ "execution_count": null,
297
+ "id": "2159a2b6-494b-41b9-ac54-dd342bfb74ba",
298
+ "metadata": {},
299
+ "outputs": [],
300
+ "source": [
301
+ "db = chromadb.PersistentClient(path=\"../models/chroma_db\")"
302
+ ]
303
+ },
304
+ {
305
+ "cell_type": "code",
306
+ "execution_count": null,
307
+ "id": "1b385644-b46e-4d13-88fa-9f4af39db405",
308
+ "metadata": {},
309
+ "outputs": [],
310
+ "source": [
311
+ "chroma_collection = db.get_or_create_collection(\"quickstart\")"
312
+ ]
313
+ },
314
+ {
315
+ "cell_type": "code",
316
+ "execution_count": null,
317
+ "id": "93cb53d1-6b8c-4b2d-a839-53501c0d54b2",
318
+ "metadata": {},
319
+ "outputs": [],
320
+ "source": [
321
+ "# assign chroma as the vector_store to the context\n",
322
+ "vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n",
323
+ "storage_context = StorageContext.from_defaults(vector_store=vector_store)"
324
+ ]
325
+ },
326
+ {
327
+ "cell_type": "code",
328
+ "execution_count": null,
329
+ "id": "c40d59e1-6d42-41f0-8c9b-70aa026093ae",
330
+ "metadata": {},
331
+ "outputs": [],
332
+ "source": [
333
+ "# create your index\n",
334
+ "index = VectorStoreIndex.from_vector_store(\n",
335
+ " vector_store=vector_store,\n",
336
+ " storage_context=storage_context\n",
337
+ ")"
338
+ ]
339
+ },
340
+ {
341
+ "cell_type": "code",
342
+ "execution_count": null,
343
+ "id": "73ba6d06-ba69-4b5e-962a-9cf7d2dc4d94",
344
+ "metadata": {},
345
+ "outputs": [],
346
+ "source": []
347
+ },
348
+ {
349
+ "cell_type": "code",
350
+ "execution_count": null,
351
+ "id": "1a506940-c2b4-4d14-ad93-fd451331c582",
352
+ "metadata": {},
353
+ "outputs": [],
354
+ "source": [
355
+ "system_content = (\"You are a helpful study assistant. \"\n",
356
+ " \"You do not respond as 'User' or pretend to be 'User'. \"\n",
357
+ " \"You only respond once as 'Assistant'.\"\n",
358
+ ")"
359
+ ]
360
+ },
361
+ {
362
+ "cell_type": "code",
363
+ "execution_count": null,
364
+ "id": "3f592848-8536-4b4d-b34a-adc32d043432",
365
+ "metadata": {},
366
+ "outputs": [],
367
+ "source": [
368
+ "memory = ChatMemoryBuffer.from_defaults(token_limit=15000)"
369
+ ]
370
+ },
371
+ {
372
+ "cell_type": "code",
373
+ "execution_count": null,
374
+ "id": "6c7df81a-fd2f-42bf-b09c-46d7750f7252",
375
+ "metadata": {},
376
+ "outputs": [],
377
+ "source": [
378
+ "chat_engine = index.as_chat_engine(\n",
379
+ " chat_mode=\"context\",\n",
380
+ " memory=memory,\n",
381
+ " system_prompt=system_content\n",
382
+ ")"
383
+ ]
384
+ },
385
+ {
386
+ "cell_type": "code",
387
+ "execution_count": null,
388
+ "id": "434f0caf-8b1f-40c6-b9ec-b039cd1ca612",
389
+ "metadata": {},
390
+ "outputs": [],
391
+ "source": [
392
+ "res = chat_engine.chat(\"what is the healthcare philosophy in singapore\")\n",
393
+ "print(res.response)"
394
+ ]
395
+ },
396
+ {
397
+ "cell_type": "code",
398
+ "execution_count": null,
399
+ "id": "1e62303c-3a00-448f-ad93-15cb6cee1f24",
400
+ "metadata": {},
401
+ "outputs": [],
402
+ "source": []
403
+ },
404
+ {
405
+ "cell_type": "code",
406
+ "execution_count": null,
407
+ "id": "dad72f9f-7f86-407d-93be-f5724cb30d5c",
408
+ "metadata": {},
409
+ "outputs": [],
410
+ "source": [
411
+ "hi_engine = index.as_query_engine(\n",
412
+ " memory=memory,\n",
413
+ " system_prompt=system_content,\n",
414
+ " similarity_top_k=3,\n",
415
+ " streaming=True\n",
416
+ ")"
417
+ ]
418
+ },
419
+ {
420
+ "cell_type": "code",
421
+ "execution_count": null,
422
+ "id": "ab778a5d-d438-4f39-88f5-c67a1f1d575e",
423
+ "metadata": {},
424
+ "outputs": [],
425
+ "source": []
426
+ },
427
+ {
428
+ "cell_type": "code",
429
+ "execution_count": null,
430
+ "id": "7bb7c21a-7461-40c1-87a7-4a1f92f70153",
431
+ "metadata": {},
432
+ "outputs": [],
433
+ "source": [
434
+ "res = hi_engine.query(\"What is llama2?\")\n",
435
+ "print(res)"
436
+ ]
437
+ },
438
+ {
439
+ "cell_type": "code",
440
+ "execution_count": null,
441
+ "id": "874a39ce-e682-42fa-8085-646bacea6cdb",
442
+ "metadata": {},
443
+ "outputs": [],
444
+ "source": []
445
+ },
446
+ {
447
+ "cell_type": "code",
448
+ "execution_count": null,
449
+ "id": "301e8270-783d-4942-a05f-9683ca96fbda",
450
+ "metadata": {},
451
+ "outputs": [],
452
+ "source": []
453
+ }
454
+ ],
455
+ "metadata": {
456
+ "kernelspec": {
457
+ "display_name": "Python 3 (ipykernel)",
458
+ "language": "python",
459
+ "name": "python3"
460
+ },
461
+ "language_info": {
462
+ "codemirror_mode": {
463
+ "name": "ipython",
464
+ "version": 3
465
+ },
466
+ "file_extension": ".py",
467
+ "mimetype": "text/x-python",
468
+ "name": "python",
469
+ "nbconvert_exporter": "python",
470
+ "pygments_lexer": "ipython3",
471
+ "version": "3.9.18"
472
+ }
473
+ },
474
+ "nbformat": 4,
475
+ "nbformat_minor": 5
476
+ }
notebooks/{create_mock_qna.ipynb → 003_create_mock_qna.ipynb} RENAMED
File without changes
notebooks/{qna_prompting_with_function_calling.ipynb → 004_qna_prompting_with_function_calling.ipynb} RENAMED
@@ -339,6 +339,32 @@
339
  "print(json_response)"
340
  ]
341
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  {
343
  "cell_type": "code",
344
  "execution_count": null,
 
339
  "print(json_response)"
340
  ]
341
  },
342
+ {
343
+ "cell_type": "code",
344
+ "execution_count": null,
345
+ "id": "049a28bf-abe5-4247-970f-615d1877a2c0",
346
+ "metadata": {},
347
+ "outputs": [],
348
+ "source": []
349
+ },
350
+ {
351
+ "cell_type": "code",
352
+ "execution_count": null,
353
+ "id": "de49c61a-0b3e-4623-abcb-a7625ac4d0db",
354
+ "metadata": {},
355
+ "outputs": [],
356
+ "source": [
357
+ "prompt = \"I am interested in 2nd chapter, can you test my understanding of this chapter?\"\n",
358
+ "response = client.chat.completions.create(\n",
359
+ " model = 'gpt-3.5-turbo',\n",
360
+ " messages = [{'role': 'user', 'content': prompt}],\n",
361
+ " functions = qna_custom_functions,\n",
362
+ " function_call = 'auto'\n",
363
+ ")\n",
364
+ "json_response = json.loads(response.choices[0].message.function_call.arguments)\n",
365
+ "print(json_response)"
366
+ ]
367
+ },
368
  {
369
  "cell_type": "code",
370
  "execution_count": null,
notebooks/005_qna_prompting_with_pydantic_embeddings.ipynb ADDED
@@ -0,0 +1,676 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "4cf3ca7c-2c43-495b-a1ee-24c770f0ad1e",
6
+ "metadata": {},
7
+ "source": [
8
+ "### Simple OpenAI agent with tool"
9
+ ]
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": null,
14
+ "id": "a9d74b11-4049-4e3c-839e-7d13d7c0dadc",
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "import json\n",
19
+ "import sqlite3\n",
20
+ "from typing import Sequence, List\n",
21
+ "from pydantic import BaseModel, Field\n",
22
+ "\n",
23
+ "from llama_index.core.llms import ChatMessage\n",
24
+ "from llama_index.core.tools import BaseTool, FunctionTool\n",
25
+ "from llama_index.llms.openai import OpenAI\n",
26
+ "from llama_index.agent.openai import OpenAIAgent\n",
27
+ "\n",
28
+ "import nest_asyncio\n",
29
+ "\n",
30
+ "nest_asyncio.apply()"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": null,
36
+ "id": "33da3ba3-7d5d-4528-8e31-cabf85a88886",
37
+ "metadata": {},
38
+ "outputs": [],
39
+ "source": []
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": null,
44
+ "id": "b27b2c3b-1876-4a20-8fb9-cddd6df51ef3",
45
+ "metadata": {},
46
+ "outputs": [],
47
+ "source": [
48
+ "db_path = \"../database/mock_qna.db\"\n",
49
+ "con = sqlite3.connect(db_path)\n",
50
+ "cur = con.cursor()"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "code",
55
+ "execution_count": null,
56
+ "id": "b69adba2-9f98-460b-b0a3-e759d6ac1b88",
57
+ "metadata": {},
58
+ "outputs": [],
59
+ "source": []
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "id": "39ca840b-0ec7-4279-9654-e4ddfda6137f",
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": [
68
+ "# define sample Tool\n",
69
+ "def multiply(a: int, b: int) -> int:\n",
70
+ " \"\"\"Multiply two integers and returns the result integer\"\"\"\n",
71
+ " return a * b\n",
72
+ "\n",
73
+ "multiply_tool = FunctionTool.from_defaults(fn=multiply)\n",
74
+ "\n",
75
+ "def add(a: int, b: int) -> int:\n",
76
+ " \"\"\"Add two integers and returns the result integer\"\"\"\n",
77
+ " return a + b\n",
78
+ "\n",
79
+ "add_tool = FunctionTool.from_defaults(fn=add)\n",
80
+ "\n",
81
+ "class Song(BaseModel):\n",
82
+ " \"\"\"A song with name and artist\"\"\"\n",
83
+ "\n",
84
+ " name: str\n",
85
+ " artist: str\n",
86
+ "\n",
87
+ "song_fn = FunctionTool.from_defaults(fn=Song)"
88
+ ]
89
+ },
90
+ {
91
+ "cell_type": "code",
92
+ "execution_count": null,
93
+ "id": "14b64612-1320-48b2-b5ff-91cde659cbf8",
94
+ "metadata": {},
95
+ "outputs": [],
96
+ "source": [
97
+ "class QnA_Model(BaseModel):\n",
98
+ " chapter_n: str = Field(..., \n",
99
+ " pattern=r'^Chapter_\\d*$',\n",
100
+ " description=(\n",
101
+ " \"which chapter to extract, the format of this function argumet\"\n",
102
+ " \"is with `Chapter_` as prefix concatenated with chapter number\"\n",
103
+ " \"in integer. For example, `Chapter_2`, `Chapter_10`.\")\n",
104
+ " )\n",
105
+ "\n",
106
+ "description = \"\"\"\n",
107
+ " Use this tool to extract the chapter information from the body of the input text, \n",
108
+ " the format looks as follow:\n",
109
+ " The output should be in the format with `Chapter_` as prefix.\n",
110
+ " Example 1: `Chapter_1` for first chapter\n",
111
+ " Example 2: For chapter 12 of the textbook, you should return `Chapter_12`\n",
112
+ " Example 3: `Chapter_5` for fifth chapter\n",
113
+ " Thereafter, the chapter_n argument will be passed to the function for Q&A question retrieval.\n",
114
+ "\"\"\"\n",
115
+ "\n",
116
+ "def get_qna_question(chapter_n: str):\n",
117
+ " \"\"\"\n",
118
+ " Use this tool to extract the chapter information from the body of the input text, \n",
119
+ " the format looks as follow:\n",
120
+ " The output should be in the format with `Chapter_` as prefix.\n",
121
+ " Example 1: `Chapter_1` for first chapter\n",
122
+ " Example 2: For chapter 12 of the textbook, you should return `Chapter_12`\n",
123
+ " Example 3: `Chapter_5` for fifth chapter\n",
124
+ " Thereafter, the chapter_n argument will be passed to the function for Q&A question retrieval.\n",
125
+ " \"\"\"\n",
126
+ " sql_string = f\"\"\"SELECT id, question, option_1, option_2, option_3, option_4, correct_answer\n",
127
+ " FROM qna_tbl\n",
128
+ " WHERE chapter='{chapter_n}'\n",
129
+ " \"\"\"\n",
130
+ " res = cur.execute(sql_string)\n",
131
+ " result = res.fetchone()\n",
132
+ "\n",
133
+ " id = result[0]\n",
134
+ " question = result[1]\n",
135
+ " option_1 = result[2]\n",
136
+ " option_2 = result[3]\n",
137
+ " option_3 = result[4]\n",
138
+ " option_4 = result[5]\n",
139
+ " c_answer = result[6]\n",
140
+ "\n",
141
+ " qna_str = \"Question: \\n\" + \\\n",
142
+ " \"========= \\n\" + \\\n",
143
+ " question.replace(\"\\\\n\", \"\\n\") + \"\\n\" + \\\n",
144
+ " \"A) \" + option_1 + \"\\n\" + \\\n",
145
+ " \"B) \" + option_2 + \"\\n\" + \\\n",
146
+ " \"C) \" + option_3 + \"\\n\" + \\\n",
147
+ " \"D) \" + option_4\n",
148
+ " \n",
149
+ " # return id, qna_str, c_answer\n",
150
+ " return qna_str\n",
151
+ "\n",
152
+ "get_qna_question_tool = FunctionTool.from_defaults(\n",
153
+ " fn=get_qna_question,\n",
154
+ " name=\"Extract_Question\",\n",
155
+ " description=description,\n",
156
+ " fn_schema=QnA_Model\n",
157
+ ")"
158
+ ]
159
+ },
160
+ {
161
+ "cell_type": "code",
162
+ "execution_count": null,
163
+ "id": "4df3e9f2-4a32-4449-b203-929dff9e7963",
164
+ "metadata": {},
165
+ "outputs": [],
166
+ "source": []
167
+ },
168
+ {
169
+ "cell_type": "code",
170
+ "execution_count": null,
171
+ "id": "bbeeea36-0bb0-4edb-9b8c-adb7c64c4cd3",
172
+ "metadata": {},
173
+ "outputs": [],
174
+ "source": [
175
+ "# initialize openai agent\n",
176
+ "llm = OpenAI(model=\"gpt-3.5-turbo-0613\")\n",
177
+ "agent = OpenAIAgent.from_tools([multiply_tool, \n",
178
+ " add_tool, \n",
179
+ " song_fn, \n",
180
+ " get_qna_question_tool], llm=llm, verbose=True)"
181
+ ]
182
+ },
183
+ {
184
+ "cell_type": "code",
185
+ "execution_count": null,
186
+ "id": "0edafe7d-a835-4882-bd7d-1717a4cad462",
187
+ "metadata": {},
188
+ "outputs": [],
189
+ "source": []
190
+ },
191
+ {
192
+ "cell_type": "code",
193
+ "execution_count": null,
194
+ "id": "65158ede-b99f-477d-9d17-3be40e57a629",
195
+ "metadata": {},
196
+ "outputs": [],
197
+ "source": [
198
+ "res = agent.chat(message=\"3 x 2 equals?\", tool_choice=\"auto\")\n",
199
+ "res"
200
+ ]
201
+ },
202
+ {
203
+ "cell_type": "code",
204
+ "execution_count": null,
205
+ "id": "d74b0e5c-47a2-4de4-acd2-d39a94941f2d",
206
+ "metadata": {},
207
+ "outputs": [],
208
+ "source": []
209
+ },
210
+ {
211
+ "cell_type": "code",
212
+ "execution_count": null,
213
+ "id": "d9787ed4-46a2-46aa-80e6-b317d9280b9e",
214
+ "metadata": {},
215
+ "outputs": [],
216
+ "source": [
217
+ "res = agent.chat(message=\"3 plus 2 equals?\", tool_choice=\"auto\")\n",
218
+ "res"
219
+ ]
220
+ },
221
+ {
222
+ "cell_type": "code",
223
+ "execution_count": null,
224
+ "id": "dd3358c6-e0e4-4354-8a4e-97d70254f648",
225
+ "metadata": {},
226
+ "outputs": [],
227
+ "source": []
228
+ },
229
+ {
230
+ "cell_type": "code",
231
+ "execution_count": null,
232
+ "id": "16e1db2c-dca3-4dc6-9cc5-c10644d5927c",
233
+ "metadata": {},
234
+ "outputs": [],
235
+ "source": [
236
+ "res = agent.chat(message=\"give me the lyrics of taylor swift's `you belong with me`\", tool_choice=\"auto\")\n",
237
+ "res"
238
+ ]
239
+ },
240
+ {
241
+ "cell_type": "code",
242
+ "execution_count": null,
243
+ "id": "97a021f4-4701-4914-9ab8-0683b396f096",
244
+ "metadata": {},
245
+ "outputs": [],
246
+ "source": []
247
+ },
248
+ {
249
+ "cell_type": "code",
250
+ "execution_count": null,
251
+ "id": "1f0b352d-8510-4b2a-a495-9f2e1fbfcddb",
252
+ "metadata": {},
253
+ "outputs": [],
254
+ "source": [
255
+ "# res_stream = agent.stream_chat(message=\"3 x 2 equals?\")\n",
256
+ "# for r in res_stream.response_gen:\n",
257
+ "# print(r, end=\"\")"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": null,
263
+ "id": "ea0a6cd4-f204-4997-bdfb-cb9b5a9e1266",
264
+ "metadata": {},
265
+ "outputs": [],
266
+ "source": []
267
+ },
268
+ {
269
+ "cell_type": "markdown",
270
+ "id": "96c978e6-62e2-46e6-ae63-76841487f618",
271
+ "metadata": {},
272
+ "source": [
273
+ "### OpenAI agent with embeddings, and function calling"
274
+ ]
275
+ },
276
+ {
277
+ "cell_type": "code",
278
+ "execution_count": null,
279
+ "id": "6f0f5f02-c8e9-43a9-853d-12bb3c19dbe8",
280
+ "metadata": {},
281
+ "outputs": [],
282
+ "source": [
283
+ "import os\n",
284
+ "import chromadb\n",
285
+ "\n",
286
+ "from llama_index.core import (\n",
287
+ " SimpleDirectoryReader,\n",
288
+ " VectorStoreIndex,\n",
289
+ " ServiceContext,\n",
290
+ " StorageContext,\n",
291
+ " load_index_from_storage,\n",
292
+ ")\n",
293
+ "from llama_index.core.memory import ChatMemoryBuffer\n",
294
+ "from llama_index.vector_stores.chroma.base import ChromaVectorStore\n",
295
+ "from llama_index.core.tools import QueryEngineTool, ToolMetadata\n",
296
+ "from llama_index.llms.openai import OpenAI\n",
297
+ "from llama_index.agent.openai import OpenAIAgent\n",
298
+ "from llama_index.core.tools import BaseTool, FunctionTool\n",
299
+ "from llama_index.core import Settings\n",
300
+ "\n",
301
+ "from pydantic import BaseModel\n",
302
+ "import nest_asyncio\n",
303
+ "\n",
304
+ "nest_asyncio.apply()"
305
+ ]
306
+ },
307
+ {
308
+ "cell_type": "code",
309
+ "execution_count": null,
310
+ "id": "54855aa4-dcad-404e-843f-c96d61046df3",
311
+ "metadata": {},
312
+ "outputs": [],
313
+ "source": []
314
+ },
315
+ {
316
+ "cell_type": "markdown",
317
+ "id": "4edb89f6-bb2f-46ff-8807-dfb03115fcd5",
318
+ "metadata": {},
319
+ "source": [
320
+ "#### Parameters"
321
+ ]
322
+ },
323
+ {
324
+ "cell_type": "code",
325
+ "execution_count": null,
326
+ "id": "61ad7369-8fd4-434f-b687-0c649940bda1",
327
+ "metadata": {},
328
+ "outputs": [],
329
+ "source": [
330
+ "selected_model = \"gpt-3.5-turbo-1106\"\n",
331
+ "temperature = 0.0\n",
332
+ "\n",
333
+ "persisted_vector_db = \"../models/chroma_db\"\n",
334
+ "input_files = [\"../raw_documents/HI_Knowledge_Base.pdf\",\n",
335
+ " \"../raw_documents/HI Chapter Summary Version 1.3.pdf\",\n",
336
+ " \"../raw_documents/qna.txt\"]\n",
337
+ "fine_tuned_path = \"local:../models/fine-tuned-embeddings\"\n",
338
+ "system_content = (\"You are a helpful study assistant. \"\n",
339
+ " \"You do not respond as 'User' or pretend to be 'User'. \"\n",
340
+ " \"You only respond once as 'Assistant'.\"\n",
341
+ ")"
342
+ ]
343
+ },
344
+ {
345
+ "cell_type": "code",
346
+ "execution_count": null,
347
+ "id": "a18117f5-48a7-4e81-9b46-541f382caf9e",
348
+ "metadata": {},
349
+ "outputs": [],
350
+ "source": []
351
+ },
352
+ {
353
+ "cell_type": "markdown",
354
+ "id": "3210c837-9b40-4cd9-bb00-ead559deff6f",
355
+ "metadata": {},
356
+ "source": [
357
+ "#### Load vector store"
358
+ ]
359
+ },
360
+ {
361
+ "cell_type": "code",
362
+ "execution_count": null,
363
+ "id": "b9dfba0c-f27d-49d1-86c5-a1d95c11b844",
364
+ "metadata": {},
365
+ "outputs": [],
366
+ "source": [
367
+ "if os.path.exists(persisted_vector_db):\n",
368
+ " db = chromadb.PersistentClient(path=persisted_vector_db)\n",
369
+ " chroma_collection = db.get_or_create_collection(\"quickstart\")\n",
370
+ " \n",
371
+ " # assign chroma as the vector_store to the context\n",
372
+ " vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n",
373
+ " storage_context = StorageContext.from_defaults(vector_store=vector_store)\n",
374
+ "\n",
375
+ "else:\n",
376
+ " documents = SimpleDirectoryReader(input_files=input_files).load_data()\n",
377
+ " document = Document(text=\"\\n\\n\".join([doc.text for doc in documents]))\n",
378
+ " \n",
379
+ " # initialize client, setting path to save data\n",
380
+ " db = chromadb.PersistentClient(path=persisted_vector_db)\n",
381
+ " \n",
382
+ " # create collection\n",
383
+ " chroma_collection = db.get_or_create_collection(\"quickstart\")\n",
384
+ "\n",
385
+ " # assign chroma as the vector_store to the context\n",
386
+ " vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n",
387
+ " storage_context = StorageContext.from_defaults(vector_store=vector_store)"
388
+ ]
389
+ },
390
+ {
391
+ "cell_type": "code",
392
+ "execution_count": null,
393
+ "id": "693c9808-efbe-47a6-a49c-7143c63d13e5",
394
+ "metadata": {},
395
+ "outputs": [],
396
+ "source": []
397
+ },
398
+ {
399
+ "cell_type": "code",
400
+ "execution_count": null,
401
+ "id": "c6bfae0b-7c97-4c2b-9996-f5e3ecf7a992",
402
+ "metadata": {},
403
+ "outputs": [],
404
+ "source": [
405
+ "# define sample Tool\n",
406
+ "def multiply(a: int, b: int) -> int:\n",
407
+ " \"\"\"Multiply two integers and returns the result integer\"\"\"\n",
408
+ " return a * b\n",
409
+ "\n",
410
+ "def add(a: int, b: int) -> int:\n",
411
+ " \"\"\"Add two integers and returns the result integer\"\"\"\n",
412
+ " return a + b\n",
413
+ "\n",
414
+ "class Song(BaseModel):\n",
415
+ " \"\"\"A song with name and artist\"\"\"\n",
416
+ "\n",
417
+ " name: str\n",
418
+ " artist: str\n",
419
+ "\n",
420
+ "add_tool = FunctionTool.from_defaults(fn=add)\n",
421
+ "multiply_tool = FunctionTool.from_defaults(fn=multiply)\n",
422
+ "song_fn = FunctionTool.from_defaults(fn=Song)"
423
+ ]
424
+ },
425
+ {
426
+ "cell_type": "code",
427
+ "execution_count": null,
428
+ "id": "16a80b2e-8e5f-462a-8616-042afe18be3a",
429
+ "metadata": {},
430
+ "outputs": [],
431
+ "source": [
432
+ "llm = OpenAI(model=selected_model, temperature=temperature)\n",
433
+ "\n",
434
+ "Settings.llm = llm\n",
435
+ "Settings.embed_model = fine_tuned_path"
436
+ ]
437
+ },
438
+ {
439
+ "cell_type": "code",
440
+ "execution_count": null,
441
+ "id": "95d3a420-1ee4-45bd-a18b-b398d9531db4",
442
+ "metadata": {},
443
+ "outputs": [],
444
+ "source": [
445
+ "index = VectorStoreIndex.from_vector_store(\n",
446
+ " vector_store=vector_store,\n",
447
+ " storage_context=storage_context\n",
448
+ ")"
449
+ ]
450
+ },
451
+ {
452
+ "cell_type": "code",
453
+ "execution_count": null,
454
+ "id": "eac6d76d-059b-40e3-b67f-c736f1ce6baa",
455
+ "metadata": {},
456
+ "outputs": [],
457
+ "source": [
458
+ "memory = ChatMemoryBuffer.from_defaults(token_limit=15000)\n",
459
+ "\n",
460
+ "hi_engine = index.as_query_engine(\n",
461
+ " memory=memory,\n",
462
+ " system_prompt=system_content,\n",
463
+ " similarity_top_k=3,\n",
464
+ " streaming=True\n",
465
+ ")"
466
+ ]
467
+ },
468
+ {
469
+ "cell_type": "code",
470
+ "execution_count": null,
471
+ "id": "18e38a8f-9b51-4675-a1d5-8aaa6c21694c",
472
+ "metadata": {},
473
+ "outputs": [],
474
+ "source": [
475
+ "res = hi_engine.query(\"what is the healthcare philosophy in singapore\")\n",
476
+ "print(res)"
477
+ ]
478
+ },
479
+ {
480
+ "cell_type": "code",
481
+ "execution_count": null,
482
+ "id": "70dae6f7-682e-42d6-be59-3b807c10482c",
483
+ "metadata": {},
484
+ "outputs": [],
485
+ "source": []
486
+ },
487
+ {
488
+ "cell_type": "code",
489
+ "execution_count": null,
490
+ "id": "1eb5df65-c926-4b22-8071-449d645b339f",
491
+ "metadata": {},
492
+ "outputs": [],
493
+ "source": [
494
+ "hi_query_tool = QueryEngineTool.from_defaults(\n",
495
+ " query_engine=hi_engine,\n",
496
+ " name=\"vector_tool\",\n",
497
+ " description=(\n",
498
+ " \"Provides information about Health Insurance landscape in Singapore. \"\n",
499
+ " \"Use a detailed plain text question as input to the tool.\"\n",
500
+ " )\n",
501
+ ")\n",
502
+ "\n",
503
+ "# hi_query_tool = QueryEngineTool(\n",
504
+ "# query_engine=hi_engine,\n",
505
+ "# metadata=ToolMetadata(\n",
506
+ "# name=\"health_insurance_mentor\",\n",
507
+ "# description=(\n",
508
+ "# \"Provides information about Health Insurance landscape in Singapore. \"\n",
509
+ "# \"Use a detailed plain text question as input to the tool.\"\n",
510
+ "# )\n",
511
+ "# )\n",
512
+ "# )"
513
+ ]
514
+ },
515
+ {
516
+ "cell_type": "code",
517
+ "execution_count": null,
518
+ "id": "a5822b1d-32ef-4b68-8629-a727ff51cd0a",
519
+ "metadata": {},
520
+ "outputs": [],
521
+ "source": []
522
+ },
523
+ {
524
+ "cell_type": "code",
525
+ "execution_count": null,
526
+ "id": "2a1235da-a379-4055-8bcf-4b21c91c9fb0",
527
+ "metadata": {},
528
+ "outputs": [],
529
+ "source": [
530
+ "agent = OpenAIAgent.from_tools([multiply_tool, \n",
531
+ " add_tool, \n",
532
+ " hi_query_tool, \n",
533
+ " get_qna_question_tool], llm=llm, verbose=True)"
534
+ ]
535
+ },
536
+ {
537
+ "cell_type": "code",
538
+ "execution_count": null,
539
+ "id": "05b65cbd-d15c-4909-b383-50b13f64e535",
540
+ "metadata": {},
541
+ "outputs": [],
542
+ "source": []
543
+ },
544
+ {
545
+ "cell_type": "code",
546
+ "execution_count": null,
547
+ "id": "63332a44-9441-4f49-85a2-934e2c55a362",
548
+ "metadata": {},
549
+ "outputs": [],
550
+ "source": [
551
+ "res = agent.chat(\"what is the healthcare philosophy in singapore\", tool_choice=\"auto\")\n",
552
+ "res.response"
553
+ ]
554
+ },
555
+ {
556
+ "cell_type": "code",
557
+ "execution_count": null,
558
+ "id": "de387041-706c-4be8-ab31-fe8bd8b16bc1",
559
+ "metadata": {},
560
+ "outputs": [],
561
+ "source": []
562
+ },
563
+ {
564
+ "cell_type": "code",
565
+ "execution_count": null,
566
+ "id": "eb8a8676-c070-4652-8c00-436be3135c12",
567
+ "metadata": {},
568
+ "outputs": [],
569
+ "source": [
570
+ "res = agent.chat(message=\"I am interested in 4th chapter, can you test my understanding of this chapter?\",\n",
571
+ " tool_choice=\"auto\")\n",
572
+ "res.response"
573
+ ]
574
+ },
575
+ {
576
+ "cell_type": "code",
577
+ "execution_count": null,
578
+ "id": "81709cbf-9a5e-482f-ae6a-ba361b8219dc",
579
+ "metadata": {},
580
+ "outputs": [],
581
+ "source": []
582
+ },
583
+ {
584
+ "cell_type": "code",
585
+ "execution_count": null,
586
+ "id": "adf26268-e40a-4ebd-a737-6b203ddc4444",
587
+ "metadata": {},
588
+ "outputs": [],
589
+ "source": [
590
+ "res = agent.stream_chat(\"what is the healthcare philosophy in singapore\", tool_choice=\"auto\")\n",
591
+ "for r in res.response_gen:\n",
592
+ " print(r, end=\"\")"
593
+ ]
594
+ },
595
+ {
596
+ "cell_type": "code",
597
+ "execution_count": null,
598
+ "id": "c4f2df51-553f-493d-874c-662ecb499e36",
599
+ "metadata": {},
600
+ "outputs": [],
601
+ "source": []
602
+ },
603
+ {
604
+ "cell_type": "code",
605
+ "execution_count": null,
606
+ "id": "4bf66e59-a394-4e6b-b7d5-af6b1612c97b",
607
+ "metadata": {},
608
+ "outputs": [],
609
+ "source": [
610
+ "res = agent.stream_chat(message=\"I am interested in 4th chapter, can you test my understanding of this chapter?\",\n",
611
+ " tool_choice=\"auto\")\n",
612
+ "for r in res.response_gen:\n",
613
+ " print(r, end=\"\")"
614
+ ]
615
+ },
616
+ {
617
+ "cell_type": "code",
618
+ "execution_count": null,
619
+ "id": "540c0f71-048a-4a64-9818-e2b1cffc0db7",
620
+ "metadata": {},
621
+ "outputs": [],
622
+ "source": []
623
+ },
624
+ {
625
+ "cell_type": "code",
626
+ "execution_count": null,
627
+ "id": "fbeabf28-30f9-4d7f-a4b9-21cd08a9b128",
628
+ "metadata": {},
629
+ "outputs": [],
630
+ "source": [
631
+ "res = agent.stream_chat(\"what is the result of 328123 + 2891230\", tool_choice=\"auto\")\n",
632
+ "for r in res.response_gen:\n",
633
+ " print(r, end=\"\")"
634
+ ]
635
+ },
636
+ {
637
+ "cell_type": "code",
638
+ "execution_count": null,
639
+ "id": "19b7e12c-0729-4181-acce-53a3a95b67b8",
640
+ "metadata": {},
641
+ "outputs": [],
642
+ "source": [
643
+ "328123 + 2891230"
644
+ ]
645
+ },
646
+ {
647
+ "cell_type": "code",
648
+ "execution_count": null,
649
+ "id": "bca4c0b2-5165-4943-af1f-d3168ee88fcd",
650
+ "metadata": {},
651
+ "outputs": [],
652
+ "source": []
653
+ }
654
+ ],
655
+ "metadata": {
656
+ "kernelspec": {
657
+ "display_name": "Python 3 (ipykernel)",
658
+ "language": "python",
659
+ "name": "python3"
660
+ },
661
+ "language_info": {
662
+ "codemirror_mode": {
663
+ "name": "ipython",
664
+ "version": 3
665
+ },
666
+ "file_extension": ".py",
667
+ "mimetype": "text/x-python",
668
+ "name": "python",
669
+ "nbconvert_exporter": "python",
670
+ "pygments_lexer": "ipython3",
671
+ "version": "3.9.18"
672
+ }
673
+ },
674
+ "nbformat": 4,
675
+ "nbformat_minor": 5
676
+ }
notebooks/{fine-tune-and-persist-vector-store.ipynb → 006_fine-tune-and-persist-vector-store.ipynb} RENAMED
File without changes
notebooks/qna_prompting_with_pydantic.ipynb DELETED
@@ -1,114 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": null,
6
- "id": "6f0f5f02-c8e9-43a9-853d-12bb3c19dbe8",
7
- "metadata": {},
8
- "outputs": [],
9
- "source": [
10
- "from pydantic import BaseModel"
11
- ]
12
- },
13
- {
14
- "cell_type": "code",
15
- "execution_count": null,
16
- "id": "94244a1e-e55a-4954-885e-4558797c6fe3",
17
- "metadata": {},
18
- "outputs": [],
19
- "source": [
20
- "from llama_index.llms import OpenAI"
21
- ]
22
- },
23
- {
24
- "cell_type": "code",
25
- "execution_count": null,
26
- "id": "641f36c7-0aa3-4146-9840-bfb0d4d78b4d",
27
- "metadata": {},
28
- "outputs": [],
29
- "source": [
30
- "from llama_index.core.tools import BaseTool, FunctionTool"
31
- ]
32
- },
33
- {
34
- "cell_type": "code",
35
- "execution_count": null,
36
- "id": "cb20cd13-20fd-4303-acde-b7abe0b48e39",
37
- "metadata": {},
38
- "outputs": [],
39
- "source": []
40
- },
41
- {
42
- "cell_type": "code",
43
- "execution_count": null,
44
- "id": "ab4d1a52-84be-492f-8275-3da20d854cb6",
45
- "metadata": {},
46
- "outputs": [],
47
- "source": [
48
- "class Song(BaseModel):\n",
49
- " \"\"\"A song with name and artist\"\"\"\n",
50
- "\n",
51
- " name: str\n",
52
- " artist: str"
53
- ]
54
- },
55
- {
56
- "cell_type": "code",
57
- "execution_count": null,
58
- "id": "a5822b1d-32ef-4b68-8629-a727ff51cd0a",
59
- "metadata": {},
60
- "outputs": [],
61
- "source": []
62
- },
63
- {
64
- "cell_type": "code",
65
- "execution_count": null,
66
- "id": "63332a44-9441-4f49-85a2-934e2c55a362",
67
- "metadata": {},
68
- "outputs": [],
69
- "source": [
70
- "song_fn = FunctionTool.from_defaults(fn=Song)"
71
- ]
72
- },
73
- {
74
- "cell_type": "code",
75
- "execution_count": null,
76
- "id": "ef0d7d67-9855-47ea-8569-7bfb20b03a07",
77
- "metadata": {},
78
- "outputs": [],
79
- "source": [
80
- "response = OpenAI().complete(\"Generate a song\", tools=[song_fn])\n",
81
- "tool_calls = response.additional_kwargs[\"tool_calls\"]"
82
- ]
83
- },
84
- {
85
- "cell_type": "code",
86
- "execution_count": null,
87
- "id": "bca4c0b2-5165-4943-af1f-d3168ee88fcd",
88
- "metadata": {},
89
- "outputs": [],
90
- "source": []
91
- }
92
- ],
93
- "metadata": {
94
- "kernelspec": {
95
- "display_name": "Python 3 (ipykernel)",
96
- "language": "python",
97
- "name": "python3"
98
- },
99
- "language_info": {
100
- "codemirror_mode": {
101
- "name": "ipython",
102
- "version": 3
103
- },
104
- "file_extension": ".py",
105
- "mimetype": "text/x-python",
106
- "name": "python",
107
- "nbconvert_exporter": "python",
108
- "pygments_lexer": "ipython3",
109
- "version": "3.9.18"
110
- }
111
- },
112
- "nbformat": 4,
113
- "nbformat_minor": 5
114
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
qna_prompting.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ from pydantic import BaseModel, Field
3
+ from llama_index.core.tools import FunctionTool
4
+
5
+
6
+ db_path = "./database/mock_qna.db"
7
+ description = """
8
+ Use this tool to extract the chapter information from the body of the input text,
9
+ when user wants to learn more about a particular chapter and requested to be asked
10
+ with a question to test his/her understanding.
11
+ The format of the function argument looks as follow:
12
+ It should be in the format with `Chapter_` as prefix.
13
+ Example 1: `Chapter_1` for first chapter
14
+ Example 2: For chapter 12 of the textbook, you should return `Chapter_12`
15
+ Example 3: `Chapter_5` for fifth chapter
16
+ Thereafter, the chapter_n argument will be passed to the function for Q&A question retrieval.
17
+ """
18
+
19
+ class QnA_Model(BaseModel):
20
+ chapter_n: str = Field(...,
21
+ pattern=r'^Chapter_\d*$',
22
+ description=(
23
+ "which chapter to extract, the format of this function argumet"
24
+ "is with `Chapter_` as prefix concatenated with chapter number"
25
+ "in integer. For example, `Chapter_2`, `Chapter_10`.")
26
+ )
27
+
28
+ def get_qna_question(chapter_n: str) -> str:
29
+ """
30
+ Use this tool to extract the chapter information from the body of the input text,
31
+ the format looks as follow:
32
+ The output should be in the format with `Chapter_` as prefix.
33
+ Example 1: `Chapter_1` for first chapter
34
+ Example 2: For chapter 12 of the textbook, you should return `Chapter_12`
35
+ Example 3: `Chapter_5` for fifth chapter
36
+ Thereafter, the chapter_n argument will be passed to the function for Q&A question retrieval.
37
+ """
38
+ con = sqlite3.connect(db_path)
39
+ cur = con.cursor()
40
+
41
+ sql_string = f"""SELECT id, question, option_1, option_2, option_3, option_4, correct_answer
42
+ FROM qna_tbl
43
+ WHERE chapter='{chapter_n}'
44
+ """
45
+ res = cur.execute(sql_string)
46
+ result = res.fetchone()
47
+
48
+ id = result[0]
49
+ question = result[1]
50
+ option_1 = result[2]
51
+ option_2 = result[3]
52
+ option_3 = result[4]
53
+ option_4 = result[5]
54
+ c_answer = result[6]
55
+
56
+ qna_str = "Question: \n" + \
57
+ "========= \n" + \
58
+ question.replace("\\n", "\n") + "\n" + \
59
+ "A) " + option_1 + "\n" + \
60
+ "B) " + option_2 + "\n" + \
61
+ "C) " + option_3 + "\n" + \
62
+ "D) " + option_4
63
+
64
+ con.close()
65
+
66
+ return qna_str
67
+
68
+ get_qna_question_tool = FunctionTool.from_defaults(
69
+ fn=get_qna_question,
70
+ name="Extract_Question",
71
+ description=description,
72
+ fn_schema=QnA_Model
73
+ )
requirements.txt CHANGED
@@ -101,7 +101,19 @@ langchain==0.0.354
101
  langchain-community==0.0.8
102
  langchain-core==0.1.5
103
  langsmith==0.0.77
104
- llama-index==0.9.39
 
 
 
 
 
 
 
 
 
 
 
 
105
  Mako==1.3.0
106
  Markdown==3.5.1
107
  markdown-it-py==3.0.0
@@ -131,7 +143,7 @@ notebook==7.0.6
131
  notebook_shim==0.2.3
132
  numpy==1.26.2
133
  oauthlib==3.2.2
134
- onnxruntime==1.16.3
135
  openai==1.6.1
136
  opentelemetry-api==1.22.0
137
  opentelemetry-exporter-otlp-proto-common==1.22.0
@@ -168,8 +180,10 @@ pydantic_core==2.14.6
168
  pydeck==0.8.1b0
169
  Pygments==2.17.2
170
  pymdown-extensions==10.7
 
 
171
  pyparsing==3.1.1
172
- pypdf==3.17.4
173
  PyPika==0.48.9
174
  pyproject_hooks==1.0.0
175
  python-dateutil==2.8.2
@@ -222,7 +236,7 @@ terminado==0.18.0
222
  threadpoolctl==3.2.0
223
  tiktoken==0.5.2
224
  tinycss2==1.2.1
225
- tokenizers==0.15.0
226
  toml==0.10.2
227
  tomli==2.0.1
228
  toolz==0.12.0
@@ -230,7 +244,7 @@ torch==2.1.2
230
  tornado==6.4
231
  tqdm==4.66.1
232
  traitlets==5.14.0
233
- transformers==4.36.2
234
  trulens==0.13.4
235
  trulens-eval==0.20.0
236
  typer==0.9.0
 
101
  langchain-community==0.0.8
102
  langchain-core==0.1.5
103
  langsmith==0.0.77
104
+ llama-index==0.10.1
105
+ llama-index-agent-openai==0.1.1
106
+ llama-index-core==0.10.1
107
+ llama-index-embeddings-huggingface==0.1.1
108
+ llama-index-embeddings-openai==0.1.1
109
+ llama-index-legacy==0.9.48
110
+ llama-index-llms-openai==0.1.1
111
+ llama-index-multi-modal-llms-openai==0.1.1
112
+ llama-index-program-openai==0.1.1
113
+ llama-index-question-gen-openai==0.1.1
114
+ llama-index-readers-file==0.1.2
115
+ llama-index-vector-stores-chroma==0.1.1
116
+ lxml==5.1.0
117
  Mako==1.3.0
118
  Markdown==3.5.1
119
  markdown-it-py==3.0.0
 
143
  notebook_shim==0.2.3
144
  numpy==1.26.2
145
  oauthlib==3.2.2
146
+ onnxruntime==1.17.0
147
  openai==1.6.1
148
  opentelemetry-api==1.22.0
149
  opentelemetry-exporter-otlp-proto-common==1.22.0
 
180
  pydeck==0.8.1b0
181
  Pygments==2.17.2
182
  pymdown-extensions==10.7
183
+ PyMuPDF==1.23.22
184
+ PyMuPDFb==1.23.22
185
  pyparsing==3.1.1
186
+ pypdf==4.0.1
187
  PyPika==0.48.9
188
  pyproject_hooks==1.0.0
189
  python-dateutil==2.8.2
 
236
  threadpoolctl==3.2.0
237
  tiktoken==0.5.2
238
  tinycss2==1.2.1
239
+ tokenizers==0.15.2
240
  toml==0.10.2
241
  tomli==2.0.1
242
  toolz==0.12.0
 
244
  tornado==6.4
245
  tqdm==4.66.1
246
  traitlets==5.14.0
247
+ transformers==4.37.2
248
  trulens==0.13.4
249
  trulens-eval==0.20.0
250
  typer==0.9.0
streamlit_app.py CHANGED
@@ -5,21 +5,26 @@ import os
5
  import pandas as pd
6
  import base64
7
  from io import BytesIO
8
- import nest_asyncio
9
 
10
  import chromadb
11
- from llama_index import (VectorStoreIndex,
12
- SimpleDirectoryReader,
13
- ServiceContext,
14
- Document)
15
- from llama_index.vector_stores import ChromaVectorStore
16
- from llama_index.storage.storage_context import StorageContext
17
- from llama_index.embeddings import HuggingFaceEmbedding
18
- from llama_index.llms import OpenAI
19
- from llama_index.memory import ChatMemoryBuffer
 
 
 
 
20
 
21
  from vision_api import get_transcribed_text
 
22
 
 
23
  nest_asyncio.apply()
24
 
25
  # App title
@@ -27,6 +32,7 @@ st.set_page_config(page_title="💬 Open AI Chatbot")
27
  openai_api = os.getenv("OPENAI_API_KEY")
28
 
29
  # "./raw_documents/HI_Knowledge_Base.pdf"
 
30
  input_files = ["./raw_documents/HI Chapter Summary Version 1.3.pdf",
31
  "./raw_documents/qna.txt"]
32
  embedding_model = "BAAI/bge-small-en-v1.5"
@@ -111,7 +117,7 @@ def clear_chat_history():
111
  embedding_model=embedding_model,
112
  fine_tuned_path=fine_tuned_path,
113
  system_content=system_content,
114
- persisted_path=persisted_vector_db)
115
  chat_engine.reset()
116
 
117
  st.sidebar.button("Clear Chat History", on_click=clear_chat_history)
@@ -143,59 +149,81 @@ def get_embedding_model(model_name, fine_tuned_path=None):
143
  @st.cache_resource
144
  def get_query_engine(input_files, llm_model, temperature,
145
  embedding_model, fine_tuned_path,
146
- system_content, persisted_path):
147
 
148
  llm = get_llm_object(llm_model, temperature)
149
  embedded_model = get_embedding_model(
150
  model_name=embedding_model,
151
  fine_tuned_path=fine_tuned_path
152
  )
153
- service_context = ServiceContext.from_defaults(
154
- llm=llm,
155
- embed_model=embedded_model
156
- )
157
-
158
- if os.path.exists(persisted_path):
159
  print("loading from vector database - chroma")
160
- db = chromadb.PersistentClient(path=persisted_path)
161
  chroma_collection = db.get_or_create_collection("quickstart")
162
  vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
163
- storage_context = StorageContext.from_defaults(
164
- vector_store=vector_store
165
- )
166
  index = VectorStoreIndex.from_vector_store(
167
- vector_store=vector_store,
168
- service_context=service_context,
169
  storage_context=storage_context
170
  )
171
  else:
172
- print("create in-memory vector store")
173
- document = get_document_object(input_files)
174
- index = VectorStoreIndex.from_documents(
175
- [document],
176
- service_context=service_context
177
- )
 
 
 
 
 
 
178
 
179
  memory = ChatMemoryBuffer.from_defaults(token_limit=15000)
180
- chat_engine = index.as_chat_engine(
181
- chat_mode="context",
182
- memory=memory,
183
- system_prompt=system_content
 
184
  )
185
 
186
- return chat_engine
187
-
188
- def generate_llm_response(prompt_input):
189
- chat_engine = get_query_engine(input_files=input_files,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  llm_model=selected_model,
191
  temperature=temperature,
192
  embedding_model=embedding_model,
193
  fine_tuned_path=fine_tuned_path,
194
  system_content=system_content,
195
- persisted_path=persisted_vector_db)
196
 
197
  # st.session_state.messages
198
- response = chat_engine.stream_chat(prompt_input)
199
  return response
200
 
201
  def handle_feedback(user_response):
@@ -256,13 +284,18 @@ if prompt := st.chat_input(disabled=not openai_api):
256
  # Retrieve text prompt from image submission
257
  if prompt is None and \
258
  st.session_state.messages[-1]["role"] == "admin":
 
259
  prompt = st.session_state.messages[-1]["content"]
260
 
261
  # Generate a new response if last message is not from assistant
262
  if st.session_state.messages[-1]["role"] != "assistant":
263
  with st.chat_message("assistant"):
264
  with st.spinner("Thinking..."):
265
- response = generate_llm_response(prompt)
 
 
 
 
266
  placeholder = st.empty()
267
  full_response = ""
268
  for token in response.response_gen:
 
5
  import pandas as pd
6
  import base64
7
  from io import BytesIO
 
8
 
9
  import chromadb
10
+ from llama_index.core import (
11
+ VectorStoreIndex,
12
+ SimpleDirectoryReader,
13
+ StorageContext,
14
+ Document
15
+ )
16
+ from llama_index.vector_stores.chroma.base import ChromaVectorStore
17
+ from llama_index.embeddings.huggingface.base import HuggingFaceEmbedding
18
+ from llama_index.llms.openai import OpenAI
19
+ from llama_index.core.memory import ChatMemoryBuffer
20
+ from llama_index.core.tools import QueryEngineTool
21
+ from llama_index.agent.openai import OpenAIAgent
22
+ from llama_index.core import Settings
23
 
24
  from vision_api import get_transcribed_text
25
+ from qna_prompting import get_qna_question_tool
26
 
27
+ import nest_asyncio
28
  nest_asyncio.apply()
29
 
30
  # App title
 
32
  openai_api = os.getenv("OPENAI_API_KEY")
33
 
34
  # "./raw_documents/HI_Knowledge_Base.pdf"
35
+ image_prompt = False
36
  input_files = ["./raw_documents/HI Chapter Summary Version 1.3.pdf",
37
  "./raw_documents/qna.txt"]
38
  embedding_model = "BAAI/bge-small-en-v1.5"
 
117
  embedding_model=embedding_model,
118
  fine_tuned_path=fine_tuned_path,
119
  system_content=system_content,
120
+ persisted_vector_db=persisted_vector_db)
121
  chat_engine.reset()
122
 
123
  st.sidebar.button("Clear Chat History", on_click=clear_chat_history)
 
149
  @st.cache_resource
150
  def get_query_engine(input_files, llm_model, temperature,
151
  embedding_model, fine_tuned_path,
152
+ system_content, persisted_vector_db):
153
 
154
  llm = get_llm_object(llm_model, temperature)
155
  embedded_model = get_embedding_model(
156
  model_name=embedding_model,
157
  fine_tuned_path=fine_tuned_path
158
  )
159
+ Settings.llm = llm
160
+ Settings.chunk_size = 1024
161
+ Settings.embed_model = embedded_model
162
+
163
+ if os.path.exists(persisted_vector_db):
 
164
  print("loading from vector database - chroma")
165
+ db = chromadb.PersistentClient(path=persisted_vector_db)
166
  chroma_collection = db.get_or_create_collection("quickstart")
167
  vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
168
+ storage_context = StorageContext.from_defaults(vector_store=vector_store)
169
+
 
170
  index = VectorStoreIndex.from_vector_store(
171
+ vector_store=vector_store,
 
172
  storage_context=storage_context
173
  )
174
  else:
175
+ print("create new chroma vector database..")
176
+ documents = SimpleDirectoryReader(input_files=input_files).load_data()
177
+
178
+ db = chromadb.PersistentClient(path=persisted_vector_db)
179
+ chroma_collection = db.get_or_create_collection("quickstart")
180
+ vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
181
+
182
+ nodes = Settings.node_parser.get_nodes_from_documents(documents)
183
+ storage_context = StorageContext.from_defaults(vector_store=vector_store)
184
+ storage_context.docstore.add_documents(nodes)
185
+
186
+ index = VectorStoreIndex(nodes, storage_context=storage_context)
187
 
188
  memory = ChatMemoryBuffer.from_defaults(token_limit=15000)
189
+ hi_content_engine = index.as_query_engine(
190
+ memory=memory,
191
+ system_prompt=system_content,
192
+ similarity_top_k=3,
193
+ streaming=True
194
  )
195
 
196
+ hi_query_tool = QueryEngineTool.from_defaults(
197
+ query_engine=hi_content_engine,
198
+ name="vector_tool",
199
+ description=(
200
+ "Provides information about Health Insurance landscape in Singapore. "
201
+ "Use a detailed plain text question as input to the tool."
202
+ )
203
+ )
204
+ agent = OpenAIAgent.from_tools(tools=[
205
+ hi_query_tool,
206
+ get_qna_question_tool
207
+ ],
208
+ llm=llm,
209
+ verbose=True)
210
+ print("loaded AI agent, let's begin the chat!")
211
+ print("="*50)
212
+ print("")
213
+
214
+ return agent
215
+
216
+ def generate_llm_response(prompt_input, tool_choice="auto"):
217
+ chat_agent = get_query_engine(input_files=input_files,
218
  llm_model=selected_model,
219
  temperature=temperature,
220
  embedding_model=embedding_model,
221
  fine_tuned_path=fine_tuned_path,
222
  system_content=system_content,
223
+ persisted_vector_db=persisted_vector_db)
224
 
225
  # st.session_state.messages
226
+ response = chat_agent.stream_chat(prompt_input, tool_choice=tool_choice)
227
  return response
228
 
229
  def handle_feedback(user_response):
 
284
  # Retrieve text prompt from image submission
285
  if prompt is None and \
286
  st.session_state.messages[-1]["role"] == "admin":
287
+ image_prompt = True
288
  prompt = st.session_state.messages[-1]["content"]
289
 
290
  # Generate a new response if last message is not from assistant
291
  if st.session_state.messages[-1]["role"] != "assistant":
292
  with st.chat_message("assistant"):
293
  with st.spinner("Thinking..."):
294
+ if image_prompt:
295
+ response = generate_llm_response(prompt, tool_choice="vector_tool")
296
+ image_prompt = False
297
+ else:
298
+ response = generate_llm_response(prompt, tool_choice="auto")
299
  placeholder = st.empty()
300
  full_response = ""
301
  for token in response.response_gen: