of GPT

In my day-to-day at, we're knee-deep in design systems, and as part of our knowledge-sharing culture, we produce tons of insightful blog posts. However, keeping up with all of the content can feel daunting. I was thinking this could be a good use case for Chat GPT's API - it seemed like the perfect tool to create concise summaries of our blog posts to help me (and others) keep up to date with blog posts.

I already had access to Chat GPT's API from a side project I was dabbling in. It was a Python project with the necessary setup, making it the perfect launchpad for this new experiment.

The first step was to gather all the blog post URLs. employs a robust CMS named Sanity. Looking at the API for Sanity and Rangle's site I found the list of all the blog posts in one of the API requests.

import requests
import json

res = requests.get('*%5B_type%20%3D%3D%20%22blogPost%22%0A%20%26%26%20!(_id%20in%20path(%27drafts.**%27))')
with open('blogPosts.json', 'w') as file:
  json.dump(res.json(), file)

This query looks like gibberish but by putting it through a URL decoder you get an easier-to-read query*[_type == "blogPost"
 && !(_id in path('drafts.**')) && "ds" in topicTags[]->.id] | order(publishDate desc)[0...99]
  "id": _id,

Having compiled the list of all blog post pages, we now scrape the HTML pages rather than navigating through Sanity's API.

With Beautiful Soup, I parsed the text from the HTML, effectively preparing the data for Chat GPT.

import requests
import json
from bs4 import BeautifulSoup

with open('blogPosts.json') as json_file:
  blogPosts = json.load(json_file)['result']

for blogPost in blogPosts:
  print('scraping blog post %s'%blogPost['slug'])
  res = requests.get(''%blogPost['slug'])
  soup = BeautifulSoup(res.text, 'html.parser')
  with open('blogPosts/%s.txt'%blogPost['slug'], 'w') as outfile:
    for p in soup.find('article').find_all('p'):
      outfile.write(p.text + '\n')

Then fed each article into Chat GPT, storing the returned responses. I initially considered having GPT output the data in JSON format (which can be unreliable), so in the interest of a more reliable structure, I opted for lists.

import requests
import json
import os

context = '''
convert the content into point form
each point should have enough context to be understood and useful
each point should provide a piece of wisdom or insight
be very informative and to the point
do not use any filler words

texts = []
for filename in os.listdir('blogPosts'):
  with open('blogPosts/%s'%filename) as file:
    name = filename.split('.')[0]

summaries = []
for text in texts:
    data = {
          'content': context
          'content': text['text'] # the content of the blog post
    config = {
      'headers': {
        'Authorization': f'Bearer {apiKey}',

    response ='', json=data, headers=config['headers'])
    summary = response.json()['choices'][0]['message']['content']
    # add to a file text
    with open('summaries.txt', 'a') as file:

Looking at the responses, some of the summaries were more like advice than summaries. This sparked the idea of a "Guru" bot - a kind of AI that provides random advice on Design System related topics.

Next was to format the data to be useable for the site, basically transforming the text into a JSON object with arrays of summaries via find and replace operations.

With the data all set, I initialized a Vite TypeScript project, implementing a feature that randomizes the piece of content to display. This way, each visit offers a fresh piece of summarized knowledge with a link out to the related blog post.

Published on: 2023-06-04