T-Flet commited on
Commit
67a7b40
1 Parent(s): e8c8660

Added a non-agent chain version for comparison

Browse files
Files changed (2) hide show
  1. explore.ipynb +176 -83
  2. serve.py +48 -9
explore.ipynb CHANGED
@@ -39,7 +39,8 @@
39
  "from langchain.chains.combine_documents import create_stuff_documents_chain\n",
40
  "from langchain.chains import create_history_aware_retriever, create_retrieval_chain\n",
41
  "from langchain.tools.retriever import create_retriever_tool\n",
42
- "from langchain_core.runnables import RunnablePassthrough, RunnableParallel\n",
 
43
  "\n",
44
  "# Agents\n",
45
  "from langchain import hub\n",
@@ -167,23 +168,24 @@
167
  },
168
  {
169
  "cell_type": "code",
170
- "execution_count": 4,
171
  "metadata": {},
172
  "outputs": [
173
  {
174
  "name": "stdout",
175
  "output_type": "stream",
176
  "text": [
177
- "Deleting the previous database and creating a new one (because otherwise content is duplicated in the db every time this block is run)\n",
178
- "The Wookieepedia database contains 10838 chunks, with mean length of 645 characters\n",
179
  "Current source pages in Wookieepedia db:\n",
180
- "393\n"
181
  ]
182
  },
183
  {
184
  "data": {
185
  "text/plain": [
186
- "{'wookieepedia\\\\1995_Topps_Star_Wars_Widevision.txt',\n",
 
 
187
  " 'wookieepedia\\\\1995_Topps_Star_Wars___The_Empire_Strikes_Back_Widevision.txt',\n",
188
  " 'wookieepedia\\\\1996_Topps_Star_Wars___Return_of_the_Jedi_Widevision.txt',\n",
189
  " 'wookieepedia\\\\2_systems_control_droid.txt',\n",
@@ -578,7 +580,7 @@
578
  " 'wookieepedia\\\\Zev.txt'}"
579
  ]
580
  },
581
- "execution_count": 4,
582
  "metadata": {},
583
  "output_type": "execute_result"
584
  }
@@ -644,7 +646,7 @@
644
  },
645
  {
646
  "cell_type": "code",
647
- "execution_count": 20,
648
  "metadata": {},
649
  "outputs": [
650
  {
@@ -662,7 +664,7 @@
662
  " Document(page_content='\\nAt an opera show, Palpatine and Skywalker discussed the situation with Palpatine revealing to know that the Council wanted Skywalker to spy on him. At the same time, Skywalker, who was dealing with the fear of his wife\\'s loss was beginning to distrust the Jedi Council. This allowed Sidious to orchestrate Skywalker\\'s downfall; he claimed that the Jedi and the Sith were alike in nearly every way, setting the stage for the young Jedi to switch sides while playing to his devotion to the Jedi ideology. Next, Palpatine told him the story of his master, \"Darth Plagueis the Wise.\" According to the story, Plagueis possessed such strength in the Force that he could use it to prevent the ones closest to him from dying. Skywalker asked what happened to him, to which Palpatine said that he was afraid of losing his power, but had taught his apprentice everything, and then his apprentice killed him in his sleep. Skywalker, enthralled by the story, wished to know more about this power, asking him if he himself could learn it with Palpatine stating that, though possible, such things could not be taught by members of the Order. Skywalker, however, was unware that Palpatine was really talking about how he killed his mentor Plagueis, in order to lure him to the dark side.', metadata={'source': 'wookieepedia\\\\Darth_Sidious.txt'})]"
663
  ]
664
  },
665
- "execution_count": 20,
666
  "metadata": {},
667
  "output_type": "execute_result"
668
  }
@@ -718,7 +720,7 @@
718
  "\n",
719
  " return wdb.similarity_search(original_query, k = 10)\n",
720
  "\n",
721
- "get_wookieepedia_context('Do you know the Tragedy of Darth Plagueis the Wise?', 'Darth Plagueis', woo_db)"
722
  ]
723
  },
724
  {
@@ -731,7 +733,7 @@
731
  },
