I built a daily personal briefing a little while ago, which gives me an overview of the day ahead and information that I’ll find relevant for my day. However, after playing around with GPT-3 for a while, I thought I could improve upon the current solution. GPT-3 should be able to summarize my briefing (as it’s currently a bit wordy and can seem repetitive day-to-day) and inject a touch of personality into it. I can still use Home Assistant to trigger an automation when I enter my office for the first time in the morning, and have it read out by the Echo in my office.

I’m not entirely convinced that GPT-3 is the ultimate solution for this idea as there are other tools and models for text summarization that I might explore in the future. Additionally, I think it would be pretty cool to train a smaller LLM with the existing information I have using something similar to NanoGPT.

Current daily briefing

There are a few key topics that I have been using in my briefing. It currently gives me an overview of:

  • Upcoming calendar events for the day
  • Latest headlines (currently from Sky News)
  • A simple version of the weather
  • Current weather warnings (you can read more about these here)

Currently the Jinja2 template for my non GPT-3 briefing looks like this.


{% set weather = states('sensor.sidebar_weather') %}
{% set weatherWarning = "Careful, there are weather warnings in effect" if states('sensor.met_office_rss_east_midlands_weather_warnings')|int > 0 %}
{% set weathermessage = 
[ 
    "It'll be a ~weather~ day outside today, with highs of <emphasis level='strong'>~high~</emphasis> degrees and lows of <emphasis level='strong'>~low~</emphasis> degrees",
    "It's going to be a ~weather~ day today, you can expect a high of ~high~ degrees and a low of ~low~ degrees"
]|random|replace("~weather~",weather)|replace("~high~",states('sensor.weather_temp_high'))|replace("~low~",states('sensor.weather_temp_low'))
%}
{% set headlines = states.sensor.sky_news_headlines.attributes.entries[:5] | map(attribute='summary_detail') | map(attribute='value') | list | join('\n') %}
<speak>
    Good Morning Mike!
    <break strength="x-strong"/> 
    {{ weatherWarning }}
    {{ weathermessage }}
    <break strength="x-strong"/>
    The latest headlines today: <break strength="x-strong"/> {{ headlines }}
</speak>

Creating a prompt for GPT-3

The replacement prompt that I’ve been playing has some simple instructions, a sentence limit, instructions to be concise and humorous. As well as to use SSML to try and inject a little bit of personality into the update. You can see an example of the full prompt below.

Acting as a personal assistant, summarize the following information in an concise and humorous manner. Try to make sure that the information fits in 8 sentences. Give the response using SSML as well, to make the update upbeat.


- It's 17:49
- Currently 3.9°C outside, high of 5.0°C and a low of 0.6°C 
- Latest headlines: Rishi Sunak will meet Ursula von der Leyen, the European Commission president, tomorrow to solve a "range of complex challenges around the Protocol on Ireland and Northern Ireland".
At least 59 migrants, including 12 children, have drowned after their boat broke up off the southern coast of Italy's mainland.
Israel and the Palestinians have agreed to de-escalate tensions and "prevent more violence".
The body of missing hillwalker Kyle Sambrook and his dog have been found in Glencoe, police confirm.
A beach in Norfolk has been closed off from the public due to erosion and the risk of homes falling into the sea, the Hemsby Lifeboat crew has said.
- Calendar for today

A sample of the output from this prompt is as follows:

<speak>It's <say-as interpret-as="time">17:49</say-as>, and it's currently <say-as interpret-as="temperature">3.9</say-as> degrees outside! The high for today was <say-as interpret-as="temperature">5.0</say-as> and the low was <say-as interpret-as="temperature">0.6</say-as>. In news, Rishi Sunak is meeting Ursula von der Leyen tomorrow to solve a "range of complex challenges" concerning Ireland and Northern Ireland. There was a tragic incident in Italy, with 59 migrants, including 12 children, drowning after their boat broke up. Israel and the Palestinians have agreed to de-escalate tensions. The body of Kyle Sambrook and his dog were found in Glencoe and a beach in Norfolk has been closed off due to erosion. Don't forget about today's calendar!</speak>

Great, now that I’ve got a prompt that I’m happy with (it’s not perfect, the SSML is sporadic and inconsistent. I’m not sure how much value it adds in hindsight), it’s time to think about how this integrates with Home Assistant. If you’re using Node-Red for your automations you might want to build this a different way. But I don’t use Node-Red so, I’m planing on building a small NodeJS application. That will take advantage of being able to use the template API that Home Assistant expose, this will allow me to build the prompt with the relevant information that all is all stored within Home Assistant. Feed this data into GPT-3 and then output the response via the Amazon Echo in my office.

Adding to Home Assistant

With my small NodeJS app, I’m going to keep things simple. I need to call the Home Assistant API to render the template (which will form the prompt), send the prompt to GPT-3 to get the completion back and then call the notify service using the Home Assistant API to get the message read out on the Amazon Echo in my office.

You can find the code for the entire application here

Now that I have a small API up and running, I just need to add a Rest Command to my Home Assistant configuration that calls my API and triggers the process.

rest_command:
  openai_daily_briefing:
    url: "<<URL OF YOUR RUNNING NODEJS APP>>"

Now that I’ve got everything up and running to allow Home Assistant to call the API, and the API to handle the GPT-3 interaction and call back to Home Assistant to trigger the notify service, I can start building the automation. There are a few conditions that I need for this to work properly. Firstly, the briefing should only happen once per day. Second, it should only be played when I enter my office to start work in the morning. Fortunately, I can use my BLE presence detection to detect when I first enter my office each day.


alias: Mike's Office - Briefing
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.mikes_phone_ble_room_presence
    to: mikes-office
condition:
  - condition: template
    value_template: >
      {{
      as_timestamp(state_attr('automation.mike_s_office_briefing','last_triggered'))|timestamp_custom('%-d')
      != as_timestamp(now())|timestamp_custom('%-d') }}
action:
  - service: rest_command.openai_daily_briefing
    data: {}
mode: single

If you found this content helpful, please consider sponsoring me on GitHub or alternatively buying me a coffee

Comments