From the uDemy course on LLM engineering.
https://www.udemy.com/course/llm-engineering-master-ai-and-large-language-models
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
385 lines
14 KiB
385 lines
14 KiB
{ |
|
"cells": [ |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 1, |
|
"id": "6e988b94-daab-4ad1-bf85-e2ee066bca17", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"import os\n", |
|
"import json\n", |
|
"from typing import List\n", |
|
"from dotenv import load_dotenv\n", |
|
"from selenium import webdriver\n", |
|
"from selenium.webdriver.chrome.service import Service\n", |
|
"from selenium.webdriver.common.by import By\n", |
|
"from selenium.webdriver.chrome.options import Options\n", |
|
"from IPython.display import Markdown, display, update_display\n", |
|
"from openai import OpenAI\n", |
|
"from bs4 import BeautifulSoup" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 2, |
|
"id": "5d58d8a6-65d6-42ee-b5c9-bbcc1cafd7fc", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"load_dotenv(override=True)\n", |
|
"api_key = os.getenv('OPENAI_API_KEY')\n", |
|
"PATH_TO_CHROME_DRIVER = 'B:\\\\Users\\\\ekfon\\\\chromeDriver\\\\chromedriver.exe'\n", |
|
"\n", |
|
"MODEL = 'gpt-4o-mini'\n", |
|
"openai = OpenAI()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 3, |
|
"id": "29ce6d79-2d5f-48e2-9f99-e249e5f0ca77", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"class Website:\n", |
|
" url: str\n", |
|
" title: str\n", |
|
" text: str\n", |
|
"\n", |
|
" def __init__(self, url):\n", |
|
" self.url = url\n", |
|
" \"\"\"\n", |
|
" begin Selenium equivalent of requests:\n", |
|
" response = requests.get(url, headers=headers)\n", |
|
" self.body = response.content #which is then passed on to bs\n", |
|
" \"\"\"\n", |
|
" options = Options()\n", |
|
"\n", |
|
" options.add_argument(\"--no-sandbox\")\n", |
|
" options.add_argument(\"--disable-dev-shm-usage\")\n", |
|
"\n", |
|
" service = Service(PATH_TO_CHROME_DRIVER)\n", |
|
" driver = webdriver.Chrome(service=service, options=options)\n", |
|
" driver.get(url)\n", |
|
"\n", |
|
" page_source = driver.page_source\n", |
|
" driver.quit()\n", |
|
" #end Selenium part\n", |
|
" \n", |
|
" soup = BeautifulSoup(page_source, 'html.parser')\n", |
|
" self.title = soup.title.string if soup.title else \"No title found\"\n", |
|
" if soup.body:\n", |
|
" for irrelevant in soup([\"script\", \"style\", \"img\", \"input\"]):\n", |
|
" irrelevant.decompose()\n", |
|
" self.text = soup.get_text(separator=\"\\n\", strip=True)\n", |
|
" else:\n", |
|
" self.text = \"\"\n", |
|
"\n", |
|
" links = [link.get('href') for link in soup.find_all('a')]\n", |
|
" self.links = [link for link in links if link]\n", |
|
"\n", |
|
" def get_contents(self):\n", |
|
" return f\"Webpage title: \\\"{self.title}\\\"\\nWebpage contents:\\n{self.text}\\n\\n\"" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 4, |
|
"id": "fbdd2015-3ae5-4121-9247-749b131552dd", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"#system prompt for the link anthology\n", |
|
"anthology_sPrompt = \"I'll provide you with a list of links from a webpage. \\\n", |
|
"You are able to decide which links are most relevant to include in a brochure about the company, \\\n", |
|
"such as the About page, any Company page, or a jobs/careers page.\\n\"\n", |
|
"\n", |
|
"anthology_sPrompt += \"You will respond in JSON format, providing full https URLs, just like in this example:\\n\"\n", |
|
"\n", |
|
"anthology_sPrompt += \"\"\"\n", |
|
"{\n", |
|
" \"links\": [\n", |
|
" {\"type\": \"about page\", \"url\": \"https://www.example-url.com/about\"}\n", |
|
" {\"type\": \"careers page\", \"url\": \"https://further.example-url.co.uk/Careers/\"}\n", |
|
" ]\n", |
|
"}\n", |
|
"\"\"\"" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 5, |
|
"id": "cb2aa2f3-e723-4267-ac54-41eaa04b2bba", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_anthology_user_prompt(website):\n", |
|
" user_prompt = f\"Below is the list of links from the webpage {website.url}. \"\n", |
|
" user_prompt += \"Please decide which of the links are relevant for a brochure about the company. \\\n", |
|
"Respond with the full https URL in JSON format. Do not include Terms of Service, Privacy, email links.\"\n", |
|
" user_prompt += \"Here is the list of links (some might be relative links):\\n\\n\"\n", |
|
" user_prompt += \"\\n\".join(website.links)\n", |
|
"\n", |
|
" return user_prompt" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 6, |
|
"id": "752885d6-5c54-4f2b-a6e1-f30e046b704e", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_links_anthology(url):\n", |
|
" website = Website(url)\n", |
|
" response = openai.chat.completions.create(\n", |
|
" model=MODEL,\n", |
|
" messages=[\n", |
|
" {\"role\": \"system\", \"content\": anthology_sPrompt},\n", |
|
" {\"role\": \"user\", \"content\": get_anthology_user_prompt(website)}\n", |
|
" ],\n", |
|
" response_format={\"type\": \"json_object\"}\n", |
|
" )\n", |
|
" result = response.choices[0].message.content\n", |
|
" return json.loads(result) #because result is a string, and what we want is an actual dictionary" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 7, |
|
"id": "989c19b4-817a-4485-a9f7-d38e495385c3", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_all_details(url):\n", |
|
" result = \"Landing page:\\n\\n\"\n", |
|
" result += Website(url).get_contents()\n", |
|
" links = get_links_anthology(url)\n", |
|
"\n", |
|
" for link in links[\"links\"]: #remember that links is a json dictionary\n", |
|
" result += f\"\\n\\n{link['type']}\\n\"\n", |
|
" result += Website(link['url']).get_contents()\n", |
|
"\n", |
|
" return result" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "6f245260-65a8-44a0-b2f9-9c522a2d0ed0", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"print(get_all_details(\"https://edwarddonner.com\"))" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 8, |
|
"id": "b74672ac-15de-4115-80b8-ba1d2c107b0f", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"brochure_sPrompt = \"You analyze the content of several relevant pages from a company's website. \\\n", |
|
"You use that knowledge to create a short brochure about the company. Your brochure is for prospective customers, investors, and recruits. \\\n", |
|
"Include details of company culture, customers, and job openings if you have the information. Respond in Markdown.\"" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 9, |
|
"id": "bfcca913-1a0b-40f3-981f-f7ab3800f55e", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_brochure_user_prompt(company_name, url):\n", |
|
" prompt = f\"You are looking at the website of the company called {company_name}.\\n\"\n", |
|
" prompt += \"Here are the contents of its landing page and other relevant pages. Based on this content, \\\n", |
|
"create a short brochure of the company in Markdown:\\n\\n\"\n", |
|
" prompt += get_all_details(url)\n", |
|
" prompt = prompt[:5_000] #this limits the prompt input, just in case\n", |
|
" \n", |
|
" return prompt" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 10, |
|
"id": "ed64addd-12c6-43b2-9293-c708f4ef5136", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def create_brochure(company_name, url):\n", |
|
" response = openai.chat.completions.create(\n", |
|
" model=MODEL,\n", |
|
" messages=[\n", |
|
" {\"role\": \"system\", \"content\": brochure_sPrompt},\n", |
|
" {\"role\": \"user\", \"content\": get_brochure_user_prompt(company_name, url)}\n", |
|
" ],\n", |
|
" )\n", |
|
" result = response.choices[0].message.content\n", |
|
" return result" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 11, |
|
"id": "953ed0d7-02cc-4639-94ce-75dde322eeac", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"translation_sPrompt = \"You are a powerful translation tool. You will be given a brochure in Markdown format. \\\n", |
|
"Translate the brochure to French. Maintain the Markdown formatting, and output the translation in Markdown. \\\n", |
|
"Output only the clean, ready-to-use translation without any further comments.\"" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 12, |
|
"id": "d8bd19b2-84b3-4e8d-b6a5-d931c10f22ca", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def get_translation_user_prompt(company_name, url):\n", |
|
" prompt = f\"Here is the {company_name} brochure for you. Translate it to French:\\n\\n\"\n", |
|
" prompt += create_brochure(company_name, url)\n", |
|
"\n", |
|
" return prompt" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 15, |
|
"id": "519dd34e-79c5-47f3-b324-3f3c4156cf0c", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def create_French_brochure(company_name, url):\n", |
|
" response = openai.chat.completions.create(\n", |
|
" model=MODEL,\n", |
|
" messages=[\n", |
|
" {\"role\": \"system\", \"content\": translation_sPrompt},\n", |
|
" {\"role\": \"user\", \"content\": get_translation_user_prompt(company_name, url)}\n", |
|
" ]\n", |
|
" )\n", |
|
" results = response.choices[0].message.content\n", |
|
" display(Markdown(results)) \n", |
|
" " |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "bb22f021-f50f-4907-b48e-70efd7cf6f4b", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"answer = create_brochure(\"Anthropic\", \"https://www.anthropic.com/\")" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 13, |
|
"id": "5405287f-1bba-4a7a-b045-075f9b32ce38", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"def stream_brochure(company_name, url):\n", |
|
" stream = openai.chat.completions.create(\n", |
|
" model=MODEL,\n", |
|
" messages=[\n", |
|
" {\"role\": \"system\", \"content\": brochure_sPrompt},\n", |
|
" {\"role\": \"user\", \"content\": get_brochure_user_prompt(company_name, url)}\n", |
|
" ],\n", |
|
" stream=True\n", |
|
" )\n", |
|
"\n", |
|
" response = \"\"\n", |
|
" display_handle = display(Markdown(\"\"), display_id=True)\n", |
|
" for chunk in stream:\n", |
|
" response += chunk.choices[0].delta.content or ''\n", |
|
" response = response.replace(\"```\",\"\").replace(\"markdown\", \"\")\n", |
|
" update_display(Markdown(response), display_id=display_handle.display_id)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 17, |
|
"id": "2bc8384e-3d82-4e47-be38-4bda7047c429", |
|
"metadata": {}, |
|
"outputs": [ |
|
{ |
|
"data": { |
|
"text/markdown": [ |
|
"```markdown\n", |
|
"# Bienvenue chez Edward Donner\n", |
|
"\n", |
|
"Chez **Edward Donner**, nous sommes à la pointe de l'utilisation de l'intelligence artificielle pour révolutionner le paysage du recrutement. Notre approche novatrice combine une IA générative de pointe avec un modèle de correspondance propriétaire pour créer une expérience fluide pour les recruteurs à la recherche de talents de premier plan.\n", |
|
"\n", |
|
"## Notre Mission\n", |
|
"Guidé par le concept japonais d'**Ikigai**, notre objectif ultime est de donner aux individus les moyens de découvrir leur potentiel et de poursuivre leur passion dans le domaine professionnel. Nous croyons qu'en alignant les bonnes personnes avec les bons rôles, nous pouvons élever la prospérité humaine—ce qui est nécessaire dans un monde où 77 % des employés déclarent ne pas se sentir inspirés au travail.\n", |
|
"\n", |
|
"## Culture d'Entreprise\n", |
|
"Notre culture est ancrée dans un mélange de créativité, d'innovation technologique et d'ardeur à construire une communauté. Nous encourageons les dialogues ouverts et les collaborations, où chaque membre de l'équipe a la possibilité de contribuer et de grandir. Nous sommes fiers de notre esprit entrepreneurial, qui se manifeste chez notre fondateur, Ed Donner, qui partage une passion pour le codage, la musique et l'apprentissage continu.\n", |
|
"\n", |
|
"## Nos Clients\n", |
|
"Nous avons établi des partenariats fructueux avec une variété d'entreprises via notre plateforme, en nous concentrant sur le secteur du recrutement pour améliorer les processus de sourcing et d'engagement. Nos clients bénéficient de correspondances plus rapides et plus précises sans se fier uniquement aux mots-clés, garantissant qu'ils découvrent les meilleurs candidats pour leurs équipes.\n", |
|
"\n", |
|
"## Rejoignez Notre Équipe\n", |
|
"Nous sommes à la recherche de penseurs innovants qui sont enthousiasmés par l'IA et son impact sur l'avenir du travail. Si vous recherchez un lieu de travail dynamique où vos contributions font la différence et où vous pouvez vous épanouir, nous vous invitons à consulter nos dernières offres d'emploi sur notre [page carrière](#).\n", |
|
"\n", |
|
"## Connectez-vous Avec Nous !\n", |
|
"Êtes-vous tout aussi enthousiaste à propos de l'IA et du recrutement que nous le sommes ? Connectons-nous ! Nous valorisons le réseautage et la collaboration, que ce soit autour d'un café virtuel ou lors d'une rencontre en personne à NYC, nous serions ravis d'avoir de vos nouvelles.\n", |
|
"\n", |
|
"**Informations de Contact :**\n", |
|
"- **Site Web :** [www.edwarddonner.com](http://www.edwarddonner.com)\n", |
|
"- **Email :** ed [at] edwarddonner [dot] com\n", |
|
"- **Suivez-nous :** [LinkedIn](#) | [Twitter](#) | [Facebook](#)\n", |
|
"\n", |
|
"Rejoignez-nous dans notre quête pour changer la façon dont les gens se connectent à leurs carrières !\n", |
|
"```" |
|
], |
|
"text/plain": [ |
|
"<IPython.core.display.Markdown object>" |
|
] |
|
}, |
|
"metadata": {}, |
|
"output_type": "display_data" |
|
} |
|
], |
|
"source": [ |
|
"reponsee = create_French_brochure(\"Edward Donner\", \"https://edwarddonner.com\")" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"id": "5b2a1387-add3-4058-a859-2e584fe39a91", |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [] |
|
} |
|
], |
|
"metadata": { |
|
"kernelspec": { |
|
"display_name": "Python 3 (ipykernel)", |
|
"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.11.11" |
|
} |
|
}, |
|
"nbformat": 4, |
|
"nbformat_minor": 5 |
|
}
|
|
|