732
  {
733
  "cell_type": "code",
734
- "execution_count": 21,
735
  "metadata": {},
736
  "outputs": [],
737
  "source": [
@@ -744,12 +746,12 @@
744
  "cell_type": "markdown",
745
  "metadata": {},
746
  "source": [
747
- "### Non-agent version"
748
  ]
749
  },
750
  {
751
  "cell_type": "code",
752
- "execution_count": 22,
753
  "metadata": {},
754
  "outputs": [],
755
  "source": [
@@ -782,7 +784,7 @@
782
  },
783
  {
784
  "cell_type": "code",
785
- "execution_count": 23,
786
  "metadata": {},
787
  "outputs": [],
788
  "source": [
@@ -809,7 +811,7 @@
809
  },
810
  {
811
  "cell_type": "code",
812
- "execution_count": 24,
813
  "metadata": {},
814
  "outputs": [],
815
  "source": [
@@ -835,7 +837,7 @@
835
  },
836
  {
837
  "cell_type": "code",
838
- "execution_count": 25,
839
  "metadata": {},
840
  "outputs": [
841
  {
@@ -843,13 +845,13 @@
843
  "text/plain": [
844
  "{'input': \"Who participates in Han's rescue from Jabba? And where is the palace?\",\n",
845
  " 'context': [Document(page_content=\"After the smuggler Han Solo failed to repay him for lost cargo, Jabba placed a high price on his head. Solo was eventually delivered to him by one of his bounty hunters, Boba Fett, as a gift from Darth Vader. However, this capture brought him to the attention of Jedi Knight Luke Skywalker, who sought to rescue his friend from Jabba's imprisonment. As he attempted to execute the Jedi and his allies in the Great Pit of Carkoon, Jabba was choked to death by Leia Organa. With the Hutts unable to decide who would inherit Jabba's criminal ventures, many of his slaves, including the Niktos, were free, and his palace was occupied by his former Majordomo Bib Fortuna, who took his place as Daimyo of Tatooine until Fett killed and usurped him. Fett sought to rebuild Jabba's criminal empire in his own image, intending to rule with respect rather than the fear that the Hutt instilled in his followers.\", metadata={'source': 'wookieepedia\\\\Jabba_Desilijic_Tiure.txt'}),\n",
846
- " Document(page_content=\"Jabba sends Han Solo, Chewbacca, and Greedo to travel to Corellia to recover the ashes of archrival Krestrel D'Naran.\\nHan Solo meets Corbus Tyra, who claims to be his father, Ovan.\\nChewbacca rescues Han Solo from bounty hunter Krrsantan and they later conduct a heist on Coruscant. Although the urn they have been after does not contain the ashes, it contains the neural core of Ajax Sigma, which Han Solo and Chewbacca bury away.\\n8/7 BBY\\nJabba Desilijic Tiure sends Krrsantan to hunt down Obi-Wan Kenobi.\\n7 BBY\\nBodhi Rook enters the Terrabe Sector Service Academy to train to be a pilot.\\nThe mission to Horuz occurs.\\nUn'hee is born.\\nObi-Wan Kenobi rescues 12-year old Luke Skywalker and his friend Windy after they are left unconscious during a sandstorm.\\n6 BBY\\nThe mission to Inusagi occurs.[source?]\\nThe Malkhani Insurrections occurs.\\nThe Leonis family migrates to Lothal.\\nThe Westhills massacre occurs.\", metadata={'source': 'wookieepedia\\\\Timeline_of_galactic_history.txt'}),\n",
847
  " Document(page_content=\"Djarin takes the Darksaber while Gideon is taken into New Republic custody, though he is broken out en route to trial.\\nAs Bo-Katan Kryze returned to her forces without the Darksaber, her Mandalorians abandon her and become privateers under Axe Woves.\\nThe Jedi Luke Skywalker beckons Grogu to train as a Jedi with him. Removing his Mandalorian helmet, Djarin gives his blessing to Grogu before letting the latter go.\\nLuke Skywalker builds a Jedi Temple on Ossus. After a brief time with Skywalker there, Grogu decides to return to Din Djarin. Jabba's Palace under new management \\nBoba Fett and Fennec Shand attack Jabba's Palace, replacing Bib Fortuna's place as master of the palace.\\nA gang war erupts on Tatooine, with Daimyo Boba Fett's Fett gotra defeating the Pyke Syndicate presence on the world and emerging as its leading criminal syndicate.\\nc. 9 ABY\", metadata={'source': 'wookieepedia\\\\Timeline_of_galactic_history.txt'}),\n",
848
  " Document(page_content=\"At the chancellor's request, Windu dispatched Kenobi and Skywalker on a mission to save Jabba's son. \\nSoon afterward Windu received a message from the Advanced Recon Force Scout Troopers who tracked Rotta's location to an old monastery on the planet Teth. Due to the monastery's heavy fortification, Windu instructed the troopers to stand by and await Republic reinforcements. He then reassigned three of Admiral Wurtz's cruisers to the rescue operation. In spite of Count Dooku's plot to form an alliance between the Confederacy and the Hutt Clan, Rotta was ultimately redeemed from captivity by Anakin Skywalker and his new Padawan, Ahsoka Tano. The Separatists were defeated on Teth and Jabba was made aware of Dooku's conspiracy, which in turn allowed the Republic to secure passage through the Hyperspace lanes in Hutt territory.\\n\\nLiberation of Ryloth\", metadata={'source': 'wookieepedia\\\\Mace_Windu.txt'})],\n",
849
- " 'answer': \"Han Solo is rescued from Jabba the Hutt by a group consisting of Jedi Knight Luke Skywalker, Princess Leia Organa (disguised as the bounty hunter Boushh), Chewbacca, Lando Calrissian, R2-D2, and C-3PO. The rescue takes place at Jabba's Palace on the desert planet of Tatooine.\"}"
850
  ]
851
  },
852
- "execution_count": 25,
853
  "metadata": {},
854
  "output_type": "execute_result"
855
  }
@@ -858,10 +860,10 @@
858
  "# full_chain = create_retrieval_chain(script_retriever_chain, document_chain)\n",
859
  "full_chain = create_retrieval_chain(woo_retriever_chain, document_chain)\n",
860
  "\n",
861
- "full_chain.invoke(dict(\n",
862
- " # chat_history = [HumanMessage(content = 'Are you knowledgeable about Star Wars?'), AIMessage(content = 'Very')],\n",
863
- " input = \"Who participates in Han's rescue from Jabba? And where is the palace?\"\n",
864
- "))"
865
  ]
866
  },
867
  {
@@ -870,15 +872,15 @@
870
  "metadata": {},
871
  "outputs": [],
872
  "source": [
873
- "simplify_query_prompt = ChatPromptTemplate.from_messages([\n",
874
- " ('system', 'Given the above conversation, generate a search query to find a relevant page in the Star Wars fandom wiki; the query should be something simple, at most 4 words, such as the name of a character, place, event, item, etc.'),\n",
875
- " MessagesPlaceholder('chat_history', optional = True), # Using this form since not clear how to have optional = True in the tuple form\n",
876
- " ('human', '{query}')\n",
877
- "])\n",
878
  "\n",
879
- "simplify_query_chain = simplify_query_prompt | llm | StrOutputParser() # To extract just the message\n",
880
  "\n",
881
- "# simplify_query_chain.invoke(dict(context = 'You are an expert of Star Wars lore', query = 'Do you know the tragedy of Darth Plagueis the Wise?'))"
882
  ]
883
  },
884
  {
@@ -890,7 +892,7 @@
890
  },
891
  {
892
  "cell_type": "code",
893
- "execution_count": 27,
894
  "metadata": {},
895
  "outputs": [],
896
  "source": [
@@ -916,7 +918,7 @@
916
  },
917
  {
918
  "cell_type": "code",
919
- "execution_count": 28,
920
  "metadata": {},
921
  "outputs": [
922
  {
@@ -927,36 +929,10 @@
927
  "\n",
928
  "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
929
  "\u001b[32;1m\u001b[1;3m\n",
930
- "Invoking: `search_film_scripts` with `{'query': 'tragedy of Darth Plagueis the Wise'}`\n",
931
  "\n",
932
  "\n",
933
- "\u001b[0m\u001b[36;1m\u001b[1;3mIn a few minutes the entire passageway is ablaze with \n",
934
- "laserfire. The deadly bolts ricochet in wild random patterns \n",
935
- "creating huge explosions. Stormtroopers scatter and duck \n",
936
- "behind storage lockers. Laserbolts hit several Rebel soldiers \n",
937
- "who scream and stagger through the smoke, holding shattered \n",
938
- "arms and faces.\n",
939
- "\n",
940
- "An explosion hits near the robots.\n",
941
- "\n",
942
- "THREEPIO\n",
943
- "I should have known better than to \n",
944
- "trust the logic of a half-sized \n",
945
- "thermocapsulary dehousing assister...\n",
946
- "\n",
947
- "Artoo counters with an angry rebuttal as the battle rages \n",
948
- "around the two hapless robots.\n",
949
- "\n",
950
- "EXT. TATOOINE - DESERT WASTELAND - DAY\n",
951
- "\n",
952
- "A death-white wasteland stretches from horizon to horizon. \n",
953
- "The tremendous heat of two huge twin suns settle on a lone \n",
954
- "figure, Luke Skywalker, a farm boy with heroic aspirations \n",
955
- "who looks much younger than his eighteen years. His shaggy \n",
956
- "hair and baggy tunic give him the air of a simple but lovable \n",
957
- "lad with a prize-winning smile.\n",
958
- "\n",
959
- "OBI-WAN: (continuing) It can't be . . . It can't be . . .\n",
960
  "\n",
961
  "As ANAKIN surveys the carnage, a DARK-ROBED SITH LORD enters. ANAKIN turns to DARTH SIDIOUS and kneels before him.\n",
962
  "\n",
@@ -1016,25 +992,55 @@
1016
  "his sword from Vader's then watches his opponent with a serene \n",
1017
  "look on his face.\n",
1018
  "\n",
1019
- "The towering creature brings down his curved, double-pointed \n",
1020
- "gaderffii -- the dreaded axe blade that has struck terror in \n",
1021
- "the heart of the local settlers. But Luke manages to block \n",
1022
- "the blow with his laser rifle, which is smashed to pieces. \n",
1023
- "The terrified farm boy scrambles backward until he is forced \n",
1024
- "to the edge of a deep crevice. The sinister Raider stands \n",
1025
- "over him with his weapon raised and lets out a horrible \n",
1026
- "shrieking laugh.\n",
 
1027
  "\n",
1028
- "EXT. TATOOINE - ROCK CANYON - FLOOR - DAY\n",
1029
  "\n",
1030
- "Artoo forces himself into the shadows of a small alcove in \n",
1031
- "the rocks as the vicious Sandpeople walk past carrying the \n",
1032
- "inert Luke Skywalker, who is dropped in a heap before the \n",
1033
- "speeder.The Sandpeople ransack the speeder, throwing parts \n",
1034
- "and supplies in all directions. Suddenly they stop. Then \n",
1035
- "everything is quiet for a few moments. A great howling moan \n",
1036
- "is heard echoing throughout the canyon which sends the \n",
1037
- "Sandpeople fleeing in terror.\u001b[0m\u001b[32;1m\u001b[1;3mThe dialogue from the Star Wars film scripts does not directly mention the tragedy of Darth Plagueis the Wise. However, in \"Star Wars: Episode III - Revenge of the Sith,\" Chancellor Palpatine tells Anakin Skywalker the story of Darth Plagueis the Wise. According to Palpatine, Darth Plagueis was a Dark Lord of the Sith who was so powerful and wise that he could influence the midi-chlorians to create life and prevent death. The tragedy of Darth Plagueis the Wise is that he was eventually betrayed and killed by his own apprentice, who was seeking to obtain his power. This story plays a significant role in Anakin's fall to the dark side as he becomes intrigued by the idea of cheating death, which ultimately leads him to become Darth Vader.\u001b[0m\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1038
  "\n",
1039
  "\u001b[1m> Finished chain.\u001b[0m\n"
1040
  ]
@@ -1045,10 +1051,10 @@
1045
  "{'chat_history': [HumanMessage(content='Are you knowledgeable about Star Wars?'),\n",
1046
  " AIMessage(content='Very')],\n",
1047
  " 'input': 'Do you know the tragedy of Darth Plagueis the Wise?',\n",
1048
- " 'output': 'The dialogue from the Star Wars film scripts does not directly mention the tragedy of Darth Plagueis the Wise. However, in \"Star Wars: Episode III - Revenge of the Sith,\" Chancellor Palpatine tells Anakin Skywalker the story of Darth Plagueis the Wise. According to Palpatine, Darth Plagueis was a Dark Lord of the Sith who was so powerful and wise that he could influence the midi-chlorians to create life and prevent death. The tragedy of Darth Plagueis the Wise is that he was eventually betrayed and killed by his own apprentice, who was seeking to obtain his power. This story plays a significant role in Anakin\\'s fall to the dark side as he becomes intrigued by the idea of cheating death, which ultimately leads him to become Darth Vader.'}"
1049
  ]
1050
  },
1051
- "execution_count": 28,
1052
  "metadata": {},
1053
  "output_type": "execute_result"
1054
  }
@@ -1079,10 +1085,97 @@
1079
  "# input = 'Do you know the tragedy of Darth Plagueis the Wise?'\n",
1080
  "# )\n",
1081
  "\n",
1082
- "agent_executor.invoke(dict(\n",
1083
- " chat_history = [HumanMessage(content = 'Are you knowledgeable about Star Wars?'), AIMessage(content = 'Very')],\n",
1084
- " input = 'Do you know the tragedy of Darth Plagueis the Wise?'\n",
1085
- "))"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1086
  ]
1087
  }
1088
  ],
 
