In addition to the other answers, in case you wish to get more familiar with expl3's various expansion-types:
If you want to rely on the statement of interface3.pdf that token-list-variables can be retrieved directly, i.e., without needing a \tl_use:N, within a single expansion-step, you can combine o-expansion with \exp_after:wN:
\ExplSyntaxOn
\tl_set:Nn \l_tmpa_tl {a}
\tl_set:No \l_tmpb_tl {\exp_after:wN \mathbf \exp_after:wN {\l_tmpa_tl}}
\tl_set:Nn \l_tmpa_tl {b}
%\(\l_tmpb_tl\)
\tl_show:N \l_tmpa_tl
\tl_show:N \l_tmpb_tl
%
% Neither \documenclass nor \begin{document} was used, so let's end the
% latex-run with the sledgehammer:
%
\stop
If you don't like \exp_after:wN, you can trigger f-expansion and have that stopped by an explicit space-token ~ or by an implicit space-token \exp_stop_f: which gets discarded by the f-expansion-mechanism when stopping:
\ExplSyntaxOn
\tl_set:Nn \l_tmpa_tl {a}
\tl_set:Nf \l_tmpb_tl {\exp_args:NnV \use:n {\exp_stop_f: \mathbf} \l_tmpa_tl}
\tl_set:Nn \l_tmpa_tl {b}
%\(\l_tmpb_tl\)
\tl_show:N \l_tmpa_tl
\tl_show:N \l_tmpb_tl
%
% Neither \documenclass nor \begin{document} was used, so let's end the
% latex-run with the sledgehammer:
%
\stop
If you want to make sure that things might still work out when expl3-policy reagarding direct usage of token-list-variables changes, you can combine o-expansion, \exp:w/\exp_end:-expansion and \exp_args:NnV:
\ExplSyntaxOn
\tl_set:Nn \l_tmpa_tl {a}
\tl_set:No \l_tmpb_tl {\exp:w \exp_args:NnV \use:n {\exp_end: \mathbf} \l_tmpa_tl}
\tl_set:Nn \l_tmpa_tl {b}
%\(\l_tmpb_tl\)
\tl_show:N \l_tmpa_tl
\tl_show:N \l_tmpb_tl
%
% Neither \documenclass nor \begin{document} was used, so let's end the
% latex-run with the sledgehammer:
%
\stop