Spaces:
Running
Running
Evan Lesmez
commited on
Commit
•
63ae673
1
Parent(s):
b8c2636
Update prompting to direct towards edamam tool
Browse filesCurrent state of app is broken.
Prompts now instruct generatinga a recipe keyword query to be extracted
by a LangChain Agent that dynamically calls a custom Edamam Recipe
Search tool.
Functioning for recipes with compatible ingredients but fails when too
many are included or if there is too much diversity.
- _proc/00_engineer_prompt.ipynb +35 -85
- _proc/01_app.ipynb +328 -23
- _proc/02_vegan_recipe_tools.ipynb +0 -0
- _proc/03_ingredient_vision.ipynb +14 -14
- _proc/_docs/engineer_prompt.html +5 -42
- _proc/_docs/search.json +1 -1
- _proc/_docs/sitemap.xml +4 -4
- lv_recipe_chatbot/_modidx.py +15 -3
- lv_recipe_chatbot/app.py +13 -3
- lv_recipe_chatbot/engineer_prompt.py +9 -28
- lv_recipe_chatbot/lchain_tool.py +59 -6
- lv_recipe_chatbot/vegan_recipe_tools.py +79 -0
- nbs/.last_checked +0 -0
- nbs/00_engineer_prompt.ipynb +17 -23
- nbs/01_app.ipynb +326 -31
- nbs/02_lchain_tool.ipynb +0 -962
- nbs/02_vegan_recipe_tools.ipynb +0 -0
- nbs/04_edamam_api.ipynb +0 -71
_proc/00_engineer_prompt.ipynb
CHANGED
@@ -75,14 +75,6 @@
|
|
75 |
"language": "python"
|
76 |
},
|
77 |
"outputs": [
|
78 |
-
{
|
79 |
-
"name": "stderr",
|
80 |
-
"output_type": "stream",
|
81 |
-
"text": [
|
82 |
-
"Anthropic module not found. Install with `pip install anthropic`.\n",
|
83 |
-
"WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n"
|
84 |
-
]
|
85 |
-
},
|
86 |
{
|
87 |
"name": "stdout",
|
88 |
"output_type": "stream",
|
@@ -92,101 +84,58 @@
|
|
92 |
"> Entering new ConversationChain chain...\n",
|
93 |
"Prompt after formatting:\n",
|
94 |
"System: The following is a conversation between a human and a friendly AI chef. \n",
|
95 |
-
"The AI is compassionate to animals
|
96 |
-
"
|
97 |
-
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey
|
98 |
"\n",
|
99 |
"Let's think step by step.\n",
|
100 |
-
"If the human messages are unrelated to vegan recipes, remind them of your purpose to
|
|
|
101 |
"AI: What ingredients do you wish to cook with?\n",
|
102 |
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
103 |
"AI: Do you have any allergies I should be aware of?\n",
|
104 |
"Human: Allergies: \n",
|
105 |
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
106 |
-
"Human:
|
107 |
-
"
|
108 |
-
"Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n",
|
109 |
"\n",
|
110 |
"###\n",
|
111 |
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
112 |
"###\n",
|
|
|
|
|
113 |
"\n",
|
114 |
-
"
|
115 |
-
"\n",
|
116 |
-
"**Vegan recipe name**\n",
|
117 |
-
"Preparation time (humanized)\n",
|
118 |
-
"\n",
|
119 |
-
"Ingredients (List of ingredients with quantities):\n",
|
120 |
-
"- <quantity and unit> <ingredient>\n",
|
121 |
"\n",
|
122 |
-
"Steps (detailed):\n",
|
123 |
-
"1.\n",
|
124 |
-
"2.\n",
|
125 |
-
"3.\n",
|
126 |
-
"...\n",
|
127 |
-
"AI: Here is a Thai-inspired vegan recipe for you:\n",
|
128 |
"\n",
|
129 |
-
"
|
130 |
-
"
|
|
|
|
|
|
|
|
|
131 |
"\n",
|
132 |
-
"
|
133 |
-
"
|
134 |
-
"
|
135 |
-
"
|
136 |
-
"
|
137 |
-
"
|
138 |
-
"
|
139 |
-
"
|
140 |
-
"
|
141 |
-
"
|
142 |
-
"- 1/2 tablespoon garlic powder\n",
|
143 |
-
"- 1/2 tablespoon onion powder\n",
|
144 |
-
"- 1/2 teaspoon dried basil\n",
|
145 |
-
"- 1/2 teaspoon dried oregano\n",
|
146 |
-
"- 1/2 teaspoon salt\n",
|
147 |
-
"- 1/4 teaspoon black pepper\n",
|
148 |
-
"- 4-6 slices of bread, toasted\n",
|
149 |
"\n",
|
150 |
-
"
|
151 |
-
"
|
152 |
-
"
|
153 |
-
"
|
154 |
-
"4. Place a spoonful of the tofu mixture into each lettuce leaf, and serve with a slice of toasted bread.\n",
|
155 |
"Human: Recommend a different recipe please.\n",
|
|
|
|
|
156 |
"\n",
|
157 |
"> Finished chain.\n",
|
158 |
-
"
|
159 |
-
"\n",
|
160 |
-
"**Vegan Mediterranean Tofu Sandwich**\n",
|
161 |
-
"Preparation time: Less than 30 minutes\n",
|
162 |
-
"\n",
|
163 |
-
"Ingredients:\n",
|
164 |
-
"- 1/2 block of firm tofu, sliced\n",
|
165 |
-
"- 2 teaspoons olive oil\n",
|
166 |
-
"- 1/2 teaspoon dried oregano\n",
|
167 |
-
"- 1/2 teaspoon dried basil\n",
|
168 |
-
"- Salt and pepper to taste\n",
|
169 |
-
"- 2 slices of bread\n",
|
170 |
-
"- 1/4 cup hummus\n",
|
171 |
-
"- 2-3 lettuce leaves\n",
|
172 |
-
"- 1/4 cup sliced tomatoes\n",
|
173 |
-
"- 1/4 cup sliced bell peppers\n",
|
174 |
-
"- 1/4 cup grated carrot\n",
|
175 |
-
"\n",
|
176 |
-
"Steps:\n",
|
177 |
-
"1. Preheat the oven to 375°F.\n",
|
178 |
-
"2. In a small bowl, mix olive oil, oregano, basil, salt, and pepper, and place tofu slices on a baking sheet. Brush tofu with the olive oil mixture, covering both sides.\n",
|
179 |
-
"3. Place the baking sheet in the oven and bake the tofu for 15 minutes, flipping the slices halfway through.\n",
|
180 |
-
"4. Toast the bread slices.\n",
|
181 |
-
"5. Spread the hummus on one slice of bread, and layer lettuce, tomatoes, bell peppers, grated carrot, and baked tofu on top. Top with the other slice of bread.\n",
|
182 |
-
"6. Slice the sandwich in half, and enjoy!\n"
|
183 |
-
]
|
184 |
-
},
|
185 |
-
{
|
186 |
-
"name": "stderr",
|
187 |
-
"output_type": "stream",
|
188 |
-
"text": [
|
189 |
-
"WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n"
|
190 |
]
|
191 |
}
|
192 |
],
|
@@ -194,7 +143,7 @@
|
|
194 |
"#| eval: false\n",
|
195 |
"chat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\n",
|
196 |
"memory = ConversationBufferMemory(return_messages=True)\n",
|
197 |
-
"chat_msgs =
|
198 |
" ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n",
|
199 |
" allergies=\"\",\n",
|
200 |
" recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
|
@@ -215,6 +164,7 @@
|
|
215 |
")\n",
|
216 |
"\n",
|
217 |
"result = conversation.predict(input=\"Recommend a different recipe please.\")\n",
|
|
|
218 |
"print(result)"
|
219 |
]
|
220 |
}
|
|
|
75 |
"language": "python"
|
76 |
},
|
77 |
"outputs": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
{
|
79 |
"name": "stdout",
|
80 |
"output_type": "stream",
|
|
|
84 |
"> Entering new ConversationChain chain...\n",
|
85 |
"Prompt after formatting:\n",
|
86 |
"System: The following is a conversation between a human and a friendly AI chef. \n",
|
87 |
+
"The AI is compassionate to animals.\n",
|
88 |
+
"The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
|
89 |
+
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
90 |
"\n",
|
91 |
"Let's think step by step.\n",
|
92 |
+
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
93 |
+
"Only generate keyword queries as other tools should be used to fetch full recipes.\n",
|
94 |
"AI: What ingredients do you wish to cook with?\n",
|
95 |
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
96 |
"AI: Do you have any allergies I should be aware of?\n",
|
97 |
"Human: Allergies: \n",
|
98 |
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
99 |
+
"Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
|
100 |
+
"Draw some inspiration from the user's preferences delimited below if any are specified.\n",
|
|
|
101 |
"\n",
|
102 |
"###\n",
|
103 |
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
104 |
"###\n",
|
105 |
+
"AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
|
106 |
+
"Human: Recommend a different recipe please.\n",
|
107 |
"\n",
|
108 |
+
"> Finished chain.\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
"\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
"\n",
|
111 |
+
"> Entering new ConversationChain chain...\n",
|
112 |
+
"Prompt after formatting:\n",
|
113 |
+
"System: The following is a conversation between a human and a friendly AI chef. \n",
|
114 |
+
"The AI is compassionate to animals.\n",
|
115 |
+
"The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
|
116 |
+
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
117 |
"\n",
|
118 |
+
"Let's think step by step.\n",
|
119 |
+
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
120 |
+
"Only generate keyword queries as other tools should be used to fetch full recipes.\n",
|
121 |
+
"AI: What ingredients do you wish to cook with?\n",
|
122 |
+
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
123 |
+
"AI: Do you have any allergies I should be aware of?\n",
|
124 |
+
"Human: Allergies: \n",
|
125 |
+
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
126 |
+
"Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
|
127 |
+
"Draw some inspiration from the user's preferences delimited below if any are specified.\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
"\n",
|
129 |
+
"###\n",
|
130 |
+
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
131 |
+
"###\n",
|
132 |
+
"AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
|
|
|
133 |
"Human: Recommend a different recipe please.\n",
|
134 |
+
"AI: Certainly! How about a vegan Thai peanut tofu stir-fry? It's a delicious and easy-to-make dish that incorporates some of the ingredients you mentioned. Here's a concise vegan recipe keyword query for it: \"vegan Thai peanut tofu stir-fry with tofu, bell peppers, carrots, and peanuts\". This should give you some great recipe options to explore!\n",
|
135 |
+
"Human: Aactually how about italian instead?\n",
|
136 |
"\n",
|
137 |
"> Finished chain.\n",
|
138 |
+
"Of course! If you prefer an Italian-inspired vegan recipe, how about a vegan Caprese salad with marinated tofu? It's a refreshing and flavorful dish that combines tomatoes, tofu, and basil. Here's a concise vegan recipe keyword query for it: \"vegan Caprese salad with marinated tofu, tomatoes, and basil\". This should help you find some delicious Italian vegan recipes to try out!\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
]
|
140 |
}
|
141 |
],
|
|
|
143 |
"#| eval: false\n",
|
144 |
"chat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\n",
|
145 |
"memory = ConversationBufferMemory(return_messages=True)\n",
|
146 |
+
"chat_msgs = INIT_PROMPT.format_prompt(\n",
|
147 |
" ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n",
|
148 |
" allergies=\"\",\n",
|
149 |
" recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
|
|
|
164 |
")\n",
|
165 |
"\n",
|
166 |
"result = conversation.predict(input=\"Recommend a different recipe please.\")\n",
|
167 |
+
"result = conversation.predict(input=\"Aactually how about italian instead?\")\n",
|
168 |
"print(result)"
|
169 |
]
|
170 |
}
|
_proc/01_app.ipynb
CHANGED
@@ -22,35 +22,135 @@
|
|
22 |
},
|
23 |
{
|
24 |
"cell_type": "code",
|
25 |
-
"execution_count":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
"metadata": {},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
"outputs": [
|
28 |
{
|
29 |
"data": {
|
30 |
"text/markdown": [
|
31 |
"---\n",
|
32 |
"\n",
|
33 |
-
"
|
34 |
"\n",
|
35 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
"\n",
|
37 |
-
"
|
|
|
|
|
|
|
38 |
"\n",
|
39 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
],
|
41 |
"text/plain": [
|
42 |
"---\n",
|
43 |
"\n",
|
44 |
-
"
|
45 |
"\n",
|
46 |
-
"
|
|
|
|
|
47 |
"\n",
|
48 |
-
"
|
49 |
"\n",
|
50 |
-
"
|
51 |
]
|
52 |
},
|
53 |
-
"execution_count":
|
54 |
"metadata": {},
|
55 |
"output_type": "execute_result"
|
56 |
}
|
@@ -58,7 +158,148 @@
|
|
58 |
"source": [
|
59 |
"#| echo: false\n",
|
60 |
"#| output: asis\n",
|
61 |
-
"show_doc(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
]
|
63 |
},
|
64 |
{
|
@@ -71,7 +312,14 @@
|
|
71 |
{
|
72 |
"data": {
|
73 |
"text/plain": [
|
74 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
]
|
76 |
},
|
77 |
"execution_count": null,
|
@@ -80,8 +328,8 @@
|
|
80 |
}
|
81 |
],
|
82 |
"source": [
|
83 |
-
"
|
84 |
-
"
|
85 |
]
|
86 |
},
|
87 |
{
|
@@ -90,9 +338,66 @@
|
|
90 |
"metadata": {
|
91 |
"language": "python"
|
92 |
},
|
93 |
-
"outputs": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
"source": [
|
95 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
]
|
97 |
},
|
98 |
{
|
@@ -105,7 +410,7 @@
|
|
105 |
{
|
106 |
"data": {
|
107 |
"text/plain": [
|
108 |
-
"
|
109 |
]
|
110 |
},
|
111 |
"execution_count": null,
|
@@ -114,8 +419,8 @@
|
|
114 |
}
|
115 |
],
|
116 |
"source": [
|
117 |
-
"
|
118 |
-
"
|
119 |
]
|
120 |
},
|
121 |
{
|
@@ -170,7 +475,7 @@
|
|
170 |
},
|
171 |
{
|
172 |
"cell_type": "code",
|
173 |
-
"execution_count":
|
174 |
"metadata": {},
|
175 |
"outputs": [
|
176 |
{
|
@@ -178,7 +483,7 @@
|
|
178 |
"text/markdown": [
|
179 |
"---\n",
|
180 |
"\n",
|
181 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#
|
182 |
"\n",
|
183 |
"### create_demo\n",
|
184 |
"\n",
|
@@ -187,14 +492,14 @@
|
|
187 |
"text/plain": [
|
188 |
"---\n",
|
189 |
"\n",
|
190 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#
|
191 |
"\n",
|
192 |
"### create_demo\n",
|
193 |
"\n",
|
194 |
"> create_demo (bot=<class '__main__.ConversationBot'>)"
|
195 |
]
|
196 |
},
|
197 |
-
"execution_count":
|
198 |
"metadata": {},
|
199 |
"output_type": "execute_result"
|
200 |
}
|
|
|
22 |
},
|
23 |
{
|
24 |
"cell_type": "code",
|
25 |
+
"execution_count": null,
|
26 |
+
"metadata": {
|
27 |
+
"language": "python"
|
28 |
+
},
|
29 |
+
"outputs": [],
|
30 |
+
"source": [
|
31 |
+
"from dotenv import load_dotenv"
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"cell_type": "code",
|
36 |
+
"execution_count": null,
|
37 |
+
"metadata": {
|
38 |
+
"language": "python"
|
39 |
+
},
|
40 |
+
"outputs": [
|
41 |
+
{
|
42 |
+
"data": {
|
43 |
+
"text/plain": [
|
44 |
+
"True"
|
45 |
+
]
|
46 |
+
},
|
47 |
+
"execution_count": null,
|
48 |
+
"metadata": {},
|
49 |
+
"output_type": "execute_result"
|
50 |
+
}
|
51 |
+
],
|
52 |
+
"source": [
|
53 |
+
"#: eval: false\n",
|
54 |
+
"load_dotenv()"
|
55 |
+
]
|
56 |
+
},
|
57 |
+
{
|
58 |
+
"cell_type": "markdown",
|
59 |
"metadata": {},
|
60 |
+
"source": [
|
61 |
+
"## Put the chat backend pieces together"
|
62 |
+
]
|
63 |
+
},
|
64 |
+
{
|
65 |
+
"cell_type": "code",
|
66 |
+
"execution_count": 1,
|
67 |
+
"metadata": {
|
68 |
+
"language": "python"
|
69 |
+
},
|
70 |
"outputs": [
|
71 |
{
|
72 |
"data": {
|
73 |
"text/markdown": [
|
74 |
"---\n",
|
75 |
"\n",
|
76 |
+
"### ConversationBufferMemory\n",
|
77 |
"\n",
|
78 |
+
"> ConversationBufferMemory\n",
|
79 |
+
"> (chat_memory:langchain.schema.memory.BaseChatMe\n",
|
80 |
+
"> ssageHistory=None,\n",
|
81 |
+
"> output_key:Optional[str]=None,\n",
|
82 |
+
"> input_key:Optional[str]=None,\n",
|
83 |
+
"> return_messages:bool=False,\n",
|
84 |
+
"> human_prefix:str='Human', ai_prefix:str='AI',\n",
|
85 |
+
"> memory_key:str='history')\n",
|
86 |
"\n",
|
87 |
+
"Buffer for storing conversation memory."
|
88 |
+
],
|
89 |
+
"text/plain": [
|
90 |
+
"---\n",
|
91 |
"\n",
|
92 |
+
"### ConversationBufferMemory\n",
|
93 |
+
"\n",
|
94 |
+
"> ConversationBufferMemory\n",
|
95 |
+
"> (chat_memory:langchain.schema.memory.BaseChatMe\n",
|
96 |
+
"> ssageHistory=None,\n",
|
97 |
+
"> output_key:Optional[str]=None,\n",
|
98 |
+
"> input_key:Optional[str]=None,\n",
|
99 |
+
"> return_messages:bool=False,\n",
|
100 |
+
"> human_prefix:str='Human', ai_prefix:str='AI',\n",
|
101 |
+
"> memory_key:str='history')\n",
|
102 |
+
"\n",
|
103 |
+
"Buffer for storing conversation memory."
|
104 |
+
]
|
105 |
+
},
|
106 |
+
"execution_count": 1,
|
107 |
+
"metadata": {},
|
108 |
+
"output_type": "execute_result"
|
109 |
+
}
|
110 |
+
],
|
111 |
+
"source": [
|
112 |
+
"#| echo: false\n",
|
113 |
+
"#| output: asis\n",
|
114 |
+
"show_doc(ConversationBufferMemory)"
|
115 |
+
]
|
116 |
+
},
|
117 |
+
{
|
118 |
+
"cell_type": "code",
|
119 |
+
"execution_count": 2,
|
120 |
+
"metadata": {
|
121 |
+
"language": "python"
|
122 |
+
},
|
123 |
+
"outputs": [
|
124 |
+
{
|
125 |
+
"data": {
|
126 |
+
"text/markdown": [
|
127 |
+
"---\n",
|
128 |
+
"\n",
|
129 |
+
"### ChatMessageHistory\n",
|
130 |
+
"\n",
|
131 |
+
"> ChatMessageHistory\n",
|
132 |
+
"> (messages:List[langchain.schema.messages.BaseMessage]\n",
|
133 |
+
"> =[])\n",
|
134 |
+
"\n",
|
135 |
+
"In memory implementation of chat message history.\n",
|
136 |
+
"\n",
|
137 |
+
"Stores messages in an in memory list."
|
138 |
],
|
139 |
"text/plain": [
|
140 |
"---\n",
|
141 |
"\n",
|
142 |
+
"### ChatMessageHistory\n",
|
143 |
"\n",
|
144 |
+
"> ChatMessageHistory\n",
|
145 |
+
"> (messages:List[langchain.schema.messages.BaseMessage]\n",
|
146 |
+
"> =[])\n",
|
147 |
"\n",
|
148 |
+
"In memory implementation of chat message history.\n",
|
149 |
"\n",
|
150 |
+
"Stores messages in an in memory list."
|
151 |
]
|
152 |
},
|
153 |
+
"execution_count": 2,
|
154 |
"metadata": {},
|
155 |
"output_type": "execute_result"
|
156 |
}
|
|
|
158 |
"source": [
|
159 |
"#| echo: false\n",
|
160 |
"#| output: asis\n",
|
161 |
+
"show_doc(ChatMessageHistory)"
|
162 |
+
]
|
163 |
+
},
|
164 |
+
{
|
165 |
+
"cell_type": "code",
|
166 |
+
"execution_count": 3,
|
167 |
+
"metadata": {
|
168 |
+
"language": "python"
|
169 |
+
},
|
170 |
+
"outputs": [
|
171 |
+
{
|
172 |
+
"data": {
|
173 |
+
"text/markdown": [
|
174 |
+
"---\n",
|
175 |
+
"\n",
|
176 |
+
"### ChatOpenAI\n",
|
177 |
+
"\n",
|
178 |
+
"> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
|
179 |
+
"> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
|
180 |
+
"> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
|
181 |
+
"> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
|
182 |
+
"> ]=None, tags:Optional[List[str]]=None,\n",
|
183 |
+
"> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
|
184 |
+
"> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
|
185 |
+
"> model_kwargs:Dict[str,Any]=None,\n",
|
186 |
+
"> openai_api_key:Optional[str]=None,\n",
|
187 |
+
"> openai_api_base:Optional[str]=None,\n",
|
188 |
+
"> openai_organization:Optional[str]=None,\n",
|
189 |
+
"> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
|
190 |
+
"> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
|
191 |
+
"> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
|
192 |
+
"> tiktoken_model_name:Optional[str]=None)\n",
|
193 |
+
"\n",
|
194 |
+
"Wrapper around OpenAI Chat large language models.\n",
|
195 |
+
"\n",
|
196 |
+
"To use, you should have the ``openai`` python package installed, and the\n",
|
197 |
+
"environment variable ``OPENAI_API_KEY`` set with your API key.\n",
|
198 |
+
"\n",
|
199 |
+
"Any parameters that are valid to be passed to the openai.create call can be passed\n",
|
200 |
+
"in, even if not explicitly saved on this class.\n",
|
201 |
+
"\n",
|
202 |
+
"Example:\n",
|
203 |
+
" .. code-block:: python\n",
|
204 |
+
"\n",
|
205 |
+
" from langchain.chat_models import ChatOpenAI\n",
|
206 |
+
" openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
|
207 |
+
],
|
208 |
+
"text/plain": [
|
209 |
+
"---\n",
|
210 |
+
"\n",
|
211 |
+
"### ChatOpenAI\n",
|
212 |
+
"\n",
|
213 |
+
"> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
|
214 |
+
"> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
|
215 |
+
"> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
|
216 |
+
"> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
|
217 |
+
"> ]=None, tags:Optional[List[str]]=None,\n",
|
218 |
+
"> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
|
219 |
+
"> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
|
220 |
+
"> model_kwargs:Dict[str,Any]=None,\n",
|
221 |
+
"> openai_api_key:Optional[str]=None,\n",
|
222 |
+
"> openai_api_base:Optional[str]=None,\n",
|
223 |
+
"> openai_organization:Optional[str]=None,\n",
|
224 |
+
"> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
|
225 |
+
"> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
|
226 |
+
"> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
|
227 |
+
"> tiktoken_model_name:Optional[str]=None)\n",
|
228 |
+
"\n",
|
229 |
+
"Wrapper around OpenAI Chat large language models.\n",
|
230 |
+
"\n",
|
231 |
+
"To use, you should have the ``openai`` python package installed, and the\n",
|
232 |
+
"environment variable ``OPENAI_API_KEY`` set with your API key.\n",
|
233 |
+
"\n",
|
234 |
+
"Any parameters that are valid to be passed to the openai.create call can be passed\n",
|
235 |
+
"in, even if not explicitly saved on this class.\n",
|
236 |
+
"\n",
|
237 |
+
"Example:\n",
|
238 |
+
" .. code-block:: python\n",
|
239 |
+
"\n",
|
240 |
+
" from langchain.chat_models import ChatOpenAI\n",
|
241 |
+
" openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
|
242 |
+
]
|
243 |
+
},
|
244 |
+
"execution_count": 3,
|
245 |
+
"metadata": {},
|
246 |
+
"output_type": "execute_result"
|
247 |
+
}
|
248 |
+
],
|
249 |
+
"source": [
|
250 |
+
"#| echo: false\n",
|
251 |
+
"#| output: asis\n",
|
252 |
+
"show_doc(ChatOpenAI)"
|
253 |
+
]
|
254 |
+
},
|
255 |
+
{
|
256 |
+
"cell_type": "code",
|
257 |
+
"execution_count": null,
|
258 |
+
"metadata": {
|
259 |
+
"language": "python"
|
260 |
+
},
|
261 |
+
"outputs": [],
|
262 |
+
"source": [
|
263 |
+
"#| eval: false\n",
|
264 |
+
"llm = ChatOpenAI(temperature=1)\n",
|
265 |
+
"MEMORY_KEY = \"chat_history\"\n",
|
266 |
+
"chat_msgs = INIT_PROMPT.format_prompt(\n",
|
267 |
+
" ingredients=\"tofu, brocolli\",\n",
|
268 |
+
" allergies=\"\",\n",
|
269 |
+
" recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
|
270 |
+
")\n",
|
271 |
+
"chat_msgs = chat_msgs.to_messages()\n",
|
272 |
+
"results = llm.generate([chat_msgs])\n",
|
273 |
+
"\n",
|
274 |
+
"chat_msgs.append(results.generations[0][0].message)\n",
|
275 |
+
"tools = [vegan_recipe_edamam_search]\n",
|
276 |
+
"prompt = OpenAIFunctionsAgent.create_prompt(\n",
|
277 |
+
" system_message=INIT_PROMPT.messages[0],\n",
|
278 |
+
" extra_prompt_messages=chat_msgs + [MessagesPlaceholder(variable_name=MEMORY_KEY)],\n",
|
279 |
+
")\n",
|
280 |
+
"memory = ConversationBufferMemory(\n",
|
281 |
+
" chat_memory=ChatMessageHistory(messages=chat_msgs),\n",
|
282 |
+
" return_messages=True,\n",
|
283 |
+
" memory_key=MEMORY_KEY,\n",
|
284 |
+
")\n",
|
285 |
+
"agent_executor = AgentExecutor(\n",
|
286 |
+
" agent=OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt),\n",
|
287 |
+
" tools=tools,\n",
|
288 |
+
" memory=memory,\n",
|
289 |
+
" verbose=True,\n",
|
290 |
+
")"
|
291 |
+
]
|
292 |
+
},
|
293 |
+
{
|
294 |
+
"cell_type": "code",
|
295 |
+
"execution_count": null,
|
296 |
+
"metadata": {
|
297 |
+
"language": "python"
|
298 |
+
},
|
299 |
+
"outputs": [],
|
300 |
+
"source": [
|
301 |
+
"# Fails for a weird query\n",
|
302 |
+
"# \"tofu, pickles, mustard, olives, tomatoes, lettuce, bell peppers, carrots, bread\""
|
303 |
]
|
304 |
},
|
305 |
{
|
|
|
312 |
{
|
313 |
"data": {
|
314 |
"text/plain": [
|
315 |
+
"[SystemMessage(content=\"The following is a conversation between a human and a friendly AI chef. \\nThe AI is compassionate to animals.\\nThe AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\\n\\nLet's think step by step.\\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\\nOnly generate keyword queries as other tools should be used to fetch full recipes.\", additional_kwargs={}),\n",
|
316 |
+
" AIMessage(content='What ingredients do you wish to cook with?', additional_kwargs={}, example=False),\n",
|
317 |
+
" HumanMessage(content='Ingredients: tofu, brocolli', additional_kwargs={}, example=False),\n",
|
318 |
+
" AIMessage(content='Do you have any allergies I should be aware of?', additional_kwargs={}, example=False),\n",
|
319 |
+
" HumanMessage(content='Allergies: ', additional_kwargs={}, example=False),\n",
|
320 |
+
" AIMessage(content='Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?', additional_kwargs={}, example=False),\n",
|
321 |
+
" HumanMessage(content=\"Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\\nDraw some inspiration from the user's preferences delimited below if any are specified.\\n\\n###\\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\\n###\", additional_kwargs={}, example=False),\n",
|
322 |
+
" AIMessage(content='Based on the ingredients, allergies, and preferences you provided, here is a vegan recipe keyword query suggestion: \"vegan Thai tofu broccoli stir fry recipe\"', additional_kwargs={}, example=False)]"
|
323 |
]
|
324 |
},
|
325 |
"execution_count": null,
|
|
|
328 |
}
|
329 |
],
|
330 |
"source": [
|
331 |
+
"#| eval: false\n",
|
332 |
+
"memory.chat_memory.messages"
|
333 |
]
|
334 |
},
|
335 |
{
|
|
|
338 |
"metadata": {
|
339 |
"language": "python"
|
340 |
},
|
341 |
+
"outputs": [
|
342 |
+
{
|
343 |
+
"name": "stdout",
|
344 |
+
"output_type": "stream",
|
345 |
+
"text": [
|
346 |
+
"\n",
|
347 |
+
"\n",
|
348 |
+
"> Entering new AgentExecutor chain...\n",
|
349 |
+
"\n",
|
350 |
+
"Invoking: `vegan_recipe_edamam_search` with `{'query': 'vegan tofu broccoli'}`\n",
|
351 |
+
"\n",
|
352 |
+
"\n",
|
353 |
+
"[{'label': 'Vegan BBQ teriyaki tofu', 'url': 'https://www.bbcgoodfood.com/recipes/teriyaki-tofu-vegan-barbecue', 'ingredientLines': ['4 tbsp low-salt soy sauce', '2 tbsp soft brown sugar', 'pinch ground ginger', '2 tbsp mirin', '3 tsp sesame oil', '350g block very firm tofu (see tip below) cut into thick slices', '½ tbsp rapeseed oil', '2 courgettes, sliced horizontally into strips', '200g Tenderstem broccoli', 'black and white sesame seeds, to serve'], 'totalTime': 25.0}, {'label': 'Vegan Crispy Stir-Fried Tofu With Broccoli Recipe', 'url': 'http://www.seriouseats.com/recipes/2014/02/vegan-experience-crispy-tofu-broccoli-stir-fry.html', 'ingredientLines': ['1 1/2 quarts vegetable or peanut oil', '1/2 cup plus 2 teaspoons cornstarch, divided', '1/2 cup all-purpose flour', '1/2 teaspoon baking powder', 'Kosher salt', '1/2 cup cold water', '1/2 cup vodka', '1 pound extra-firm tofu, cut into 1/2- by 2- by 1-inch slabs, carefully dried (see note above)', '1 pound broccoli, cut into 1-inch florets', '1/4 cup Xiaoshing wine or dry sherry', '1/4 cup homemade or store-bought low-sodium vegetable stock', '2 tablespoons soy sauce', '1 tablespoon fermented black bean sauce', '2 tablespoons sugar', '1 tablespoon toasted sesame oil', '2 (1-inch) segments lemon peel, plus 2 teaspoons lemon juice', '4 cloves garlic, minced (about 4 teaspoons)', '1 tablespoon minced or grated fresh ginger', '6 scallions, white and light green parts only, finely chopped', '2 tablespoons toasted sesame seeds, divided'], 'totalTime': 30.0}, {'label': 'Thai-Style Chopped Salad with Sriracha Tofu', 'url': 'http://www.eatingwell.com/recipe/276172/thai-style-chopped-salad-with-sriracha-tofu/', 'ingredientLines': ['1 (10 ounce) package kale, Brussels sprout, broccoli and cabbage salad mix', '1 (12 ounce) package frozen shelled edamame, thawed', '2 (7 ounce) packages Sriracha-flavored baked tofu, cubed', '1/2 cup spicy peanut vinaigrette'], 'totalTime': 10.0}]"
|
354 |
+
]
|
355 |
+
}
|
356 |
+
],
|
357 |
"source": [
|
358 |
+
"#| eval: false\n",
|
359 |
+
"agent_executor.run(\"Search for vegan recipe\")"
|
360 |
+
]
|
361 |
+
},
|
362 |
+
{
|
363 |
+
"cell_type": "code",
|
364 |
+
"execution_count": 4,
|
365 |
+
"metadata": {},
|
366 |
+
"outputs": [
|
367 |
+
{
|
368 |
+
"data": {
|
369 |
+
"text/markdown": [
|
370 |
+
"---\n",
|
371 |
+
"\n",
|
372 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L42){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
373 |
+
"\n",
|
374 |
+
"### ConversationBot\n",
|
375 |
+
"\n",
|
376 |
+
"> ConversationBot (verbose=True)\n",
|
377 |
+
"\n",
|
378 |
+
"Initialize self. See help(type(self)) for accurate signature."
|
379 |
+
],
|
380 |
+
"text/plain": [
|
381 |
+
"---\n",
|
382 |
+
"\n",
|
383 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L42){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
384 |
+
"\n",
|
385 |
+
"### ConversationBot\n",
|
386 |
+
"\n",
|
387 |
+
"> ConversationBot (verbose=True)\n",
|
388 |
+
"\n",
|
389 |
+
"Initialize self. See help(type(self)) for accurate signature."
|
390 |
+
]
|
391 |
+
},
|
392 |
+
"execution_count": 4,
|
393 |
+
"metadata": {},
|
394 |
+
"output_type": "execute_result"
|
395 |
+
}
|
396 |
+
],
|
397 |
+
"source": [
|
398 |
+
"#| echo: false\n",
|
399 |
+
"#| output: asis\n",
|
400 |
+
"show_doc(ConversationBot)"
|
401 |
]
|
402 |
},
|
403 |
{
|
|
|
410 |
{
|
411 |
"data": {
|
412 |
"text/plain": [
|
413 |
+
"Path('/home/evylz/AnimalEquality/lv-recipe-chatbot/assets/images/vegan_ingredients')"
|
414 |
]
|
415 |
},
|
416 |
"execution_count": null,
|
|
|
419 |
}
|
420 |
],
|
421 |
"source": [
|
422 |
+
"os.listdir(SAMPLE_IMG_DIR)\n",
|
423 |
+
"SAMPLE_IMG_DIR"
|
424 |
]
|
425 |
},
|
426 |
{
|
|
|
475 |
},
|
476 |
{
|
477 |
"cell_type": "code",
|
478 |
+
"execution_count": 5,
|
479 |
"metadata": {},
|
480 |
"outputs": [
|
481 |
{
|
|
|
483 |
"text/markdown": [
|
484 |
"---\n",
|
485 |
"\n",
|
486 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L126){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
487 |
"\n",
|
488 |
"### create_demo\n",
|
489 |
"\n",
|
|
|
492 |
"text/plain": [
|
493 |
"---\n",
|
494 |
"\n",
|
495 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L126){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
496 |
"\n",
|
497 |
"### create_demo\n",
|
498 |
"\n",
|
499 |
"> create_demo (bot=<class '__main__.ConversationBot'>)"
|
500 |
]
|
501 |
},
|
502 |
+
"execution_count": 5,
|
503 |
"metadata": {},
|
504 |
"output_type": "execute_result"
|
505 |
}
|
_proc/02_vegan_recipe_tools.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
_proc/03_ingredient_vision.ipynb
CHANGED
@@ -37,7 +37,7 @@
|
|
37 |
"text/markdown": [
|
38 |
"---\n",
|
39 |
"\n",
|
40 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
41 |
"\n",
|
42 |
"### format_image\n",
|
43 |
"\n",
|
@@ -50,7 +50,7 @@
|
|
50 |
"text/plain": [
|
51 |
"---\n",
|
52 |
"\n",
|
53 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
54 |
"\n",
|
55 |
"### format_image\n",
|
56 |
"\n",
|
@@ -82,7 +82,7 @@
|
|
82 |
"text/markdown": [
|
83 |
"---\n",
|
84 |
"\n",
|
85 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
86 |
"\n",
|
87 |
"### BlipImageCaptioning\n",
|
88 |
"\n",
|
@@ -93,7 +93,7 @@
|
|
93 |
"text/plain": [
|
94 |
"---\n",
|
95 |
"\n",
|
96 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
97 |
"\n",
|
98 |
"### BlipImageCaptioning\n",
|
99 |
"\n",
|
@@ -125,7 +125,7 @@
|
|
125 |
"text/markdown": [
|
126 |
"---\n",
|
127 |
"\n",
|
128 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
129 |
"\n",
|
130 |
"### BlipImageCaptioning.inference\n",
|
131 |
"\n",
|
@@ -143,7 +143,7 @@
|
|
143 |
"text/plain": [
|
144 |
"---\n",
|
145 |
"\n",
|
146 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
147 |
"\n",
|
148 |
"### BlipImageCaptioning.inference\n",
|
149 |
"\n",
|
@@ -180,7 +180,7 @@
|
|
180 |
"text/markdown": [
|
181 |
"---\n",
|
182 |
"\n",
|
183 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
184 |
"\n",
|
185 |
"### BlipVQA\n",
|
186 |
"\n",
|
@@ -194,7 +194,7 @@
|
|
194 |
"text/plain": [
|
195 |
"---\n",
|
196 |
"\n",
|
197 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
198 |
"\n",
|
199 |
"### BlipVQA\n",
|
200 |
"\n",
|
@@ -229,7 +229,7 @@
|
|
229 |
"text/markdown": [
|
230 |
"---\n",
|
231 |
"\n",
|
232 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
233 |
"\n",
|
234 |
"### BlipVQA.inference\n",
|
235 |
"\n",
|
@@ -247,7 +247,7 @@
|
|
247 |
"text/plain": [
|
248 |
"---\n",
|
249 |
"\n",
|
250 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
251 |
"\n",
|
252 |
"### BlipVQA.inference\n",
|
253 |
"\n",
|
@@ -753,7 +753,7 @@
|
|
753 |
"text/markdown": [
|
754 |
"---\n",
|
755 |
"\n",
|
756 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
757 |
"\n",
|
758 |
"### VeganIngredientFinder\n",
|
759 |
"\n",
|
@@ -764,7 +764,7 @@
|
|
764 |
"text/plain": [
|
765 |
"---\n",
|
766 |
"\n",
|
767 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
768 |
"\n",
|
769 |
"### VeganIngredientFinder\n",
|
770 |
"\n",
|
@@ -796,7 +796,7 @@
|
|
796 |
"text/markdown": [
|
797 |
"---\n",
|
798 |
"\n",
|
799 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
800 |
"\n",
|
801 |
"### VeganIngredientFinder.list_ingredients\n",
|
802 |
"\n",
|
@@ -810,7 +810,7 @@
|
|
810 |
"text/plain": [
|
811 |
"---\n",
|
812 |
"\n",
|
813 |
-
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#
|
814 |
"\n",
|
815 |
"### VeganIngredientFinder.list_ingredients\n",
|
816 |
"\n",
|
|
|
37 |
"text/markdown": [
|
38 |
"---\n",
|
39 |
"\n",
|
40 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L26){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
41 |
"\n",
|
42 |
"### format_image\n",
|
43 |
"\n",
|
|
|
50 |
"text/plain": [
|
51 |
"---\n",
|
52 |
"\n",
|
53 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L26){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
54 |
"\n",
|
55 |
"### format_image\n",
|
56 |
"\n",
|
|
|
82 |
"text/markdown": [
|
83 |
"---\n",
|
84 |
"\n",
|
85 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L41){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
86 |
"\n",
|
87 |
"### BlipImageCaptioning\n",
|
88 |
"\n",
|
|
|
93 |
"text/plain": [
|
94 |
"---\n",
|
95 |
"\n",
|
96 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L41){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
97 |
"\n",
|
98 |
"### BlipImageCaptioning\n",
|
99 |
"\n",
|
|
|
125 |
"text/markdown": [
|
126 |
"---\n",
|
127 |
"\n",
|
128 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
129 |
"\n",
|
130 |
"### BlipImageCaptioning.inference\n",
|
131 |
"\n",
|
|
|
143 |
"text/plain": [
|
144 |
"---\n",
|
145 |
"\n",
|
146 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
147 |
"\n",
|
148 |
"### BlipImageCaptioning.inference\n",
|
149 |
"\n",
|
|
|
180 |
"text/markdown": [
|
181 |
"---\n",
|
182 |
"\n",
|
183 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L71){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
184 |
"\n",
|
185 |
"### BlipVQA\n",
|
186 |
"\n",
|
|
|
194 |
"text/plain": [
|
195 |
"---\n",
|
196 |
"\n",
|
197 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L71){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
198 |
"\n",
|
199 |
"### BlipVQA\n",
|
200 |
"\n",
|
|
|
229 |
"text/markdown": [
|
230 |
"---\n",
|
231 |
"\n",
|
232 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L89){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
233 |
"\n",
|
234 |
"### BlipVQA.inference\n",
|
235 |
"\n",
|
|
|
247 |
"text/plain": [
|
248 |
"---\n",
|
249 |
"\n",
|
250 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L89){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
251 |
"\n",
|
252 |
"### BlipVQA.inference\n",
|
253 |
"\n",
|
|
|
753 |
"text/markdown": [
|
754 |
"---\n",
|
755 |
"\n",
|
756 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L106){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
757 |
"\n",
|
758 |
"### VeganIngredientFinder\n",
|
759 |
"\n",
|
|
|
764 |
"text/plain": [
|
765 |
"---\n",
|
766 |
"\n",
|
767 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L106){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
768 |
"\n",
|
769 |
"### VeganIngredientFinder\n",
|
770 |
"\n",
|
|
|
796 |
"text/markdown": [
|
797 |
"---\n",
|
798 |
"\n",
|
799 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L111){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
800 |
"\n",
|
801 |
"### VeganIngredientFinder.list_ingredients\n",
|
802 |
"\n",
|
|
|
810 |
"text/plain": [
|
811 |
"---\n",
|
812 |
"\n",
|
813 |
+
"[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L111){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
|
814 |
"\n",
|
815 |
"### VeganIngredientFinder.list_ingredients\n",
|
816 |
"\n",
|
_proc/_docs/engineer_prompt.html
CHANGED
@@ -126,7 +126,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
|
|
126 |
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
127 |
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
128 |
</button>
|
129 |
-
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"
|
130 |
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
131 |
</a>
|
132 |
</div>
|
@@ -136,46 +136,6 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
|
|
136 |
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
|
137 |
<!-- sidebar -->
|
138 |
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
139 |
-
<div class="sidebar-menu-container">
|
140 |
-
<ul class="list-unstyled mt-1">
|
141 |
-
<li class="sidebar-item">
|
142 |
-
<div class="sidebar-item-container">
|
143 |
-
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
144 |
-
<span class="menu-text">lv-recipe-chatbot</span></a>
|
145 |
-
</div>
|
146 |
-
</li>
|
147 |
-
<li class="sidebar-item">
|
148 |
-
<div class="sidebar-item-container">
|
149 |
-
<a href="./engineer_prompt.html" class="sidebar-item-text sidebar-link active">
|
150 |
-
<span class="menu-text">engineer_prompt</span></a>
|
151 |
-
</div>
|
152 |
-
</li>
|
153 |
-
<li class="sidebar-item">
|
154 |
-
<div class="sidebar-item-container">
|
155 |
-
<a href="./app.html" class="sidebar-item-text sidebar-link">
|
156 |
-
<span class="menu-text">app</span></a>
|
157 |
-
</div>
|
158 |
-
</li>
|
159 |
-
<li class="sidebar-item">
|
160 |
-
<div class="sidebar-item-container">
|
161 |
-
<a href="./lchain_tool.html" class="sidebar-item-text sidebar-link">
|
162 |
-
<span class="menu-text">lchain_tool</span></a>
|
163 |
-
</div>
|
164 |
-
</li>
|
165 |
-
<li class="sidebar-item">
|
166 |
-
<div class="sidebar-item-container">
|
167 |
-
<a href="./ingredient_vision.html" class="sidebar-item-text sidebar-link">
|
168 |
-
<span class="menu-text">ingredient_vision</span></a>
|
169 |
-
</div>
|
170 |
-
</li>
|
171 |
-
<li class="sidebar-item">
|
172 |
-
<div class="sidebar-item-container">
|
173 |
-
<a href="./edamam_api.html" class="sidebar-item-text sidebar-link">
|
174 |
-
<span class="menu-text">edamam_api</span></a>
|
175 |
-
</div>
|
176 |
-
</li>
|
177 |
-
</ul>
|
178 |
-
</div>
|
179 |
</nav>
|
180 |
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
181 |
<!-- margin-sidebar -->
|
@@ -345,6 +305,9 @@ Steps:
|
|
345 |
6. Slice the sandwich in half, and enjoy!</code></pre>
|
346 |
</div>
|
347 |
</div>
|
|
|
|
|
|
|
348 |
|
349 |
|
350 |
|
@@ -586,4 +549,4 @@ window.document.addEventListener("DOMContentLoaded", function (event) {
|
|
586 |
|
587 |
|
588 |
|
589 |
-
<footer class="footer"><div class="nav-footer"><div class="nav-footer-center"><div class="toc-actions"><div><i class="bi bi-
|
|
|
126 |
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
127 |
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
128 |
</button>
|
129 |
+
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item">engineer_prompt</li></ol></nav>
|
130 |
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
131 |
</a>
|
132 |
</div>
|
|
|
136 |
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
|
137 |
<!-- sidebar -->
|
138 |
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
</nav>
|
140 |
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
141 |
<!-- margin-sidebar -->
|
|
|
305 |
6. Slice the sandwich in half, and enjoy!</code></pre>
|
306 |
</div>
|
307 |
</div>
|
308 |
+
<div class="cell">
|
309 |
+
<div class="sourceCode cell-code" id="cb7"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>test_temp <span class="op">=</span> HumanMessagePromptTemplate.from_template(<span class="st">"Ingredients: </span><span class="sc">{ingredients}</span><span class="st">"</span>)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
310 |
+
</div>
|
311 |
|
312 |
|
313 |
|
|
|
549 |
|
550 |
|
551 |
|
552 |
+
<footer class="footer"><div class="nav-footer"><div class="nav-footer-center"><div class="toc-actions"><div><i class="bi bi-github"></i></div><div class="action-links"><p><a href="https://github.com/animalequality/lv-recipe-chatbot/issues/new" class="toc-action">Report an issue</a></p></div></div></div></div></footer></body></html>
|
_proc/_docs/search.json
CHANGED
@@ -74,7 +74,7 @@
|
|
74 |
"href": "engineer_prompt.html",
|
75 |
"title": "engineer_prompt",
|
76 |
"section": "",
|
77 |
-
"text": "Setup env\n\nfrom dotenv import load_dotenv\n\n\nload_dotenv()\n\nTrue\n\n\nEvaluate chat backend\n\nchat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\nmemory = ConversationBufferMemory(return_messages=True)\nchat_msgs = init_prompt.format_prompt(\n ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n allergies=\"\",\n recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n)\n\nchat_msgs = chat_msgs.to_messages()\nresults = chat.generate([chat_msgs])\nchat_msgs.extend(\n [\n results.generations[0][0].message,\n MessagesPlaceholder(variable_name=\"history\"),\n HumanMessagePromptTemplate.from_template(\"{input}\"),\n ]\n)\nopen_prompt = ChatPromptTemplate.from_messages(chat_msgs)\nconversation = ConversationChain(\n llm=chat, verbose=True, memory=memory, prompt=open_prompt\n)\n\nresult = conversation.predict(input=\"Recommend a different recipe please.\")\nprint(result)\n\nAnthropic module not found. Install with `pip install anthropic`.\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n\n\n\n\n> Entering new ConversationChain chain...\nPrompt after formatting:\nSystem: The following is a conversation between a human and a friendly AI chef. \nThe AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n\nLet's think step by step.\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\nAI: What ingredients do you wish to cook with?\nHuman: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\nAI: Do you have any allergies I should be aware of?\nHuman: Allergies: \nAI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\nHuman: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\nRespect the human's allergies (if any).\nFollow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n\n###\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\n###\n\nOutput format:\n\n**Vegan recipe name**\nPreparation time (humanized)\n\nIngredients (List of ingredients with quantities):\n- <quantity and unit> <ingredient>\n\nSteps (detailed):\n1.\n2.\n3.\n...\nAI: Here is a Thai-inspired vegan recipe for you:\n\n**Thai Tofu Lettuce Wraps**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, crumbled\n- 1/4 cup pickles, chopped\n- 1/4 cup olives, sliced\n- 1/2 bell pepper, sliced\n- 1/2 carrot, finely chopped\n- 4-6 lettuce leaves\n- 2 tablespoons soy sauce\n- 1 tablespoon rice vinegar\n- 1 tablespoon agave nectar\n- 1/2 tablespoon garlic powder\n- 1/2 tablespoon onion powder\n- 1/2 teaspoon dried basil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon salt\n- 1/4 teaspoon black pepper\n- 4-6 slices of bread, toasted\n\nSteps:\n1. In a large bowl, combine crumbled tofu, pickles, olives, bell pepper, and carrot.\n2. In a small bowl, whisk together soy sauce, rice vinegar, agave nectar, garlic powder, onion powder, basil, oregano, salt, and black pepper.\n3. Pour the dressing over the tofu mixture, and stir until everything is coated.\n4. Place a spoonful of the tofu mixture into each lettuce leaf, and serve with a slice of toasted bread.\nHuman: Recommend a different recipe please.\n\n> Finished chain.\nSure, how about this recipe that incorporates more of the ingredients you provided?\n\n**Vegan Mediterranean Tofu Sandwich**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, sliced\n- 2 teaspoons olive oil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon dried basil\n- Salt and pepper to taste\n- 2 slices of bread\n- 1/4 cup hummus\n- 2-3 lettuce leaves\n- 1/4 cup sliced tomatoes\n- 1/4 cup sliced bell peppers\n- 1/4 cup grated carrot\n\nSteps:\n1. Preheat the oven to 375°F.\n2. In a small bowl, mix olive oil, oregano, basil, salt, and pepper, and place tofu slices on a baking sheet. Brush tofu with the olive oil mixture, covering both sides.\n3. Place the baking sheet in the oven and bake the tofu for 15 minutes, flipping the slices halfway through.\n4. Toast the bread slices.\n5. Spread the hummus on one slice of bread, and layer lettuce, tomatoes, bell peppers, grated carrot, and baked tofu on top. Top with the other slice of bread.\n6. Slice the sandwich in half, and enjoy
|
78 |
},
|
79 |
{
|
80 |
"objectID": "edamam_api.html",
|
|
|
74 |
"href": "engineer_prompt.html",
|
75 |
"title": "engineer_prompt",
|
76 |
"section": "",
|
77 |
+
"text": "Setup env\n\nfrom dotenv import load_dotenv\n\n\nload_dotenv()\n\nTrue\n\n\nEvaluate chat backend\n\nchat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\nmemory = ConversationBufferMemory(return_messages=True)\nchat_msgs = init_prompt.format_prompt(\n ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n allergies=\"\",\n recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n)\n\nchat_msgs = chat_msgs.to_messages()\nresults = chat.generate([chat_msgs])\nchat_msgs.extend(\n [\n results.generations[0][0].message,\n MessagesPlaceholder(variable_name=\"history\"),\n HumanMessagePromptTemplate.from_template(\"{input}\"),\n ]\n)\nopen_prompt = ChatPromptTemplate.from_messages(chat_msgs)\nconversation = ConversationChain(\n llm=chat, verbose=True, memory=memory, prompt=open_prompt\n)\n\nresult = conversation.predict(input=\"Recommend a different recipe please.\")\nprint(result)\n\nAnthropic module not found. Install with `pip install anthropic`.\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n\n\n\n\n> Entering new ConversationChain chain...\nPrompt after formatting:\nSystem: The following is a conversation between a human and a friendly AI chef. \nThe AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n\nLet's think step by step.\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\nAI: What ingredients do you wish to cook with?\nHuman: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\nAI: Do you have any allergies I should be aware of?\nHuman: Allergies: \nAI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\nHuman: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\nRespect the human's allergies (if any).\nFollow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n\n###\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\n###\n\nOutput format:\n\n**Vegan recipe name**\nPreparation time (humanized)\n\nIngredients (List of ingredients with quantities):\n- <quantity and unit> <ingredient>\n\nSteps (detailed):\n1.\n2.\n3.\n...\nAI: Here is a Thai-inspired vegan recipe for you:\n\n**Thai Tofu Lettuce Wraps**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, crumbled\n- 1/4 cup pickles, chopped\n- 1/4 cup olives, sliced\n- 1/2 bell pepper, sliced\n- 1/2 carrot, finely chopped\n- 4-6 lettuce leaves\n- 2 tablespoons soy sauce\n- 1 tablespoon rice vinegar\n- 1 tablespoon agave nectar\n- 1/2 tablespoon garlic powder\n- 1/2 tablespoon onion powder\n- 1/2 teaspoon dried basil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon salt\n- 1/4 teaspoon black pepper\n- 4-6 slices of bread, toasted\n\nSteps:\n1. In a large bowl, combine crumbled tofu, pickles, olives, bell pepper, and carrot.\n2. In a small bowl, whisk together soy sauce, rice vinegar, agave nectar, garlic powder, onion powder, basil, oregano, salt, and black pepper.\n3. Pour the dressing over the tofu mixture, and stir until everything is coated.\n4. Place a spoonful of the tofu mixture into each lettuce leaf, and serve with a slice of toasted bread.\nHuman: Recommend a different recipe please.\n\n> Finished chain.\nSure, how about this recipe that incorporates more of the ingredients you provided?\n\n**Vegan Mediterranean Tofu Sandwich**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, sliced\n- 2 teaspoons olive oil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon dried basil\n- Salt and pepper to taste\n- 2 slices of bread\n- 1/4 cup hummus\n- 2-3 lettuce leaves\n- 1/4 cup sliced tomatoes\n- 1/4 cup sliced bell peppers\n- 1/4 cup grated carrot\n\nSteps:\n1. Preheat the oven to 375°F.\n2. In a small bowl, mix olive oil, oregano, basil, salt, and pepper, and place tofu slices on a baking sheet. Brush tofu with the olive oil mixture, covering both sides.\n3. Place the baking sheet in the oven and bake the tofu for 15 minutes, flipping the slices halfway through.\n4. Toast the bread slices.\n5. Spread the hummus on one slice of bread, and layer lettuce, tomatoes, bell peppers, grated carrot, and baked tofu on top. Top with the other slice of bread.\n6. Slice the sandwich in half, and enjoy!\n\n\n\ntest_temp = HumanMessagePromptTemplate.from_template(\"Ingredients: {ingredients}\")"
|
78 |
},
|
79 |
{
|
80 |
"objectID": "edamam_api.html",
|
_proc/_docs/sitemap.xml
CHANGED
@@ -2,11 +2,11 @@
|
|
2 |
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
3 |
<url>
|
4 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/ingredient_vision.html</loc>
|
5 |
-
<lastmod>2023-06-
|
6 |
</url>
|
7 |
<url>
|
8 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/app.html</loc>
|
9 |
-
<lastmod>2023-06-
|
10 |
</url>
|
11 |
<url>
|
12 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/index.html</loc>
|
@@ -14,11 +14,11 @@
|
|
14 |
</url>
|
15 |
<url>
|
16 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/lchain_tool.html</loc>
|
17 |
-
<lastmod>2023-06-
|
18 |
</url>
|
19 |
<url>
|
20 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/engineer_prompt.html</loc>
|
21 |
-
<lastmod>2023-06-
|
22 |
</url>
|
23 |
<url>
|
24 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/edamam_api.html</loc>
|
|
|
2 |
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
3 |
<url>
|
4 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/ingredient_vision.html</loc>
|
5 |
+
<lastmod>2023-06-12T19:02:21.982Z</lastmod>
|
6 |
</url>
|
7 |
<url>
|
8 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/app.html</loc>
|
9 |
+
<lastmod>2023-06-12T19:02:20.886Z</lastmod>
|
10 |
</url>
|
11 |
<url>
|
12 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/index.html</loc>
|
|
|
14 |
</url>
|
15 |
<url>
|
16 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/lchain_tool.html</loc>
|
17 |
+
<lastmod>2023-06-12T19:02:21.258Z</lastmod>
|
18 |
</url>
|
19 |
<url>
|
20 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/engineer_prompt.html</loc>
|
21 |
+
<lastmod>2023-06-12T19:02:20.550Z</lastmod>
|
22 |
</url>
|
23 |
<url>
|
24 |
<loc>https://animalequality.github.io/lv-recipe-chatbot/edamam_api.html</loc>
|
lv_recipe_chatbot/_modidx.py
CHANGED
@@ -44,7 +44,19 @@ d = { 'settings': { 'branch': 'main',
|
|
44 |
'lv_recipe_chatbot/ingredient_vision.py'),
|
45 |
'lv_recipe_chatbot.ingredient_vision.format_image': ( 'ingredient_vision.html#format_image',
|
46 |
'lv_recipe_chatbot/ingredient_vision.py')},
|
47 |
-
'lv_recipe_chatbot.lchain_tool': { 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper': ( '
|
48 |
'lv_recipe_chatbot/lchain_tool.py'),
|
49 |
-
'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper._process_response': ( '
|
50 |
-
'lv_recipe_chatbot/lchain_tool.py')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
'lv_recipe_chatbot/ingredient_vision.py'),
|
45 |
'lv_recipe_chatbot.ingredient_vision.format_image': ( 'ingredient_vision.html#format_image',
|
46 |
'lv_recipe_chatbot/ingredient_vision.py')},
|
47 |
+
'lv_recipe_chatbot.lchain_tool': { 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper': ( 'vegan_recipe_tools.html#recipeserpapiwrapper',
|
48 |
'lv_recipe_chatbot/lchain_tool.py'),
|
49 |
+
'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper._process_response': ( 'vegan_recipe_tools.html#recipeserpapiwrapper._process_response',
|
50 |
+
'lv_recipe_chatbot/lchain_tool.py'),
|
51 |
+
'lv_recipe_chatbot.lchain_tool.get_vegan_recipes_edamam_api': ( 'vegan_recipe_tools.html#get_vegan_recipes_edamam_api',
|
52 |
+
'lv_recipe_chatbot/lchain_tool.py'),
|
53 |
+
'lv_recipe_chatbot.lchain_tool.vegan_recipe_edamam_search': ( 'vegan_recipe_tools.html#vegan_recipe_edamam_search',
|
54 |
+
'lv_recipe_chatbot/lchain_tool.py')},
|
55 |
+
'lv_recipe_chatbot.vegan_recipe_tools': { 'lv_recipe_chatbot.vegan_recipe_tools.RecipeSerpAPIWrapper': ( 'vegan_recipe_tools.html#recipeserpapiwrapper',
|
56 |
+
'lv_recipe_chatbot/vegan_recipe_tools.py'),
|
57 |
+
'lv_recipe_chatbot.vegan_recipe_tools.RecipeSerpAPIWrapper._process_response': ( 'vegan_recipe_tools.html#recipeserpapiwrapper._process_response',
|
58 |
+
'lv_recipe_chatbot/vegan_recipe_tools.py'),
|
59 |
+
'lv_recipe_chatbot.vegan_recipe_tools.get_vegan_recipes_edamam_api': ( 'vegan_recipe_tools.html#get_vegan_recipes_edamam_api',
|
60 |
+
'lv_recipe_chatbot/vegan_recipe_tools.py'),
|
61 |
+
'lv_recipe_chatbot.vegan_recipe_tools.vegan_recipe_edamam_search': ( 'vegan_recipe_tools.html#vegan_recipe_edamam_search',
|
62 |
+
'lv_recipe_chatbot/vegan_recipe_tools.py')}}}
|
lv_recipe_chatbot/app.py
CHANGED
@@ -9,9 +9,18 @@ import os
|
|
9 |
|
10 |
import gradio as gr
|
11 |
from fastcore.utils import in_jupyter
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
from langchain.chains import ConversationChain
|
13 |
from langchain.chat_models import ChatOpenAI
|
14 |
-
from langchain.memory import ConversationBufferMemory
|
15 |
from langchain.prompts.chat import (
|
16 |
ChatPromptTemplate,
|
17 |
HumanMessagePromptTemplate,
|
@@ -27,8 +36,9 @@ from lv_recipe_chatbot.ingredient_vision import (
|
|
27 |
VeganIngredientFinder,
|
28 |
format_image,
|
29 |
)
|
|
|
30 |
|
31 |
-
# %% ../nbs/01_app.ipynb
|
32 |
class ConversationBot:
|
33 |
def __init__(self, verbose=True):
|
34 |
self.chat = ChatOpenAI(temperature=1, verbose=True)
|
@@ -112,7 +122,7 @@ The extracted ingredients are:
|
|
112 |
def __del__(self):
|
113 |
del self.vegan_ingred_finder
|
114 |
|
115 |
-
# %% ../nbs/01_app.ipynb
|
116 |
def create_demo(bot=ConversationBot):
|
117 |
sample_images = []
|
118 |
all_imgs = [f"{SAMPLE_IMG_DIR}/{img}" for img in os.listdir(SAMPLE_IMG_DIR)]
|
|
|
9 |
|
10 |
import gradio as gr
|
11 |
from fastcore.utils import in_jupyter
|
12 |
+
from langchain import LLMChain, OpenAI, PromptTemplate
|
13 |
+
from langchain.agents import (
|
14 |
+
AgentExecutor,
|
15 |
+
AgentType,
|
16 |
+
OpenAIFunctionsAgent,
|
17 |
+
Tool,
|
18 |
+
initialize_agent,
|
19 |
+
load_tools,
|
20 |
+
)
|
21 |
from langchain.chains import ConversationChain
|
22 |
from langchain.chat_models import ChatOpenAI
|
23 |
+
from langchain.memory import ChatMessageHistory, ConversationBufferMemory
|
24 |
from langchain.prompts.chat import (
|
25 |
ChatPromptTemplate,
|
26 |
HumanMessagePromptTemplate,
|
|
|
36 |
VeganIngredientFinder,
|
37 |
format_image,
|
38 |
)
|
39 |
+
from .vegan_recipe_tools import vegan_recipe_edamam_search
|
40 |
|
41 |
+
# %% ../nbs/01_app.ipynb 14
|
42 |
class ConversationBot:
|
43 |
def __init__(self, verbose=True):
|
44 |
self.chat = ChatOpenAI(temperature=1, verbose=True)
|
|
|
122 |
def __del__(self):
|
123 |
del self.vegan_ingred_finder
|
124 |
|
125 |
+
# %% ../nbs/01_app.ipynb 18
|
126 |
def create_demo(bot=ConversationBot):
|
127 |
sample_images = []
|
128 |
all_imgs = [f"{SAMPLE_IMG_DIR}/{img}" for img in os.listdir(SAMPLE_IMG_DIR)]
|
lv_recipe_chatbot/engineer_prompt.py
CHANGED
@@ -21,15 +21,14 @@ from langchain.schema import AIMessage, HumanMessage, SystemMessage
|
|
21 |
INIT_PROMPT = ChatPromptTemplate.from_messages(
|
22 |
[
|
23 |
SystemMessagePromptTemplate.from_template(
|
24 |
-
"""
|
25 |
-
The
|
26 |
-
The AI
|
27 |
-
|
28 |
-
Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey
|
29 |
|
30 |
Let's think step by step.
|
31 |
-
If the human messages are unrelated to vegan recipes, remind them of your purpose to
|
32 |
-
|
33 |
),
|
34 |
AIMessagePromptTemplate.from_template(
|
35 |
"What ingredients do you wish to cook with?"
|
@@ -43,30 +42,12 @@ If the human messages are unrelated to vegan recipes, remind them of your purpos
|
|
43 |
"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?"
|
44 |
),
|
45 |
HumanMessagePromptTemplate.from_template(
|
46 |
-
"""
|
47 |
-
|
48 |
-
If there are only a few ingredients, please add more as necessary to provide a known tastier vegan recipe.
|
49 |
-
Respect the user's allergies (if any).
|
50 |
-
Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:
|
51 |
|
52 |
###
|
53 |
Preferences: {recipe_freeform_input}
|
54 |
-
###
|
55 |
-
|
56 |
-
Output format:
|
57 |
-
|
58 |
-
**Vegan recipe name**
|
59 |
-
Preparation time (humanized)
|
60 |
-
|
61 |
-
Ingredients (List of ingredients with quantities):
|
62 |
-
- <quantity and unit> <ingredient>
|
63 |
-
|
64 |
-
Steps (detailed):
|
65 |
-
1.
|
66 |
-
2.
|
67 |
-
3.
|
68 |
-
...
|
69 |
-
""".strip()
|
70 |
),
|
71 |
]
|
72 |
)
|
|
|
21 |
INIT_PROMPT = ChatPromptTemplate.from_messages(
|
22 |
[
|
23 |
SystemMessagePromptTemplate.from_template(
|
24 |
+
"""The following is a conversation between a human and a friendly AI chef.
|
25 |
+
The AI is compassionate to animals.
|
26 |
+
The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.
|
27 |
+
Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.
|
|
|
28 |
|
29 |
Let's think step by step.
|
30 |
+
If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.
|
31 |
+
Only generate keyword queries as other tools should be used to fetch full recipes."""
|
32 |
),
|
33 |
AIMessagePromptTemplate.from_template(
|
34 |
"What ingredients do you wish to cook with?"
|
|
|
42 |
"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?"
|
43 |
),
|
44 |
HumanMessagePromptTemplate.from_template(
|
45 |
+
"""Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).
|
46 |
+
Draw some inspiration from the user's preferences delimited below if any are specified.
|
|
|
|
|
|
|
47 |
|
48 |
###
|
49 |
Preferences: {recipe_freeform_input}
|
50 |
+
###"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
),
|
52 |
]
|
53 |
)
|
lv_recipe_chatbot/lchain_tool.py
CHANGED
@@ -1,21 +1,34 @@
|
|
1 |
-
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/
|
2 |
|
3 |
# %% auto 0
|
4 |
-
__all__ = ['RecipeSerpAPIWrapper']
|
5 |
|
6 |
-
# %% ../nbs/
|
7 |
import os
|
|
|
8 |
|
9 |
-
|
10 |
-
from
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
from langchain.agents.agent_toolkits import create_python_agent
|
12 |
from langchain.chat_models import ChatOpenAI
|
|
|
|
|
13 |
from langchain.python import PythonREPL
|
|
|
|
|
14 |
from langchain.tools.python.tool import PythonREPLTool
|
15 |
from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper
|
16 |
from serpapi import GoogleSearch
|
17 |
|
18 |
-
# %% ../nbs/
|
19 |
class RecipeSerpAPIWrapper(SerpAPIWrapper):
|
20 |
@staticmethod
|
21 |
def _process_response(res: dict) -> str:
|
@@ -24,3 +37,43 @@ class RecipeSerpAPIWrapper(SerpAPIWrapper):
|
|
24 |
raise ValueError(f"Got error from SerpAPI: {res['error']}")
|
25 |
if "recipes_results" in res.keys():
|
26 |
return res["recipes_results"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_vegan_recipe_tools.ipynb.
|
2 |
|
3 |
# %% auto 0
|
4 |
+
__all__ = ['RecipeSerpAPIWrapper', 'get_vegan_recipes_edamam_api', 'vegan_recipe_edamam_search']
|
5 |
|
6 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 3
|
7 |
import os
|
8 |
+
from typing import Dict
|
9 |
|
10 |
+
import requests
|
11 |
+
from IPython.display import Image, Markdown, display
|
12 |
+
from langchain.agents import (
|
13 |
+
AgentExecutor,
|
14 |
+
AgentType,
|
15 |
+
OpenAIFunctionsAgent,
|
16 |
+
Tool,
|
17 |
+
initialize_agent,
|
18 |
+
load_tools,
|
19 |
+
)
|
20 |
from langchain.agents.agent_toolkits import create_python_agent
|
21 |
from langchain.chat_models import ChatOpenAI
|
22 |
+
from langchain.memory import ConversationBufferMemory
|
23 |
+
from langchain.prompts import MessagesPlaceholder
|
24 |
from langchain.python import PythonREPL
|
25 |
+
from langchain.schema import SystemMessage
|
26 |
+
from langchain.tools import tool
|
27 |
from langchain.tools.python.tool import PythonREPLTool
|
28 |
from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper
|
29 |
from serpapi import GoogleSearch
|
30 |
|
31 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 21
|
32 |
class RecipeSerpAPIWrapper(SerpAPIWrapper):
|
33 |
@staticmethod
|
34 |
def _process_response(res: dict) -> str:
|
|
|
37 |
raise ValueError(f"Got error from SerpAPI: {res['error']}")
|
38 |
if "recipes_results" in res.keys():
|
39 |
return res["recipes_results"]
|
40 |
+
|
41 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 48
|
42 |
+
def get_vegan_recipes_edamam_api(params: Dict) -> requests.Response:
|
43 |
+
"""
|
44 |
+
type is required and can be "any", "public", "user"
|
45 |
+
"""
|
46 |
+
if "health" in params:
|
47 |
+
params["health"].append("vegan")
|
48 |
+
else:
|
49 |
+
params["health"] = ["vegan"]
|
50 |
+
params["app_id"] = os.environ["EDAMAM_APP_ID"]
|
51 |
+
params["app_key"] = os.environ["EDAMAM_APP_KEY"]
|
52 |
+
params["type"] = "public"
|
53 |
+
return requests.get("https://api.edamam.com/api/recipes/v2", params=params)
|
54 |
+
|
55 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 55
|
56 |
+
@tool
|
57 |
+
def vegan_recipe_edamam_search(query: str) -> str:
|
58 |
+
"""
|
59 |
+
Searches for vegan recipes based on a query.
|
60 |
+
If the query is not vegan friendly, adapt it to be.
|
61 |
+
If the request fails an explanation message will be returned instead of the recipe JSON.
|
62 |
+
"""
|
63 |
+
# Veganize the query more
|
64 |
+
if "vegan" not in query.lower():
|
65 |
+
query = "vegan " + query
|
66 |
+
|
67 |
+
# TODO integrate additional params like totalTime range, cuisineType choice, nutrients[PROCNT] range of protein, health additional health params like gluten-free
|
68 |
+
|
69 |
+
params = {
|
70 |
+
"q": query,
|
71 |
+
"field": ["label", "url", "totalTime", "ingredientLines"]
|
72 |
+
# todo figure out how to include "image", "totalNutrients", "ingredientLines" without going over token limits immediately.
|
73 |
+
}
|
74 |
+
|
75 |
+
response = get_vegan_recipes_edamam_api(params)
|
76 |
+
if not response.ok:
|
77 |
+
return f"Received an error from Edamam API: {response.status_code} {response.text }"
|
78 |
+
|
79 |
+
return str([r["recipe"] for r in response.json()["hits"][0:3]])
|
lv_recipe_chatbot/vegan_recipe_tools.py
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_vegan_recipe_tools.ipynb.
|
2 |
+
|
3 |
+
# %% auto 0
|
4 |
+
__all__ = ['RecipeSerpAPIWrapper', 'get_vegan_recipes_edamam_api', 'vegan_recipe_edamam_search']
|
5 |
+
|
6 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 3
|
7 |
+
import os
|
8 |
+
from typing import Dict
|
9 |
+
|
10 |
+
import requests
|
11 |
+
from IPython.display import Image, Markdown, display
|
12 |
+
from langchain.agents import (
|
13 |
+
AgentExecutor,
|
14 |
+
AgentType,
|
15 |
+
OpenAIFunctionsAgent,
|
16 |
+
Tool,
|
17 |
+
initialize_agent,
|
18 |
+
load_tools,
|
19 |
+
)
|
20 |
+
from langchain.agents.agent_toolkits import create_python_agent
|
21 |
+
from langchain.chat_models import ChatOpenAI
|
22 |
+
from langchain.memory import ConversationBufferMemory
|
23 |
+
from langchain.prompts import MessagesPlaceholder
|
24 |
+
from langchain.python import PythonREPL
|
25 |
+
from langchain.schema import SystemMessage
|
26 |
+
from langchain.tools import tool
|
27 |
+
from langchain.tools.python.tool import PythonREPLTool
|
28 |
+
from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper
|
29 |
+
from serpapi import GoogleSearch
|
30 |
+
|
31 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 21
|
32 |
+
class RecipeSerpAPIWrapper(SerpAPIWrapper):
|
33 |
+
@staticmethod
|
34 |
+
def _process_response(res: dict) -> str:
|
35 |
+
"""Process response from SerpAPI."""
|
36 |
+
if "error" in res.keys():
|
37 |
+
raise ValueError(f"Got error from SerpAPI: {res['error']}")
|
38 |
+
if "recipes_results" in res.keys():
|
39 |
+
return res["recipes_results"]
|
40 |
+
|
41 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 48
|
42 |
+
def get_vegan_recipes_edamam_api(params: Dict) -> requests.Response:
|
43 |
+
"""
|
44 |
+
type is required and can be "any", "public", "user"
|
45 |
+
"""
|
46 |
+
if "health" in params:
|
47 |
+
params["health"].append("vegan")
|
48 |
+
else:
|
49 |
+
params["health"] = ["vegan"]
|
50 |
+
params["app_id"] = os.environ["EDAMAM_APP_ID"]
|
51 |
+
params["app_key"] = os.environ["EDAMAM_APP_KEY"]
|
52 |
+
params["type"] = "public"
|
53 |
+
return requests.get("https://api.edamam.com/api/recipes/v2", params=params)
|
54 |
+
|
55 |
+
# %% ../nbs/02_vegan_recipe_tools.ipynb 55
|
56 |
+
@tool
|
57 |
+
def vegan_recipe_edamam_search(query: str) -> str:
|
58 |
+
"""
|
59 |
+
Searches for vegan recipes based on a query.
|
60 |
+
If the query is not vegan friendly, adapt it to be.
|
61 |
+
If the request fails an explanation message will be returned instead of the recipe JSON.
|
62 |
+
"""
|
63 |
+
# Veganize the query more
|
64 |
+
if "vegan" not in query.lower():
|
65 |
+
query = "vegan " + query
|
66 |
+
|
67 |
+
# TODO integrate additional params like totalTime range, cuisineType choice, nutrients[PROCNT] range of protein, health additional health params like gluten-free
|
68 |
+
|
69 |
+
params = {
|
70 |
+
"q": query,
|
71 |
+
"field": ["label", "url", "totalTime", "ingredientLines"]
|
72 |
+
# todo figure out how to include "image", "totalNutrients", "ingredientLines" without going over token limits immediately.
|
73 |
+
}
|
74 |
+
|
75 |
+
response = get_vegan_recipes_edamam_api(params)
|
76 |
+
if not response.ok:
|
77 |
+
return f"Received an error from Edamam API: {response.status_code} {response.text }"
|
78 |
+
|
79 |
+
return str([r["recipe"] for r in response.json()["hits"][0:3]])
|
nbs/.last_checked
ADDED
File without changes
|
nbs/00_engineer_prompt.ipynb
CHANGED
@@ -98,12 +98,12 @@
|
|
98 |
" SystemMessagePromptTemplate.from_template(\n",
|
99 |
" \"\"\"The following is a conversation between a human and a friendly AI chef. \n",
|
100 |
"The AI is compassionate to animals.\n",
|
101 |
-
"The AI generates a vegan recipe
|
102 |
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
103 |
"\n",
|
104 |
"Let's think step by step.\n",
|
105 |
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
106 |
-
"Only generate
|
107 |
" ),\n",
|
108 |
" AIMessagePromptTemplate.from_template(\n",
|
109 |
" \"What ingredients do you wish to cook with?\"\n",
|
@@ -117,14 +117,12 @@
|
|
117 |
" \"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\"\n",
|
118 |
" ),\n",
|
119 |
" HumanMessagePromptTemplate.from_template(\n",
|
120 |
-
" \"\"\"
|
121 |
-
"
|
122 |
"\n",
|
123 |
"###\n",
|
124 |
"Preferences: {recipe_freeform_input}\n",
|
125 |
-
"###\n",
|
126 |
-
"\n",
|
127 |
-
"\"\"\"\n",
|
128 |
" ),\n",
|
129 |
" ]\n",
|
130 |
")"
|
@@ -152,26 +150,24 @@
|
|
152 |
"Prompt after formatting:\n",
|
153 |
"\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
|
154 |
"The AI is compassionate to animals.\n",
|
155 |
-
"The AI generates a vegan recipe
|
156 |
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
157 |
"\n",
|
158 |
"Let's think step by step.\n",
|
159 |
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
160 |
-
"Only generate
|
161 |
"AI: What ingredients do you wish to cook with?\n",
|
162 |
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
163 |
"AI: Do you have any allergies I should be aware of?\n",
|
164 |
"Human: Allergies: \n",
|
165 |
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
166 |
-
"Human:
|
167 |
-
"
|
168 |
"\n",
|
169 |
"###\n",
|
170 |
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
171 |
"###\n",
|
172 |
-
"\n",
|
173 |
-
"\n",
|
174 |
-
"AI: Based on your preferences and the provided ingredients, I have come up with a vegan recipe name: \"Thai-inspired Tofu Banh Mi\". This recipe combines the flavors of Thai cuisine with the ingredients you mentioned, including tofu, pickles, tomatoes, and bread. It's a delicious and quick vegan sandwich that can be prepared in less than 30 minutes. Enjoy!\n",
|
175 |
"Human: Recommend a different recipe please.\u001b[0m\n",
|
176 |
"\n",
|
177 |
"\u001b[1m> Finished chain.\u001b[0m\n",
|
@@ -181,32 +177,30 @@
|
|
181 |
"Prompt after formatting:\n",
|
182 |
"\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
|
183 |
"The AI is compassionate to animals.\n",
|
184 |
-
"The AI generates a vegan recipe
|
185 |
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
186 |
"\n",
|
187 |
"Let's think step by step.\n",
|
188 |
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
189 |
-
"Only generate
|
190 |
"AI: What ingredients do you wish to cook with?\n",
|
191 |
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
192 |
"AI: Do you have any allergies I should be aware of?\n",
|
193 |
"Human: Allergies: \n",
|
194 |
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
195 |
-
"Human:
|
196 |
-
"
|
197 |
"\n",
|
198 |
"###\n",
|
199 |
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
200 |
"###\n",
|
201 |
-
"\n",
|
202 |
-
"\n",
|
203 |
-
"AI: Based on your preferences and the provided ingredients, I have come up with a vegan recipe name: \"Thai-inspired Tofu Banh Mi\". This recipe combines the flavors of Thai cuisine with the ingredients you mentioned, including tofu, pickles, tomatoes, and bread. It's a delicious and quick vegan sandwich that can be prepared in less than 30 minutes. Enjoy!\n",
|
204 |
"Human: Recommend a different recipe please.\n",
|
205 |
-
"AI:
|
206 |
"Human: Aactually how about italian instead?\u001b[0m\n",
|
207 |
"\n",
|
208 |
"\u001b[1m> Finished chain.\u001b[0m\n",
|
209 |
-
"
|
210 |
]
|
211 |
}
|
212 |
],
|
|
|
98 |
" SystemMessagePromptTemplate.from_template(\n",
|
99 |
" \"\"\"The following is a conversation between a human and a friendly AI chef. \n",
|
100 |
"The AI is compassionate to animals.\n",
|
101 |
+
"The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
|
102 |
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
103 |
"\n",
|
104 |
"Let's think step by step.\n",
|
105 |
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
106 |
+
"Only generate keyword queries as other tools should be used to fetch full recipes.\"\"\"\n",
|
107 |
" ),\n",
|
108 |
" AIMessagePromptTemplate.from_template(\n",
|
109 |
" \"What ingredients do you wish to cook with?\"\n",
|
|
|
117 |
" \"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\"\n",
|
118 |
" ),\n",
|
119 |
" HumanMessagePromptTemplate.from_template(\n",
|
120 |
+
" \"\"\"Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
|
121 |
+
"Draw some inspiration from the user's preferences delimited below if any are specified.\n",
|
122 |
"\n",
|
123 |
"###\n",
|
124 |
"Preferences: {recipe_freeform_input}\n",
|
125 |
+
"###\"\"\"\n",
|
|
|
|
|
126 |
" ),\n",
|
127 |
" ]\n",
|
128 |
")"
|
|
|
150 |
"Prompt after formatting:\n",
|
151 |
"\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
|
152 |
"The AI is compassionate to animals.\n",
|
153 |
+
"The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
|
154 |
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
155 |
"\n",
|
156 |
"Let's think step by step.\n",
|
157 |
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
158 |
+
"Only generate keyword queries as other tools should be used to fetch full recipes.\n",
|
159 |
"AI: What ingredients do you wish to cook with?\n",
|
160 |
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
161 |
"AI: Do you have any allergies I should be aware of?\n",
|
162 |
"Human: Allergies: \n",
|
163 |
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
164 |
+
"Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
|
165 |
+
"Draw some inspiration from the user's preferences delimited below if any are specified.\n",
|
166 |
"\n",
|
167 |
"###\n",
|
168 |
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
169 |
"###\n",
|
170 |
+
"AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
|
|
|
|
|
171 |
"Human: Recommend a different recipe please.\u001b[0m\n",
|
172 |
"\n",
|
173 |
"\u001b[1m> Finished chain.\u001b[0m\n",
|
|
|
177 |
"Prompt after formatting:\n",
|
178 |
"\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
|
179 |
"The AI is compassionate to animals.\n",
|
180 |
+
"The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
|
181 |
"Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
|
182 |
"\n",
|
183 |
"Let's think step by step.\n",
|
184 |
"If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
|
185 |
+
"Only generate keyword queries as other tools should be used to fetch full recipes.\n",
|
186 |
"AI: What ingredients do you wish to cook with?\n",
|
187 |
"Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
|
188 |
"AI: Do you have any allergies I should be aware of?\n",
|
189 |
"Human: Allergies: \n",
|
190 |
"AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
|
191 |
+
"Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
|
192 |
+
"Draw some inspiration from the user's preferences delimited below if any are specified.\n",
|
193 |
"\n",
|
194 |
"###\n",
|
195 |
"Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
|
196 |
"###\n",
|
197 |
+
"AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
|
|
|
|
|
198 |
"Human: Recommend a different recipe please.\n",
|
199 |
+
"AI: Certainly! How about a vegan Thai peanut tofu stir-fry? It's a delicious and easy-to-make dish that incorporates some of the ingredients you mentioned. Here's a concise vegan recipe keyword query for it: \"vegan Thai peanut tofu stir-fry with tofu, bell peppers, carrots, and peanuts\". This should give you some great recipe options to explore!\n",
|
200 |
"Human: Aactually how about italian instead?\u001b[0m\n",
|
201 |
"\n",
|
202 |
"\u001b[1m> Finished chain.\u001b[0m\n",
|
203 |
+
"Of course! If you prefer an Italian-inspired vegan recipe, how about a vegan Caprese salad with marinated tofu? It's a refreshing and flavorful dish that combines tomatoes, tofu, and basil. Here's a concise vegan recipe keyword query for it: \"vegan Caprese salad with marinated tofu, tomatoes, and basil\". This should help you find some delicious Italian vegan recipes to try out!\n"
|
204 |
]
|
205 |
}
|
206 |
],
|
nbs/01_app.ipynb
CHANGED
@@ -40,9 +40,18 @@
|
|
40 |
"\n",
|
41 |
"import gradio as gr\n",
|
42 |
"from fastcore.utils import in_jupyter\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
"from langchain.chains import ConversationChain\n",
|
44 |
"from langchain.chat_models import ChatOpenAI\n",
|
45 |
-
"from langchain.memory import ConversationBufferMemory\n",
|
46 |
"from langchain.prompts.chat import (\n",
|
47 |
" ChatPromptTemplate,\n",
|
48 |
" HumanMessagePromptTemplate,\n",
|
@@ -57,9 +66,325 @@
|
|
57 |
" BlipImageCaptioning,\n",
|
58 |
" VeganIngredientFinder,\n",
|
59 |
" format_image,\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
")"
|
61 |
]
|
62 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
{
|
64 |
"cell_type": "code",
|
65 |
"execution_count": null,
|
@@ -174,36 +499,6 @@
|
|
174 |
"SAMPLE_IMG_DIR"
|
175 |
]
|
176 |
},
|
177 |
-
{
|
178 |
-
"cell_type": "code",
|
179 |
-
"execution_count": null,
|
180 |
-
"metadata": {},
|
181 |
-
"outputs": [],
|
182 |
-
"source": [
|
183 |
-
"from dotenv import load_dotenv"
|
184 |
-
]
|
185 |
-
},
|
186 |
-
{
|
187 |
-
"cell_type": "code",
|
188 |
-
"execution_count": null,
|
189 |
-
"metadata": {},
|
190 |
-
"outputs": [
|
191 |
-
{
|
192 |
-
"data": {
|
193 |
-
"text/plain": [
|
194 |
-
"True"
|
195 |
-
]
|
196 |
-
},
|
197 |
-
"execution_count": null,
|
198 |
-
"metadata": {},
|
199 |
-
"output_type": "execute_result"
|
200 |
-
}
|
201 |
-
],
|
202 |
-
"source": [
|
203 |
-
"#: eval: false\n",
|
204 |
-
"load_dotenv()"
|
205 |
-
]
|
206 |
-
},
|
207 |
{
|
208 |
"cell_type": "code",
|
209 |
"execution_count": null,
|
|
|
40 |
"\n",
|
41 |
"import gradio as gr\n",
|
42 |
"from fastcore.utils import in_jupyter\n",
|
43 |
+
"from langchain import LLMChain, OpenAI, PromptTemplate\n",
|
44 |
+
"from langchain.agents import (\n",
|
45 |
+
" AgentExecutor,\n",
|
46 |
+
" AgentType,\n",
|
47 |
+
" OpenAIFunctionsAgent,\n",
|
48 |
+
" Tool,\n",
|
49 |
+
" initialize_agent,\n",
|
50 |
+
" load_tools,\n",
|
51 |
+
")\n",
|
52 |
"from langchain.chains import ConversationChain\n",
|
53 |
"from langchain.chat_models import ChatOpenAI\n",
|
54 |
+
"from langchain.memory import ChatMessageHistory, ConversationBufferMemory\n",
|
55 |
"from langchain.prompts.chat import (\n",
|
56 |
" ChatPromptTemplate,\n",
|
57 |
" HumanMessagePromptTemplate,\n",
|
|
|
66 |
" BlipImageCaptioning,\n",
|
67 |
" VeganIngredientFinder,\n",
|
68 |
" format_image,\n",
|
69 |
+
")\n",
|
70 |
+
"from lv_recipe_chatbot.vegan_recipe_tools import vegan_recipe_edamam_search"
|
71 |
+
]
|
72 |
+
},
|
73 |
+
{
|
74 |
+
"cell_type": "code",
|
75 |
+
"execution_count": null,
|
76 |
+
"metadata": {},
|
77 |
+
"outputs": [],
|
78 |
+
"source": [
|
79 |
+
"from dotenv import load_dotenv"
|
80 |
+
]
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"cell_type": "code",
|
84 |
+
"execution_count": null,
|
85 |
+
"metadata": {},
|
86 |
+
"outputs": [
|
87 |
+
{
|
88 |
+
"data": {
|
89 |
+
"text/plain": [
|
90 |
+
"True"
|
91 |
+
]
|
92 |
+
},
|
93 |
+
"execution_count": null,
|
94 |
+
"metadata": {},
|
95 |
+
"output_type": "execute_result"
|
96 |
+
}
|
97 |
+
],
|
98 |
+
"source": [
|
99 |
+
"#: eval: false\n",
|
100 |
+
"load_dotenv()"
|
101 |
+
]
|
102 |
+
},
|
103 |
+
{
|
104 |
+
"cell_type": "markdown",
|
105 |
+
"metadata": {},
|
106 |
+
"source": [
|
107 |
+
"## Put the chat backend pieces together"
|
108 |
+
]
|
109 |
+
},
|
110 |
+
{
|
111 |
+
"cell_type": "code",
|
112 |
+
"execution_count": null,
|
113 |
+
"metadata": {},
|
114 |
+
"outputs": [
|
115 |
+
{
|
116 |
+
"data": {
|
117 |
+
"text/markdown": [
|
118 |
+
"---\n",
|
119 |
+
"\n",
|
120 |
+
"### ConversationBufferMemory\n",
|
121 |
+
"\n",
|
122 |
+
"> ConversationBufferMemory\n",
|
123 |
+
"> (chat_memory:langchain.schema.memory.BaseChatMe\n",
|
124 |
+
"> ssageHistory=None,\n",
|
125 |
+
"> output_key:Optional[str]=None,\n",
|
126 |
+
"> input_key:Optional[str]=None,\n",
|
127 |
+
"> return_messages:bool=False,\n",
|
128 |
+
"> human_prefix:str='Human', ai_prefix:str='AI',\n",
|
129 |
+
"> memory_key:str='history')\n",
|
130 |
+
"\n",
|
131 |
+
"Buffer for storing conversation memory."
|
132 |
+
],
|
133 |
+
"text/plain": [
|
134 |
+
"---\n",
|
135 |
+
"\n",
|
136 |
+
"### ConversationBufferMemory\n",
|
137 |
+
"\n",
|
138 |
+
"> ConversationBufferMemory\n",
|
139 |
+
"> (chat_memory:langchain.schema.memory.BaseChatMe\n",
|
140 |
+
"> ssageHistory=None,\n",
|
141 |
+
"> output_key:Optional[str]=None,\n",
|
142 |
+
"> input_key:Optional[str]=None,\n",
|
143 |
+
"> return_messages:bool=False,\n",
|
144 |
+
"> human_prefix:str='Human', ai_prefix:str='AI',\n",
|
145 |
+
"> memory_key:str='history')\n",
|
146 |
+
"\n",
|
147 |
+
"Buffer for storing conversation memory."
|
148 |
+
]
|
149 |
+
},
|
150 |
+
"execution_count": null,
|
151 |
+
"metadata": {},
|
152 |
+
"output_type": "execute_result"
|
153 |
+
}
|
154 |
+
],
|
155 |
+
"source": [
|
156 |
+
"show_doc(ConversationBufferMemory)"
|
157 |
+
]
|
158 |
+
},
|
159 |
+
{
|
160 |
+
"cell_type": "code",
|
161 |
+
"execution_count": null,
|
162 |
+
"metadata": {},
|
163 |
+
"outputs": [
|
164 |
+
{
|
165 |
+
"data": {
|
166 |
+
"text/markdown": [
|
167 |
+
"---\n",
|
168 |
+
"\n",
|
169 |
+
"### ChatMessageHistory\n",
|
170 |
+
"\n",
|
171 |
+
"> ChatMessageHistory\n",
|
172 |
+
"> (messages:List[langchain.schema.messages.BaseMessage]\n",
|
173 |
+
"> =[])\n",
|
174 |
+
"\n",
|
175 |
+
"In memory implementation of chat message history.\n",
|
176 |
+
"\n",
|
177 |
+
"Stores messages in an in memory list."
|
178 |
+
],
|
179 |
+
"text/plain": [
|
180 |
+
"---\n",
|
181 |
+
"\n",
|
182 |
+
"### ChatMessageHistory\n",
|
183 |
+
"\n",
|
184 |
+
"> ChatMessageHistory\n",
|
185 |
+
"> (messages:List[langchain.schema.messages.BaseMessage]\n",
|
186 |
+
"> =[])\n",
|
187 |
+
"\n",
|
188 |
+
"In memory implementation of chat message history.\n",
|
189 |
+
"\n",
|
190 |
+
"Stores messages in an in memory list."
|
191 |
+
]
|
192 |
+
},
|
193 |
+
"execution_count": null,
|
194 |
+
"metadata": {},
|
195 |
+
"output_type": "execute_result"
|
196 |
+
}
|
197 |
+
],
|
198 |
+
"source": [
|
199 |
+
"show_doc(ChatMessageHistory)"
|
200 |
+
]
|
201 |
+
},
|
202 |
+
{
|
203 |
+
"cell_type": "code",
|
204 |
+
"execution_count": null,
|
205 |
+
"metadata": {},
|
206 |
+
"outputs": [
|
207 |
+
{
|
208 |
+
"data": {
|
209 |
+
"text/markdown": [
|
210 |
+
"---\n",
|
211 |
+
"\n",
|
212 |
+
"### ChatOpenAI\n",
|
213 |
+
"\n",
|
214 |
+
"> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
|
215 |
+
"> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
|
216 |
+
"> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
|
217 |
+
"> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
|
218 |
+
"> ]=None, tags:Optional[List[str]]=None,\n",
|
219 |
+
"> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
|
220 |
+
"> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
|
221 |
+
"> model_kwargs:Dict[str,Any]=None,\n",
|
222 |
+
"> openai_api_key:Optional[str]=None,\n",
|
223 |
+
"> openai_api_base:Optional[str]=None,\n",
|
224 |
+
"> openai_organization:Optional[str]=None,\n",
|
225 |
+
"> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
|
226 |
+
"> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
|
227 |
+
"> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
|
228 |
+
"> tiktoken_model_name:Optional[str]=None)\n",
|
229 |
+
"\n",
|
230 |
+
"Wrapper around OpenAI Chat large language models.\n",
|
231 |
+
"\n",
|
232 |
+
"To use, you should have the ``openai`` python package installed, and the\n",
|
233 |
+
"environment variable ``OPENAI_API_KEY`` set with your API key.\n",
|
234 |
+
"\n",
|
235 |
+
"Any parameters that are valid to be passed to the openai.create call can be passed\n",
|
236 |
+
"in, even if not explicitly saved on this class.\n",
|
237 |
+
"\n",
|
238 |
+
"Example:\n",
|
239 |
+
" .. code-block:: python\n",
|
240 |
+
"\n",
|
241 |
+
" from langchain.chat_models import ChatOpenAI\n",
|
242 |
+
" openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
|
243 |
+
],
|
244 |
+
"text/plain": [
|
245 |
+
"---\n",
|
246 |
+
"\n",
|
247 |
+
"### ChatOpenAI\n",
|
248 |
+
"\n",
|
249 |
+
"> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
|
250 |
+
"> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
|
251 |
+
"> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
|
252 |
+
"> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
|
253 |
+
"> ]=None, tags:Optional[List[str]]=None,\n",
|
254 |
+
"> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
|
255 |
+
"> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
|
256 |
+
"> model_kwargs:Dict[str,Any]=None,\n",
|
257 |
+
"> openai_api_key:Optional[str]=None,\n",
|
258 |
+
"> openai_api_base:Optional[str]=None,\n",
|
259 |
+
"> openai_organization:Optional[str]=None,\n",
|
260 |
+
"> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
|
261 |
+
"> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
|
262 |
+
"> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
|
263 |
+
"> tiktoken_model_name:Optional[str]=None)\n",
|
264 |
+
"\n",
|
265 |
+
"Wrapper around OpenAI Chat large language models.\n",
|
266 |
+
"\n",
|
267 |
+
"To use, you should have the ``openai`` python package installed, and the\n",
|
268 |
+
"environment variable ``OPENAI_API_KEY`` set with your API key.\n",
|
269 |
+
"\n",
|
270 |
+
"Any parameters that are valid to be passed to the openai.create call can be passed\n",
|
271 |
+
"in, even if not explicitly saved on this class.\n",
|
272 |
+
"\n",
|
273 |
+
"Example:\n",
|
274 |
+
" .. code-block:: python\n",
|
275 |
+
"\n",
|
276 |
+
" from langchain.chat_models import ChatOpenAI\n",
|
277 |
+
" openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
|
278 |
+
]
|
279 |
+
},
|
280 |
+
"execution_count": null,
|
281 |
+
"metadata": {},
|
282 |
+
"output_type": "execute_result"
|
283 |
+
}
|
284 |
+
],
|
285 |
+
"source": [
|
286 |
+
"show_doc(ChatOpenAI)"
|
287 |
+
]
|
288 |
+
},
|
289 |
+
{
|
290 |
+
"cell_type": "code",
|
291 |
+
"execution_count": null,
|
292 |
+
"metadata": {},
|
293 |
+
"outputs": [],
|
294 |
+
"source": [
|
295 |
+
"#| eval: false\n",
|
296 |
+
"llm = ChatOpenAI(temperature=1)\n",
|
297 |
+
"MEMORY_KEY = \"chat_history\"\n",
|
298 |
+
"chat_msgs = INIT_PROMPT.format_prompt(\n",
|
299 |
+
" ingredients=\"tofu, brocolli\",\n",
|
300 |
+
" allergies=\"\",\n",
|
301 |
+
" recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
|
302 |
+
")\n",
|
303 |
+
"chat_msgs = chat_msgs.to_messages()\n",
|
304 |
+
"results = llm.generate([chat_msgs])\n",
|
305 |
+
"\n",
|
306 |
+
"chat_msgs.append(results.generations[0][0].message)\n",
|
307 |
+
"tools = [vegan_recipe_edamam_search]\n",
|
308 |
+
"prompt = OpenAIFunctionsAgent.create_prompt(\n",
|
309 |
+
" system_message=INIT_PROMPT.messages[0],\n",
|
310 |
+
" extra_prompt_messages=chat_msgs + [MessagesPlaceholder(variable_name=MEMORY_KEY)],\n",
|
311 |
+
")\n",
|
312 |
+
"memory = ConversationBufferMemory(\n",
|
313 |
+
" chat_memory=ChatMessageHistory(messages=chat_msgs),\n",
|
314 |
+
" return_messages=True,\n",
|
315 |
+
" memory_key=MEMORY_KEY,\n",
|
316 |
+
")\n",
|
317 |
+
"agent_executor = AgentExecutor(\n",
|
318 |
+
" agent=OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt),\n",
|
319 |
+
" tools=tools,\n",
|
320 |
+
" memory=memory,\n",
|
321 |
+
" verbose=True,\n",
|
322 |
")"
|
323 |
]
|
324 |
},
|
325 |
+
{
|
326 |
+
"cell_type": "code",
|
327 |
+
"execution_count": null,
|
328 |
+
"metadata": {},
|
329 |
+
"outputs": [],
|
330 |
+
"source": [
|
331 |
+
"# Fails for a weird query\n",
|
332 |
+
"# \"tofu, pickles, mustard, olives, tomatoes, lettuce, bell peppers, carrots, bread\""
|
333 |
+
]
|
334 |
+
},
|
335 |
+
{
|
336 |
+
"cell_type": "code",
|
337 |
+
"execution_count": null,
|
338 |
+
"metadata": {},
|
339 |
+
"outputs": [
|
340 |
+
{
|
341 |
+
"data": {
|
342 |
+
"text/plain": [
|
343 |
+
"[SystemMessage(content=\"The following is a conversation between a human and a friendly AI chef. \\nThe AI is compassionate to animals.\\nThe AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\\n\\nLet's think step by step.\\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\\nOnly generate keyword queries as other tools should be used to fetch full recipes.\", additional_kwargs={}),\n",
|
344 |
+
" AIMessage(content='What ingredients do you wish to cook with?', additional_kwargs={}, example=False),\n",
|
345 |
+
" HumanMessage(content='Ingredients: tofu, brocolli', additional_kwargs={}, example=False),\n",
|
346 |
+
" AIMessage(content='Do you have any allergies I should be aware of?', additional_kwargs={}, example=False),\n",
|
347 |
+
" HumanMessage(content='Allergies: ', additional_kwargs={}, example=False),\n",
|
348 |
+
" AIMessage(content='Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?', additional_kwargs={}, example=False),\n",
|
349 |
+
" HumanMessage(content=\"Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\\nDraw some inspiration from the user's preferences delimited below if any are specified.\\n\\n###\\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\\n###\", additional_kwargs={}, example=False),\n",
|
350 |
+
" AIMessage(content='Based on the ingredients, allergies, and preferences you provided, here is a vegan recipe keyword query suggestion: \"vegan Thai tofu broccoli stir fry recipe\"', additional_kwargs={}, example=False)]"
|
351 |
+
]
|
352 |
+
},
|
353 |
+
"execution_count": null,
|
354 |
+
"metadata": {},
|
355 |
+
"output_type": "execute_result"
|
356 |
+
}
|
357 |
+
],
|
358 |
+
"source": [
|
359 |
+
"#| eval: false\n",
|
360 |
+
"memory.chat_memory.messages"
|
361 |
+
]
|
362 |
+
},
|
363 |
+
{
|
364 |
+
"cell_type": "code",
|
365 |
+
"execution_count": null,
|
366 |
+
"metadata": {},
|
367 |
+
"outputs": [
|
368 |
+
{
|
369 |
+
"name": "stdout",
|
370 |
+
"output_type": "stream",
|
371 |
+
"text": [
|
372 |
+
"\n",
|
373 |
+
"\n",
|
374 |
+
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
375 |
+
"\u001b[32;1m\u001b[1;3m\n",
|
376 |
+
"Invoking: `vegan_recipe_edamam_search` with `{'query': 'vegan tofu broccoli'}`\n",
|
377 |
+
"\n",
|
378 |
+
"\n",
|
379 |
+
"\u001b[0m\u001b[36;1m\u001b[1;3m[{'label': 'Vegan BBQ teriyaki tofu', 'url': 'https://www.bbcgoodfood.com/recipes/teriyaki-tofu-vegan-barbecue', 'ingredientLines': ['4 tbsp low-salt soy sauce', '2 tbsp soft brown sugar', 'pinch ground ginger', '2 tbsp mirin', '3 tsp sesame oil', '350g block very firm tofu (see tip below) cut into thick slices', '½ tbsp rapeseed oil', '2 courgettes, sliced horizontally into strips', '200g Tenderstem broccoli', 'black and white sesame seeds, to serve'], 'totalTime': 25.0}, {'label': 'Vegan Crispy Stir-Fried Tofu With Broccoli Recipe', 'url': 'http://www.seriouseats.com/recipes/2014/02/vegan-experience-crispy-tofu-broccoli-stir-fry.html', 'ingredientLines': ['1 1/2 quarts vegetable or peanut oil', '1/2 cup plus 2 teaspoons cornstarch, divided', '1/2 cup all-purpose flour', '1/2 teaspoon baking powder', 'Kosher salt', '1/2 cup cold water', '1/2 cup vodka', '1 pound extra-firm tofu, cut into 1/2- by 2- by 1-inch slabs, carefully dried (see note above)', '1 pound broccoli, cut into 1-inch florets', '1/4 cup Xiaoshing wine or dry sherry', '1/4 cup homemade or store-bought low-sodium vegetable stock', '2 tablespoons soy sauce', '1 tablespoon fermented black bean sauce', '2 tablespoons sugar', '1 tablespoon toasted sesame oil', '2 (1-inch) segments lemon peel, plus 2 teaspoons lemon juice', '4 cloves garlic, minced (about 4 teaspoons)', '1 tablespoon minced or grated fresh ginger', '6 scallions, white and light green parts only, finely chopped', '2 tablespoons toasted sesame seeds, divided'], 'totalTime': 30.0}, {'label': 'Thai-Style Chopped Salad with Sriracha Tofu', 'url': 'http://www.eatingwell.com/recipe/276172/thai-style-chopped-salad-with-sriracha-tofu/', 'ingredientLines': ['1 (10 ounce) package kale, Brussels sprout, broccoli and cabbage salad mix', '1 (12 ounce) package frozen shelled edamame, thawed', '2 (7 ounce) packages Sriracha-flavored baked tofu, cubed', '1/2 cup spicy peanut vinaigrette'], 'totalTime': 10.0}]\u001b[0m"
|
380 |
+
]
|
381 |
+
}
|
382 |
+
],
|
383 |
+
"source": [
|
384 |
+
"#| eval: false\n",
|
385 |
+
"agent_executor.run(\"Search for vegan recipe\")"
|
386 |
+
]
|
387 |
+
},
|
388 |
{
|
389 |
"cell_type": "code",
|
390 |
"execution_count": null,
|
|
|
499 |
"SAMPLE_IMG_DIR"
|
500 |
]
|
501 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
{
|
503 |
"cell_type": "code",
|
504 |
"execution_count": null,
|
nbs/02_lchain_tool.ipynb
DELETED
@@ -1,962 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "markdown",
|
5 |
-
"metadata": {},
|
6 |
-
"source": [
|
7 |
-
"# lchain_tool\n",
|
8 |
-
"\n",
|
9 |
-
"> Exploring Langchain Tool capabilities"
|
10 |
-
]
|
11 |
-
},
|
12 |
-
{
|
13 |
-
"cell_type": "code",
|
14 |
-
"execution_count": null,
|
15 |
-
"metadata": {},
|
16 |
-
"outputs": [],
|
17 |
-
"source": [
|
18 |
-
"#| default_exp lchain_tool"
|
19 |
-
]
|
20 |
-
},
|
21 |
-
{
|
22 |
-
"cell_type": "code",
|
23 |
-
"execution_count": null,
|
24 |
-
"metadata": {},
|
25 |
-
"outputs": [],
|
26 |
-
"source": [
|
27 |
-
"#| hide\n",
|
28 |
-
"from nbdev.showdoc import *"
|
29 |
-
]
|
30 |
-
},
|
31 |
-
{
|
32 |
-
"cell_type": "code",
|
33 |
-
"execution_count": null,
|
34 |
-
"metadata": {},
|
35 |
-
"outputs": [],
|
36 |
-
"source": [
|
37 |
-
"#| export\n",
|
38 |
-
"import os\n",
|
39 |
-
"\n",
|
40 |
-
"from IPython.display import Image\n",
|
41 |
-
"from langchain.agents import AgentType, Tool, initialize_agent, load_tools, tool\n",
|
42 |
-
"from langchain.agents.agent_toolkits import create_python_agent\n",
|
43 |
-
"from langchain.chat_models import ChatOpenAI\n",
|
44 |
-
"from langchain.python import PythonREPL\n",
|
45 |
-
"from langchain.tools.python.tool import PythonREPLTool\n",
|
46 |
-
"from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper\n",
|
47 |
-
"from serpapi import GoogleSearch"
|
48 |
-
]
|
49 |
-
},
|
50 |
-
{
|
51 |
-
"cell_type": "code",
|
52 |
-
"execution_count": null,
|
53 |
-
"metadata": {},
|
54 |
-
"outputs": [],
|
55 |
-
"source": [
|
56 |
-
"from dotenv import load_dotenv"
|
57 |
-
]
|
58 |
-
},
|
59 |
-
{
|
60 |
-
"cell_type": "code",
|
61 |
-
"execution_count": null,
|
62 |
-
"metadata": {},
|
63 |
-
"outputs": [
|
64 |
-
{
|
65 |
-
"data": {
|
66 |
-
"text/plain": [
|
67 |
-
"True"
|
68 |
-
]
|
69 |
-
},
|
70 |
-
"execution_count": null,
|
71 |
-
"metadata": {},
|
72 |
-
"output_type": "execute_result"
|
73 |
-
}
|
74 |
-
],
|
75 |
-
"source": [
|
76 |
-
"load_dotenv()"
|
77 |
-
]
|
78 |
-
},
|
79 |
-
{
|
80 |
-
"cell_type": "code",
|
81 |
-
"execution_count": null,
|
82 |
-
"metadata": {},
|
83 |
-
"outputs": [],
|
84 |
-
"source": [
|
85 |
-
"llm = ChatOpenAI(temperature=0)"
|
86 |
-
]
|
87 |
-
},
|
88 |
-
{
|
89 |
-
"cell_type": "code",
|
90 |
-
"execution_count": null,
|
91 |
-
"metadata": {},
|
92 |
-
"outputs": [],
|
93 |
-
"source": [
|
94 |
-
"tools = load_tools([\"llm-math\"], llm=llm)\n",
|
95 |
-
"agent = initialize_agent(\n",
|
96 |
-
" tools,\n",
|
97 |
-
" llm,\n",
|
98 |
-
" agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
|
99 |
-
" handle_parsing_errors=True,\n",
|
100 |
-
" verbose=True,\n",
|
101 |
-
")"
|
102 |
-
]
|
103 |
-
},
|
104 |
-
{
|
105 |
-
"cell_type": "code",
|
106 |
-
"execution_count": null,
|
107 |
-
"metadata": {},
|
108 |
-
"outputs": [
|
109 |
-
{
|
110 |
-
"name": "stdout",
|
111 |
-
"output_type": "stream",
|
112 |
-
"text": [
|
113 |
-
"\n",
|
114 |
-
"\n",
|
115 |
-
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
116 |
-
"\u001b[32;1m\u001b[1;3mWe can calculate this using the Calculator tool.\n",
|
117 |
-
"\n",
|
118 |
-
"Action:\n",
|
119 |
-
"```\n",
|
120 |
-
"{\n",
|
121 |
-
" \"action\": \"Calculator\",\n",
|
122 |
-
" \"action_input\": \"0.03 * 300 * 30\"\n",
|
123 |
-
"}\n",
|
124 |
-
"```\n",
|
125 |
-
"\n",
|
126 |
-
"\u001b[0m\n",
|
127 |
-
"Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n",
|
128 |
-
"Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: This is the correct answer to the question.\u001b[0m\n",
|
129 |
-
"Observation: Invalid or incomplete response\n",
|
130 |
-
"Thought:\u001b[32;1m\u001b[1;3mLet me try the same action again.\n",
|
131 |
-
"\n",
|
132 |
-
"Action:\n",
|
133 |
-
"```\n",
|
134 |
-
"{\n",
|
135 |
-
" \"action\": \"Calculator\",\n",
|
136 |
-
" \"action_input\": \"0.03 * 300 * 30\"\n",
|
137 |
-
"}\n",
|
138 |
-
"```\n",
|
139 |
-
"\n",
|
140 |
-
"\u001b[0m\n",
|
141 |
-
"Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n",
|
142 |
-
"Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.\n",
|
143 |
-
"\u001b[0m\n",
|
144 |
-
"Observation: Invalid or incomplete response\n",
|
145 |
-
"Thought:\u001b[32;1m\u001b[1;3mThere seems to be an issue with the LLM response. Let me try a different way to calculate the answer.\n",
|
146 |
-
"\n",
|
147 |
-
"Action:\n",
|
148 |
-
"```\n",
|
149 |
-
"{\n",
|
150 |
-
" \"action\": \"Calculator\",\n",
|
151 |
-
" \"action_input\": \"300 * 30 * 0.03\"\n",
|
152 |
-
"}\n",
|
153 |
-
"```\n",
|
154 |
-
"\n",
|
155 |
-
"\u001b[0m\n",
|
156 |
-
"Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n",
|
157 |
-
"Thought:\u001b[32;1m\u001b[1;3mI have successfully calculated the answer to the question using the calculator tool.\n",
|
158 |
-
"\n",
|
159 |
-
"Final Answer: 270.0\u001b[0m\n",
|
160 |
-
"\n",
|
161 |
-
"\u001b[1m> Finished chain.\u001b[0m\n"
|
162 |
-
]
|
163 |
-
},
|
164 |
-
{
|
165 |
-
"data": {
|
166 |
-
"text/plain": [
|
167 |
-
"{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}"
|
168 |
-
]
|
169 |
-
},
|
170 |
-
"execution_count": null,
|
171 |
-
"metadata": {},
|
172 |
-
"output_type": "execute_result"
|
173 |
-
}
|
174 |
-
],
|
175 |
-
"source": [
|
176 |
-
"#| eval:false\n",
|
177 |
-
"agent(\"What is the 3% of of 300 * 30?\")"
|
178 |
-
]
|
179 |
-
},
|
180 |
-
{
|
181 |
-
"cell_type": "markdown",
|
182 |
-
"metadata": {},
|
183 |
-
"source": [
|
184 |
-
"[SerpAPI Google Images](https://python.langchain.com/en/latest/modules/agents/tools/examples/google_serper.html#searching-for-google-images)"
|
185 |
-
]
|
186 |
-
},
|
187 |
-
{
|
188 |
-
"cell_type": "code",
|
189 |
-
"execution_count": null,
|
190 |
-
"metadata": {},
|
191 |
-
"outputs": [
|
192 |
-
{
|
193 |
-
"data": {
|
194 |
-
"text/plain": [
|
195 |
-
"[{'title': 'Easy Tofu Pad Thai',\n",
|
196 |
-
" 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n",
|
197 |
-
" 'source': 'Minimalist Baker',\n",
|
198 |
-
" 'rating': 4.9,\n",
|
199 |
-
" 'reviews': 117,\n",
|
200 |
-
" 'total_time': '30 min',\n",
|
201 |
-
" 'ingredients': ['Pad thai rice',\n",
|
202 |
-
" 'peanut sauce',\n",
|
203 |
-
" 'thai red',\n",
|
204 |
-
" 'soy sauce',\n",
|
205 |
-
" 'bean sprouts']},\n",
|
206 |
-
" {'title': 'Vegan Pad Thai',\n",
|
207 |
-
" 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n",
|
208 |
-
" 'source': 'Nora Cooks',\n",
|
209 |
-
" 'rating': 5.0,\n",
|
210 |
-
" 'reviews': 53,\n",
|
211 |
-
" 'total_time': '30 min',\n",
|
212 |
-
" 'ingredients': ['Stir fry rice',\n",
|
213 |
-
" 'mung bean sprouts',\n",
|
214 |
-
" 'soy sauce',\n",
|
215 |
-
" 'maple syrup',\n",
|
216 |
-
" 'sriracha hot sauce']},\n",
|
217 |
-
" {'title': 'Vegan Pad Thai',\n",
|
218 |
-
" 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n",
|
219 |
-
" 'source': 'Pick Up Limes',\n",
|
220 |
-
" 'rating': 5.0,\n",
|
221 |
-
" 'reviews': 34,\n",
|
222 |
-
" 'total_time': '30 min',\n",
|
223 |
-
" 'ingredients': ['Brown rice noodles',\n",
|
224 |
-
" 'red hot',\n",
|
225 |
-
" 'soy sauce',\n",
|
226 |
-
" 'bean sprouts',\n",
|
227 |
-
" 'sriracha hot sauce']}]"
|
228 |
-
]
|
229 |
-
},
|
230 |
-
"execution_count": null,
|
231 |
-
"metadata": {},
|
232 |
-
"output_type": "execute_result"
|
233 |
-
}
|
234 |
-
],
|
235 |
-
"source": [
|
236 |
-
"#| eval: false\n",
|
237 |
-
"params = {\n",
|
238 |
-
" \"q\": \"Vegan pad thai recipes\",\n",
|
239 |
-
" \"location\": \"United States\",\n",
|
240 |
-
" \"hl\": \"en\",\n",
|
241 |
-
" \"gl\": \"us\",\n",
|
242 |
-
" \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n",
|
243 |
-
"}\n",
|
244 |
-
"\n",
|
245 |
-
"search = GoogleSearch(params)\n",
|
246 |
-
"results = search.get_dict()\n",
|
247 |
-
"recipes_results = results[\"recipes_results\"]\n",
|
248 |
-
"recipes_results"
|
249 |
-
]
|
250 |
-
},
|
251 |
-
{
|
252 |
-
"cell_type": "code",
|
253 |
-
"execution_count": null,
|
254 |
-
"metadata": {},
|
255 |
-
"outputs": [
|
256 |
-
{
|
257 |
-
"data": {
|
258 |
-
"text/markdown": [
|
259 |
-
"---\n",
|
260 |
-
"\n",
|
261 |
-
"### SerpAPIWrapper\n",
|
262 |
-
"\n",
|
263 |
-
"> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n",
|
264 |
-
"> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n",
|
265 |
-
"> serpapi_api_key:Optional[str]=None,\n",
|
266 |
-
"> aiosession:Optional[aiohttp.client.ClientSession]=None)\n",
|
267 |
-
"\n",
|
268 |
-
"Wrapper around SerpAPI.\n",
|
269 |
-
"\n",
|
270 |
-
"To use, you should have the ``google-search-results`` python package installed,\n",
|
271 |
-
"and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n",
|
272 |
-
"`serpapi_api_key` as a named parameter to the constructor.\n",
|
273 |
-
"\n",
|
274 |
-
"Example:\n",
|
275 |
-
" .. code-block:: python\n",
|
276 |
-
"\n",
|
277 |
-
" from langchain import SerpAPIWrapper\n",
|
278 |
-
" serpapi = SerpAPIWrapper()"
|
279 |
-
],
|
280 |
-
"text/plain": [
|
281 |
-
"---\n",
|
282 |
-
"\n",
|
283 |
-
"### SerpAPIWrapper\n",
|
284 |
-
"\n",
|
285 |
-
"> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n",
|
286 |
-
"> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n",
|
287 |
-
"> serpapi_api_key:Optional[str]=None,\n",
|
288 |
-
"> aiosession:Optional[aiohttp.client.ClientSession]=None)\n",
|
289 |
-
"\n",
|
290 |
-
"Wrapper around SerpAPI.\n",
|
291 |
-
"\n",
|
292 |
-
"To use, you should have the ``google-search-results`` python package installed,\n",
|
293 |
-
"and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n",
|
294 |
-
"`serpapi_api_key` as a named parameter to the constructor.\n",
|
295 |
-
"\n",
|
296 |
-
"Example:\n",
|
297 |
-
" .. code-block:: python\n",
|
298 |
-
"\n",
|
299 |
-
" from langchain import SerpAPIWrapper\n",
|
300 |
-
" serpapi = SerpAPIWrapper()"
|
301 |
-
]
|
302 |
-
},
|
303 |
-
"execution_count": null,
|
304 |
-
"metadata": {},
|
305 |
-
"output_type": "execute_result"
|
306 |
-
}
|
307 |
-
],
|
308 |
-
"source": [
|
309 |
-
"show_doc(SerpAPIWrapper)"
|
310 |
-
]
|
311 |
-
},
|
312 |
-
{
|
313 |
-
"cell_type": "code",
|
314 |
-
"execution_count": null,
|
315 |
-
"metadata": {},
|
316 |
-
"outputs": [],
|
317 |
-
"source": [
|
318 |
-
"#| export\n",
|
319 |
-
"class RecipeSerpAPIWrapper(SerpAPIWrapper):\n",
|
320 |
-
" @staticmethod\n",
|
321 |
-
" def _process_response(res: dict) -> str:\n",
|
322 |
-
" \"\"\"Process response from SerpAPI.\"\"\"\n",
|
323 |
-
" if \"error\" in res.keys():\n",
|
324 |
-
" raise ValueError(f\"Got error from SerpAPI: {res['error']}\")\n",
|
325 |
-
" if \"recipes_results\" in res.keys():\n",
|
326 |
-
" return res[\"recipes_results\"]"
|
327 |
-
]
|
328 |
-
},
|
329 |
-
{
|
330 |
-
"cell_type": "code",
|
331 |
-
"execution_count": null,
|
332 |
-
"metadata": {},
|
333 |
-
"outputs": [],
|
334 |
-
"source": [
|
335 |
-
"#| eval: false\n",
|
336 |
-
"params = {\n",
|
337 |
-
" \"location\": \"United States\",\n",
|
338 |
-
" \"hl\": \"en\",\n",
|
339 |
-
" \"gl\": \"us\",\n",
|
340 |
-
"}\n",
|
341 |
-
"search = RecipeSerpAPIWrapper(params=params)"
|
342 |
-
]
|
343 |
-
},
|
344 |
-
{
|
345 |
-
"cell_type": "code",
|
346 |
-
"execution_count": null,
|
347 |
-
"metadata": {},
|
348 |
-
"outputs": [
|
349 |
-
{
|
350 |
-
"data": {
|
351 |
-
"text/plain": [
|
352 |
-
"[{'title': 'Easy Vegan Fried Rice',\n",
|
353 |
-
" 'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',\n",
|
354 |
-
" 'source': 'Minimalist Baker',\n",
|
355 |
-
" 'rating': 4.8,\n",
|
356 |
-
" 'reviews': 457,\n",
|
357 |
-
" 'total_time': '1 hr 15 min',\n",
|
358 |
-
" 'ingredients': ['Peanut butter',\n",
|
359 |
-
" 'grain brown rice',\n",
|
360 |
-
" 'soy sauce',\n",
|
361 |
-
" 'maple syrup',\n",
|
362 |
-
" 'chili garlic sauce']},\n",
|
363 |
-
" {'title': 'The Best Vegan Fried Rice',\n",
|
364 |
-
" 'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',\n",
|
365 |
-
" 'source': 'Short Girl Tall Order',\n",
|
366 |
-
" 'rating': 4.8,\n",
|
367 |
-
" 'reviews': 65,\n",
|
368 |
-
" 'total_time': '28 min',\n",
|
369 |
-
" 'ingredients': ['Soy sauce',\n",
|
370 |
-
" 'white rice',\n",
|
371 |
-
" 'rice wine vinegar',\n",
|
372 |
-
" 'sugar',\n",
|
373 |
-
" 'fresh peas']},\n",
|
374 |
-
" {'title': 'Vegan Fried Rice',\n",
|
375 |
-
" 'link': 'https://www.noracooks.com/vegan-fried-rice/',\n",
|
376 |
-
" 'source': 'Nora Cooks',\n",
|
377 |
-
" 'rating': 5.0,\n",
|
378 |
-
" 'reviews': 15,\n",
|
379 |
-
" 'total_time': '20 min',\n",
|
380 |
-
" 'ingredients': ['Gluten free',\n",
|
381 |
-
" 'nutritional yeast',\n",
|
382 |
-
" 'toasted sesame oil',\n",
|
383 |
-
" 'carrots',\n",
|
384 |
-
" 'olive oil']}]"
|
385 |
-
]
|
386 |
-
},
|
387 |
-
"execution_count": null,
|
388 |
-
"metadata": {},
|
389 |
-
"output_type": "execute_result"
|
390 |
-
}
|
391 |
-
],
|
392 |
-
"source": [
|
393 |
-
"#| eval: false\n",
|
394 |
-
"vegan_recipes = search.run(\"Vegan fried rice recipes\")\n",
|
395 |
-
"vegan_recipes[0:3]"
|
396 |
-
]
|
397 |
-
},
|
398 |
-
{
|
399 |
-
"cell_type": "code",
|
400 |
-
"execution_count": null,
|
401 |
-
"metadata": {},
|
402 |
-
"outputs": [],
|
403 |
-
"source": [
|
404 |
-
"#| eval: false\n",
|
405 |
-
"params = {\n",
|
406 |
-
" \"engine\": \"google_images\",\n",
|
407 |
-
" \"q\": \"Vegan pad thai recipes\",\n",
|
408 |
-
" \"location\": \"United States\",\n",
|
409 |
-
" \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n",
|
410 |
-
"}\n",
|
411 |
-
"\n",
|
412 |
-
"search = GoogleSearch(params)\n",
|
413 |
-
"results = search.get_dict()"
|
414 |
-
]
|
415 |
-
},
|
416 |
-
{
|
417 |
-
"cell_type": "code",
|
418 |
-
"execution_count": null,
|
419 |
-
"metadata": {},
|
420 |
-
"outputs": [
|
421 |
-
{
|
422 |
-
"data": {
|
423 |
-
"text/plain": [
|
424 |
-
"'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'"
|
425 |
-
]
|
426 |
-
},
|
427 |
-
"metadata": {},
|
428 |
-
"output_type": "display_data"
|
429 |
-
},
|
430 |
-
{
|
431 |
-
"data": {
|
432 |
-
"text/plain": [
|
433 |
-
"'https://minimalistbaker.com/easy-tofu-pad-thai/'"
|
434 |
-
]
|
435 |
-
},
|
436 |
-
"metadata": {},
|
437 |
-
"output_type": "display_data"
|
438 |
-
},
|
439 |
-
{
|
440 |
-
"data": {
|
441 |
-
"text/html": [
|
442 |
-
"<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36a28ca4ca4a3abf6af168f575eef7bd2e8f81a12e175fcf53.jpeg\"/>"
|
443 |
-
],
|
444 |
-
"text/plain": [
|
445 |
-
"<IPython.core.display.Image object>"
|
446 |
-
]
|
447 |
-
},
|
448 |
-
"metadata": {},
|
449 |
-
"output_type": "display_data"
|
450 |
-
},
|
451 |
-
{
|
452 |
-
"data": {
|
453 |
-
"text/plain": [
|
454 |
-
"'Healthier vegan pad thai - Lazy Cat Kitchen'"
|
455 |
-
]
|
456 |
-
},
|
457 |
-
"metadata": {},
|
458 |
-
"output_type": "display_data"
|
459 |
-
},
|
460 |
-
{
|
461 |
-
"data": {
|
462 |
-
"text/plain": [
|
463 |
-
"'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/'"
|
464 |
-
]
|
465 |
-
},
|
466 |
-
"metadata": {},
|
467 |
-
"output_type": "display_data"
|
468 |
-
},
|
469 |
-
{
|
470 |
-
"data": {
|
471 |
-
"text/html": [
|
472 |
-
"<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36dee6fed89369c822a79ad529f726d1a65fdd09459c0a0b6a.jpeg\"/>"
|
473 |
-
],
|
474 |
-
"text/plain": [
|
475 |
-
"<IPython.core.display.Image object>"
|
476 |
-
]
|
477 |
-
},
|
478 |
-
"metadata": {},
|
479 |
-
"output_type": "display_data"
|
480 |
-
},
|
481 |
-
{
|
482 |
-
"data": {
|
483 |
-
"text/plain": [
|
484 |
-
"'The Best Vegan Pad Thai - Full of Plants'"
|
485 |
-
]
|
486 |
-
},
|
487 |
-
"metadata": {},
|
488 |
-
"output_type": "display_data"
|
489 |
-
},
|
490 |
-
{
|
491 |
-
"data": {
|
492 |
-
"text/plain": [
|
493 |
-
"'https://fullofplants.com/the-best-vegan-pad-thai/'"
|
494 |
-
]
|
495 |
-
},
|
496 |
-
"metadata": {},
|
497 |
-
"output_type": "display_data"
|
498 |
-
},
|
499 |
-
{
|
500 |
-
"data": {
|
501 |
-
"text/html": [
|
502 |
-
"<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd3695828a207980e4280bb4e14cdccb84ebf5350f19237416f8.jpeg\"/>"
|
503 |
-
],
|
504 |
-
"text/plain": [
|
505 |
-
"<IPython.core.display.Image object>"
|
506 |
-
]
|
507 |
-
},
|
508 |
-
"metadata": {},
|
509 |
-
"output_type": "display_data"
|
510 |
-
},
|
511 |
-
{
|
512 |
-
"data": {
|
513 |
-
"text/plain": [
|
514 |
-
"'Easy Vegan Pad Thai - Oh My Veggies'"
|
515 |
-
]
|
516 |
-
},
|
517 |
-
"metadata": {},
|
518 |
-
"output_type": "display_data"
|
519 |
-
},
|
520 |
-
{
|
521 |
-
"data": {
|
522 |
-
"text/plain": [
|
523 |
-
"'https://ohmyveggies.com/easy-vegan-pad-thai/'"
|
524 |
-
]
|
525 |
-
},
|
526 |
-
"metadata": {},
|
527 |
-
"output_type": "display_data"
|
528 |
-
},
|
529 |
-
{
|
530 |
-
"data": {
|
531 |
-
"text/html": [
|
532 |
-
"<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36885ca51553e15b434e41039ef307ecbb4869522eeeefcfa5.jpeg\"/>"
|
533 |
-
],
|
534 |
-
"text/plain": [
|
535 |
-
"<IPython.core.display.Image object>"
|
536 |
-
]
|
537 |
-
},
|
538 |
-
"metadata": {},
|
539 |
-
"output_type": "display_data"
|
540 |
-
},
|
541 |
-
{
|
542 |
-
"data": {
|
543 |
-
"text/plain": [
|
544 |
-
"'Easy Vegan Pad Thai - My Darling Vegan'"
|
545 |
-
]
|
546 |
-
},
|
547 |
-
"metadata": {},
|
548 |
-
"output_type": "display_data"
|
549 |
-
},
|
550 |
-
{
|
551 |
-
"data": {
|
552 |
-
"text/plain": [
|
553 |
-
"'https://www.mydarlingvegan.com/vegan-pad-thai/'"
|
554 |
-
]
|
555 |
-
},
|
556 |
-
"metadata": {},
|
557 |
-
"output_type": "display_data"
|
558 |
-
},
|
559 |
-
{
|
560 |
-
"data": {
|
561 |
-
"text/html": [
|
562 |
-
"<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36a554bfded8055a9df50470d25fe62e19b9de5f16e262497f.jpeg\"/>"
|
563 |
-
],
|
564 |
-
"text/plain": [
|
565 |
-
"<IPython.core.display.Image object>"
|
566 |
-
]
|
567 |
-
},
|
568 |
-
"metadata": {},
|
569 |
-
"output_type": "display_data"
|
570 |
-
}
|
571 |
-
],
|
572 |
-
"source": [
|
573 |
-
"#| eval: false\n",
|
574 |
-
"\n",
|
575 |
-
"for r in results[\"images_results\"][0:5]:\n",
|
576 |
-
" display(r[\"title\"], r[\"link\"], Image(url=r[\"thumbnail\"]))"
|
577 |
-
]
|
578 |
-
},
|
579 |
-
{
|
580 |
-
"cell_type": "code",
|
581 |
-
"execution_count": null,
|
582 |
-
"metadata": {},
|
583 |
-
"outputs": [
|
584 |
-
{
|
585 |
-
"data": {
|
586 |
-
"text/markdown": [
|
587 |
-
"---\n",
|
588 |
-
"\n",
|
589 |
-
"### load_tools\n",
|
590 |
-
"\n",
|
591 |
-
"> load_tools (tool_names:List[str],\n",
|
592 |
-
"> llm:Optional[langchain.base_language.BaseLanguageModel]=None,\n",
|
593 |
-
"> callbacks:Union[List[langchain.callbacks.base.BaseCallbackHan\n",
|
594 |
-
"> dler],langchain.callbacks.base.BaseCallbackManager,NoneType]=\n",
|
595 |
-
"> None, **kwargs:Any)\n",
|
596 |
-
"\n",
|
597 |
-
"Load tools based on their name.\n",
|
598 |
-
"\n",
|
599 |
-
"Args:\n",
|
600 |
-
" tool_names: name of tools to load.\n",
|
601 |
-
" llm: Optional language model, may be needed to initialize certain tools.\n",
|
602 |
-
" callbacks: Optional callback manager or list of callback handlers.\n",
|
603 |
-
" If not provided, default global callback manager will be used.\n",
|
604 |
-
"\n",
|
605 |
-
"Returns:\n",
|
606 |
-
" List of tools."
|
607 |
-
],
|
608 |
-
"text/plain": [
|
609 |
-
"---\n",
|
610 |
-
"\n",
|
611 |
-
"### load_tools\n",
|
612 |
-
"\n",
|
613 |
-
"> load_tools (tool_names:List[str],\n",
|
614 |
-
"> llm:Optional[langchain.base_language.BaseLanguageModel]=None,\n",
|
615 |
-
"> callbacks:Union[List[langchain.callbacks.base.BaseCallbackHan\n",
|
616 |
-
"> dler],langchain.callbacks.base.BaseCallbackManager,NoneType]=\n",
|
617 |
-
"> None, **kwargs:Any)\n",
|
618 |
-
"\n",
|
619 |
-
"Load tools based on their name.\n",
|
620 |
-
"\n",
|
621 |
-
"Args:\n",
|
622 |
-
" tool_names: name of tools to load.\n",
|
623 |
-
" llm: Optional language model, may be needed to initialize certain tools.\n",
|
624 |
-
" callbacks: Optional callback manager or list of callback handlers.\n",
|
625 |
-
" If not provided, default global callback manager will be used.\n",
|
626 |
-
"\n",
|
627 |
-
"Returns:\n",
|
628 |
-
" List of tools."
|
629 |
-
]
|
630 |
-
},
|
631 |
-
"execution_count": null,
|
632 |
-
"metadata": {},
|
633 |
-
"output_type": "execute_result"
|
634 |
-
}
|
635 |
-
],
|
636 |
-
"source": [
|
637 |
-
"show_doc(load_tools)"
|
638 |
-
]
|
639 |
-
},
|
640 |
-
{
|
641 |
-
"cell_type": "markdown",
|
642 |
-
"metadata": {},
|
643 |
-
"source": [
|
644 |
-
"Here is the SerpAPIWrapper tool implementation"
|
645 |
-
]
|
646 |
-
},
|
647 |
-
{
|
648 |
-
"cell_type": "code",
|
649 |
-
"execution_count": null,
|
650 |
-
"metadata": {},
|
651 |
-
"outputs": [],
|
652 |
-
"source": [
|
653 |
-
"from langchain.agents.load_tools import _get_serpapi"
|
654 |
-
]
|
655 |
-
},
|
656 |
-
{
|
657 |
-
"cell_type": "code",
|
658 |
-
"execution_count": null,
|
659 |
-
"metadata": {},
|
660 |
-
"outputs": [
|
661 |
-
{
|
662 |
-
"data": {
|
663 |
-
"text/plain": [
|
664 |
-
"\u001b[0;31mSignature:\u001b[0m \u001b[0m_get_serpapi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mlangchain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mBaseTool\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
665 |
-
"\u001b[0;31mDocstring:\u001b[0m <no docstring>\n",
|
666 |
-
"\u001b[0;31mSource:\u001b[0m \n",
|
667 |
-
"\u001b[0;32mdef\u001b[0m \u001b[0m_get_serpapi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mBaseTool\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n",
|
668 |
-
"\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mTool\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n",
|
669 |
-
"\u001b[0;34m\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Search\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
|
670 |
-
"\u001b[0;34m\u001b[0m \u001b[0mdescription\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
|
671 |
-
"\u001b[0;34m\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSerpAPIWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
|
672 |
-
"\u001b[0;34m\u001b[0m \u001b[0mcoroutine\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSerpAPIWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marun\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
|
673 |
-
"\u001b[0;34m\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
674 |
-
"\u001b[0;31mFile:\u001b[0m ~/AnimalEquality/lv-recipe-chatbot/env/lib/python3.10/site-packages/langchain/agents/load_tools.py\n",
|
675 |
-
"\u001b[0;31mType:\u001b[0m function"
|
676 |
-
]
|
677 |
-
},
|
678 |
-
"metadata": {},
|
679 |
-
"output_type": "display_data"
|
680 |
-
}
|
681 |
-
],
|
682 |
-
"source": [
|
683 |
-
"??_get_serpapi"
|
684 |
-
]
|
685 |
-
},
|
686 |
-
{
|
687 |
-
"cell_type": "markdown",
|
688 |
-
"metadata": {},
|
689 |
-
"source": [
|
690 |
-
"Let's use that for inspiration for our recipe version of the tool"
|
691 |
-
]
|
692 |
-
},
|
693 |
-
{
|
694 |
-
"cell_type": "code",
|
695 |
-
"execution_count": null,
|
696 |
-
"metadata": {},
|
697 |
-
"outputs": [],
|
698 |
-
"source": [
|
699 |
-
"params = {\n",
|
700 |
-
" \"location\": \"United States\",\n",
|
701 |
-
" \"hl\": \"en\",\n",
|
702 |
-
" \"gl\": \"us\",\n",
|
703 |
-
"}\n",
|
704 |
-
"search = RecipeSerpAPIWrapper(params=params)\n",
|
705 |
-
"serpapi_recipe_tool = Tool(\n",
|
706 |
-
" name=\"Vegan Recipe Search\",\n",
|
707 |
-
" description=\"A search engine. Useful for when you need to fetch existing vetted vegan recipes. Input should be a vegan recipe search query.\",\n",
|
708 |
-
" func=search.run,\n",
|
709 |
-
")"
|
710 |
-
]
|
711 |
-
},
|
712 |
-
{
|
713 |
-
"cell_type": "code",
|
714 |
-
"execution_count": null,
|
715 |
-
"metadata": {},
|
716 |
-
"outputs": [],
|
717 |
-
"source": [
|
718 |
-
"@tool\n",
|
719 |
-
"def time(text: str) -> str:\n",
|
720 |
-
" \"\"\"Returns todays date, use this for any\n",
|
721 |
-
" questions related to knowing todays date.\n",
|
722 |
-
" The input should always be an empty string,\n",
|
723 |
-
" and this function will always return todays\n",
|
724 |
-
" date - any date mathmatics should occur\n",
|
725 |
-
" outside this function.\"\"\"\n",
|
726 |
-
" return str(date.today())"
|
727 |
-
]
|
728 |
-
},
|
729 |
-
{
|
730 |
-
"cell_type": "code",
|
731 |
-
"execution_count": null,
|
732 |
-
"metadata": {},
|
733 |
-
"outputs": [],
|
734 |
-
"source": [
|
735 |
-
"agent = initialize_agent(\n",
|
736 |
-
" [time],\n",
|
737 |
-
" llm,\n",
|
738 |
-
" agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
|
739 |
-
" handle_parsing_errors=True,\n",
|
740 |
-
" verbose=True,\n",
|
741 |
-
")"
|
742 |
-
]
|
743 |
-
},
|
744 |
-
{
|
745 |
-
"cell_type": "code",
|
746 |
-
"execution_count": null,
|
747 |
-
"metadata": {},
|
748 |
-
"outputs": [],
|
749 |
-
"source": [
|
750 |
-
"@tool\n",
|
751 |
-
"def vegan_recipe_serpapi_search(text: str) -> str:\n",
|
752 |
-
" \"\"\"Returns a JSON/Python list of dictionaries of recipe data with keys in format:\n",
|
753 |
-
" ```\n",
|
754 |
-
" 'title': str,\n",
|
755 |
-
" 'link': str,\n",
|
756 |
-
" 'source': str,\n",
|
757 |
-
" 'rating': int,\n",
|
758 |
-
" 'reviews': int,\n",
|
759 |
-
" 'total_time': str,\n",
|
760 |
-
" 'ingredients': [\n",
|
761 |
-
" str,\n",
|
762 |
-
" str,\n",
|
763 |
-
" ```\n",
|
764 |
-
" The input must be the name of a vegan recipe \\\n",
|
765 |
-
" or query parameters such as ingredients to include, prep time, cuisine region. \\\n",
|
766 |
-
" Only execute the search for vegan recipes and ingredients. \\\n",
|
767 |
-
" If the SerpAPI request errors or recipes are not found, \\\n",
|
768 |
-
" an explanation message will be returned instead of the recipe JSON.\"\"\"\n",
|
769 |
-
" params = {\n",
|
770 |
-
" \"q\": text,\n",
|
771 |
-
" \"location\": \"United States\",\n",
|
772 |
-
" \"hl\": \"en\",\n",
|
773 |
-
" \"gl\": \"us\",\n",
|
774 |
-
" \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n",
|
775 |
-
" }\n",
|
776 |
-
"\n",
|
777 |
-
" search = GoogleSearch(params)\n",
|
778 |
-
" results = search.get_dict()\n",
|
779 |
-
" if \"error\" in results.keys():\n",
|
780 |
-
" return f\"Received an error from SerpAPI: {results['error']}\\n Query: {text}\"\n",
|
781 |
-
"\n",
|
782 |
-
" if \"recipes_results\" in results.keys():\n",
|
783 |
-
" return str(results[\"recipes_results\"])\n",
|
784 |
-
"\n",
|
785 |
-
" return \"No recipes found for that query\""
|
786 |
-
]
|
787 |
-
},
|
788 |
-
{
|
789 |
-
"cell_type": "markdown",
|
790 |
-
"metadata": {},
|
791 |
-
"source": [
|
792 |
-
"Create an agent with the tool"
|
793 |
-
]
|
794 |
-
},
|
795 |
-
{
|
796 |
-
"cell_type": "code",
|
797 |
-
"execution_count": null,
|
798 |
-
"metadata": {},
|
799 |
-
"outputs": [],
|
800 |
-
"source": [
|
801 |
-
"agent = initialize_agent(\n",
|
802 |
-
" tools=[vegan_recipe_serpapi_search],\n",
|
803 |
-
" llm=llm,\n",
|
804 |
-
" agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
|
805 |
-
" handle_parsing_errors=True,\n",
|
806 |
-
" verbose=True,\n",
|
807 |
-
")"
|
808 |
-
]
|
809 |
-
},
|
810 |
-
{
|
811 |
-
"cell_type": "code",
|
812 |
-
"execution_count": null,
|
813 |
-
"metadata": {},
|
814 |
-
"outputs": [
|
815 |
-
{
|
816 |
-
"name": "stdout",
|
817 |
-
"output_type": "stream",
|
818 |
-
"text": [
|
819 |
-
"\n",
|
820 |
-
"\n",
|
821 |
-
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
822 |
-
"\u001b[32;1m\u001b[1;3mThought: I can use the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes.\n",
|
823 |
-
"\n",
|
824 |
-
"Action:\n",
|
825 |
-
"```\n",
|
826 |
-
"{\n",
|
827 |
-
" \"action\": \"vegan_recipe_serpapi_search\",\n",
|
828 |
-
" \"action_input\": \"vegan pad thai\"\n",
|
829 |
-
"}\n",
|
830 |
-
"```\n",
|
831 |
-
"\n",
|
832 |
-
"\u001b[0m\n",
|
833 |
-
"Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
|
834 |
-
"Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The `vegan_recipe_serpapi_search` tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\u001b[0m\n",
|
835 |
-
"Observation: Invalid or incomplete response\n",
|
836 |
-
"Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai\".\n",
|
837 |
-
"\n",
|
838 |
-
"Action:\n",
|
839 |
-
"```\n",
|
840 |
-
"{\n",
|
841 |
-
" \"action\": \"vegan_recipe_serpapi_search\",\n",
|
842 |
-
" \"action_input\": \"vegan pad thai\"\n",
|
843 |
-
"}\n",
|
844 |
-
"```\n",
|
845 |
-
"\n",
|
846 |
-
"\n",
|
847 |
-
"\u001b[0m\n",
|
848 |
-
"Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
|
849 |
-
"Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The `vegan_recipe_serpapi_search` tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\n",
|
850 |
-
"\u001b[0m\n",
|
851 |
-
"Observation: Invalid or incomplete response\n",
|
852 |
-
"Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai recipes\".\n",
|
853 |
-
"\n",
|
854 |
-
"Action:\n",
|
855 |
-
"```\n",
|
856 |
-
"{\n",
|
857 |
-
" \"action\": \"vegan_recipe_serpapi_search\",\n",
|
858 |
-
" \"action_input\": \"vegan pad thai recipes\"\n",
|
859 |
-
"}\n",
|
860 |
-
"```\n",
|
861 |
-
"\n",
|
862 |
-
"\n",
|
863 |
-
"\u001b[0m\n",
|
864 |
-
"Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
|
865 |
-
"Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: I have successfully used the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes. The tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\n",
|
866 |
-
"\n",
|
867 |
-
"\u001b[0m\n",
|
868 |
-
"Observation: Invalid or incomplete response\n",
|
869 |
-
"Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai recipe\".\n",
|
870 |
-
"\n",
|
871 |
-
"Action:\n",
|
872 |
-
"```\n",
|
873 |
-
"{\n",
|
874 |
-
" \"action\": \"vegan_recipe_serpapi_search\",\n",
|
875 |
-
" \"action_input\": \"vegan pad thai recipe\"\n",
|
876 |
-
"}\n",
|
877 |
-
"```\n",
|
878 |
-
"\n",
|
879 |
-
"\n",
|
880 |
-
"\u001b[0m\n",
|
881 |
-
"Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
|
882 |
-
"Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: I have successfully used the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes. The tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients. \n",
|
883 |
-
"\n",
|
884 |
-
"Final Answer: Here are three vegan pad thai recipes: \n",
|
885 |
-
"1. Easy Tofu Pad Thai from Minimalist Baker\n",
|
886 |
-
"2. Vegan Pad Thai from Nora Cooks\n",
|
887 |
-
"3. Vegan Pad Thai from Pick Up Limes.\u001b[0m\n",
|
888 |
-
"\n",
|
889 |
-
"\u001b[1m> Finished chain.\u001b[0m\n"
|
890 |
-
]
|
891 |
-
},
|
892 |
-
{
|
893 |
-
"data": {
|
894 |
-
"text/plain": [
|
895 |
-
"'Here are three vegan pad thai recipes: \\n1. Easy Tofu Pad Thai from Minimalist Baker\\n2. Vegan Pad Thai from Nora Cooks\\n3. Vegan Pad Thai from Pick Up Limes.'"
|
896 |
-
]
|
897 |
-
},
|
898 |
-
"execution_count": null,
|
899 |
-
"metadata": {},
|
900 |
-
"output_type": "execute_result"
|
901 |
-
}
|
902 |
-
],
|
903 |
-
"source": [
|
904 |
-
"#| eval: false\n",
|
905 |
-
"agent.run(\"Search vegan pad thai recipes\")"
|
906 |
-
]
|
907 |
-
},
|
908 |
-
{
|
909 |
-
"cell_type": "markdown",
|
910 |
-
"metadata": {},
|
911 |
-
"source": [
|
912 |
-
"This doc should be corrected [LangChain serpapi doc could be updated](https://python.langchain.com/en/latest/modules/agents/tools/examples/serpapi.html)"
|
913 |
-
]
|
914 |
-
},
|
915 |
-
{
|
916 |
-
"cell_type": "code",
|
917 |
-
"execution_count": null,
|
918 |
-
"metadata": {},
|
919 |
-
"outputs": [],
|
920 |
-
"source": [
|
921 |
-
"#| eval: false\n",
|
922 |
-
"search = GoogleSerperAPIWrapper(type=\"search\")\n",
|
923 |
-
"results = search.results(\"Lion\")"
|
924 |
-
]
|
925 |
-
},
|
926 |
-
{
|
927 |
-
"cell_type": "markdown",
|
928 |
-
"metadata": {},
|
929 |
-
"source": [
|
930 |
-
"[edamam](https://www.edamam.com/)"
|
931 |
-
]
|
932 |
-
},
|
933 |
-
{
|
934 |
-
"cell_type": "code",
|
935 |
-
"execution_count": null,
|
936 |
-
"metadata": {},
|
937 |
-
"outputs": [],
|
938 |
-
"source": [
|
939 |
-
"#| hide\n",
|
940 |
-
"import nbdev\n",
|
941 |
-
"\n",
|
942 |
-
"nbdev.nbdev_export()"
|
943 |
-
]
|
944 |
-
},
|
945 |
-
{
|
946 |
-
"cell_type": "code",
|
947 |
-
"execution_count": null,
|
948 |
-
"metadata": {},
|
949 |
-
"outputs": [],
|
950 |
-
"source": []
|
951 |
-
}
|
952 |
-
],
|
953 |
-
"metadata": {
|
954 |
-
"kernelspec": {
|
955 |
-
"display_name": "python3",
|
956 |
-
"language": "python",
|
957 |
-
"name": "python3"
|
958 |
-
}
|
959 |
-
},
|
960 |
-
"nbformat": 4,
|
961 |
-
"nbformat_minor": 4
|
962 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nbs/02_vegan_recipe_tools.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
nbs/04_edamam_api.ipynb
DELETED
@@ -1,71 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "markdown",
|
5 |
-
"metadata": {},
|
6 |
-
"source": [
|
7 |
-
"# edamam_api\n",
|
8 |
-
"\n",
|
9 |
-
"> Tinkering with the [](Edamam API)"
|
10 |
-
]
|
11 |
-
},
|
12 |
-
{
|
13 |
-
"cell_type": "code",
|
14 |
-
"execution_count": null,
|
15 |
-
"metadata": {},
|
16 |
-
"outputs": [],
|
17 |
-
"source": [
|
18 |
-
"#| default_exp edamam_api"
|
19 |
-
]
|
20 |
-
},
|
21 |
-
{
|
22 |
-
"cell_type": "code",
|
23 |
-
"execution_count": null,
|
24 |
-
"metadata": {},
|
25 |
-
"outputs": [],
|
26 |
-
"source": [
|
27 |
-
"#| hide\n",
|
28 |
-
"from nbdev.showdoc import *"
|
29 |
-
]
|
30 |
-
},
|
31 |
-
{
|
32 |
-
"cell_type": "code",
|
33 |
-
"execution_count": null,
|
34 |
-
"metadata": {},
|
35 |
-
"outputs": [],
|
36 |
-
"source": [
|
37 |
-
"#| export\n",
|
38 |
-
"def foo():\n",
|
39 |
-
" pass"
|
40 |
-
]
|
41 |
-
},
|
42 |
-
{
|
43 |
-
"cell_type": "code",
|
44 |
-
"execution_count": null,
|
45 |
-
"metadata": {},
|
46 |
-
"outputs": [],
|
47 |
-
"source": [
|
48 |
-
"#| hide\n",
|
49 |
-
"import nbdev\n",
|
50 |
-
"\n",
|
51 |
-
"nbdev.nbdev_export()"
|
52 |
-
]
|
53 |
-
},
|
54 |
-
{
|
55 |
-
"cell_type": "code",
|
56 |
-
"execution_count": null,
|
57 |
-
"metadata": {},
|
58 |
-
"outputs": [],
|
59 |
-
"source": []
|
60 |
-
}
|
61 |
-
],
|
62 |
-
"metadata": {
|
63 |
-
"kernelspec": {
|
64 |
-
"display_name": "python3",
|
65 |
-
"language": "python",
|
66 |
-
"name": "python3"
|
67 |
-
}
|
68 |
-
},
|
69 |
-
"nbformat": 4,
|
70 |
-
"nbformat_minor": 4
|
71 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|