39
  "from langchain.chains.combine_documents import create_stuff_documents_chain\n",
40
  "from langchain.chains import create_history_aware_retriever, create_retrieval_chain\n",
41
  "from langchain.tools.retriever import create_retriever_tool\n",
42
+ "from langchain_core.runnables import RunnablePassthrough, RunnableParallel, chain\n",
43
+ "from langchain_core.pydantic_v1 import BaseModel, Field\n",
44
  "\n",
45
  "# Agents\n",
46
  "from langchain import hub\n",
 
168
  },
169
  {
170
  "cell_type": "code",
171
+ "execution_count": 3,
172
  "metadata": {},
173
  "outputs": [
174
  {
175
  "name": "stdout",
176
  "output_type": "stream",
177
  "text": [
178
+ "The Wookieepedia database contains 10927 chunks, with mean length of 645 characters\n",
 
179
  "Current source pages in Wookieepedia db:\n",
180
+ "395\n"
181
  ]
182
  },
183
  {
184
  "data": {
185
  "text/plain": [
186
+ "{'https://starwars.fandom.com/wiki/Darth_Plagueis',\n",
187
+ " 'https://starwars.fandom.com/wiki/Voss',\n",
188
+ " 'wookieepedia\\\\1995_Topps_Star_Wars_Widevision.txt',\n",
189
  " 'wookieepedia\\\\1995_Topps_Star_Wars___The_Empire_Strikes_Back_Widevision.txt',\n",
190
  " 'wookieepedia\\\\1996_Topps_Star_Wars___Return_of_the_Jedi_Widevision.txt',\n",
191
  " 'wookieepedia\\\\2_systems_control_droid.txt',\n",
 
580
  " 'wookieepedia\\\\Zev.txt'}"
581
  ]
582
  },
583
+ "execution_count": 3,
584
  "metadata": {},
585
  "output_type": "execute_result"
586
  }
 
646
  },
647
  {
648
  "cell_type": "code",
649
+ "execution_count": 4,
650
  "metadata": {},
651
  "outputs": [
652
  {
 
664
  " Document(page_content='\\nAt an opera show, Palpatine and Skywalker discussed the situation with Palpatine revealing to know that the Council wanted Skywalker to spy on him. At the same time, Skywalker, who was dealing with the fear of his wife\\'s loss was beginning to distrust the Jedi Council. This allowed Sidious to orchestrate Skywalker\\'s downfall; he claimed that the Jedi and the Sith were alike in nearly every way, setting the stage for the young Jedi to switch sides while playing to his devotion to the Jedi ideology. Next, Palpatine told him the story of his master, \"Darth Plagueis the Wise.\" According to the story, Plagueis possessed such strength in the Force that he could use it to prevent the ones closest to him from dying. Skywalker asked what happened to him, to which Palpatine said that he was afraid of losing his power, but had taught his apprentice everything, and then his apprentice killed him in his sleep. Skywalker, enthralled by the story, wished to know more about this power, asking him if he himself could learn it with Palpatine stating that, though possible, such things could not be taught by members of the Order. Skywalker, however, was unware that Palpatine was really talking about how he killed his mentor Plagueis, in order to lure him to the dark side.', metadata={'source': 'wookieepedia\\\\Darth_Sidious.txt'})]"
665
  ]
666
  },
667
+ "execution_count": 4,
668
  "metadata": {},
669
  "output_type": "execute_result"
670
  }
 
720
  "\n",
721
  " return wdb.similarity_search(original_query, k = 10)\n",
722
  "\n",
723
+ "# get_wookieepedia_context('Do you know the Tragedy of Darth Plagueis the Wise?', 'Darth Plagueis', woo_db)"
724
  ]
