In this case:
a = "{dic[string_key]}"
print(a.format(dic=dic))
... the string is formatted when .format() is called and that function uses a formatting language that is documented here https://docs.python.org/3/library/string.html#formatstrings.
But in this case:
b = f"{dic['string_key']}"
print(b)
... the string is formatted when the assignment to b is executed, by Python itself. The expression inside the f-string follows normal Python syntax, with the exception that you cannot reuse the quotes used to enclose the f-string.
As a result, you need to specify the quotes around the dictionary key as you would normally, while the mini-language for .format() expects you to omit them.
Also note that this makes a lot of sense: b = f"{dic[string_key]}" should use the value of the variable string_key to index the dictionary.