Я программист и всегда ищу способ повысить свою продуктивность, чтобы найти больше времени для чего-то более значимого в жизни, например, спорить с незнакомцами в Твиттере. Для этого я использую множество инструментов, включая IDE, плагины и недавно GitHub Copilot. ИИ помогает мне завершать мой код больше, чем ваша жена может завершать ваши предложения, но он не идеален. Ему все еще нужен программист, чтобы подумать о том, как закодировать его на основе требований, и часто код, сгенерированный из GitHub Copilot, даже не может работать. В основном я использую его для автоматического завершения моего хорошо продуманного кода.
Наконец-то появился ChatGPT. Чат-бот, который может говорить и вести глубокую беседу и помнить, что вы сказали, что он сказал, может быть правильным. Я попробовал его на длинных выходных, в основном пытаясь сломать его, исследовать пределы ИИ и узнать, что он способен генерировать функциональный код.
В рабочее время мне пришла в голову идея использовать ChatGPT, чтобы полностью выполнять свою работу. По сути, превратите требование в реальный код. Мое требование очень простое: RESTAPI, который имеет возможность глобально приостанавливать и возобновлять вызовы других RESTAPI (также известный как автоматический выключатель). Я решил представить требование в виде диалога, а не эссе, как это делает настоящий владелец продукта.
Сначала я попросил ChatGPT сделать простой фиктивный API, который делает что-то похожее на обычный функциональный RESTAPI.
Я: Напишите Python FastAPI для возврата удаленного IP-адреса пользователя.
ChatGPT:
Вот пример приложения FastAPI, которое возвращает удаленный IP-адрес пользователя:
from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware app = FastAPI() app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"]) app.add_middleware(HTTPSRedirectMiddleware) @app.get("/") async def get_ip_address(request): return {"remote_ip": request.client.host}
Это приложение использует
TrustedHostMiddleware
, чтобы убедиться, что запрос исходит от доверенного хоста (например, «example.com» в данном случае). Он также используетHTTPSRedirectMiddleware
для автоматического перенаправления HTTP-запросов на HTTPS.
Чтобы получить доступ к IP-адресу пользователя, приложение использует атрибут
request.client.host
. Это возвращает IP-адрес клиента пользователя, который в данном случае является удаленным IP-адресом.
В этот момент я уже был впечатлен результатом. Он описывает, что код делает действительно хорошо, но я не буду его запускать, так как это не является реальным требованием. Я продолжаю просить о своем главном требовании.
Я: добавьте функцию приостановки и возобновления работы API
ChatGPT:
Вот пример того, как вы можете добавить функцию для приостановки и возобновления работы приложения FastAPI:
from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware from starlette.requests import Request from starlette.responses import Response app = FastAPI() app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"]) app.add_middleware(HTTPSRedirectMiddleware) PAUSED = False @app.middleware("http") async def pause_middleware(request: Request, call_next): global PAUSED if PAUSED: return Response("The API is currently paused", status_code=503) response = await call_next(request) return response @app.get("/pause") async def pause(): global PAUSED PAUSED = True return {"message": "The API has been paused"} @app.get("/resume") async def resume(): global PAUSED PAUSED = False return {"message": "The API has been resumed"} @app.get("/") async def get_ip_address(request): return {"remote_ip": request.client.host}
Это приложение добавляет глобальную переменную
PAUSED
, которая изначально имеет значениеFalse
. Он также добавляет функциюpause_middleware
, которая проверяет значение переменнойPAUSED
и возвращает ответ с кодом состояния503
(служба недоступна), если работа API приостановлена. Это промежуточное ПО добавляется в приложение с помощью декоратораapp.middleware
, что позволяет ему выполняться для каждого HTTP-запроса.
Приложение также добавляет две новые конечные точки:
/pause
и/resume
, которые можно использовать для приостановки и возобновления работы API соответственно. Эти конечные точки просто переключают значение переменнойPAUSED
.
Когда работа API приостановлена, все запросы к нему будут получать ответ с кодом состояния
503
и сообщением о том, что работа API приостановлена. Когда он будет возобновлен, запросы будут обрабатываться в обычном режиме.
Это продолжает меня впечатлять. Он добавил промежуточное программное обеспечение для перехвата всех запросов и проверки состояния приостановки с помощью глобальной переменной PAUSED и возврата HTTP-ошибки 503, когда она приостановлена. На самом деле я копирую код и запускаю его в своей реальной работе, но мне не нравится результат ошибки, который представляет собой простой текст. Я мог бы легко изменить его сам, но я мог бы просто попросить ChatGPT изменить его.
ME: Измените ответ промежуточного программного обеспечения на JSON
ChatGPT:
Вот пример того, как вы можете изменить промежуточное ПО в предыдущем примере, чтобы возвращать ответ JSON вместо обычного текстового ответа: Скопировать код
from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware from starlette.requests import Request from starlette.responses import JSONResponse app = FastAPI() app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"]) app.add_middleware(HTTPSRedirectMiddleware) PAUSED = False @app.middleware("http") async def pause_middleware(request: Request, call_next): global PAUSED if PAUSED: return JSONResponse( {"message": "The API is currently paused"}, status_code=503 ) response = await call_next(request) return response @app.get("/pause") async def pause(): global PAUSED PAUSED = True return {"message": "The API has been paused"} @app.get("/resume") async def resume(): global PAUSED PAUSED = False return {"message": "The API has been resumed"} @app.get("/") async def get_ip_address(request): return {"remote_ip": request.client.host}
Это приложение похоже на предыдущий пример, но вместо того, чтобы возвращать объект
Response
в промежуточном программном обеспечении, оно возвращает объектJSONResponse
. Это позволяет указать тело ответа JSON и код состояния HTTP.
Он может запомнить сгенерированный код. Я могу исправить код, просто поговорив с ним, но в коде есть серьезный недостаток. Он не может возобновить работу API после первой паузы, вызванной при вызове /resume промежуточного программного обеспечения, всегда отвечает 503 и не сможет снова изменить флаг PAUSED. Я рассеянно спросил о проблеме.
Я: Но как он может возобновиться, если промежуточное ПО всегда отвечает ошибкой 503?
ЧатGPT:
Промежуточное ПО возвращает ответ с кодом состояния
503
только в том случае, если переменнаяPAUSED
равнаTrue
. Если переменнаяPAUSED
равнаFalse
, ПО промежуточного слоя просто передает запрос следующему компоненту ПО промежуточного слоя или обработчику конечной точки, а ответ обрабатывается как обычно.
Это означает, что когда вызывается конечная точка
/resume
и для переменнойPAUSED
установлено значениеFalse
, промежуточное программное обеспечение не будет возвращать ответ, а запрос будет обрабатываться обработчиком конечной точки. Это позволяет возобновить работу API и снова начать обслуживать запросы.
Вот пример того, как это может выглядеть:
Первоначально переменная
PAUSED
имеет значениеFalse
.
Выполняется запрос к конечной точке
/
Вызывается функция
pause_middleware
и проверяет значение переменнойPAUSED
Переменная
PAUSED
равнаFalse
, поэтому промежуточное ПО передает запрос обработчику конечной точкиget_ip_address
.
Обработчик конечной точки
get_ip_address
возвращает ответ с IP-адресом пользователя.
Ответ возвращается клиенту
Теперь предположим, что вызывается конечная точка
/pause
, которая устанавливает для переменнойPAUSED
значениеTrue
. Если сделать запрос к конечной точке/
, произойдет следующее:
Переменная
PAUSED
установлена наTrue
Выполняется запрос к конечной точке
/
Вызывается функция
pause_middleware
и проверяет значение переменнойPAUSED
Переменная
PAUSED
имеет значениеTrue
, поэтому промежуточное ПО возвращает ответ JSON с кодом состояния503
и сообщением о том, что работа API приостановлена.
Ответ возвращается клиенту
Если вызывается конечная точка
/resume
, которая устанавливает для переменнойPAUSED
значениеFalse
, последующие запросы к конечной точке/
будут обрабатываться как обычно, поскольку промежуточное ПО будет передавать их обработчику конечной точки вместо возврата ответа.
Ответ в основном описывает простую логическую логику, как будто мне было 10 лет, и я ничего не исправил. Я должен спросить еще раз, но более конкретно о логической ошибке.
Я: Но он не может использовать /resume для возобновления работы API, пока переменная PAUSED имеет значение True, потому что промежуточное ПО всегда будет возвращать ошибку 503.
ChatGPT:
Вы правы в том, что если переменная
PAUSED
равнаTrue
, промежуточное ПО всегда будет возвращать ответ с кодом состояния503
, а конечная точка/resume
не сможет возобновить работу API.
Однако вы можете изменить промежуточное ПО, чтобы оно возвращало ответ только с кодом состояния
503
, если путь запроса не/resume
. Это позволит вызывать конечную точку/resume
, даже если переменнаяPAUSED
равнаTrue
.
Вот пример того, как вы могли бы это сделать:
from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware from starlette.requests import Request from starlette.responses import JSONResponse app = FastAPI() app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"]) app.add_middleware(HTTPSRedirectMiddleware) PAUSED = False @app.middleware("http") async def pause_middleware(request: Request, call_next): global PAUSED if PAUSED and request.url.path != "/resume": return JSONResponse( {"message": "The API is currently paused"}, status_code=503 ) response = await call_next(request) return response @app.get("/pause") async def pause(): global PAUSED PAUSED = True return {"message": "The API has been paused"} @app.get("/resume") async def resume(): global PAUSED PAUSED = False return {"message": "The API has been resumed"} @app.get("/") async def get_ip_address(request): return {"remote_ip": request.client.host}
В этом приложении функция
pause_middleware
проверяет значение переменнойPAUSED
, но возвращает ответ с кодом состояния503
только в том случае, если переменнаяPAUSED
равнаTrue
, а путь запроса не равен/resume
. Это позволяет вызывать конечную точку/resume
, даже когда работа API приостановлена.
Когда вызывается конечная точка
/resume
, она устанавливает для переменнойPAUSED
значениеFalse
, что приводит к тому, что промежуточное ПО перестает возвращать ответ с кодом состояния503
для последующих запросов. Это позволяет возобновить работу API и снова начать обслуживать запросы.
Это показывает, как он может уверенно ошибаться и бесстыдно признавать свою ошибку. Кроме того, может исправить себя, если дать руководство. При этом я пытаюсь сам исправить код с помощью GitHub Copilot. Он завершает условие промежуточного ПО с помощью request.url.path != “/pause”, что неверно. Я копирую код из ChatGPT и добавляю его в реальный проект.
Теперь я почти уверен, что ChatGPT может кодировать из требований и может быть адаптирован к изменениям. Но я чувствую, что кодирование ИИ — это временное решение. Разработка программного обеспечения в далеком будущем может не нуждаться в языке программирования. Мы можем просто говорить на естественном языке с ИИ, и он сгенерирует работающий исполняемый двоичный файл, который делает то, что мы сказали.