725
  },
726
  {
 
733
  },
734
  {
735
  "cell_type": "code",
736
+ "execution_count": 5,
737
  "metadata": {},
738
  "outputs": [],
739
  "source": [
 
746
  "cell_type": "markdown",
747
  "metadata": {},
748
  "source": [
749
+ "### Base version (only one retriever)"
750
  ]
751
  },
752
  {
753
  "cell_type": "code",
754
+ "execution_count": 6,
755
  "metadata": {},
756
  "outputs": [],
757
  "source": [
 
784
  },
785
  {
786
  "cell_type": "code",
787
+ "execution_count": 7,
788
  "metadata": {},
789
  "outputs": [],
790
  "source": [
 
811
  },
812
  {
813
  "cell_type": "code",
814
+ "execution_count": 8,
815
  "metadata": {},
816
  "outputs": [],
817
  "source": [
 
837
  },
838
  {
839
  "cell_type": "code",
840
+ "execution_count": 9,
841
  "metadata": {},
842
  "outputs": [
843
  {
 
845
  "text/plain": [
846
  "{'input': \"Who participates in Han's rescue from Jabba? And where is the palace?\",\n",
847
  " 'context': [Document(page_content=\"After the smuggler Han Solo failed to repay him for lost cargo, Jabba placed a high price on his head. Solo was eventually delivered to him by one of his bounty hunters, Boba Fett, as a gift from Darth Vader. However, this capture brought him to the attention of Jedi Knight Luke Skywalker, who sought to rescue his friend from Jabba's imprisonment. As he attempted to execute the Jedi and his allies in the Great Pit of Carkoon, Jabba was choked to death by Leia Organa. With the Hutts unable to decide who would inherit Jabba's criminal ventures, many of his slaves, including the Niktos, were free, and his palace was occupied by his former Majordomo Bib Fortuna, who took his place as Daimyo of Tatooine until Fett killed and usurped him. Fett sought to rebuild Jabba's criminal empire in his own image, intending to rule with respect rather than the fear that the Hutt instilled in his followers.\", metadata={'source': 'wookieepedia\\\\Jabba_Desilijic_Tiure.txt'}),\n",
848
+ " Document(page_content=\"On a distant spaceport, Mira manages to escape from the stormtroopers who were guarding her and sneak into the Millennium Falcon, which was being loading with spice. Han Solo and Chewbacca are going to make another Kessel Run for Jabba the Hutt, but first he was going to pick up Luke Skywalker. On the hidden Rebel base on the planet Randa, Han picks up Luke, Artoo and Threepio and finds his unexpected guest. Mira tells Luke and Han about Bzorn's plan and asks Han to deliver her to the professor, knowing that he will stop the destruction after he learns that Mira is safe.\", metadata={'source': 'wookieepedia\\\\The_Second_Kessel_Run.txt'}),\n",
849
  " Document(page_content=\"Djarin takes the Darksaber while Gideon is taken into New Republic custody, though he is broken out en route to trial.\\nAs Bo-Katan Kryze returned to her forces without the Darksaber, her Mandalorians abandon her and become privateers under Axe Woves.\\nThe Jedi Luke Skywalker beckons Grogu to train as a Jedi with him. Removing his Mandalorian helmet, Djarin gives his blessing to Grogu before letting the latter go.\\nLuke Skywalker builds a Jedi Temple on Ossus. After a brief time with Skywalker there, Grogu decides to return to Din Djarin. Jabba's Palace under new management \\nBoba Fett and Fennec Shand attack Jabba's Palace, replacing Bib Fortuna's place as master of the palace.\\nA gang war erupts on Tatooine, with Daimyo Boba Fett's Fett gotra defeating the Pyke Syndicate presence on the world and emerging as its leading criminal syndicate.\\nc. 9 ABY\", metadata={'source': 'wookieepedia\\\\Timeline_of_galactic_history.txt'}),\n",
850
  " Document(page_content=\"At the chancellor's request, Windu dispatched Kenobi and Skywalker on a mission to save Jabba's son. \\nSoon afterward Windu received a message from the Advanced Recon Force Scout Troopers who tracked Rotta's location to an old monastery on the planet Teth. Due to the monastery's heavy fortification, Windu instructed the troopers to stand by and await Republic reinforcements. He then reassigned three of Admiral Wurtz's cruisers to the rescue operation. In spite of Count Dooku's plot to form an alliance between the Confederacy and the Hutt Clan, Rotta was ultimately redeemed from captivity by Anakin Skywalker and his new Padawan, Ahsoka Tano. The Separatists were defeated on Teth and Jabba was made aware of Dooku's conspiracy, which in turn allowed the Republic to secure passage through the Hyperspace lanes in Hutt territory.\\n\\nLiberation of Ryloth\", metadata={'source': 'wookieepedia\\\\Mace_Windu.txt'})],\n",
851
+ " 'answer': \"Han Solo's rescue from Jabba the Hutt's palace involves a team consisting of Jedi Knight Luke Skywalker, Princess Leia Organa (disguised as the bounty hunter Boushh), Chewbacca, Lando Calrissian, R2-D2, and C-3PO. The palace where Han is held captive is located on the desert planet of Tatooine. Jabba's palace is a large and imposing structure situated in the Dune Sea of Tatooine, serving as the crime lord's headquarters and residence.\"}"
852
  ]
853
  },
854
+ "execution_count": 9,
855
  "metadata": {},
856
  "output_type": "execute_result"
857
  }
 
860
  "# full_chain = create_retrieval_chain(script_retriever_chain, document_chain)\n",
861
  "full_chain = create_retrieval_chain(woo_retriever_chain, document_chain)\n",
862
  "\n",
863
+ "# full_chain.invoke(dict(\n",
864
+ "# # chat_history = [HumanMessage(content = 'Are you knowledgeable about Star Wars?'), AIMessage(content = 'Very')],\n",
865
+ "# input = \"Who participates in Han's rescue from Jabba? And where is the palace?\"\n",
866
+ "# ))"
867
  ]
868
  },
869
  {
 
872
  "metadata": {},
873
  "outputs": [],
874
  "source": [
875
+ "# simplify_query_prompt = ChatPromptTemplate.from_messages([\n",
876
+ "# ('system', 'Given the above conversation, generate a search query to find a relevant page in the Star Wars fandom wiki; the query should be something simple, at most 4 words, such as the name of a character, place, event, item, etc.'),\n",
877
+ "# MessagesPlaceholder('chat_history', optional = True), # Using this form since not clear how to have optional = True in the tuple form\n",
878
+ "# ('human', '{query}')\n",
879
+ "# ])\n",
880
  "\n",
881
+ "# simplify_query_chain = simplify_query_prompt | llm | StrOutputParser() # To extract just the message\n",
882
  "\n",
883
+ "# # simplify_query_chain.invoke(dict(context = 'You are an expert of Star Wars lore', query = 'Do you know the tragedy of Darth Plagueis the Wise?'))"
884
  ]
885
  },
886
  {
 
892
  },
893
  {
894
  "cell_type": "code",
895
+ "execution_count": 10,
896
  "metadata": {},
897
  "outputs": [],
898
  "source": [
 
918
  },
919
  {
920
  "cell_type": "code",
921
+ "execution_count": 11,
922
  "metadata": {},
923
  "outputs": [
924
  {
 
929
  "\n",
930
  "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
931
  "\u001b[32;1m\u001b[1;3m\n",
932
+ "Invoking: `search_film_scripts` with `{'query': 'Darth Plagueis the Wise'}`\n",
933
  "\n",
934
  "\n",
935
+ "\u001b[0m\u001b[36;1m\u001b[1;3mOBI-WAN: (continuing) It can't be . . . It can't be . . .\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
  "\n",
937
  "As ANAKIN surveys the carnage, a DARK-ROBED SITH LORD enters. ANAKIN turns to DARTH SIDIOUS and kneels before him.\n",
938
  "\n",
 
992
  "his sword from Vader's then watches his opponent with a serene \n",
993
  "look on his face.\n",
994
  "\n",
995
+ "LUKE\n",
996
+ "Hurry up! Come with me! What are you \n",
997
+ "waiting for?! Get in gear!\n",
998
+ "\n",
999
+ "The robot scoots around in a tight circle, stops short, and \n",
1000
+ "smoke begins to pour out of every joint. Luke throws his \n",
1001
+ "arms up in disgust. Exasperated, the young farm boy jumps \n",
1002
+ "into his Landspeeder leaving the smoldering robot to hum \n",
1003
+ "madly.\n",
1004
  "\n",
1005
+ "INT. REBEL BLOCKADE RUNNER - MAIN HALLWAY\n",
1006
  "\n",
1007
+ "The awesome, seven-foot-tall Dark Lord of the Sith makes his \n",
1008
+ "way into the blinding light of the main passageway. This is \n",
1009
+ "Darth Vader, right hand of the Emperor. His face is obscured \n",
1010
+ "by his flowing black robes and grotesque breath mask, which \n",
1011
+ "stands out next to the fascist white armored suits of the \n",
1012
+ "Imperial stormtroopers. Everyone instinctively backs away \n",
1013
+ "from the imposing warrior and a deathly quiet sweeps through \n",
1014
+ "the Rebel troops. Several of the Rebel troops break and run \n",
1015
+ "in a frenzied panic.\n",
1016
+ "\n",
1017
+ "INT. REBEL BLOCKADE RUNNER\n",
1018
+ "\n",
1019
+ "A woman's hand puts a card into an opening in Artoo's dome.\n",
1020
+ "Artoo makes beeping sounds.\n",
1021
+ "\n",
1022
+ "47INT DEATH STAR - CORRIDOR TO DOCKING BAY\n",
1023
+ "\n",
1024
+ "Lord Vader strides down the hallway, accompanied by a very nervous \n",
1025
+ "Death Star commander.\n",
1026
+ "\n",
1027
+ "48INT DOCKING BAY - DEATH STAR\n",
1028
+ "\n",
1029
+ "Thousands of Imperial troops in tight formation fill the mammoth \n",
1030
+ "docking bay. Vader and the officer walk to the landing platform, where \n",
1031
+ "the shuttle is coming to rest.\n",
1032
+ "\n",
1033
+ "The shuttle's ramp lowers and the Emperor's Royal Guards come out and \n",
1034
+ "create a lethal perimeter. The assembled troops move to rigid attention \n",
1035
+ "with a momentous SNAP.\n",
1036
+ "\n",
1037
+ "Then, in the huge SILENCE which follows, the EMPEROR appears. He is a \n",
1038
+ "rather small, shriveled old man. His bent frame slowly makes its way \n",
1039
+ "down the ramp with the aid of a gnarled cane. He wears a hooded cloak \n",
1040
+ "similar to the one Ben wears, except that it is black. The Emperor's \n",
1041
+ "face is shrouded and difficult to see, except for his piercing yellow \n",
1042
+ "eyes. Commander Jerjerrod and Darth Vader kneel to him. The Supreme \n",
1043
+ "Ruler of the galaxy beckons to the Dark Lord.\u001b[0m\u001b[32;1m\u001b[1;3mThe dialogue from the Star Wars film scripts does not directly mention the tragedy of Darth Plagueis the Wise. However, in \"Star Wars: Episode III - Revenge of the Sith,\" Chancellor Palpatine tells Anakin Skywalker the story of Darth Plagueis the Wise. According to Palpatine, Darth Plagueis was a Dark Lord of the Sith who was so powerful and wise that he could influence the midi-chlorians to create life and prevent death. Unfortunately, Darth Plagueis was betrayed and killed by his own apprentice, who was seeking to obtain his power. This story plays a significant role in Anakin's fall to the dark side as he becomes intrigued by the idea of cheating death, ultimately leading him to become Darth Vader under the influence of Palpatine.\u001b[0m\n",
1044
  "\n",
1045
  "\u001b[1m> Finished chain.\u001b[0m\n"
1046
  ]
 
1051
  "{'chat_history': [HumanMessage(content='Are you knowledgeable about Star Wars?'),\n",
1052
  " AIMessage(content='Very')],\n",
1053
  " 'input': 'Do you know the tragedy of Darth Plagueis the Wise?',\n",
1054
+ " 'output': 'The dialogue from the Star Wars film scripts does not directly mention the tragedy of Darth Plagueis the Wise. However, in \"Star Wars: Episode III - Revenge of the Sith,\" Chancellor Palpatine tells Anakin Skywalker the story of Darth Plagueis the Wise. According to Palpatine, Darth Plagueis was a Dark Lord of the Sith who was so powerful and wise that he could influence the midi-chlorians to create life and prevent death. Unfortunately, Darth Plagueis was betrayed and killed by his own apprentice, who was seeking to obtain his power. This story plays a significant role in Anakin\\'s fall to the dark side as he becomes intrigued by the idea of cheating death, ultimately leading him to become Darth Vader under the influence of Palpatine.'}"
1055
  ]
1056
  },
1057
+ "execution_count": 11,
1058
  "metadata": {},
1059
  "output_type": "execute_result"
1060
  }
 
1085
  "# input = 'Do you know the tragedy of Darth Plagueis the Wise?'\n",
1086
  "# )\n",
1087
  "\n",
1088
+ "# agent_executor.invoke(dict(\n",
1089
+ "# chat_history = [HumanMessage(content = 'Are you knowledgeable about Star Wars?'), AIMessage(content = 'Very')],\n",
1090
+ "# input = 'Do you know the tragedy of Darth Plagueis the Wise?'\n",
1091
+ "# ))"
1092
+ ]
1093
+ },
1094
+ {
1095
+ "cell_type": "markdown",
1096
+ "metadata": {},
1097
+ "source": [
1098
+ "### Non-agent chain-logic version"
1099
+ ]
1100
+ },
1101
+ {
1102
+ "cell_type": "code",
1103
+ "execution_count": 12,
1104
+ "metadata": {},
1105
+ "outputs": [],
1106
+ "source": [
1107
+ "# Determine which retriever is best and generate an appropriate query for it\n",
1108
+ "\n",
1109
+ "# Again, many LangChain objects seem to use the class-scope fields instead of instance ones in __init__...\n",
1110
+ "# Separately, the advantage of using a class over a dictionary is simply the descriptions\n",
1111
+ "class DirectedQuery(BaseModel):\n",
1112
+ " '''Determine whether a query is best answered by looking at scripts rather than articles'''\n",
1113
+ "\n",
1114
+ " query: str = Field(\n",
1115
+ " ...,\n",
1116
+ " description = '''The query to either search film scripts or wiki articles.\n",
1117
+ " A film script query should include character names and relevant keywords of what they are saying in the a scene which is likely to contain the required information.\n",
1118
+ " A wiki articles search should instead be at most 4 words, simply being the name of a character or location or event whose page is likely to contain the required information.''',\n",
1119
+ " )\n",
1120
+ " source: str = Field(\n",
1121
+ " ...,\n",
1122
+ " description = 'Either \"wiki\" or \"scripts\", indicating which source the query should be passed to.',\n",
1123
+ " )\n",
1124
+ "\n",
1125
+ "\n",
1126
+ "# output_parser = PydanticToolsParser(tools = [DirectedQuery])\n",
1127
+ "\n",
1128
+ "query_analyser_prompt = ChatPromptTemplate.from_messages([\n",
1129
+ " ('system', 'You have the ability to issue search queries of one of two kinds to get information to help answer questions.'),\n",
1130
+ " ('human', '{question}'),\n",
1131
+ "])\n",
1132
+ "structured_llm = llm.with_structured_output(DirectedQuery)\n",
1133
+ "query_generator = dict(question = RunnablePassthrough()) | query_analyser_prompt | structured_llm"
1134
+ ]
1135
+ },
1136
+ {
1137
+ "cell_type": "code",
1138
+ "execution_count": 15,
1139
+ "metadata": {},
1140
+ "outputs": [],
1141
+ "source": [
1142
+ "retrievers = dict(wiki = woo_db.as_retriever(search_kwargs = dict(k = 4)), scripts = script_db.as_retriever(search_kwargs = dict(k = 4)))\n",
1143
+ "\n",
1144
+ "@chain\n",
1145
+ "def compound_retriever(question):\n",
1146
+ " response = query_generator.invoke(question)\n",
1147
+ " retriever = retrievers[response.source]\n",
1148
+ " return retriever.invoke(response.query)\n",
1149
+ "\n",
1150
+ "\n",
1151
+ "# compound_retriever.invoke('Do you know the tragedy of Darth Plagueis the Wise?')"
1152
+ ]
1153
+ },
1154
+ {
1155
+ "cell_type": "code",
1156
+ "execution_count": 18,
1157
+ "metadata": {},
1158
+ "outputs": [
1159
+ {
1160
+ "data": {
1161
+ "text/plain": [
1162
+ "{'input': 'Do you know the tragedy of Darth Plagueis the Wise?',\n",
1163
+ " 'context': [Document(page_content='The Tragedy of Darth Plagueis the Wise', metadata={'source': 'https://starwars.fandom.com/wiki/Darth_Plagueis'}),\n",
1164
+ " Document(page_content='Biography\\nEarly life\\nDarth Plagueis was a legendary Dark Lord of the Sith trained by the Sith Master Darth Tenebrous. At some point during his life, Plagueis acquired the protocol droid 11-4D. During his time as a Sith Lord and studying the Force, Plagueis acquired a vast amount of knowledge about the dark side and its teachings.\\n\\nMaster of Darth Sidious', metadata={'source': 'https://starwars.fandom.com/wiki/Darth_Plagueis'}),\n",
1165
+ " Document(page_content='\"Darth Plagueis was a Dark Lord of the Sith so powerful and so wise, he could use the Force to influence the midi-chlorians to create life. He had such a knowledge of the dark side, he could even keep the ones he cared about from dying.\"\\n―Sheev Palpatine', metadata={'source': 'https://starwars.fandom.com/wiki/Darth_Plagueis'}),\n",
1166
+ " Document(page_content='Behind the scenes\\n Darth Plagueis as depicted in Star Wars Legends \\nDarth Plagueis was first mentioned on-screen in the 2005 film Star Wars: Episode III Revenge of the Sith, the third and final installment of the Star Wars prequel trilogy. Although Palpatine was never confirmed to be Plagueis\\' apprentice in the movie itself, a link to the official encyclopedia on StarWars.com did refer to Sidious as having been \"trained by Darth Plagueis.\"\\nThe character was created by George Lucas as early as the first draft of Revenge of the Sith—dated April 2003—and possibly earlier. His story was massively expanded upon in the 2012 Star Wars Legends novel Darth Plagueis, written by James Luceno. It notably established Plagueis to be a Muun just as Lucas proposed.', metadata={'source': 'https://starwars.fandom.com/wiki/Darth_Plagueis'})],\n",
1167
+ " 'answer': 'Yes, I am familiar with the tragedy of Darth Plagueis the Wise. Darth Plagueis was a legendary Dark Lord of the Sith who was so powerful and knowledgeable about the dark side of the Force that he could manipulate midi-chlorians to create life and prevent death. However, despite his immense power and wisdom, he was ultimately betrayed and killed by his own apprentice, Darth Sidious (Emperor Palpatine), who later became the Emperor of the Galactic Empire. This tragic story was famously recounted by Palpatine to Anakin Skywalker in \"Star Wars: Episode III Revenge of the Sith.\"'}"
1168
+ ]
1169
+ },
1170
+ "execution_count": 18,
1171
+ "metadata": {},
1172
+ "output_type": "execute_result"
1173
+ }
1174
+ ],
1175
+ "source": [
1176
+ "compound_chain = create_retrieval_chain(compound_retriever, document_chain)\n",
1177
+ "\n",
1178
+ "compound_chain.invoke(dict(input = 'Do you know the tragedy of Darth Plagueis the Wise?'))"
1179
  ]
1180
  }
1181
  ],
