Return promises of values instead of values, so once steps that depend on a value have run, the values aren't loaded when evaluating later steps
const lazyEmbedding = await step.runAction(..., { lazy: true });
const foo = await step.runMutation(api.foo.bar, { embedding: lazyEmbedding });
the args are now LazyValue where LazyValue is either a Value or Promise<Value> for primitives, or LazyValue[] or Record<string, LazyValue> or { [K in keyof T]: T[K] | Promise<T[K]> }