pocketflow/cookbook/pocketflow_demo copy.ipynb

570 lines
139 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"! pip install pocketflow\n",
"! pip install faiss-cpu\n",
"! pip install openai"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p style=\"font-family: Arial, sans-serif; font-size: 36px; font-weight: bold; color: #333; margin: 0; padding: 0;\">\n",
"Cookbook: Pocket Flow + Cursor AI\n",
"</p>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p style=\"font-family: Arial, sans-serif; font-size: 24px; font-weight: bold; color: #333; margin: 4px 0; padding: 0;\">\n",
"1. Utility Function\n",
"</p>\n",
"\n",
"<p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333;\">\n",
" Utility Functions are the <b>helper functions</b> like <i>calling an LLM, generating embeddings, or using external APIs</i>. Pocket Flow is deliberately kept minimal and does <b>NOT</b> provide any of these. \n",
"</p>\n",
"\n",
"<p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333;\">\n",
"But dont worry: you can simply ask Cursor AI to create them for you. \n",
"</p>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> Help me implement (1) `call_llm` function that takes a prompt and returns the response from the OpenAI gpt-4o model. (2) `get_embedding` function that takes a text and returns the embedding from the OpenAI text-embedding-ada-002 model. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from openai import OpenAI\n",
"import os\n",
"\n",
"def call_llm(prompt):\n",
" client = OpenAI(api_key=API_KEY)\n",
" response = client.chat.completions.create(\n",
" model=\"gpt-4o\",\n",
" messages=[{\"role\": \"user\", \"content\": prompt}]\n",
" )\n",
" return response.choices[0].message.content\n",
"\n",
"def get_embedding(text):\n",
" client = OpenAI(api_key=API_KEY)\n",
" response = client.embeddings.create(\n",
" model=\"text-embedding-ada-002\",\n",
" input=text\n",
" )\n",
" return response.data[0].embedding\n",
"\n",
"# Example usage:\n",
"response = call_llm(\"What's the meaning of life?\")\n",
"print(response)\n",
"embedding = get_embedding(\"What's the meaning of life?\")\n",
"print(embedding)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p style=\"font-family: Arial, sans-serif; font-size: 24px; font-weight: bold; color: #333; margin: 4px 0; padding: 0;\">\n",
"2. Node\n",
"</p>\n",
"\n",
" <!-- Description of a Node -->\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333;\">\n",
" A <strong>Node</strong> is your smallest unit of work with 3 steps \n",
" <code>prep-&gt;exec-&gt;post</code>:\n",
" </p>\n",
"\n",
"<!-- Ordered list of steps with spacing between lines inside each list item -->\n",
"<ol style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; margin: 20px 0; padding-left: 20px;\">\n",
"\n",
"<li style=\"margin-bottom: 16px;\">\n",
" <p style=\"margin: 0 0 8px 0;\">\n",
" <code>prep(shared)</code>\n",
" </p>\n",
" <p style=\"margin: 0 0 8px 0;\">\n",
" - Reads and preprocess data from the <strong>shared store</strong>.\n",
" </p>\n",
" <p style=\"margin: 0;\">\n",
" - E.g., load a file, query a database, or turn data into a string.\n",
" </p>\n",
"</li>\n",
"\n",
"<li style=\"margin-bottom: 16px;\">\n",
" <p style=\"margin: 0 0 8px 0;\">\n",
" <code>exec(prep_res)</code>\n",
" </p>\n",
" <p style=\"margin: 0 0 8px 0;\">\n",
" - Executes the core logic\n",
" </p>\n",
" <p style=\"margin: 0 0 8px 0;\">\n",
" - E.g., call an LLM, invoke remote APIs, or embed texts.\n",
" </p>\n",
"</li>\n",
"\n",
"<li style=\"margin-bottom: 16px;\">\n",
" <p style=\"margin: 0 0 8px 0;\">\n",
" <code>post(shared, prep_res, exec_res)</code>\n",
" </p>\n",
" <p style=\"margin: 0;\">\n",
" - Writes data back to the <strong>shared store</strong>.\n",
" </p>\n",
"</li>\n",
"\n",
"</ol>\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img\n",
" src=\"data:image/png;base64,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\"\n",
" alt=\"My Image\"\n",
" width=\"300\"\n",
"/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> Help me implement a single summarization node that reads data from the shared store, calls an LLM to summarize the text into 50 words, and writes the summary back to the shared store. Then, test it with a shared store that have pre-loaded data from `./data/PaulGrahamEssaysLarge/before.txt`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Summary: This essay highlights the counterintuitive nature of startups, emphasizing that instincts often lead to mistakes. Key advice includes trusting instincts about people, not needing deep startup knowledge, and focusing on creating products users want. Startups are all-consuming, best pursued after college, and require openness to learning and serendipity.\n"
]
}
],
"source": [
"from pocketflow import Node\n",
"\n",
"class SummarizeNode(Node):\n",
" def prep(self, shared):\n",
" # Read data from shared store\n",
" return shared[\"data\"][\"before.txt\"]\n",
" \n",
" def exec(self, text):\n",
" # Call LLM to summarize\n",
" prompt = f\"Summarize this text in 50 words:\\n\\n{text}\"\n",
" return call_llm(prompt)\n",
" \n",
" def post(self, shared, prep_res, exec_res):\n",
" # Store the summary back\n",
" shared[\"summary\"] = exec_res\n",
" # No specific next action needed\n",
" return \"default\"\n",
"\n",
"# Create test data\n",
"shared = {\n",
" \"data\": {},\n",
" \"summary\": None\n",
"}\n",
"\n",
"# Load the file\n",
"with open(\"./data/PaulGrahamEssaysLarge/before.txt\", \"r\") as f:\n",
" shared[\"data\"][\"before.txt\"] = f.read()\n",
"\n",
"# Create and run the node\n",
"summarize_node = SummarizeNode()\n",
"summarize_node.run(shared)\n",
"\n",
"# Print the result\n",
"print(\"Summary:\", shared[\"summary\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <!-- Title -->\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 24px; font-weight: bold; color: #333; \">\n",
" 3. Batch\n",
" </p>\n",
"\n",
" <!-- Description of Batch processing -->\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; margin-bottom: 16px;\">\n",
" <strong>Batch</strong> helps repeat the same work multiple items. \n",
" Instead of calling <code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">exec()</code> once, a Batch Node calls \n",
" <code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">exec()</code> \n",
" for each item in a list from <code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">prep()</code>. \n",
" </p>\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; margin-bottom: 16px;\">\n",
" Think of it as \"item-by-item\" processing:\n",
" </p>\n",
"\n",
" <!-- Bullet points -->\n",
" <ul style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; list-style-type: disc; padding-left: 20px;\">\n",
" <li style=\"margin-bottom: 16px;\">\n",
" <code>prep(shared)</code>: Return a list of items.\n",
" </li>\n",
" <li style=\"margin-bottom: 16px;\">\n",
" <code>exec(item)</code>: Called once per item.\n",
" </li>\n",
" <li style=\"margin-bottom: 16px;\">\n",
" <code>post(shared, item_list, results_list)</code>: Combines all results.\n",
" </li>\n",
" </ul>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img\n",
" src=\"data:image/png;base64,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\"\n",
" alt=\"My Image\"\n",
" width=\"150\"\n",
"/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> Help me implement a batch summarization node that reads the list of data from the shared store, calls an LLM to summarize the text into 50 words, and writes the summary back to the shared store. Then, test it with a shared store that have pre-loaded all text files from `./data/PaulGrahamEssaysLarge/`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Summaries:\n",
"\n",
"aord.txt:\n",
"The text discusses the critical concern of whether startups are \"default alive\" or \"default dead,\" meaning whether they can reach profitability with existing resources. Many founders are unaware of this status. Addressing this concern early is vital since assumptions about easy fundraising can be misleading. Over-hiring is a common pitfall, emphasizing growth over prudent scaling.\n",
"\n",
"apple.txt:\n",
"Apple's App Store approval process is harming its reputation with developers, damaging their goodwill and causing app delays. The approval system, akin to outdated software publishing, obstructs modern iterative app development. This misalignment with programmers' needs risks alienating talented potential employees and developers essential for Apple's platform success.\n",
"\n",
"avg.txt:\n",
"In 1995, Paul Graham and Robert Morris founded Viaweb, a startup enabling users to create online stores. Using Lisp for its innovative capabilities, they gained a competitive edge due to Lisp's rapid development potential. Viaweb's success highlighted Lisps power, challenging conventional language choices and showcasing unconventional advantages in business.\n",
"\n",
"before.txt:\n",
"The text advises potential startup founders to understand the counterintuitive nature of startups, emphasizing trust in instincts about people, focusing on solving user problems, and avoiding the illusion of gaming the system. It suggests gaining broad knowledge, exploring diverse interests, and delaying startup efforts until post-college to maximize potential and personal growth.\n",
"\n",
"addiction.txt:\n",
"The text discusses the accelerating process of technological progress, leading to more addictive forms of various substances and experiences. It warns that this trend will continue, making it harder to distinguish between beneficial and harmful advancements. Society must adapt by developing new customs to manage increasing addiction, while individuals need to find personal strategies to avoid negative impacts.\n"
]
}
],
"source": [
"from pocketflow import BatchNode\n",
"import os\n",
"\n",
"class BatchSummarizeNode(BatchNode):\n",
" def prep(self, shared):\n",
" # Return list of (filename, content) tuples from shared store\n",
" return [(fn, content) for fn, content in shared[\"data\"].items()]\n",
" \n",
" def exec(self, item):\n",
" # Unpack the filename and content\n",
" filename, text = item\n",
" # Call LLM to summarize\n",
" prompt = f\"Summarize this text in 50 words:\\n\\n{text}\"\n",
" summary = call_llm(prompt)\n",
" return filename, summary\n",
" \n",
" def post(self, shared, prep_res, exec_res_list):\n",
" # Store all summaries in a dict by filename\n",
" shared[\"summaries\"] = {\n",
" filename: summary \n",
" for filename, summary in exec_res_list\n",
" }\n",
" return \"default\"\n",
"\n",
"# Create test data structure\n",
"shared = {\n",
" \"data\": {},\n",
" \"summaries\": {}\n",
"}\n",
"\n",
"# Load all files from the directory\n",
"path = \"./data/PaulGrahamEssaysLarge\"\n",
"for filename in os.listdir(path):\n",
" with open(os.path.join(path, filename), \"r\") as f:\n",
" shared[\"data\"][filename] = f.read()\n",
"\n",
"# Create and run the batch node\n",
"batch_summarize = BatchSummarizeNode()\n",
"batch_summarize.run(shared)\n",
"\n",
"# Print results\n",
"print(\"Summaries:\")\n",
"for filename, summary in shared[\"summaries\"].items():\n",
" print(f\"\\n{filename}:\")\n",
" print(summary)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <!-- Title -->\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 24px; font-weight: bold; color: #333; \">\n",
" 4. Flow\n",
" </p>\n",
"\n",
" <!-- Brief description of Flow -->\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; margin: 4px 0;\">\n",
" <strong>Flow</strong> connects your Nodes to a graph.\n",
" </p>\n",
"\n",
" <!-- Unordered list of key points -->\n",
" <ul style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; list-style-type: disc; margin: 10px 0; padding-left: 20px;\">\n",
" <li style=\"margin-bottom: 8px;\">\n",
" <strong>Chaining</strong> \n",
" (<code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">node_1 &gt;&gt; node_2</code>): Break down complex problems into simple chained steps.\n",
" </li>\n",
" <li style=\"margin-bottom: 8px;\">\n",
" <strong>Directed Branching</strong> \n",
" (<code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">node_1 - \"action\" -&gt;&gt; node_2</code>): \n",
" Agentic decisions—where a Nodes \n",
" <code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">post()</code> return the action string.\n",
" </li>\n",
" <li style=\"margin-bottom: 8px;\">\n",
" <strong>Set a Start Point</strong>: Create flow by specifying \n",
" <code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">Flow(start=node_a)</code>. \n",
" Then call \n",
" <code style=\"background: #f2f2f2; padding: 2px 4px; border-radius: 3px;\">flow.run(shared)</code>.\n",
" </li>\n",
" </ul>\n",
"\n",
" <!-- Closing note -->\n",
" <p style=\"font-family: Arial, sans-serif; font-size: 16px; color: #333; margin: 0; padding: 0;\">\n",
" Thats it! You can nest Flows, branch your actions, or keep it simple with a straight chain of Nodes.\n",
" </p>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img\n",
" src=\"data:image/png;base64,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H4CoqCh9c51Rw5SqTZs2Ho9FzbtY14kQQgjf5hfTr93DQV5eHufPn/doxzU25eTJkxgMBm644QZ9c50pKCjweNyoUSOPx6L2XGyciBBCCN/kFxWZffv2af9/8uRJSktLPdoB9u7di9PppGXLlrRr107ffFWEhob6dJeeEEIIcbVpQaamZ1/UlbNnz7Jjxw7t8enTpyt03zgcDrZv3w5Ahw4dLlqRKS0tZfPmzUyePJnExETef/997Ha713B0pTp16nTJ33t2djYDBgwgMjKSyMhIoqOjZWuDyyCBUQgh/FMAPtylBLB//3727t2rPXY6nZSXl3ucc/LkSX744QcA7r//fgIDAz3aAcrKyli2bBnR0dH079+fefPmsWjRIqZMmYLVauX222/n9ddf5/jx4/qnVnDu3DkWLFhAz5496devH0lJSWzfvp2ysjKP83r37k3Dhg09jqkcDgezZ8/m4YcfZsOGDdrxU6dOkZSUxKhRo2o8zJw7d44PP/yQRx99FLPZjNlspl+/frz77rucO3dOf7oQQghx1fl819LGjRu5cOGC9rikpERbo0X166+/cvjwYRo1asSf/vQnjzaAI0eOMHz4cEaOHFnpB3Z5eTmffvopDzzwAF9//TVOp1N/CgBbtmzh/vvv54033mDnzp1kZmaSmppK7969GTRoEL/88gsAwcHBlQ70dTqdfPTRR0yfPh2AyMhIZs+ezbx587jzzjsBWLNmDd9//73umZfv119/pUePHrz55pvs3buXw4cPc/jwYTIzM5k2bRoff/xxhSAmhBBCXG0eQUa/+FV9V1hYyMaNGwEwGAza8Z9//tntrP9sTeB0OomIiKjQlXP8+HGsVitr1qzRjnXt2pV169aRm5tLbm4u69ato3fv3gAUFxczdOhQMjIy3F7lP3bt2sWwYcPIz88HIDAwkJYtW9K8eXMANmzYwNKlS3XPqigjI4O33noLALPZzPLly+nRowePPvooCxcu5I477sDpdLJnzx79Uy/L5s2b6dWrlzary2QyMXbsWObOncvChQvp3r0706dP55133tE/1af4cuVRCCGEdz5dkcnOzubHH3/EYDAwYcIEbVn1TZs2aTOXTp48qe0wbTabadasmcdrFBQUcPbsWe1xXFwcX3zxBVFRURgMBgwGA1FRUSQnJ7Nx40batGlDeXk548aN8xhkfPr0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\"\n",
" alt=\"My Image\"\n",
" width=\"350\"\n",
"/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> Help me implement a RAG chatbot that, given a users input question, finds the most relevant file based on embeddings and then answers the user's question. Test it with a shared store that has preloaded all text files from `./data/PaulGrahamEssaysLarge/`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img\n",
" src=\"data:image/png;base64,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AYIgwGg0+tx7UVEOHjyIH3/8ER07dsTKlSuxd+9eHDt2DEePHsXOnTvx6aef4t5775XzHzt2DK+++io6deqEX375RfFagSgvLw8vv/wyWrdujY4dO+L48ePqLOQlfxra52+uXbuGU6dOVbphrG3atIHBYMDAgQOh0+mQm5srBxdGoxFmsxm///67+mmV3oEDB/D111/Lj2+66SbccsstijxEai49FYF+Ud68eTP69u2LlJQUvPTSS0hJScG6devk1s1GjRqhX79++PjjjzFjxgzMmDED48aNQ/Xq1dUvVWYOHDgAAKhWrRpCQkLUh/3CtWvXFMM+atSo4ddDtSoTdXABx6TuQOq9OHfuHIYOHYpDhw7hwoULaNy4sRxgh4SEoE6dOnjiiSewYsUK7N69G2PGjMFNN90EOIKLHj16YOHChWXeinb16lWcOXNGnVwqjh49iq1btwIATpw4gdGjR+PixYvqbEQlIjWwSb3zd9xxB+Li4nDXXXfhnXfeKbOy88cff2Djxo1uG++8VVBQgJ9++glfffWVSw+l3W7H2bNnUVBQoEh3JyIiAo888ggMBgMMBgP0ej0iIiJcei9KMjzKufEtWNjtdsyaNQtnz56V06pWrYobb7xRkY9ILeh6KtypU6cOxowZgx07dmDTpk2YNGkSunfvjscffxyPP/44Bg0ahEWLFiE5ORm1a9dWP71UiaIoXxzr1auHGjVqqLP4BZvNprgp3H777X77XisrKbjIzMxEamoqtFptkb0X/lTG8/PzceHCBQDAr7/+qphboVarVi0MGTIEO3bswPjx41G9enXY7Xa8+eabWLVqlTp7qdu/fz+sVis2bNiA9957D6NHj8bo0aMxbdo0n5ZYjI2NxcMPPyw/zsrKwkcffVRmlb3KQAjyHePPnTuH7777DkePHlUfkomiiB9//BFxcXHo27ev2975vXv34urVq4o0id1ux5kzZ1wq8cWxe/du6PV6PP/883LA7KygoABff/01/vOf/yAmJgYxMTHo1q0bcnJy3J73+/fvx+DBg5GSkiKvPHT48GF0794djRs3xr333otGjRrhzTffLNb7jYiIgE6nk4OL5ORkdOnSBXBabc95eFQwn0tF2bRpE5YtW6ZOLleVtWct0Ln0VAS6G2+8UW79r169OqZNm4bt27djyJAhuPXWW9XZZffffz969epV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zopT7tXU54Inxc13Pb6cX6X1HgKJ+vtyfuypjKsrWBLpXtK2bdsSLXFI5K+k+5rzNfB61wtvrq0lUZLrcXFd77NVBPW1qjSVZsDijvq+68z5PJHy6RybNJblZ/Y5qHDHuaCUxUlUml9Iaf3opfme1MrytdVK4/cqzmt4unAV9Vznimywtpj7KynIyMnJKfJCVhzenM/elE9vXtebvP6kqPJREqXxep7KsrPi/h2r1aq4AbKcExEFjjIJKoiIiIiIqPJwu6M2ERERERFRcTGoICIiIiIinzCoICIiIiIinzCoICIqI9KiFURERMGOQQURURnJzs7G8OHD1clERERBh0EFERERERH5hEEFERERERH5hEEFERERERH5hEEFEVEZ4kRtIiKqDBhUEBGVkaioKHUSERFRUGJQQUREREREPmFQQUREREREPmFQQUREREREPmFQQUREREREPmFQQURUhrj6ExERVQYMKoiIyohGo1EnERERBSUGFURERERE5BMGFURERERE5BMGFUREZYhDoIiIqDJgUEFERERERD5hUEFEVIa4+hMREVUGDCqIiIiIiMgnDCqIiIiIiMgnDCqIiIiIiMgnDCqIiIiIiMgnDCqIiMoIJ2kTEVFlwaCCiIiIiIh8wqCCiIiIiIh8wqCCiIiIiIh8wqCCiIiIiIh8wqCCiIiIiIh8wqCCiKiM5ObmqpOIiIiCEoMKIiIiIiLyCYMKIiIiIiLyCYMKIiIiIiLyCYMKIiIiIiLyCYMKIiIiIiLyCYMKIqIyIgiCOomIiCgoMaggIiIiIiKfMKggIiIiIiKfMKggIiojzZo1Q/fu3dXJREREQSdEFEVRnUhERERERFRc7KkgIiIiIiKfMKggIiIiIiKfMKggIiIiIiKfMKggIiIiIiKfMKggIiIiIiKfMKggIiIiIiKfMKggIiIiIiKfMKggIgoQZ86cwciRIzF//nzk5eWpDxMREVUYBhVERAFi+/btWLp0KcaPH48ff/xRfZiIiKjCMKggIgoQBw8edPt/IiKiisaggogoAIiiiP3798uPDxw4oDhORERUkRhUEBEFgCtXruDEiRPqZCIiIr/AoIKIKACcOXMGR48eVScTERH5BQYVREQB4OTJkzh37pz8uH79+orjVLoEQYAgCOpkIiLygEEFEVEAuHDhAux2u/z4pptuUhyn0mU0GhEf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\"\n",
" alt=\"My Image\"\n",
" width=\"500\"\n",
"/>"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Q: how to find startup idea\n",
"A: To find a startup idea, the context advises not to make a conscious effort to think of startup ideas, as this often results in bad and plausible-sounding ideas that can waste time. Instead, it suggests turning your mind into the type that generates startup ideas unconsciously. This can be achieved by:\n",
"\n",
"1. Learning extensively about things that matter.\n",
"2. Working on problems that genuinely interest you.\n",
"3. Collaborating with people you like and respect.\n",
"\n",
"By engaging in these activities, you'll naturally start to encounter ideas that have the potential to become startups, often without initially realizing it. The essay emphasizes that many successful startups, like Apple, Yahoo, Google, and Facebook, began as side projects rather than direct pursuits to start a company.\n",
"\n",
"Source: before.txt\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/zh2408/.venv/lib/python3.9/site-packages/pocketflow/__init__.py:43: UserWarning: Flow ends: 'end' not found in ['answer', 'end']\n",
" if not nxt and curr.successors: warnings.warn(f\"Flow ends: '{action}' not found in {list(curr.successors)}\")\n"
]
}
],
"source": [
"from pocketflow import Node, Flow\n",
"import faiss\n",
"import numpy as np\n",
"import os\n",
"\n",
"class PrepareEmbeddings(Node):\n",
" def prep(self, shared):\n",
" # Get list of (filename, content) pairs\n",
" return list(shared[\"data\"].items())\n",
" \n",
" def exec(self, items):\n",
" # Create embeddings for each document\n",
" embeddings = []\n",
" filenames = []\n",
" for filename, content in items:\n",
" embedding = get_embedding(content)\n",
" embeddings.append(embedding)\n",
" filenames.append(filename)\n",
" \n",
" # Create FAISS index\n",
" dim = len(embeddings[0])\n",
" index = faiss.IndexFlatL2(dim)\n",
" index.add(np.array(embeddings).astype('float32'))\n",
" \n",
" return index, filenames\n",
" \n",
" def post(self, shared, prep_res, exec_res):\n",
" # Store index and filenames in shared store\n",
" index, filenames = exec_res\n",
" shared[\"search_index\"] = index\n",
" shared[\"filenames\"] = filenames\n",
" return \"default\"\n",
"\n",
"class FindRelevantDocument(Node):\n",
" def prep(self, shared):\n",
" # Get user question\n",
" question = input(\"Enter your question (or press Enter to quit): \")\n",
" if not question:\n",
" return None\n",
" return question\n",
" \n",
" def exec(self, question):\n",
" if question is None:\n",
" return None\n",
" \n",
" # Get question embedding and search\n",
" query_embedding = get_embedding(question)\n",
" \n",
" # Search for most similar document\n",
" D, I = shared[\"search_index\"].search(\n",
" np.array([query_embedding]).astype('float32'),\n",
" k=1\n",
" )\n",
" most_relevant_idx = I[0][0]\n",
" most_relevant_file = shared[\"filenames\"][most_relevant_idx]\n",
" \n",
" return question, most_relevant_file\n",
" \n",
" def post(self, shared, prep_res, exec_res):\n",
" if exec_res is None:\n",
" return \"end\"\n",
" \n",
" question, filename = exec_res\n",
" shared[\"current_question\"] = question\n",
" shared[\"relevant_file\"] = filename\n",
" shared[\"context\"] = shared[\"data\"][filename]\n",
" return \"answer\"\n",
" \n",
"class AnswerQuestion(Node):\n",
" def prep(self, shared):\n",
" return (\n",
" shared[\"current_question\"],\n",
" shared[\"context\"]\n",
" )\n",
" \n",
" def exec(self, inputs):\n",
" question, context = inputs\n",
" prompt = f\"\"\"\n",
"Context: {context}\n",
"\n",
"Question: {question}\n",
"\n",
"Answer the question based on the context above. If the context doesn't contain relevant information, say so.\n",
"Answer:\"\"\"\n",
" return call_llm(prompt)\n",
" \n",
" def post(self, shared, prep_res, exec_res):\n",
" print(f\"\\nQ: {shared['current_question']}\")\n",
" print(f\"A: {exec_res}\")\n",
" print(f\"\\nSource: {shared['relevant_file']}\")\n",
" return \"continue\" # Loop back for more questions\n",
"\n",
"# Create test data\n",
"shared = {\"data\": {}}\n",
"\n",
"# Load all files\n",
"path = \"./data/PaulGrahamEssaysLarge\"\n",
"for filename in os.listdir(path):\n",
" with open(os.path.join(path, filename), \"r\") as f:\n",
" shared[\"data\"][filename] = f.read()\n",
"\n",
"# Create nodes and flow\n",
"prep_embeddings = PrepareEmbeddings()\n",
"find_relevant = FindRelevantDocument()\n",
"answer = AnswerQuestion()\n",
"\n",
"# Connect nodes\n",
"prep_embeddings >> find_relevant\n",
"find_relevant - \"answer\" >> answer\n",
"find_relevant - \"end\" >> None\n",
"answer - \"continue\" >> find_relevant\n",
"\n",
"# Create and run flow\n",
"rag_flow = Flow(start=prep_embeddings)\n",
"rag_flow.run(shared)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "myvenv",
"language": "python",
"name": "myvenv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}