Прежде чем идти дальше, мне нужно немного рассказать вам о моем прошлом.
В этом месяце я отработал 5 лет в контент-маркетинге и получил степень бакалавра компьютерных наук в одном из 10 лучших колледжей в моем штате. Прошло почти 5,5-6 лет с тех пор, как я в последний раз что-либо программировал. На самом деле, я так и не развил ничего во время учебы в колледже. Несколько лет назад я писал о том, как я присоединился к Zoho в качестве автора контента.
Достаточно моего прошлого. Теперь я дам вам контекст этого блога.
В Requestly, где я сейчас руковожу командой роста, мы решили провести день, изучая ИИ и то, как он может повлиять на нашу производительность. Нам было поручено либо создать, либо найти хороший инструмент искусственного интеллекта, и у нас был демонстрационный час, на котором мы продемонстрировали, что мы создали/нашли.
Неудивительно, что многие из моих коллег нашли много полезных инструментов, которые действительно могут улучшить нашу работу в Requestly. Несколько инструментов, которые я хотел бы здесь упомянуть, это writemyPRD, yoodli и reword. Я нашел эти инструменты очень интересными, и вы все должны попробовать их.
Теперь у меня было слишком много идей, и я не был уверен, какую из них мне следует изучить. Затем я, наконец, остановился на идее создания модуля ChatGPT в наших блогах и продуктах. Пока я изучал ChatGPT, я нашел этот плагин под названием LinkReader, который помогает ChatGPT читать весь контент в пределах заданного URL-адреса.
(P.S. К тому времени, когда я опубликовал эту статью, этот плагин еще не был доступен! Еще одна причина, по которой я рад, что создал этот инструмент )
Я хотел создать аналогичный инструмент, который мог бы читать уже опубликованный нами контент и предоставлять сводку заданных вопросов со ссылкой на соответствующую страницу. Как человек, который на самом деле не умеет строить, я просто обратился к самому ChatGPT, чтобы создать собственный ChatGPT.
Все дело в подсказках!
Сначала я даже не знал, с чего начать, и не мог найти ни орла, ни решки. Я начал с создания скребка ссылок, поэтому я пошел в ChatGPT и попросил его создать мне скраппер самостоятельно. Он дал мне код, который я даже не знал, как его запустить!!
Я вернулся к основам. Я пытался узнать, что такое Python Flask, как установить Python на свой Mac и как запускать скрипты Python. Набрались идей, установили Python и запустили скрипт.
Бум! столкнулся с тем, с чем сталкивается каждый разработчик.
Мне пришлось вызвать авиаподдержку, чтобы убрать багги. Мои соучредители и коллеги: Сагар, Сахил и Рохан были достаточно любезны, чтобы пообщаться со мной и обнаружили, что порт, который я пытался вызвать, использовался каким-то другим инструментом, и поэтому Localhost не загружался. Изучая это, я изучил методы определения того, какие инструменты используют определенные порты. Вы также можете узнать это отсюда.
Моя цель состояла в том, чтобы создать инструмент, который может отвечать на вопросы на основе URL-адреса, который я даю. Я снова обратился к ChatGPT, и мне посоветовали использовать Python Flask. Я остался с Bootstrap в качестве внешнего интерфейса, потому что раньше у меня был опыт создания базовых веб-страниц. Я назвал приложение Vina
, так как это означает «вопрос» на тамильском языке.
Для чтения всего содержимого в данном URL-адресе потребуется комбинация различных библиотек, таких как requests
для обработки HTTP-запросов и beautifulsoup4
или lxml
для анализа содержимого HTML. Итак, позвольте мне рассказать вам о процессе создания приложения Vina.
Шаг 1. Получение и анализ веб-контента
Сначала вам нужно будет получить и проанализировать веб-контент. Вот как будет выглядеть код:
import requests from bs4 import BeautifulSoup def fetch_webpage(url): response = requests.get(url) return response.text def parse_webpage(html_content): soup = BeautifulSoup(html_content, 'html.parser') return soup def extract_content(soup): text = ' '.join(soup.stripped_strings) return text def main(url): html_content = fetch_webpage(url) soup = parse_webpage(html_content) text = extract_content(soup) print(text) if __name__ == '__main__': main('<https://example.com>')
Функция fetch_webpage
принимает URL-адрес и возвращает содержимое HTML этой страницы в виде строки. Функция parse_webpage
принимает содержимое HTML и возвращает объект BeautifulSoup, который можно использовать для навигации по дереву HTML. Функция extract_content
принимает объект BeautifulSoup и возвращает строку со всем текстом на странице. Функция main
связывает все вместе. Он извлекает веб-страницу, анализирует ее, извлекает содержимое, а затем распечатывает содержимое.
Шаг 2. Настройте модель OpenAI GPT
Во-первых, вам нужно установить клиент Python OpenAI.
pip install openai
Далее вам нужно настроить ключ API. Этот ключ обычно предоставляется при регистрации в службе API OpenAI. Вы можете настроить это в своей среде, используя:
import openai openai.api_key = 'your-api-key'
Шаг 3. Обработайте вопрос пользователя и создайте ответ
С веб-контентом и вопросом пользователя вы можете затем вызвать API для создания ответа. Идея здесь состоит в том, чтобы добавить к вопросу содержание веб-страницы, которая будет служить контекстом для модели. Затем попросите модель создать сводку или ответ на основе этого контекста.
def generate_answer(context, question): prompt = context + "\\n\\n" + question response = openai.Completion.create( engine="text-davinci-002", prompt=prompt, temperature=0.5, max_tokens=150 ) return response.choices[0].text.strip()
В этой функции context
— это содержимое веб-страницы, а question
— вопрос пользователя.
Шаг 4. Соедините все вместе
Теперь, когда мы создали парсер контента и генератор ответов, пришло время соединить их вместе, чтобы получить наше приложение Vina.
import requests from bs4 import BeautifulSoup import openai # Functions to Fetch and Parse Web Content def fetch_webpage(url): response = requests.get(url) return response.text def parse_webpage(html_content): soup = BeautifulSoup(html_content, 'html.parser') return soup def extract_content(soup): text = ' '.join(soup.stripped_strings) return text # Function to Generate Answer Using OpenAI GPT-3/GPT-4 def generate_answer(context, question): prompt = context + "\\n\\n" + question response = openai.Completion.create( engine="text-davinci-002", prompt=prompt, temperature=0.5, max_tokens=150 ) return response.choices[0].text.strip() # Main Function def main(url, question): # Fetch and parse web content html_content = fetch_webpage(url) soup = parse_webpage(html_content) context = extract_content(soup) # Set OpenAI API Key openai.api_key = 'your-api-key' # Replace with your actual OpenAI API key # Generate and print the answer answer = generate_answer(context, question) print(answer) # Execution if __name__ == '__main__': url = input("Enter a URL: ") question = input("Enter your question: ") main(url, question)
Однако я столкнулся с двумя серьезными проблемами. Когда я запустил этот код, я столкнулся с этой ошибкой:
InvalidRequestError: This model's maximum context length is 4097 tokens, however you requested 4694 tokens (4544 in your prompt; 150 for the completion). Please reduce your prompt; or completion length.
Это означает, что ограничение на максимальное количество токенов, которое OpenAI API может обработать в одном запросе, составляет 4097, но мой запрос — 4694 токена. Пришлось обрезать запрос и ограничить его.
def extract_content(soup): text = ' '.join(soup.stripped_strings) # Truncate text to fit within token limits truncated_text = text[:4096] return truncated_text
Вторая серьезная проблема, с которой я столкнулся, заключалась в том, что код, предоставленный ChatGPT, просто возвращал вопрос, который я задал, вместо того, чтобы давать на него ответ. Он добавлял вопрос в конец контекста, что может привести к таким ситуациям, когда ответ не соответствует ожидаемому.
Итак, я вернулся в ChatGPT и поделился ошибкой, и она была исправлена, изменив функцию generate_answer
следующим образом:
def generate_answer(context, question): prompt = f"{context}\\n\\n{question}\\nAnswer:" response = openai.Completion.create( engine="text-davinci-002", prompt=prompt, temperature=0.5, max_tokens=150 ) return response.choices[0].text.strip()
Он просто изменил формат моих подсказок на формат вопросов и ответов, чтобы код мог обработать вопрос и ответить на него. Как только я обновил код, Вина смогла дать мне ответы на вопросы, которые я задавал.
Теперь я попросил ChatGPT изменить существующий код, чтобы он отвечал на несколько вопросов по заданному URL-адресу, и он изменил код следующим образом:
from flask import Flask, request, render_template, redirect, url_for, session import requests from bs4 import BeautifulSoup import openai app = Flask(__name__) app.secret_key = 'your_secret_key' # Replace with your secret key # Functions to Fetch and Parse Web Content def fetch_webpage(url): response = requests.get(url) return response.text def parse_webpage(html_content): soup = BeautifulSoup(html_content, 'html.parser') return soup def extract_content(soup): text = ' '.join(soup.stripped_strings) truncated_text = text[:3946] # Truncate text to fit within token limits return truncated_text # Function to Generate Answer Using OpenAI GPT-3/GPT-4 def generate_answer(context, question): prompt = f"{context}\\n\\n{question}\\nAnswer:" response = openai.Completion.create( engine="text-davinci-002", prompt=prompt, temperature=0.5, max_tokens=150 ) return response.choices[0].text.strip() @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': url = request.form.get('url') # Fetch and parse web content html_content = fetch_webpage(url) soup = parse_webpage(html_content) context = extract_content(soup) session['context'] = context return redirect(url_for('ask')) return render_template('index.html') @app.route('/ask', methods=['GET', 'POST']) def ask(): if 'context' not in session: return redirect(url_for('index')) if 'answer' in session: answer = session['answer'] session.pop('answer', None) else: answer = None if request.method == 'POST': question = request.form.get('question') # Set OpenAI API Key openai.api_key = 'your-api-key' # Replace with your actual OpenAI API key # Generate answer answer = generate_answer(session['context'], question) session['answer'] = answer return redirect(url_for('ask')) return render_template('ask.html', answer=answer) if __name__ == '__main__': app.run(port=5000, debug=True)
Теперь все, что мне нужно сделать, это создать прикрытие для этого кода, где я могу поделиться URL-адресом и задать вопросы по URL-адресу. Итак, это веб-страница, которую я создал для инструмента Vina. Мне понадобились две страницы — страница «индекс», где я буду вводить URL-адрес, и страница «спрашивать», где я буду задавать свои вопросы и получать ответы.
<!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Content QA</title> <link href="<https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css>" rel="stylesheet"> </head> <body class="bg-light"> <div class="container py-5"> <h1 class="mb-4">Enter URL</h1> <form method="POST" action="/"> <div class="mb-3"> <input type="url" id="url" name="url" class="form-control" placeholder="<https://example.com>" required> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </body> </html> <!-- ask.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Content QA</title> <link href="<https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css>" rel="stylesheet"> </head> <body class="bg-light"> <div class="container py-5"> <h1 class="mb-4">Ask a Question</h1> <form method="POST" action="/ask"> <div class="mb-3"> <label for="question" class="form-label">Enter Question:</label> <input type="text" id="question" name="question" class="form-control" required> </div> <button type="submit" class="btn btn-primary">Ask</button> </form> {% if answer %} <div class="mt-5"> <h2>Answer:</h2> <p>{{ answer }}</p> </div> {% endif %} </div> </body> </html>
Наконец, потратив почти 4 часа, приложение Vina выглядит так:
P.S. Этот блог был написан НЕ с использованием ChatGPT😜