Прежде чем идти дальше, мне нужно немного рассказать вам о моем прошлом.

В этом месяце я отработал 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😜