Last active
February 9, 2024 21:06
-
-
Save DaveOkpare/172340a50e65a5a895d29b4c5da954dc to your computer and use it in GitHub Desktop.
Automate email replies and drafts with Zapier and Langchain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# pip install -q langchain openai chromadb tiktoken | |
import os | |
from langchain.embeddings.openai import OpenAIEmbeddings | |
from langchain.vectorstores import Chroma | |
from langchain.text_splitter import CharacterTextSplitter | |
from langchain.llms import OpenAI | |
from langchain.chains import RetrievalQA, LLMChain, TransformChain, SimpleSequentialChain, SequentialChain | |
from langchain.document_loaders import TextLoader | |
from langchain.prompts import PromptTemplate | |
from langchain.tools.zapier.tool import ZapierNLARunAction | |
from langchain.utilities.zapier import ZapierNLAWrapper | |
# get from https://platform.openai.com/ | |
os.environ["OPENAI_API_KEY"] = "<OPENAI_API_KEY>" | |
# get from https://nla.zapier.com/demo/provider/debug (under User Information, after logging in): | |
os.environ["ZAPIER_NLA_API_KEY"] = "<ZAPIER_NLA_API_KEY>" | |
loader = TextLoader("/content/resume.txt") | |
documents = loader.load() | |
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) | |
texts = text_splitter.split_documents(documents) | |
embeddings = OpenAIEmbeddings() | |
docsearch = Chroma.from_documents(texts, embeddings) | |
actions = ZapierNLAWrapper().list() | |
## step 1. gmail find email | |
GMAIL_SEARCH_INSTRUCTIONS = "Grab the latest email from David Ian" | |
def nla_gmail(inputs): | |
action = next((a for a in actions if a["description"].startswith("Gmail: Find Email")), None) | |
return {"email_data": ZapierNLARunAction(action_id=action["id"], zapier_description=action["description"], params_schema=action["params"]).run(inputs["instructions"])} | |
gmail_chain = TransformChain(input_variables=["instructions"], output_variables=["email_data"], transform=nla_gmail) | |
## step 2. generate retrieval question | |
question_template = """Converts this email into a one sentence question. Be concise. Use less than 30 words. Output question in plain text (not JSON). | |
Incoming email: | |
{email_data} | |
Question:""" | |
prompt_template = PromptTemplate(input_variables=["email_data"], template=question_template) | |
question_chain = LLMChain(llm=OpenAI(temperature=.7), prompt=prompt_template) | |
## step 3. draft email from context | |
context_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. | |
Use the answer to write an email. | |
{context} | |
Question: {question} | |
Draft email:""" | |
PROMPT = PromptTemplate( | |
template=context_template, input_variables=["context", "question"] | |
) | |
chain_type_kwargs = {"prompt": PROMPT} | |
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever(), chain_type_kwargs=chain_type_kwargs) | |
retrieval = lambda inputs: {"retrieved_data": qa.run(inputs["question"])} | |
retrieval_chain = TransformChain(input_variables=["question"], output_variables=["retrieved_data"], transform=retrieval) | |
## step 4. save drafted email | |
def create_draft(inputs): | |
action = next((a for a in actions if a["description"].startswith("Gmail: Create Draft")), None) | |
instructions = f'Create a draft with this: {inputs["draft_reply"]}' | |
return {"gmail_data": ZapierNLARunAction(action_id=action["id"], zapier_description=action["description"], params_schema=action["params"]).run(instructions)} | |
draft_chain = TransformChain(input_variables=["draft_reply"], output_variables=["gmail_data"], transform=create_draft) | |
## finally, execute | |
overall_chain = SimpleSequentialChain(chains=[gmail_chain, question_chain, retrieval_chain, draft_chain], verbose=True) | |
overall_chain.run(GMAIL_SEARCH_INSTRUCTIONS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment