pub struct RunnableParallel<I: Send + Sync + 'static> { /* private fields */ }Expand description
A Runnable that runs multiple steps in parallel on the same input.
Each step is identified by a string key. The output is a
HashMap<String, Value> where each key maps to the corresponding
step’s output (serialized as serde_json::Value).
§Example
let parallel = RunnableParallel::<String>::new()
.with("length", RunnableLambda::new_sync(|s: String| s.len() as i64))
.with("upper", RunnableLambda::new_sync(|s: String| s.to_uppercase()));
let result = parallel.invoke("hello".to_string(), None).await?;
// result = {"length": 5, "upper": "HELLO"}Implementations§
Source§impl<I: Clone + Send + Sync + 'static> RunnableParallel<I>
impl<I: Clone + Send + Sync + 'static> RunnableParallel<I>
Sourcepub fn with<O, R>(self, key: &str, runnable: R) -> Self
pub fn with<O, R>(self, key: &str, runnable: R) -> Self
Add a step with the given key.
The step’s output will be serialized to serde_json::Value
and stored under the key in the output HashMap.
Sourcepub fn assign<O, R>(
self,
key: &str,
runnable: R,
) -> RunnableSequence<I, HashMap<String, Value>>
pub fn assign<O, R>( self, key: &str, runnable: R, ) -> RunnableSequence<I, HashMap<String, Value>>
Add an assign step that injects a new key into the output HashMap.
This is the LCEL equivalent of Python’s RunnableParallel.assign().
It pipes the parallel output (a HashMap<String, Value>) through
a RunnableAssign that runs the given runnable on the HashMap
and merges the result under the specified key.
§Example
let chain = RunnableParallel::<String>::new()
.with("context", retriever.pipe(format_docs))
.assign("question", RunnableLambda::new_sync(|m: HashMap<String, Value>| {
m.get("context").map(|c| c.to_string()).unwrap_or_default()
}))
.pipe(prompt_template)
.pipe(llm);§How it works
assign() returns self.pipe(RunnableAssign). The RunnableAssign
receives the HashMap output from the parallel step, runs the
provided runnable on it, and merges the result back.
Trait Implementations§
Source§impl<I: Clone + Send + Sync + 'static> Runnable<I, HashMap<String, Value>> for RunnableParallel<I>
impl<I: Clone + Send + Sync + 'static> Runnable<I, HashMap<String, Value>> for RunnableParallel<I>
Source§fn invoke<'life0, 'async_trait>(
&'life0 self,
input: I,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<HashMap<String, Value>, LcelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn invoke<'life0, 'async_trait>(
&'life0 self,
input: I,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<HashMap<String, Value>, LcelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Execute all steps in parallel using tokio tasks.
Source§fn batch<'life0, 'async_trait>(
&'life0 self,
inputs: Vec<I>,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<Vec<HashMap<String, Value>>, LcelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn batch<'life0, 'async_trait>(
&'life0 self,
inputs: Vec<I>,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<Vec<HashMap<String, Value>>, LcelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Batch: each step processes all inputs independently.
Source§fn stream<'life0, 'async_trait>(
&'life0 self,
input: I,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<HashMap<String, Value>, LcelError>> + Send>>, LcelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn stream<'life0, 'async_trait>(
&'life0 self,
input: I,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<HashMap<String, Value>, LcelError>> + Send>>, LcelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Stream: invoke and return single-element stream.
Source§fn transform<'life0, 'async_trait>(
&'life0 self,
input: Pin<Box<dyn Stream<Item = Result<Input, Self::Error>> + Send>>,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<Output, Self::Error>> + Send>>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn transform<'life0, 'async_trait>(
&'life0 self,
input: Pin<Box<dyn Stream<Item = Result<Input, Self::Error>> + Send>>,
config: Option<RunnableConfig>,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<Output, Self::Error>> + Send>>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Auto Trait Implementations§
impl<I> !RefUnwindSafe for RunnableParallel<I>
impl<I> !UnwindSafe for RunnableParallel<I>
impl<I> Freeze for RunnableParallel<I>
impl<I> Send for RunnableParallel<I>
impl<I> Sync for RunnableParallel<I>
impl<I> Unpin for RunnableParallel<I>
impl<I> UnsafeUnpin for RunnableParallel<I>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<I, O, R> RunnableExt<I, O> for R
impl<I, O, R> RunnableExt<I, O> for R
Source§fn pipe<O2, R2>(self, other: R2) -> RunnableSequence<Input, O2>
fn pipe<O2, R2>(self, other: R2) -> RunnableSequence<Input, O2>
Source§fn into_sequence(self) -> RunnableSequence<Input, Output>
fn into_sequence(self) -> RunnableSequence<Input, Output>
RunnableSequence from this runnable as a single step. Read more