langchain
langchain copied to clipboard
Add chain to get multiple inputs from the LLM
Right now, it seems that if you want to get multiple inputs from the LLM, you have to write a custom regex parser like ZeroShotAgent does with its get_action_and_input. I would like to suggest that we add an optional generic way to retrieve such inputs.
Please feel free to suggest or make changes to this PR!
im not sure i really understand what this will be used for, so having a tough time reviewing it. what's a concrete example of how you would use it?
sorry for not understanding!
Sorry, I should've been clearer :P
You can use it like this to quickly get multiple inputs, one at a time:
from langchain.chains.multiple_outputs import GetMultipleOutputsChain
from langchain.llms.openai import OpenAI
llm = OpenAI(temperature=0, model_name="text-davinci-002")
print(GetMultipleOutputsChain(
llm=llm,
prefix="Generate a fictional person for me. Make sure to put all attributes in quotes.\n\n",
variables={
"first_name": "First Name",
"last_name": "Last Name",
"dob": "Date of birth",
"gender": "Gender",
"address": "Address",
}
)({}))
Output:
{'first_name': 'Lydia', 'last_name': 'Smith', 'dob': 'June 12, 1990', 'gender': 'Female', 'address': '123 Elm Street'}
Extra complexity results from allowing the user to specify their own per-variable prompting for different types of LLM output (e.g. code blocks). For example, to get multiple pieces of code all at once:
from langchain.chains.multiple_outputs import GetMultipleOutputsChain, VariableConfig
from langchain.llms.openai import OpenAI
PREFIX = """
This is a Python function that calculates the Fibonacci sequence in a slow, recursive way.
```python
def fib(n):
if n == 0 or n == 1:
return n
return fib(n - 1) + fib(n - 2)
```
Now rewrite this function in C++, JS, and Rust, along with accompany tests for each. Make sure to surround each code block with ```. Begin:
"""
async def do():
llm = OpenAI(temperature=0, model_name="code-davinci-002")
print(GetMultipleOutputsChain(
llm=llm,
prefix=PREFIX,
variable_configs=[
VariableConfig.for_code("cpp", "C++ Code", language="cpp"),
VariableConfig.for_code("cpp_tests", "C++ Test Code", language="cpp"),
VariableConfig.for_code("js", "JS Code", language="js"),
VariableConfig.for_code("js_tests", "JS Test Code", language="js"),
]
)({}))
Fragment of result (colored text is LLM output - sorry I mentioned "Rust" in the prefix but forgot to add it in the list of outputs to get from the LLM):
Having this chain lets you ask for all that without needing special parsing logic every time you want multiple outputs out of the LLM.
If you've gotten it working but don't want to use so many LLM calls, you can also write a custom output parser and parse the generated outputs all at once. Here is me refactoring ZeroShotAgent to use get_action_and_input as the basis for an output parser, so that I can compare between asking it for one input at a time, versus asking it for many (and also to compare between returning "Final Answer" as a decision rather than as a special dialogue option):
https://github.com/amosjyng/langchain/commit/a4670feb#diff-a97b7d5316f498629288bf0ce84cb650892bc9eeb696c16cf51fafcb5cde789a
Results were mixed in that case, but I had wanted to experiment to see how it goes.
This is the general idea. Please let me know if that helps clear things up!
Closing as stale