From 8690c0c5084e3e91a99f386ddcfd37561a8c73ad Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Sat, 9 Nov 2024 21:28:01 -0800
Subject: [PATCH 01/48] update bug report template
---
.github/ISSUE_TEMPLATE/1_bug_report.yaml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/1_bug_report.yaml b/.github/ISSUE_TEMPLATE/1_bug_report.yaml
index e15a7dc3f..3bdc75529 100644
--- a/.github/ISSUE_TEMPLATE/1_bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/1_bug_report.yaml
@@ -71,10 +71,7 @@ body:
Please provide details about your environment, including the following:
- OS (e.g., Linux, Windows, macOS)
value: |
-
- Current environment
-
-
+ - OS: [e.g., Linux, Windows, macOS]
validations:
required: false
From 22d5ebfc7c6482d8afd36688497eda555efc29e7 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Sat, 9 Nov 2024 21:30:16 -0800
Subject: [PATCH 02/48] fix integration proposal
---
.github/ISSUE_TEMPLATE/5_suggest_integration.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml b/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml
index f26eed2c2..8b2a3870c 100644
--- a/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml
+++ b/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml
@@ -1,4 +1,4 @@
-name: Feature request
+name: New integration proposal
description: Propose a new integration for this project, either db, retriever, model_client. We highly recommend you to find a POC from the provider team to work together on this.
labels: ['needs triage', 'feature']
body:
From 802c3af51d42bbad7032de725e753caacede30d1 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Sat, 9 Nov 2024 21:35:45 -0800
Subject: [PATCH 03/48] fix the issue lables and add use cases template
---
.github/ISSUE_TEMPLATE/1_bug_report.yaml | 2 +-
.../ISSUE_TEMPLATE/2_suggest_improvement.yaml | 2 +-
.github/ISSUE_TEMPLATE/3_feature_request.yaml | 2 +-
.github/ISSUE_TEMPLATE/4_documenting.yaml | 2 +-
.../ISSUE_TEMPLATE/5_suggest_integration.yaml | 2 +-
.../6_suggest_usecases_benchmarks.yaml | 32 +++++++++++++++++++
6 files changed, 37 insertions(+), 5 deletions(-)
create mode 100644 .github/ISSUE_TEMPLATE/6_suggest_usecases_benchmarks.yaml
diff --git a/.github/ISSUE_TEMPLATE/1_bug_report.yaml b/.github/ISSUE_TEMPLATE/1_bug_report.yaml
index 3bdc75529..7657b0cd9 100644
--- a/.github/ISSUE_TEMPLATE/1_bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/1_bug_report.yaml
@@ -1,6 +1,6 @@
name: Report a bug
description: Any errors that you encounter.
-labels: ['needs triage', 'bug']
+labels: ['bug']
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/2_suggest_improvement.yaml b/.github/ISSUE_TEMPLATE/2_suggest_improvement.yaml
index 68bcf055a..a9c471fde 100644
--- a/.github/ISSUE_TEMPLATE/2_suggest_improvement.yaml
+++ b/.github/ISSUE_TEMPLATE/2_suggest_improvement.yaml
@@ -1,6 +1,6 @@
name: Improvement suggestion
description: Suggest an improvement, a code refactor, or deprecation
-labels: ['needs triage', 'refactor']
+labels: ['[adalflow] improvement']
body:
- type: textarea
attributes:
diff --git a/.github/ISSUE_TEMPLATE/3_feature_request.yaml b/.github/ISSUE_TEMPLATE/3_feature_request.yaml
index 8aa0bc38e..c11f05f27 100644
--- a/.github/ISSUE_TEMPLATE/3_feature_request.yaml
+++ b/.github/ISSUE_TEMPLATE/3_feature_request.yaml
@@ -1,6 +1,6 @@
name: Feature request
description: Propose a feature for this project
-labels: ["needs triage", "feature"]
+labels: ["[adalflow] new feature request"]
body:
- type: textarea
attributes:
diff --git a/.github/ISSUE_TEMPLATE/4_documenting.yaml b/.github/ISSUE_TEMPLATE/4_documenting.yaml
index a7c6e7b77..e5b77b0a5 100644
--- a/.github/ISSUE_TEMPLATE/4_documenting.yaml
+++ b/.github/ISSUE_TEMPLATE/4_documenting.yaml
@@ -1,6 +1,6 @@
name: Typos and doc fixes
description: Tell us about how we can improve our documentation and Google colab/ipynb notebooks.
-labels: ["needs triage", "docs"]
+labels: ["documentation"]
body:
- type: textarea
attributes:
diff --git a/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml b/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml
index 8b2a3870c..819dbd6ee 100644
--- a/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml
+++ b/.github/ISSUE_TEMPLATE/5_suggest_integration.yaml
@@ -1,6 +1,6 @@
name: New integration proposal
description: Propose a new integration for this project, either db, retriever, model_client. We highly recommend you to find a POC from the provider team to work together on this.
-labels: ['needs triage', 'feature']
+labels: ['[adalflow] integration']
body:
- type: textarea
attributes:
diff --git a/.github/ISSUE_TEMPLATE/6_suggest_usecases_benchmarks.yaml b/.github/ISSUE_TEMPLATE/6_suggest_usecases_benchmarks.yaml
new file mode 100644
index 000000000..ea93a39ed
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/6_suggest_usecases_benchmarks.yaml
@@ -0,0 +1,32 @@
+name: Suggest use cases and benchmarks
+description: Propose new use cases that AdalFlow should support or benchmarks that we should compare against
+labels: ["new use cases/benchmarks"]
+body:
+ - type: textarea
+ attributes:
+ label: Description & Motivation
+ description: A clear and concise description of the new use case or benchmark proposal
+ placeholder: |
+ Please outline the motivation for the proposal.
+
+
+ - type: textarea
+ attributes:
+ label: Pitch
+ description: A clear and concise description of what you want to happen.
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Alternatives
+ description: A clear and concise description of any alternative solutions or features you've considered, if any.
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Additional context
+ description: Add any other context or screenshots about the feature request here.
+ validations:
+ required: false
From c9af641b81bdbb4fdb6e6a9f6667c3ed15a2b875 Mon Sep 17 00:00:00 2001
From: jaggik
Date: Mon, 11 Nov 2024 12:46:52 -0500
Subject: [PATCH 04/48] removed pickling section as it is currently broken.
fixed few import issues. Added pip install for Adalflow
---
tutorials/component.ipynb | 1572 +++++++++++++++++++++----------------
1 file changed, 896 insertions(+), 676 deletions(-)
diff --git a/tutorials/component.ipynb b/tutorials/component.ipynb
index 17e371a47..2e459a453 100644
--- a/tutorials/component.ipynb
+++ b/tutorials/component.ipynb
@@ -1,711 +1,931 @@
{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "import re\n",
- "from adalflow.core import Component, Generator\n",
- "from adalflow.components.model_client import OpenAIClient\n",
- "from adalflow.components.model_client import GroqAPIClient\n",
- "from adalflow.utils import setup_env # make sure you have a .env file with OPENAI_API_KEY and GROQ_API_KEY"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "template_doc = r\"\"\" You are a doctor User: {{input_str}}\"\"\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's turn on the library log to help with debugging."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
+ "cells": [
{
- "data": {
- "text/plain": [
- ""
+ "cell_type": "code",
+ "source": [
+ "from IPython.display import clear_output\n",
+ "\n",
+ "!pip install -U adalflow[openai,groq,datasets]\n",
+ "\n",
+ "clear_output()"
+ ],
+ "metadata": {
+ "id": "Ab_OmE6XTl4h"
+ },
+ "execution_count": 4,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "id": "PbAIsBeeTQUk"
+ },
+ "outputs": [],
+ "source": [
+ "import re\n",
+ "from adalflow.core import Component, Generator\n",
+ "from adalflow.components.model_client import OpenAIClient\n",
+ "from adalflow.components.model_client import GroqAPIClient\n",
+ "from adalflow.utils import setup_env # make sure you have a .env file with OPENAI_API_KEY and GROQ_API_KEY"
]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "from adalflow.utils import get_logger\n",
- "get_logger()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [],
- "source": [
- "#Toy example\n",
- "\n",
- "class DocQA(Component):\n",
- " def __init__(self):\n",
- " super(DocQA, self).__init__()\n",
- " self.doc = Generator(\n",
- " template=template_doc,\n",
- " model_client=OpenAIClient(),\n",
- " model_kwargs={\"model\": \"gpt-3.5-turbo\"},\n",
- " )\n",
- "\n",
- " def call(self, query: str) -> str:\n",
- " return self.doc(prompt_kwargs={\"input_str\": query}).data\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {},
- "outputs": [
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'type': 'DocQA', 'data': {'_components': {'_ordered_dict': True, 'data': [('doc', {'type': 'Generator', 'data': {'_components': {'_ordered_dict': True, 'data': [('prompt', {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': [], 'preset_prompt_kwargs': {}}}), ('model_client', {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, '_api_key': None}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'template': ' You are a doctor User: {{input_str}}', 'preset_prompt_kwargs': {}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'output_processors': None, '_trainable_params': []}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False}}\n"
- ]
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "kRymwpwHTQUm",
+ "outputId": "6a992f52-1661-4002-ef74-ed26938c6baa"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Please enter your OpenAI API key: ··········\n",
+ "API keys have been set.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from getpass import getpass\n",
+ "import os\n",
+ "\n",
+ "# Prompt user to enter their API keys securely\n",
+ "openai_api_key = getpass(\"Please enter your OpenAI API key: \")\n",
+ "\n",
+ "# Set environment variables\n",
+ "os.environ['OPENAI_API_KEY'] = openai_api_key\n",
+ "\n",
+ "print(\"API keys have been set.\")"
+ ]
},
{
- "data": {
- "text/plain": [
- "{'_components': OrderedDict([('doc',\n",
- " Generator(\n",
- " model_kwargs={'model': 'gpt-3.5-turbo'}, \n",
- " (prompt): Prompt(template: You are a doctor User: {{input_str}})\n",
- " (model_client): OpenAIClient()\n",
- " ))]),\n",
- " '_parameters': OrderedDict(),\n",
- " 'training': False}"
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "id": "czGDvnVUTQUm"
+ },
+ "outputs": [],
+ "source": [
+ "template_doc = r\"\"\" You are a doctor User: {{input_str}}\"\"\""
]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# states\n",
- "states = doc.to_dict()\n",
- "print(states)\n",
- "doc.__dict__"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
+ },
{
- "data": {
- "text/plain": [
- "{'_components': OrderedDict([('doc',\n",
- " Generator(\n",
- " model_kwargs={'model': 'gpt-3.5-turbo'}, \n",
- " (prompt): Prompt(template: You are a doctor User: {{input_str}})\n",
- " (model_client): OpenAIClient()\n",
- " ))]),\n",
- " '_parameters': OrderedDict(),\n",
- " 'training': False}"
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PPs3gHqeTQUn"
+ },
+ "source": [
+ "Let's turn on the library log to help with debugging."
]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# restore the states\n",
- "doc2 = DocQA.from_dict(states)\n",
- "# print(doc2.call(\"What is the capital of France?\"))\n",
- "doc2.__dict__\n",
- "# doc2.to_dict()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
+ },
{
- "data": {
- "text/plain": [
- "{'type': 'DocQA',\n",
- " 'data': {'_components': {'_ordered_dict': True,\n",
- " 'data': [('doc',\n",
- " {'type': 'Generator',\n",
- " 'data': {'_components': {'_ordered_dict': True,\n",
- " 'data': [('prompt',\n",
- " {'type': 'Prompt',\n",
- " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False,\n",
- " 'template': ' You are a doctor User: {{input_str}}',\n",
- " 'prompt_variables': [],\n",
- " 'preset_prompt_kwargs': {}}}),\n",
- " ('model_client',\n",
- " {'type': 'OpenAIClient',\n",
- " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False,\n",
- " '_api_key': None}})]},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False,\n",
- " 'template': ' You are a doctor User: {{input_str}}',\n",
- " 'preset_prompt_kwargs': {},\n",
- " 'model_kwargs': {'model': 'gpt-3.5-turbo'},\n",
- " 'output_processors': None,\n",
- " '_trainable_params': []}})]},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False}}"
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "98QNsOcSTQUn",
+ "outputId": "d63cba1b-6087-4b04-bb2b-0a9d9d4500a5"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "execution_count": 8
+ }
+ ],
+ "source": [
+ "from adalflow.utils import get_logger\n",
+ "get_logger()"
]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "doc2.to_dict() == doc.to_dict()\n",
- "doc2.to_dict()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [],
- "source": [
- "# pickle to states\n",
- "import pickle\n",
- "# from collections import OrderedDict\n",
- "# from openai import OpenAI # cant pickle this\n",
- "\n",
- "# class DummpyDocQA():\n",
- "# a = OrderedDict()\n",
- "# def __init__(self):\n",
- "# self.dummpy = 1\n",
- "# self.client = OpenAI()\n",
- "\n",
- "# doc_dummy = DummpyDocQA()\n",
- "with open(\"doc.pkl\", \"wb\") as f:\n",
- " pickle.dump(doc.to_dict(), f)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [],
- "source": [
- "# save the serialized states to a file\n",
- "from adalflow.utils.file_io import save_pickle, save_json\n",
- "states = doc.to_dict()\n",
- "# save_json(states, \"doc.json\")\n",
- "save_pickle(states, \"doc.pkl\")\n",
- "\n",
- "# load the serialized states from a file\n",
- "from adalflow.utils.file_io import load_pickle, load_json\n",
- "states_loaded = load_pickle(\"doc.pkl\")\n",
- "# states_loaded = load_json(\"doc.json\")\n",
- "\n",
- "states_loaded == states\n",
- "\n",
- "doc3 = DocQA.from_dict(states_loaded)\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2024-06-14 17:42:48 - INFO - [generator.py:199:call] - prompt_kwargs: {'input_str': 'What is the capital of France?'}\n",
- "2024-06-14 17:42:48 - INFO - [generator.py:200:call] - model_kwargs: {}\n",
- "2024-06-14 17:42:48 - WARNING - [prompt_builder.py:120:compose_prompt_kwargs] - Key input_str does not exist in the prompt_kwargs.\n",
- "2024-06-14 17:42:48 - INFO - [openai_client.py:139:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the capital of France?'}]}\n",
- "2024-06-14 17:42:48 - INFO - [_client.py:1026:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
- "2024-06-14 17:42:48 - INFO - [generator.py:208:call] - output: GeneratorOutput(data='The capital of France is Paris.', error=None, usage=None, raw_response='The capital of France is Paris.')\n"
- ]
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "id": "b3ey1lozTQUo"
+ },
+ "outputs": [],
+ "source": [
+ "#Toy example\n",
+ "\n",
+ "class DocQA(Component):\n",
+ " def __init__(self):\n",
+ " super(DocQA, self).__init__()\n",
+ " self.doc = Generator(\n",
+ " template=template_doc,\n",
+ " model_client=OpenAIClient(),\n",
+ " model_kwargs={\"model\": \"gpt-3.5-turbo\"},\n",
+ " )\n",
+ "\n",
+ " def call(self, query: str) -> str:\n",
+ " return self.doc(prompt_kwargs={\"input_str\": query}).data\n",
+ ""
+ ]
},
{
- "data": {
- "text/plain": [
- "'The capital of France is Paris.'"
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "TZAHSrbUTQUo",
+ "outputId": "66e81fb3-17f9-4570-dbbd-681cad1afc65"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-11-11 17:40:52 - prompt_builder - INFO - [prompt_builder.py:65:__init__] - Prompt has variables: ['input_str']\n",
+ "2024-11-11 17:40:52 - generator - INFO - [generator.py:144:__init__] - Generator Generator initialized.\n"
+ ]
+ }
+ ],
+ "source": [
+ "doc = DocQA()"
]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "doc3\n",
- "doc3.call(\"What is the capital of France?\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2024-06-14 17:12:51 - INFO - [generator.py:199:call] - prompt_kwargs: {'input_str': 'What is the best treatment for headache?'}\n",
- "2024-06-14 17:12:51 - INFO - [generator.py:200:call] - model_kwargs: {}\n",
- "2024-06-14 17:12:51 - INFO - [openai_client.py:140:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?'}]}\n",
- "2024-06-14 17:12:54 - INFO - [_client.py:1026:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
- "2024-06-14 17:12:54 - INFO - [generator.py:208:call] - output: GeneratorOutput(data='As a doctor, the best treatment for a headache depends on the cause of the headache. In general, some common treatments for headaches include:\\n\\n1. Over-the-counter pain relievers such as acetaminophen, ibuprofen, or aspirin\\n2. Rest and relaxation in a quiet, dark room\\n3. Hydration\\n4. Applying a cold or warm compress to the forehead or neck\\n5. Avoiding triggers such as stress, lack of sleep, or certain foods\\n6. Practicing relaxation techniques such as deep breathing, meditation, or yoga\\n7. Prescription medications for chronic or severe headaches\\n\\nIt is important to consult with a healthcare provider for a proper diagnosis and treatment plan for your specific type of headache.', error=None, usage=None, raw_response='As a doctor, the best treatment for a headache depends on the cause of the headache. In general, some common treatments for headaches include:\\n\\n1. Over-the-counter pain relievers such as acetaminophen, ibuprofen, or aspirin\\n2. Rest and relaxation in a quiet, dark room\\n3. Hydration\\n4. Applying a cold or warm compress to the forehead or neck\\n5. Avoiding triggers such as stress, lack of sleep, or certain foods\\n6. Practicing relaxation techniques such as deep breathing, meditation, or yoga\\n7. Prescription medications for chronic or severe headaches\\n\\nIt is important to consult with a healthcare provider for a proper diagnosis and treatment plan for your specific type of headache.')\n",
- "As a doctor, the best treatment for a headache depends on the cause of the headache. In general, some common treatments for headaches include:\n",
- "\n",
- "1. Over-the-counter pain relievers such as acetaminophen, ibuprofen, or aspirin\n",
- "2. Rest and relaxation in a quiet, dark room\n",
- "3. Hydration\n",
- "4. Applying a cold or warm compress to the forehead or neck\n",
- "5. Avoiding triggers such as stress, lack of sleep, or certain foods\n",
- "6. Practicing relaxation techniques such as deep breathing, meditation, or yoga\n",
- "7. Prescription medications for chronic or severe headaches\n",
- "\n",
- "It is important to consult with a healthcare provider for a proper diagnosis and treatment plan for your specific type of headache.\n"
- ]
- }
- ],
- "source": [
- "print(doc(\"What is the best treatment for headache?\"))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "f-y6l44PTQUp",
+ "outputId": "e24aabd5-d758-4700-fa0d-46b66a88c412"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "{'type': 'DocQA', 'data': {'_components': {'_ordered_dict': True, 'data': [('doc', {'type': 'Generator', 'data': {'model_str': 'OpenAIClient_gpt-3_5-turbo', 'cache_path': PosixPath('/root/.adalflow/cache_OpenAIClient_gpt-3_5-turbo.db'), 'callbacks': {'on_success': [], 'on_failure': [], 'on_complete': []}, 'cache': , '_components': {'_ordered_dict': True, 'data': [('prompt', {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Prompt', '_init_args': {'template': None, 'prompt_kwargs': {}}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': ['input_str'], 'prompt_kwargs': {}}}), ('model_client', {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Generator', '_init_args': {'model_client': None, 'model_kwargs': {}, 'template': None, 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, 'backward_engine': None, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'output_processors': None, 'mock_output': False, 'mock_output_data': 'mock data', 'data_map_func': .default_map_func at 0x7b8d471c97e0>, '_use_cache': False, '_kwargs': {'model_client': {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, '_teacher': None}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'DocQA', '_init_args': {}}}\n"
+ ]
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'_components': OrderedDict([('doc',\n",
+ " Generator(\n",
+ " model_kwargs={'model': 'gpt-3.5-turbo'}, trainable_prompt_kwargs=[]\n",
+ " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
+ " (model_client): OpenAIClient()\n",
+ " ))]),\n",
+ " '_parameters': OrderedDict(),\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'DocQA',\n",
+ " '_init_args': {}}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 12
+ }
+ ],
+ "source": [
+ "# states\n",
+ "states = doc.to_dict()\n",
+ "print(states)\n",
+ "doc.__dict__"
+ ]
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2024-06-14 17:12:54 - INFO - [generator.py:199:call] - prompt_kwargs: {'input_str': 'What is the best treatment for headache?'}\n",
- "2024-06-14 17:12:54 - INFO - [generator.py:200:call] - model_kwargs: {}\n",
- "2024-06-14 17:12:54 - INFO - [openai_client.py:140:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?'}]}\n",
- "2024-06-14 17:12:56 - INFO - [_client.py:1026:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
- "2024-06-14 17:12:56 - INFO - [generator.py:208:call] - output: GeneratorOutput(data='As a doctor, the best treatment for a headache can depend on the cause of the headache. If the headache is mild and infrequent, over-the-counter pain relievers such as ibuprofen or acetaminophen can help. Additionally, getting enough rest, staying hydrated, and practicing relaxation techniques such as deep breathing exercises or meditation can also provide relief. If the headache is severe, persistent, or accompanied by other concerning symptoms, it is important to consult a healthcare professional for a proper diagnosis and individualized treatment plan.', error=None, usage=None, raw_response='As a doctor, the best treatment for a headache can depend on the cause of the headache. If the headache is mild and infrequent, over-the-counter pain relievers such as ibuprofen or acetaminophen can help. Additionally, getting enough rest, staying hydrated, and practicing relaxation techniques such as deep breathing exercises or meditation can also provide relief. If the headache is severe, persistent, or accompanied by other concerning symptoms, it is important to consult a healthcare professional for a proper diagnosis and individualized treatment plan.')\n",
- "As a doctor, the best treatment for a headache can depend on the cause of the headache. If the headache is mild and infrequent, over-the-counter pain relievers such as ibuprofen or acetaminophen can help. Additionally, getting enough rest, staying hydrated, and practicing relaxation techniques such as deep breathing exercises or meditation can also provide relief. If the headache is severe, persistent, or accompanied by other concerning symptoms, it is important to consult a healthcare professional for a proper diagnosis and individualized treatment plan.\n"
- ]
- }
- ],
- "source": [
- "print(doc2(\"What is the best treatment for headache?\"))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "z_sH59_bTQUp"
+ },
+ "source": []
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "('', DocQA(\n",
- " (doc): Generator(\n",
- " model_kwargs={'model': 'gpt-3.5-turbo'}, \n",
- " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
- " (model_client): OpenAIClient()\n",
- " )\n",
- "))\n",
- "('doc', Generator(\n",
- " model_kwargs={'model': 'gpt-3.5-turbo'}, \n",
- " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
- " (model_client): OpenAIClient()\n",
- "))\n",
- "('doc.prompt', Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str']))\n",
- "('doc.model_client', OpenAIClient())\n"
- ]
- }
- ],
- "source": [
- "# list other subcomponents\n",
- "\n",
- "for subcomponent in doc.named_components():\n",
- " print(subcomponent)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's add a parameter"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from adalflow.core.parameter import Parameter\n",
- "\n",
- "doc.register_parameter(\"demo\", param=Parameter(data=\"demo\"))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "P81kIS2qTQUp",
+ "outputId": "d8e0e398-d704-4a85-8692-66a8c570b910"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-11-11 17:40:58 - component - INFO - [component.py:350:_restore_value] - Restoring class using from_dict Generator, {'type': 'Generator', 'data': {'model_str': 'OpenAIClient_gpt-3_5-turbo', 'cache_path': PosixPath('/root/.adalflow/cache_OpenAIClient_gpt-3_5-turbo.db'), 'callbacks': {'on_success': [], 'on_failure': [], 'on_complete': []}, 'cache': , '_components': {'_ordered_dict': True, 'data': [('prompt', {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Prompt', '_init_args': {'template': None, 'prompt_kwargs': {}}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': ['input_str'], 'prompt_kwargs': {}}}), ('model_client', {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Generator', '_init_args': {'model_client': None, 'model_kwargs': {}, 'template': None, 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, 'backward_engine': None, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'output_processors': None, 'mock_output': False, 'mock_output_data': 'mock data', 'data_map_func': .default_map_func at 0x7b8d471c97e0>, '_use_cache': False, '_kwargs': {'model_client': {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, '_teacher': None}}\n",
+ "2024-11-11 17:40:58 - component - INFO - [component.py:350:_restore_value] - Restoring class using from_dict Prompt, {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Prompt', '_init_args': {'template': None, 'prompt_kwargs': {}}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': ['input_str'], 'prompt_kwargs': {}}}\n",
+ "2024-11-11 17:40:58 - component - INFO - [component.py:350:_restore_value] - Restoring class using from_dict OpenAIClient, {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}}\n",
+ "2024-11-11 17:40:58 - component - INFO - [component.py:350:_restore_value] - Restoring class using from_dict OpenAIClient, {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}}\n"
+ ]
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'_components': OrderedDict([('doc',\n",
+ " Generator(\n",
+ " model_kwargs={'model': 'gpt-3.5-turbo'}, trainable_prompt_kwargs=[]\n",
+ " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
+ " (model_client): OpenAIClient()\n",
+ " ))]),\n",
+ " '_parameters': OrderedDict(),\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'DocQA',\n",
+ " '_init_args': {}}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 13
+ }
+ ],
+ "source": [
+ "# restore the states\n",
+ "doc2 = DocQA.from_dict(states)\n",
+ "# print(doc2.call(\"What is the capital of France?\"))\n",
+ "doc2.__dict__\n",
+ "# doc2.to_dict()"
+ ]
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "('demo', Parameter: demo)\n"
- ]
- }
- ],
- "source": [
- "# list all parameters\n",
- "for param in doc.named_parameters():\n",
- " print(param)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "198xYpLGTQUp",
+ "outputId": "ffd33d12-6db0-45c2-dfb1-3d57460ad4c9"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'type': 'DocQA',\n",
+ " 'data': {'_components': {'_ordered_dict': True,\n",
+ " 'data': [('doc',\n",
+ " {'type': 'Generator',\n",
+ " 'data': {'model_str': 'OpenAIClient_gpt-3_5-turbo',\n",
+ " 'cache_path': PosixPath('/root/.adalflow/cache_OpenAIClient_gpt-3_5-turbo.db'),\n",
+ " 'callbacks': {'on_success': [], 'on_failure': [], 'on_complete': []},\n",
+ " 'cache': ,\n",
+ " '_components': {'_ordered_dict': True,\n",
+ " 'data': [('prompt',\n",
+ " {'type': 'Prompt',\n",
+ " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'Prompt',\n",
+ " '_init_args': {'template': None, 'prompt_kwargs': {}},\n",
+ " 'template': ' You are a doctor User: {{input_str}}',\n",
+ " 'prompt_variables': ['input_str'],\n",
+ " 'prompt_kwargs': {}}}),\n",
+ " ('model_client',\n",
+ " {'type': 'OpenAIClient',\n",
+ " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'OpenAIClient',\n",
+ " '_init_args': {'api_key': None,\n",
+ " 'chat_completion_parser': None,\n",
+ " 'input_type': 'text'},\n",
+ " '_api_key': None,\n",
+ " 'chat_completion_parser': str>,\n",
+ " '_input_type': 'text'}})]},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'Generator',\n",
+ " '_init_args': {'model_client': None,\n",
+ " 'model_kwargs': {},\n",
+ " 'template': None,\n",
+ " 'prompt_kwargs': {},\n",
+ " 'output_processors': None,\n",
+ " 'name': None,\n",
+ " 'cache_path': None,\n",
+ " 'use_cache': False},\n",
+ " 'backward_engine': None,\n",
+ " 'template': ' You are a doctor User: {{input_str}}',\n",
+ " 'prompt_kwargs': {},\n",
+ " 'model_kwargs': {'model': 'gpt-3.5-turbo'},\n",
+ " 'output_processors': None,\n",
+ " 'mock_output': False,\n",
+ " 'mock_output_data': 'mock data',\n",
+ " 'data_map_func': .default_map_func(data: 'GeneratorOutputType') -> str>,\n",
+ " '_use_cache': False,\n",
+ " '_kwargs': {'model_client': {'type': 'OpenAIClient',\n",
+ " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'OpenAIClient',\n",
+ " '_init_args': {'api_key': None,\n",
+ " 'chat_completion_parser': None,\n",
+ " 'input_type': 'text'},\n",
+ " '_api_key': None,\n",
+ " 'chat_completion_parser': str>,\n",
+ " '_input_type': 'text'}},\n",
+ " 'model_kwargs': {'model': 'gpt-3.5-turbo'},\n",
+ " 'template': ' You are a doctor User: {{input_str}}',\n",
+ " 'prompt_kwargs': {},\n",
+ " 'output_processors': None,\n",
+ " 'name': None,\n",
+ " 'cache_path': None,\n",
+ " 'use_cache': False},\n",
+ " '_teacher': None}})]},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'DocQA',\n",
+ " '_init_args': {}}}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 14
+ }
+ ],
+ "source": [
+ "doc2.to_dict() == doc.to_dict()\n",
+ "doc2.to_dict()"
+ ]
+ },
{
- "data": {
- "text/plain": [
- "{'type': 'DocQA',\n",
- " 'data': {'_components': {'_ordered_dict': True,\n",
- " 'data': [('doc',\n",
- " {'type': 'Generator',\n",
- " 'data': {'_components': {'_ordered_dict': True,\n",
- " 'data': [('prompt',\n",
- " {'type': 'Prompt',\n",
- " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False,\n",
- " '_template_string': ' You are a doctor User: {{input_str}}',\n",
- " 'template': ,\n",
- " 'prompt_variables': ['input_str'],\n",
- " 'preset_prompt_kwargs': {}}}),\n",
- " ('model_client',\n",
- " {'type': 'OpenAIClient',\n",
- " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False,\n",
- " 'sync_client': ,\n",
- " 'async_client': None,\n",
- " '_api_key': None}})]},\n",
- " '_parameters': {'_ordered_dict': True, 'data': []},\n",
- " 'training': False,\n",
- " 'template': ' You are a doctor User: {{input_str}}',\n",
- " 'preset_prompt_kwargs': {},\n",
- " 'model_kwargs': {'model': 'gpt-3.5-turbo'},\n",
- " 'output_processors': None,\n",
- " '_trainable_params': []}})]},\n",
- " '_parameters': {'_ordered_dict': True,\n",
- " 'data': [('demo', {'data': 'demo', 'requires_opt': True})]},\n",
- " 'training': False}}"
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "Ulb1OWxxTQUq",
+ "outputId": "99972fcd-ed52-43b4-e461-a76c19bd9522"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-11-11 17:41:29 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?'}]}\n",
+ "2024-11-11 17:41:30 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
+ "2024-11-11 17:41:30 - generator - INFO - [generator.py:798:call] - output: GeneratorOutput(id=None, data='As a doctor, the best treatment for a headache depends on the underlying cause of the headache. In general, for tension headaches or migraines, over-the-counter pain medications such as acetaminophen, ibuprofen, or aspirin can help alleviate symptoms. It is also important to rest in a quiet, dark room and stay hydrated. If headaches are frequent or severe, it is important to consult with a healthcare provider for further evaluation and treatment options.', error=None, usage=CompletionUsage(completion_tokens=92, prompt_tokens=27, total_tokens=119), raw_response='As a doctor, the best treatment for a headache depends on the underlying cause of the headache. In general, for tension headaches or migraines, over-the-counter pain medications such as acetaminophen, ibuprofen, or aspirin can help alleviate symptoms. It is also important to rest in a quiet, dark room and stay hydrated. If headaches are frequent or severe, it is important to consult with a healthcare provider for further evaluation and treatment options.', metadata=None)\n",
+ "As a doctor, the best treatment for a headache depends on the underlying cause of the headache. In general, for tension headaches or migraines, over-the-counter pain medications such as acetaminophen, ibuprofen, or aspirin can help alleviate symptoms. It is also important to rest in a quiet, dark room and stay hydrated. If headaches are frequent or severe, it is important to consult with a healthcare provider for further evaluation and treatment options.\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(doc(\"What is the best treatment for headache?\"))"
]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "doc.to_dict()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from adalflow.utils.file_io import save_json\n",
- "\n",
- "save_json(doc.to_dict(), \"doc.json\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ },
{
- "data": {
- "text/plain": [
- "OrderedDict([('demo', Parameter: demo)])"
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "POVal8CgTQUq",
+ "outputId": "2fadb1d6-b858-4964-9045-8ea7454178e3"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-11-11 17:41:35 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?'}]}\n",
+ "2024-11-11 17:41:36 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
+ "2024-11-11 17:41:36 - generator - INFO - [generator.py:798:call] - output: GeneratorOutput(id=None, data='As a doctor, the best treatment for a headache will depend on the underlying cause of the headache. In general, over-the-counter pain medications such as acetaminophen, ibuprofen, or aspirin can help relieve mild to moderate headaches. It is also important to stay hydrated, get adequate rest, manage stress, and practice good posture. If the headache persists or is severe, it is important to see a healthcare provider for further evaluation and treatment.', error=None, usage=CompletionUsage(completion_tokens=92, prompt_tokens=27, total_tokens=119), raw_response='As a doctor, the best treatment for a headache will depend on the underlying cause of the headache. In general, over-the-counter pain medications such as acetaminophen, ibuprofen, or aspirin can help relieve mild to moderate headaches. It is also important to stay hydrated, get adequate rest, manage stress, and practice good posture. If the headache persists or is severe, it is important to see a healthcare provider for further evaluation and treatment.', metadata=None)\n",
+ "As a doctor, the best treatment for a headache will depend on the underlying cause of the headache. In general, over-the-counter pain medications such as acetaminophen, ibuprofen, or aspirin can help relieve mild to moderate headaches. It is also important to stay hydrated, get adequate rest, manage stress, and practice good posture. If the headache persists or is severe, it is important to see a healthcare provider for further evaluation and treatment.\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(doc2(\"What is the best treatment for headache?\"))"
]
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "doc.state_dict()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2024-06-14 17:12:56 - INFO - [generator.py:199:call] - prompt_kwargs: {'input_str': 'What is the best treatment for a cold?'}\n",
- "2024-06-14 17:12:56 - INFO - [generator.py:200:call] - model_kwargs: {}\n",
- "2024-06-14 17:12:56 - INFO - [openai_client.py:140:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for a cold?'}]}\n",
- "2024-06-14 17:12:57 - INFO - [_client.py:1026:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
- "2024-06-14 17:12:57 - INFO - [generator.py:208:call] - output: GeneratorOutput(data=\"As a doctor, I recommend a combination of rest, staying hydrated, over-the-counter cold medications (such as decongestants or pain relievers), throat lozenges, and steam inhalation. It's also important to eat a balanced diet, get plenty of rest, and avoid close contact with others to prevent spreading the cold. If symptoms persist or worsen, it's best to consult with a healthcare provider for further evaluation and treatment.\", error=None, usage=None, raw_response=\"As a doctor, I recommend a combination of rest, staying hydrated, over-the-counter cold medications (such as decongestants or pain relievers), throat lozenges, and steam inhalation. It's also important to eat a balanced diet, get plenty of rest, and avoid close contact with others to prevent spreading the cold. If symptoms persist or worsen, it's best to consult with a healthcare provider for further evaluation and treatment.\")\n"
- ]
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R5gTO1-8TQUr"
+ },
+ "source": []
},
{
- "data": {
- "text/plain": [
- "\"As a doctor, I recommend a combination of rest, staying hydrated, over-the-counter cold medications (such as decongestants or pain relievers), throat lozenges, and steam inhalation. It's also important to eat a balanced diet, get plenty of rest, and avoid close contact with others to prevent spreading the cold. If symptoms persist or worsen, it's best to consult with a healthcare provider for further evaluation and treatment.\""
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "jhgSpKrMTQUr",
+ "outputId": "15615bf7-2b72-4ac7-d1fe-f436a7304734"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "('', DocQA(\n",
+ " (doc): Generator(\n",
+ " model_kwargs={'model': 'gpt-3.5-turbo'}, trainable_prompt_kwargs=[]\n",
+ " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
+ " (model_client): OpenAIClient()\n",
+ " )\n",
+ "))\n",
+ "('doc', Generator(\n",
+ " model_kwargs={'model': 'gpt-3.5-turbo'}, trainable_prompt_kwargs=[]\n",
+ " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
+ " (model_client): OpenAIClient()\n",
+ "))\n",
+ "('doc.prompt', Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str']))\n",
+ "('doc.model_client', OpenAIClient())\n"
+ ]
+ }
+ ],
+ "source": [
+ "# list other subcomponents\n",
+ "\n",
+ "for subcomponent in doc.named_components():\n",
+ " print(subcomponent)"
]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "doc.call(\"What is the best treatment for a cold?\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2\n",
- "\n"
- ]
- }
- ],
- "source": [
- "from adalflow.core.component import FunComponent\n",
- "\n",
- "def add_one(x):\n",
- " return x + 1\n",
- "\n",
- "fun_component = FunComponent(add_one)\n",
- "print(fun_component(1)) \n",
- "print(type(fun_component)) \n",
- "\n",
- "# output:\n",
- "# 2\n",
- "# "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XjIHAY6bTQUr"
+ },
+ "source": [
+ "Let's add a parameter"
+ ]
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2\n",
- "\n"
- ]
- }
- ],
- "source": [
- "from adalflow.core.component import fun_to_component \n",
- "\n",
- "fun_component = fun_to_component(add_one)\n",
- "print(fun_component(1))\n",
- "print(type(fun_component))\n",
- "\n",
- "# output:\n",
- "# 2\n",
- "# "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {},
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {
+ "id": "vxgjAUiFTQUr"
+ },
+ "outputs": [],
+ "source": [
+ "from adalflow.optim.parameter import Parameter\n",
+ "\n",
+ "doc.register_parameter(\"demo\", param=Parameter(data=\"demo\"))"
+ ]
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2\n",
- "\n"
- ]
- }
- ],
- "source": [
- "# use it as a decorator\n",
- "@fun_to_component\n",
- "def add_one(x):\n",
- " return x + 1\n",
- "\n",
- "print(add_one(1))\n",
- "print(type(add_one))\n",
- "\n",
- "# output:\n",
- "# 2\n",
- "# "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "86C-h1e1TQUr",
+ "outputId": "57cab4d0-eddf-433d-e364-5d7f07072fbf"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "('demo', Parameter(name=param_313f196d-3c48-4eb3-8138-b7bd74298fbd, requires_opt=True, param_type=none (), role_desc=, data=demo, predecessors=set(), gradients=[], raw_response=None, input_args=None, traces={}))\n"
+ ]
+ }
+ ],
+ "source": [
+ "# list all parameters\n",
+ "for param in doc.named_parameters():\n",
+ " print(param)"
+ ]
+ },
{
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2024-06-14 17:12:57 - INFO - [generator.py:199:call] - prompt_kwargs: {'input_str': 'What is the best treatment for headache?Please be concise and only list the top treatments.'}\n",
- "2024-06-14 17:12:57 - INFO - [generator.py:200:call] - model_kwargs: {}\n",
- "2024-06-14 17:12:57 - INFO - [openai_client.py:140:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?Please be concise and only list the top treatments.'}]}\n",
- "2024-06-14 17:12:58 - INFO - [_client.py:1026:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
- "2024-06-14 17:12:58 - INFO - [generator.py:208:call] - output: GeneratorOutput(data='1. Over-the-counter pain relievers such as ibuprofen or acetaminophen\\n2. Stay hydrated and rest\\n3. Apply a cold compress to the forehead\\n4. Practice relaxation techniques such as deep breathing or meditation', error=None, usage=None, raw_response='1. Over-the-counter pain relievers such as ibuprofen or acetaminophen\\n2. Stay hydrated and rest\\n3. Apply a cold compress to the forehead\\n4. Practice relaxation techniques such as deep breathing or meditation')\n",
- "1. Over-the-counter pain relievers such as ibuprofen or acetaminophen\n",
- "2. Stay hydrated and rest\n",
- "3. Apply a cold compress to the forehead\n",
- "4. Practice relaxation techniques such as deep breathing or meditation\n"
- ]
- }
- ],
- "source": [
- "from adalflow.core.component import Sequential\n",
- "\n",
- "@fun_to_component\n",
- "def enhance_query(query:str) -> str:\n",
- " return query + \"Please be concise and only list the top treatments.\"\n",
- "\n",
- "seq = Sequential(enhance_query, doc)\n",
- "\n",
- "query = \"What is the best treatment for headache?\"\n",
- "print(seq(query))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# sequential with just a function, will raise error\n",
- "# def enhance_query(query:str) -> str:\n",
- "# return query + \"Please be concise and only list the top treatments.\"\n",
- "# seq2 = Sequential(enhance_query, doc)\n",
- "# print(seq2(query))\n",
- "# print(seq2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "_s2MPukiTQUr",
+ "outputId": "b51c7d09-fb52-42d9-b2d5-4f44f5d22dc9"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'type': 'DocQA',\n",
+ " 'data': {'_components': {'_ordered_dict': True,\n",
+ " 'data': [('doc',\n",
+ " {'type': 'Generator',\n",
+ " 'data': {'model_str': 'OpenAIClient_gpt-3_5-turbo',\n",
+ " 'cache_path': PosixPath('/root/.adalflow/cache_OpenAIClient_gpt-3_5-turbo.db'),\n",
+ " 'callbacks': {'on_success': [], 'on_failure': [], 'on_complete': []},\n",
+ " 'cache': ,\n",
+ " '_components': {'_ordered_dict': True,\n",
+ " 'data': [('prompt',\n",
+ " {'type': 'Prompt',\n",
+ " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'Prompt',\n",
+ " '_init_args': {'template': None, 'prompt_kwargs': {}},\n",
+ " 'template': ' You are a doctor User: {{input_str}}',\n",
+ " 'prompt_variables': ['input_str'],\n",
+ " 'prompt_kwargs': {}}}),\n",
+ " ('model_client',\n",
+ " {'type': 'OpenAIClient',\n",
+ " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'OpenAIClient',\n",
+ " '_init_args': {'api_key': None,\n",
+ " 'chat_completion_parser': None,\n",
+ " 'input_type': 'text'},\n",
+ " '_api_key': None,\n",
+ " 'chat_completion_parser': str>,\n",
+ " '_input_type': 'text'}})]},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'Generator',\n",
+ " '_init_args': {'model_client': None,\n",
+ " 'model_kwargs': {},\n",
+ " 'template': None,\n",
+ " 'prompt_kwargs': {},\n",
+ " 'output_processors': None,\n",
+ " 'name': None,\n",
+ " 'cache_path': None,\n",
+ " 'use_cache': False},\n",
+ " 'backward_engine': None,\n",
+ " 'template': ' You are a doctor User: {{input_str}}',\n",
+ " 'prompt_kwargs': {},\n",
+ " 'model_kwargs': {'model': 'gpt-3.5-turbo'},\n",
+ " 'output_processors': None,\n",
+ " 'mock_output': False,\n",
+ " 'mock_output_data': 'mock data',\n",
+ " 'data_map_func': .default_map_func(data: 'GeneratorOutputType') -> str>,\n",
+ " '_use_cache': False,\n",
+ " '_kwargs': {'model_client': {'type': 'OpenAIClient',\n",
+ " 'data': {'_components': {'_ordered_dict': True, 'data': []},\n",
+ " '_parameters': {'_ordered_dict': True, 'data': []},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'OpenAIClient',\n",
+ " '_init_args': {'api_key': None,\n",
+ " 'chat_completion_parser': None,\n",
+ " 'input_type': 'text'},\n",
+ " '_api_key': None,\n",
+ " 'chat_completion_parser': str>,\n",
+ " '_input_type': 'text'}},\n",
+ " 'model_kwargs': {'model': 'gpt-3.5-turbo'},\n",
+ " 'template': ' You are a doctor User: {{input_str}}',\n",
+ " 'prompt_kwargs': {},\n",
+ " 'output_processors': None,\n",
+ " 'name': None,\n",
+ " 'cache_path': None,\n",
+ " 'use_cache': False},\n",
+ " '_teacher': None}})]},\n",
+ " '_parameters': {'_ordered_dict': True,\n",
+ " 'data': [('demo',\n",
+ " {'name': 'param_313f196d-3c48-4eb3-8138-b7bd74298fbd',\n",
+ " 'role_desc': '',\n",
+ " 'data': 'demo',\n",
+ " 'requires_opt': True,\n",
+ " 'param_type': 'none ()',\n",
+ " 'predecessors': [],\n",
+ " 'gradients': [],\n",
+ " 'previous_data': None,\n",
+ " 'gradients_context': [],\n",
+ " 'grad_fn': 'None',\n",
+ " 'gradient_prompt': 'None',\n",
+ " 'raw_response': None,\n",
+ " 'score': None,\n",
+ " 'traces': {},\n",
+ " 'input_args': None,\n",
+ " 'demos': []})]},\n",
+ " 'training': False,\n",
+ " 'teacher_mode': False,\n",
+ " 'tracing': False,\n",
+ " 'name': 'DocQA',\n",
+ " '_init_args': {}}}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 20
+ }
+ ],
+ "source": [
+ "doc.to_dict()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {
+ "id": "mcIO1DuVTQUr"
+ },
+ "outputs": [],
+ "source": [
+ "from adalflow.utils.file_io import save_json\n",
+ "\n",
+ "save_json(doc.to_dict(), \"doc.json\")"
+ ]
+ },
{
- "data": {
- "text/plain": [
- "Sequential(\n",
- " (0): EnhanceQueryComponent()\n",
- " (1): DocQA(\n",
- " (doc): Generator(\n",
- " model_kwargs={'model': 'gpt-3.5-turbo'}, \n",
- " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
- " (model_client): OpenAIClient()\n",
- " )\n",
- " )\n",
- ")"
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "0vvO0nogTQUr",
+ "outputId": "59131d9e-a996-4c8b-f32c-9a6a623d3db6"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('demo',\n",
+ " Parameter(name=param_313f196d-3c48-4eb3-8138-b7bd74298fbd, requires_opt=True, param_type=none (), role_desc=, data=demo, predecessors=set(), gradients=[], raw_response=None, input_args=None, traces={}))])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 22
+ }
+ ],
+ "source": [
+ "doc.state_dict()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 125
+ },
+ "id": "uroqi93tTQUs",
+ "outputId": "8a3e4ecc-1368-475b-dc4d-2ff38821b8ac"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-11-11 17:42:18 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for a cold?'}]}\n",
+ "2024-11-11 17:42:19 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
+ "2024-11-11 17:42:19 - generator - INFO - [generator.py:798:call] - output: GeneratorOutput(id=None, data='As a doctor, I recommend getting plenty of rest, staying hydrated, and taking over-the-counter medications like ibuprofen or acetaminophen to help relieve symptoms such as fever and congestion. Additionally, you can try using saline nasal sprays or lozenges to help soothe a sore throat. If your symptoms persist or worsen, it is best to consult with a healthcare provider for further evaluation and treatment.', error=None, usage=CompletionUsage(completion_tokens=85, prompt_tokens=28, total_tokens=113), raw_response='As a doctor, I recommend getting plenty of rest, staying hydrated, and taking over-the-counter medications like ibuprofen or acetaminophen to help relieve symptoms such as fever and congestion. Additionally, you can try using saline nasal sprays or lozenges to help soothe a sore throat. If your symptoms persist or worsen, it is best to consult with a healthcare provider for further evaluation and treatment.', metadata=None)\n"
+ ]
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "'As a doctor, I recommend getting plenty of rest, staying hydrated, and taking over-the-counter medications like ibuprofen or acetaminophen to help relieve symptoms such as fever and congestion. Additionally, you can try using saline nasal sprays or lozenges to help soothe a sore throat. If your symptoms persist or worsen, it is best to consult with a healthcare provider for further evaluation and treatment.'"
+ ],
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ }
+ },
+ "metadata": {},
+ "execution_count": 23
+ }
+ ],
+ "source": [
+ "doc.call(\"What is the best treatment for a cold?\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "mYSDr462TQUs",
+ "outputId": "82414c82-8feb-4667-90ed-91c594cc6a73"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "from adalflow.core.component import FunComponent\n",
+ "\n",
+ "def add_one(x):\n",
+ " return x + 1\n",
+ "\n",
+ "fun_component = FunComponent(add_one)\n",
+ "print(fun_component(1))\n",
+ "print(type(fun_component))\n",
+ "\n",
+ "# output:\n",
+ "# 2\n",
+ "# "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "3MW1tpzRTQUs",
+ "outputId": "351b8922-1423-434a-f470-ff435a1962d2"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "from adalflow.core.component import fun_to_component\n",
+ "\n",
+ "fun_component = fun_to_component(add_one)\n",
+ "print(fun_component(1))\n",
+ "print(type(fun_component))\n",
+ "\n",
+ "# output:\n",
+ "# 2\n",
+ "# "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "dxAoGrnQTQUs",
+ "outputId": "38c462a3-5abf-41f4-9231-746c8d0ffcb3"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "# use it as a decorator\n",
+ "@fun_to_component\n",
+ "def add_one(x):\n",
+ " return x + 1\n",
+ "\n",
+ "print(add_one(1))\n",
+ "print(type(add_one))\n",
+ "\n",
+ "# output:\n",
+ "# 2\n",
+ "# "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "7BvJEP_mTQUs",
+ "outputId": "066281b8-a650-4c48-c786-312022198015"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "2024-11-11 17:42:39 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?Please be concise and only list the top treatments.'}]}\n",
+ "2024-11-11 17:42:40 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
+ "2024-11-11 17:42:40 - generator - INFO - [generator.py:798:call] - output: GeneratorOutput(id=None, data='The top treatments for headache are rest, hydration, over-the-counter pain relievers such as ibuprofen or acetaminophen, and relaxation techniques such as deep breathing or meditation.', error=None, usage=CompletionUsage(completion_tokens=37, prompt_tokens=37, total_tokens=74), raw_response='The top treatments for headache are rest, hydration, over-the-counter pain relievers such as ibuprofen or acetaminophen, and relaxation techniques such as deep breathing or meditation.', metadata=None)\n",
+ "The top treatments for headache are rest, hydration, over-the-counter pain relievers such as ibuprofen or acetaminophen, and relaxation techniques such as deep breathing or meditation.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from adalflow.core import Sequential\n",
+ "\n",
+ "@fun_to_component\n",
+ "def enhance_query(query:str) -> str:\n",
+ " return query + \"Please be concise and only list the top treatments.\"\n",
+ "\n",
+ "seq = Sequential(enhance_query, doc)\n",
+ "\n",
+ "query = \"What is the best treatment for headache?\"\n",
+ "print(seq(query))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "aoZ2w8RUTQUt",
+ "outputId": "115d0ccf-33d1-4464-a951-cf9f5476284b"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Sequential(\n",
+ " (0): EnhanceQueryComponent(fun_name=enhance_query)\n",
+ " (1): DocQA(\n",
+ " (doc): Generator(\n",
+ " model_kwargs={'model': 'gpt-3.5-turbo'}, trainable_prompt_kwargs=[]\n",
+ " (prompt): Prompt(template: You are a doctor User: {{input_str}}, prompt_variables: ['input_str'])\n",
+ " (model_client): OpenAIClient()\n",
+ " )\n",
+ " )\n",
+ ")"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 29
+ }
+ ],
+ "source": [
+ "seq"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "F-ffAlC6TQUt"
+ },
+ "source": [
+ "# TODO: LLM for single choices"
]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
}
- ],
- "source": [
- "seq"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# TODO: LLM for single choices"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": ".venv",
- "language": "python",
- "name": "python3"
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "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.10.12"
+ },
+ "colab": {
+ "provenance": []
+ }
},
- "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.11.6"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
\ No newline at end of file
From e2843b17857c6aa3b55aeaa2812e54dab412d34b Mon Sep 17 00:00:00 2001
From: jaggik
Date: Mon, 11 Nov 2024 15:20:13 -0500
Subject: [PATCH 05/48] added .py for component
---
tutorials/component.py | 111 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
create mode 100644 tutorials/component.py
diff --git a/tutorials/component.py b/tutorials/component.py
new file mode 100644
index 000000000..b4b8e080b
--- /dev/null
+++ b/tutorials/component.py
@@ -0,0 +1,111 @@
+import re
+from adalflow.core import Component, Generator
+from adalflow.components.model_client import OpenAIClient
+from adalflow.components.model_client import GroqAPIClient
+from adalflow.utils import setup_env # make sure you have a .env file with OPENAI_API_KEY and GROQ_API_KEY
+
+from getpass import getpass
+import os
+
+# Prompt user to enter their API keys securely
+openai_api_key = getpass("Please enter your OpenAI API key: ")
+# Set environment variables
+os.environ['OPENAI_API_KEY'] = openai_api_key
+print("API keys have been set.")
+
+template_doc = r""" You are a doctor User: {{input_str}}"""
+
+from adalflow.utils import get_logger
+get_logger()
+
+class DocQA(Component):
+ def __init__(self):
+ super(DocQA, self).__init__()
+ self.doc = Generator(
+ template=template_doc,
+ model_client=OpenAIClient(),
+ model_kwargs={"model": "gpt-3.5-turbo"},
+ )
+
+ def call(self, query: str) -> str:
+ return self.doc(prompt_kwargs={"input_str": query}).data
+
+doc = DocQA()
+# states
+states = doc.to_dict()
+print(states)
+print(doc.__dict__)
+
+# restore the states
+doc2 = DocQA.from_dict(states)
+# print(doc2.call("What is the capital of France?"))
+print(doc2.__dict__)
+print(doc2.to_dict())
+
+print(doc2.to_dict() == doc.to_dict())
+doc2.to_dict()
+
+print(doc("What is the best treatment for headache?"))
+print(doc2("What is the best treatment for headache?"))
+
+# list other subcomponents
+for subcomponent in doc.named_components():
+ print(subcomponent)
+
+from adalflow.optim.parameter import Parameter
+doc.register_parameter("demo", param=Parameter(data="demo"))
+
+# list all parameters
+for param in doc.named_parameters():
+ print(param)
+
+print(doc.to_dict())
+
+from adalflow.utils.file_io import save_json
+save_json(doc.to_dict(), "doc.json")
+
+print(doc.state_dict())
+print(doc.call("What is the best treatment for a cold?"))
+
+from adalflow.core.component import FunComponent
+
+def add_one(x):
+ return x + 1
+
+fun_component = FunComponent(add_one)
+print(fun_component(1))
+print(type(fun_component))
+# output:
+# 2
+#
+
+from adalflow.core.component import fun_to_component
+
+fun_component = fun_to_component(add_one)
+print(fun_component(1))
+print(type(fun_component))
+# output:
+# 2
+#
+
+# use it as a decorator
+@fun_to_component
+def add_one(x):
+ return x + 1
+print(add_one(1))
+print(type(add_one))
+# output:
+# 2
+#
+
+from adalflow.core import Sequential
+
+@fun_to_component
+def enhance_query(query:str) -> str:
+ return query + "Please be concise and only list the top treatments."
+
+seq = Sequential(enhance_query, doc)
+query = "What is the best treatment for headache?"
+print(seq(query))
+print(seq)
+
From a6d02d5458a41f8472610c25cbeeb68598abe7c3 Mon Sep 17 00:00:00 2001
From: jaggik
Date: Mon, 11 Nov 2024 15:22:55 -0500
Subject: [PATCH 06/48] moved component.ipynb to notebooks/tutorials as
adalflow_component.ipynb
---
.../tutorials/adalflow_component.ipynb | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename tutorials/component.ipynb => notebooks/tutorials/adalflow_component.ipynb (100%)
diff --git a/tutorials/component.ipynb b/notebooks/tutorials/adalflow_component.ipynb
similarity index 100%
rename from tutorials/component.ipynb
rename to notebooks/tutorials/adalflow_component.ipynb
From 6b95abb10724932dac7c8f7027b8af597952ad9b Mon Sep 17 00:00:00 2001
From: jaggik
Date: Mon, 11 Nov 2024 15:40:07 -0500
Subject: [PATCH 07/48] updated links and documentation for template adherence
---
notebooks/tutorials/adalflow_component.ipynb | 144 +++++++++++++------
1 file changed, 99 insertions(+), 45 deletions(-)
diff --git a/notebooks/tutorials/adalflow_component.ipynb b/notebooks/tutorials/adalflow_component.ipynb
index 2e459a453..2da8aa78e 100644
--- a/notebooks/tutorials/adalflow_component.ipynb
+++ b/notebooks/tutorials/adalflow_component.ipynb
@@ -1,19 +1,63 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 🤗 Welcome to AdalFlow!\n",
+ "## The library to build & auto-optimize any LLM task pipelines\n",
+ "\n",
+ "Thanks for trying us out, we're here to provide you with the best LLM application development experience you can dream of 😊 any questions or concerns you may have, [come talk to us on discord,](https://discord.gg/ezzszrRZvT) we're always here to help! ⭐ Star us on Github ⭐\n",
+ "\n",
+ "\n",
+ "# Quick Links\n",
+ "\n",
+ "Github repo: https://github.com/SylphAI-Inc/AdalFlow\n",
+ "\n",
+ "Full Tutorials: https://adalflow.sylph.ai/index.html#.\n",
+ "\n",
+ "Deep dive on each API: check out the [developer notes](https://adalflow.sylph.ai/tutorials/index.html).\n",
+ "\n",
+ "Common use cases along with the auto-optimization: check out [Use cases](https://adalflow.sylph.ai/use_cases/index.html).\n",
+ "\n",
+ "# Author\n",
+ "\n",
+ "This notebook was created by community contributor [Ajith](https://github.com/ajithvcoder).\n",
+ "\n",
+ "# Outline\n",
+ "\n",
+ "This is a quick introduction of what AdalFlow is capable of. We will cover:\n",
+ "\n",
+ "* How to use `DataClass` with `DataClassParser`.\n",
+ "* How to do nested dataclass, we will test both one and two levels of nesting.\n",
+ "\n",
+ "**Next: Try our [auto-optimization](https://colab.research.google.com/drive/1n3mHUWekTEYHiBdYBTw43TKlPN41A9za?usp=sharing)**\n",
+ "\n",
+ "\n",
+ "# Installation\n",
+ "\n",
+ "1. Use `pip` to install the `adalflow` Python package. We will need `openai` and `groq`from the extra packages.\n",
+ "\n",
+ " ```bash\n",
+ " pip install adalflow[openai,groq]\n",
+ " ```\n",
+ "2. Setup `openai` and `groq` API key in the environment variables"
+ ]
+ },
{
"cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "id": "Ab_OmE6XTl4h"
+ },
+ "outputs": [],
"source": [
"from IPython.display import clear_output\n",
"\n",
"!pip install -U adalflow[openai,groq,datasets]\n",
"\n",
"clear_output()"
- ],
- "metadata": {
- "id": "Ab_OmE6XTl4h"
- },
- "execution_count": 4,
- "outputs": []
+ ]
},
{
"cell_type": "code",
@@ -42,8 +86,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"Please enter your OpenAI API key: ··········\n",
"API keys have been set.\n"
@@ -95,14 +139,14 @@
},
"outputs": [
{
- "output_type": "execute_result",
"data": {
"text/plain": [
""
]
},
+ "execution_count": 8,
"metadata": {},
- "execution_count": 8
+ "output_type": "execute_result"
}
],
"source": [
@@ -130,8 +174,7 @@
" )\n",
"\n",
" def call(self, query: str) -> str:\n",
- " return self.doc(prompt_kwargs={\"input_str\": query}).data\n",
- ""
+ " return self.doc(prompt_kwargs={\"input_str\": query}).data\n"
]
},
{
@@ -146,8 +189,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2024-11-11 17:40:52 - prompt_builder - INFO - [prompt_builder.py:65:__init__] - Prompt has variables: ['input_str']\n",
"2024-11-11 17:40:52 - generator - INFO - [generator.py:144:__init__] - Generator Generator initialized.\n"
@@ -170,14 +213,13 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"{'type': 'DocQA', 'data': {'_components': {'_ordered_dict': True, 'data': [('doc', {'type': 'Generator', 'data': {'model_str': 'OpenAIClient_gpt-3_5-turbo', 'cache_path': PosixPath('/root/.adalflow/cache_OpenAIClient_gpt-3_5-turbo.db'), 'callbacks': {'on_success': [], 'on_failure': [], 'on_complete': []}, 'cache': , '_components': {'_ordered_dict': True, 'data': [('prompt', {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Prompt', '_init_args': {'template': None, 'prompt_kwargs': {}}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': ['input_str'], 'prompt_kwargs': {}}}), ('model_client', {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Generator', '_init_args': {'model_client': None, 'model_kwargs': {}, 'template': None, 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, 'backward_engine': None, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'output_processors': None, 'mock_output': False, 'mock_output_data': 'mock data', 'data_map_func': .default_map_func at 0x7b8d471c97e0>, '_use_cache': False, '_kwargs': {'model_client': {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, '_teacher': None}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'DocQA', '_init_args': {}}}\n"
]
},
{
- "output_type": "execute_result",
"data": {
"text/plain": [
"{'_components': OrderedDict([('doc',\n",
@@ -194,8 +236,9 @@
" '_init_args': {}}"
]
},
+ "execution_count": 12,
"metadata": {},
- "execution_count": 12
+ "output_type": "execute_result"
}
],
"source": [
@@ -224,8 +267,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2024-11-11 17:40:58 - component - INFO - [component.py:350:_restore_value] - Restoring class using from_dict Generator, {'type': 'Generator', 'data': {'model_str': 'OpenAIClient_gpt-3_5-turbo', 'cache_path': PosixPath('/root/.adalflow/cache_OpenAIClient_gpt-3_5-turbo.db'), 'callbacks': {'on_success': [], 'on_failure': [], 'on_complete': []}, 'cache': , '_components': {'_ordered_dict': True, 'data': [('prompt', {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Prompt', '_init_args': {'template': None, 'prompt_kwargs': {}}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': ['input_str'], 'prompt_kwargs': {}}}), ('model_client', {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}})]}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Generator', '_init_args': {'model_client': None, 'model_kwargs': {}, 'template': None, 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, 'backward_engine': None, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'output_processors': None, 'mock_output': False, 'mock_output_data': 'mock data', 'data_map_func': .default_map_func at 0x7b8d471c97e0>, '_use_cache': False, '_kwargs': {'model_client': {'type': 'OpenAIClient', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'OpenAIClient', '_init_args': {'api_key': None, 'chat_completion_parser': None, 'input_type': 'text'}, '_api_key': None, 'chat_completion_parser': , '_input_type': 'text'}}, 'model_kwargs': {'model': 'gpt-3.5-turbo'}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_kwargs': {}, 'output_processors': None, 'name': None, 'cache_path': None, 'use_cache': False}, '_teacher': None}}\n",
"2024-11-11 17:40:58 - component - INFO - [component.py:350:_restore_value] - Restoring class using from_dict Prompt, {'type': 'Prompt', 'data': {'_components': {'_ordered_dict': True, 'data': []}, '_parameters': {'_ordered_dict': True, 'data': []}, 'training': False, 'teacher_mode': False, 'tracing': False, 'name': 'Prompt', '_init_args': {'template': None, 'prompt_kwargs': {}}, 'template': ' You are a doctor User: {{input_str}}', 'prompt_variables': ['input_str'], 'prompt_kwargs': {}}}\n",
@@ -234,7 +277,6 @@
]
},
{
- "output_type": "execute_result",
"data": {
"text/plain": [
"{'_components': OrderedDict([('doc',\n",
@@ -251,8 +293,9 @@
" '_init_args': {}}"
]
},
+ "execution_count": 13,
"metadata": {},
- "execution_count": 13
+ "output_type": "execute_result"
}
],
"source": [
@@ -275,7 +318,6 @@
},
"outputs": [
{
- "output_type": "execute_result",
"data": {
"text/plain": [
"{'type': 'DocQA',\n",
@@ -364,8 +406,9 @@
" '_init_args': {}}}"
]
},
+ "execution_count": 14,
"metadata": {},
- "execution_count": 14
+ "output_type": "execute_result"
}
],
"source": [
@@ -385,8 +428,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2024-11-11 17:41:29 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?'}]}\n",
"2024-11-11 17:41:30 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
@@ -411,8 +454,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2024-11-11 17:41:35 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?'}]}\n",
"2024-11-11 17:41:36 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
@@ -444,8 +487,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"('', DocQA(\n",
" (doc): Generator(\n",
@@ -505,8 +548,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"('demo', Parameter(name=param_313f196d-3c48-4eb3-8138-b7bd74298fbd, requires_opt=True, param_type=none (), role_desc=, data=demo, predecessors=set(), gradients=[], raw_response=None, input_args=None, traces={}))\n"
]
@@ -530,7 +573,6 @@
},
"outputs": [
{
- "output_type": "execute_result",
"data": {
"text/plain": [
"{'type': 'DocQA',\n",
@@ -636,8 +678,9 @@
" '_init_args': {}}}"
]
},
+ "execution_count": 20,
"metadata": {},
- "execution_count": 20
+ "output_type": "execute_result"
}
],
"source": [
@@ -669,15 +712,15 @@
},
"outputs": [
{
- "output_type": "execute_result",
"data": {
"text/plain": [
"OrderedDict([('demo',\n",
" Parameter(name=param_313f196d-3c48-4eb3-8138-b7bd74298fbd, requires_opt=True, param_type=none (), role_desc=, data=demo, predecessors=set(), gradients=[], raw_response=None, input_args=None, traces={}))])"
]
},
+ "execution_count": 22,
"metadata": {},
- "execution_count": 22
+ "output_type": "execute_result"
}
],
"source": [
@@ -697,8 +740,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2024-11-11 17:42:18 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for a cold?'}]}\n",
"2024-11-11 17:42:19 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
@@ -706,17 +749,17 @@
]
},
{
- "output_type": "execute_result",
"data": {
- "text/plain": [
- "'As a doctor, I recommend getting plenty of rest, staying hydrated, and taking over-the-counter medications like ibuprofen or acetaminophen to help relieve symptoms such as fever and congestion. Additionally, you can try using saline nasal sprays or lozenges to help soothe a sore throat. If your symptoms persist or worsen, it is best to consult with a healthcare provider for further evaluation and treatment.'"
- ],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "string"
- }
+ },
+ "text/plain": [
+ "'As a doctor, I recommend getting plenty of rest, staying hydrated, and taking over-the-counter medications like ibuprofen or acetaminophen to help relieve symptoms such as fever and congestion. Additionally, you can try using saline nasal sprays or lozenges to help soothe a sore throat. If your symptoms persist or worsen, it is best to consult with a healthcare provider for further evaluation and treatment.'"
+ ]
},
+ "execution_count": 23,
"metadata": {},
- "execution_count": 23
+ "output_type": "execute_result"
}
],
"source": [
@@ -735,8 +778,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2\n",
"\n"
@@ -770,8 +813,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2\n",
"\n"
@@ -802,8 +845,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2\n",
"\n"
@@ -836,8 +879,8 @@
},
"outputs": [
{
- "output_type": "stream",
"name": "stdout",
+ "output_type": "stream",
"text": [
"2024-11-11 17:42:39 - openai_client - INFO - [openai_client.py:279:call] - api_kwargs: {'model': 'gpt-3.5-turbo', 'messages': [{'role': 'system', 'content': ' You are a doctor User: What is the best treatment for headache?Please be concise and only list the top treatments.'}]}\n",
"2024-11-11 17:42:40 - _client - INFO - [_client.py:1038:_send_single_request] - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
@@ -871,7 +914,6 @@
},
"outputs": [
{
- "output_type": "execute_result",
"data": {
"text/plain": [
"Sequential(\n",
@@ -886,8 +928,9 @@
")"
]
},
+ "execution_count": 29,
"metadata": {},
- "execution_count": 29
+ "output_type": "execute_result"
}
],
"source": [
@@ -902,9 +945,23 @@
"source": [
"# TODO: LLM for single choices"
]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Issues and feedback\n",
+ "\n",
+ "If you encounter any issues, please report them here: [GitHub Issues](https://github.com/SylphAI-Inc/LightRAG/issues).\n",
+ "\n",
+ "For feedback, you can use either the [GitHub discussions](https://github.com/SylphAI-Inc/LightRAG/discussions) or [Discord](https://discord.gg/ezzszrRZvT)."
+ ]
}
],
"metadata": {
+ "colab": {
+ "provenance": []
+ },
"kernelspec": {
"display_name": "Python 3",
"language": "python",
@@ -921,11 +978,8 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
- },
- "colab": {
- "provenance": []
}
},
"nbformat": 4,
"nbformat_minor": 0
-}
\ No newline at end of file
+}
From 7cf02fb9b8a647eab6c6d0730dbeabfb385da5bc Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Wed, 13 Nov 2024 11:31:53 -0800
Subject: [PATCH 08/48] add a quick start in the readme
---
README.md | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 04ec9a5ac..7ef08ee4d 100644
--- a/README.md
+++ b/README.md
@@ -111,6 +111,8 @@ Here is an optimization demonstration on a text classification task:
Among all libraries, AdalFlow achieved the highest accuracy with manual prompting (starting at 82%) and the highest accuracy after optimization.
+
+
Further reading: [Optimize Classification](https://adalflow.sylph.ai/use_cases/classification.html)
## Light, Modular, and Model-Agnostic Task Pipeline
@@ -192,7 +194,8 @@ Just define it as a ``Parameter`` and pass it to AdalFlow's ``Generator``.
-# Quick Install
+# Quick Start
+
Install AdalFlow with pip:
@@ -203,6 +206,9 @@ pip install adalflow
Please refer to the [full installation guide](https://adalflow.sylph.ai/get_started/installation.html) for more details.
+* Try the [Building Quickstart](https://colab.research.google.com/drive/1TKw_JHE42Z_AWo8UuRYZCO2iuMgyslTZ?usp=sharing) in Colab to see how AdalFlow can build the task pipeline, including Chatbot, RAG, agent, and structured output.
+* Try the [Optimization Quickstart](https://colab.research.google.com/github/SylphAI-Inc/AdalFlow/blob/main/notebooks/qas/adalflow_object_count_auto_optimization.ipynb) to see how AdalFlow can optimize the task pipeline.
+
# Documentation
From 1ad66acec3072e2d75b78ec7b26283e978483c10 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Sat, 16 Nov 2024 12:29:54 -0800
Subject: [PATCH 09/48] add structuring, and first version of what to
contribute, let user upvote an issue to mark how important it is
---
.github/ISSUE_TEMPLATE/config.yml | 2 +
docs/source/_static/images/adalflow_files.png | Bin 0 -> 76820 bytes
.../source/_static/images/adalflow_issues.png | Bin 0 -> 175575 bytes
docs/source/contributor/contribution.rst | 179 +++++++++++++++---
docs/source/contributor/index.rst | 8 +-
5 files changed, 164 insertions(+), 25 deletions(-)
create mode 100644 docs/source/_static/images/adalflow_files.png
create mode 100644 docs/source/_static/images/adalflow_issues.png
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index ad44518c2..5e8701896 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,7 @@
blank_issues_enabled: false
contact_links:
+ - name: 👍 Upvote an issue
+ about: You should upvote an issue if it is important to you.
- name: 💬 Chat with us
url: https://discord.gg/ezzszrRZvT
about: Live chat with experts, engineers, and users in our Discord community.
diff --git a/docs/source/_static/images/adalflow_files.png b/docs/source/_static/images/adalflow_files.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcffa12b7b5f4a0286ab78855bae5f83b16c602b
GIT binary patch
literal 76820
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 h-JmeOc2?=N9A^^Bxr
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 |O&)3cqo?QG22^eZ-g4
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 |