serve.py CHANGED
@@ -13,7 +13,8 @@ from langchain_core.output_parsers import StrOutputParser
13
  from langchain.chains.combine_documents import create_stuff_documents_chain
14
  from langchain.chains import create_history_aware_retriever, create_retrieval_chain
15
  from langchain.tools.retriever import create_retriever_tool
16
- from langchain_core.runnables import RunnablePassthrough, RunnableParallel
 
17
 
18
  # Agents
19
  from langchain import hub
@@ -25,7 +26,6 @@ from langchain_core.documents import Document
25
 
26
  # To serve the app
27
  from fastapi import FastAPI
28
- from langchain.pydantic_v1 import BaseModel, Field
29
  from langchain_core.messages import BaseMessage
30
  from langserve import add_routes, CustomUserType
31
 
@@ -90,6 +90,8 @@ def get_wookieepedia_context(original_query: str, simple_query: str, wdb: Chroma
90
  llm = ChatOpenAI(model = 'gpt-3.5-turbo-0125', temperature = 0)
91
 
92
 
 
 
93
  document_prompt_system_text = '''
94
  You are very knowledgeable about Star Wars and your job is to answer questions about its plot, characters, etc.
95
  Use the context below to produce your answers with as much detail as possible.
@@ -129,13 +131,13 @@ full_chain = create_retrieval_chain(woo_retriever_chain, document_chain)
129
 
130
 
131
 
132
- simplify_query_prompt = ChatPromptTemplate.from_messages([
133
- ('system', 'Given the above conversation, generate a search query to find a relevant page in the Star Wars fandom wiki; the query should be something simple, at most 4 words, such as the name of a character, place, event, item, etc.'),
134
- MessagesPlaceholder('chat_history', optional = True), # Using this form since not clear how to have optional = True in the tuple form
135
- ('human', '{query}')
136
- ])
137
 
138
- simplify_query_chain = simplify_query_prompt | llm | StrOutputParser() # To extract just the message
139
 
140
 
141
 
@@ -171,6 +173,41 @@ agent_executor = AgentExecutor(agent = agent, tools = tools, verbose = True)
171
 
172
 
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  ## Type specifications (with unusual class-scope fields)
175
 
176
  class StrInput(BaseModel):
@@ -198,13 +235,15 @@ app = FastAPI(
198
 
199
 
200
  # add_routes(app, script_db.as_retriever())
201
- add_routes(app, full_chain.with_types(input_type = StrInput, output_type = Output), playground_type = 'default')
202
 
203
  # NOTE: The chat playground type has a web page issue (flashes and becomes white, hence non-interactable; this was supposedly solved in an issue late last year)
204
 
205
  # add_routes(app, agent_executor, playground_type = 'chat')
206
  # add_routes(app, agent_executor.with_types(input_type = StrInput, output_type = Output))
207
 
 
 
208
 
209
 
210
  if __name__ == '__main__':
 
13
  from langchain.chains.combine_documents import create_stuff_documents_chain
14
  from langchain.chains import create_history_aware_retriever, create_retrieval_chain
15
  from langchain.tools.retriever import create_retriever_tool
16
+ from langchain_core.runnables import RunnablePassthrough, RunnableParallel, chain
17
+ from langchain_core.pydantic_v1 import BaseModel, Field
18
 
19
  # Agents
20
  from langchain import hub
 
26
 
27
  # To serve the app
28
  from fastapi import FastAPI
 
29
  from langchain_core.messages import BaseMessage
30
  from langserve import add_routes, CustomUserType
31
 
 
90
  llm = ChatOpenAI(model = 'gpt-3.5-turbo-0125', temperature = 0)
91
 
92
 
93
+ ## Base version (only one retriever)
94
+
95
  document_prompt_system_text = '''
96
  You are very knowledgeable about Star Wars and your job is to answer questions about its plot, characters, etc.
97
  Use the context below to produce your answers with as much detail as possible.
 
131
 
132
 
133
 
134
+ # simplify_query_prompt = ChatPromptTemplate.from_messages([
135
+ # ('system', 'Given the above conversation, generate a search query to find a relevant page in the Star Wars fandom wiki; the query should be something simple, at most 4 words, such as the name of a character, place, event, item, etc.'),
136
+ # MessagesPlaceholder('chat_history', optional = True), # Using this form since not clear how to have optional = True in the tuple form
137
+ # ('human', '{query}')
138
+ # ])
139
 
140
+ # simplify_query_chain = simplify_query_prompt | llm | StrOutputParser() # To extract just the message
141
 
142
 
143
 
 
173
 
174
 
175
 
176
+ ## Non-agent chain-logic version
177
+
178
+ # Determine which retriever is best and generate an appropriate query for it
179
+ class DirectedQuery(BaseModel):
180
+ '''Determine whether a query is best answered by looking at scripts rather than articles'''
181
+
182
+ query: str = Field(
183
+ ...,
184
+ description = '''The query to either search film scripts or wiki articles.
185
+ A film script query should include character names and relevant keywords of what they are saying in the a scene which is likely to contain the required information.
186
+ A wiki articles search should instead be at most 4 words, simply being the name of a character or location or event whose page is likely to contain the required information.''',
187
+ )
188
+ source: str = Field(
189
+ ...,
190
+ description = 'Either "wiki" or "scripts", indicating which source the query should be passed to.',
191
+ )
192
+ query_analyser_prompt = ChatPromptTemplate.from_messages([
193
+ ('system', 'You have the ability to issue search queries of one of two kinds to get information to help answer questions.'),
194
+ ('human', '{question}'),
195
+ ])
196
+ structured_llm = llm.with_structured_output(DirectedQuery)
197
+ query_generator = dict(question = RunnablePassthrough()) | query_analyser_prompt | structured_llm
198
+
199
+ retrievers = dict(wiki = woo_db.as_retriever(search_kwargs = dict(k = 4)), scripts = script_db.as_retriever(search_kwargs = dict(k = 4)))
200
+
201
+ @chain
202
+ def compound_retriever(question):
203
+ response = query_generator.invoke(question)
204
+ retriever = retrievers[response.source]
205
+ return retriever.invoke(response.query)
206
+
207
+ compound_chain = create_retrieval_chain(compound_retriever, document_chain)
208
+
209
+
210
+
211
  ## Type specifications (with unusual class-scope fields)
212
 
213
  class StrInput(BaseModel):
 
235
 
236
 
237
  # add_routes(app, script_db.as_retriever())
238
+ # add_routes(app, full_chain.with_types(input_type = StrInput, output_type = Output), playground_type = 'default')
239
 
240
  # NOTE: The chat playground type has a web page issue (flashes and becomes white, hence non-interactable; this was supposedly solved in an issue late last year)
241
 
242
  # add_routes(app, agent_executor, playground_type = 'chat')
243
  # add_routes(app, agent_executor.with_types(input_type = StrInput, output_type = Output))
244
 
245
+ add_routes(app, compound_chain.with_types(input_type = StrInput))
246
+
247
 
248
 
249
  if __name__ == '__main__':