|
|
@ -1,3 +1,4 @@
|
|
|
|
|
|
|
|
"""Implementation of the RunnablePassthrough."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
import asyncio
|
|
|
@ -31,16 +32,70 @@ from langchain.utils.iter import safetee
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def identity(x: Input) -> Input:
|
|
|
|
def identity(x: Input) -> Input:
|
|
|
|
|
|
|
|
"""An identity function"""
|
|
|
|
return x
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def aidentity(x: Input) -> Input:
|
|
|
|
async def aidentity(x: Input) -> Input:
|
|
|
|
|
|
|
|
"""An async identity function"""
|
|
|
|
return x
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RunnablePassthrough(RunnableSerializable[Input, Input]):
|
|
|
|
class RunnablePassthrough(RunnableSerializable[Input, Input]):
|
|
|
|
"""
|
|
|
|
"""A runnable to passthrough inputs unchanged or with additional keys.
|
|
|
|
A runnable that passes through the input.
|
|
|
|
|
|
|
|
|
|
|
|
This runnable behaves almost like the identity function, except that it
|
|
|
|
|
|
|
|
can be configured to add additional keys to the output, if the input is a
|
|
|
|
|
|
|
|
dict.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The examples below demonstrate this runnable works using a few simple
|
|
|
|
|
|
|
|
chains. The chains rely on simple lambdas to make the examples easy to execute
|
|
|
|
|
|
|
|
and experiment with.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from langchain.schema.runnable import RunnablePassthrough, RunnableParallel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
runnable = RunnableParallel(
|
|
|
|
|
|
|
|
origin=RunnablePassthrough(),
|
|
|
|
|
|
|
|
modified=lambda x: x+1
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
runnable.invoke(1) # {'origin': 1, 'modified': 2}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fake_llm(prompt: str) -> str: # Fake LLM for the example
|
|
|
|
|
|
|
|
return "completion"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chain = RunnableLambda(fake_llm) | {
|
|
|
|
|
|
|
|
'original': RunnablePassthrough(), # Original LLM output
|
|
|
|
|
|
|
|
'parsed': lambda text: text[::-1] # Parsing logic
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chain.invoke('hello') # {'original': 'completion', 'parsed': 'noitelpmoc'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In some cases, it may be useful to pass the input through while adding some
|
|
|
|
|
|
|
|
keys to the output. In this case, you can use the `assign` method:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from langchain.schema.runnable import RunnablePassthrough, RunnableParallel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fake_llm(prompt: str) -> str: # Fake LLM for the example
|
|
|
|
|
|
|
|
return "completion"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
runnable = {
|
|
|
|
|
|
|
|
'llm1': fake_llm,
|
|
|
|
|
|
|
|
'llm2': fake_llm,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
| RunnablePassthrough.assign(
|
|
|
|
|
|
|
|
total_chars=lambda inputs: len(inputs['llm1'] + inputs['llm2'])
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
runnable.invoke('hello')
|
|
|
|
|
|
|
|
# {'llm1': 'completion', 'llm2': 'completion', 'total_chars': 20}
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
input_type: Optional[Type[Input]] = None
|
|
|
|
input_type: Optional[Type[Input]] = None
|
|
|
@ -73,8 +128,7 @@ class RunnablePassthrough(RunnableSerializable[Input, Input]):
|
|
|
|
],
|
|
|
|
],
|
|
|
|
],
|
|
|
|
],
|
|
|
|
) -> RunnableAssign:
|
|
|
|
) -> RunnableAssign:
|
|
|
|
"""
|
|
|
|
"""Merge the Dict input with the output produced by the mapping argument.
|
|
|
|
Merge the Dict input with the output produced by the mapping argument.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
Args:
|
|
|
|
mapping: A mapping from keys to runnables or callables.
|
|
|
|
mapping: A mapping from keys to runnables or callables.
|
|
|
|