mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-25 16:13:25 +00:00
Add basic critique revise template (#12688)
@baskaryan @hwchase17 --------- Co-authored-by: Erick Friis <erick@langchain.dev>
This commit is contained in:
parent
ee3ceb0fb8
commit
cf271784fa
21
templates/basic-critique-revise/LICENSE
Normal file
21
templates/basic-critique-revise/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 LangChain, Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
66
templates/basic-critique-revise/README.md
Normal file
66
templates/basic-critique-revise/README.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# basic-critique-revise
|
||||||
|
|
||||||
|
TODO: What does this package do
|
||||||
|
|
||||||
|
## Environment Setup
|
||||||
|
|
||||||
|
TODO: What environment variables need to be set (if any)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To use this package, you should first have the LangChain CLI installed:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pip install -U "langchain-cli[serve]"
|
||||||
|
```
|
||||||
|
|
||||||
|
To create a new LangChain project and install this as the only package, you can do:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
langchain app new my-app --package basic-critique-revise
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to add this to an existing project, you can just run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
langchain app add basic-critique-revise
|
||||||
|
```
|
||||||
|
|
||||||
|
And add the following code to your `server.py` file:
|
||||||
|
```python
|
||||||
|
from basic_critique_revise import chain as basic_critique_revise_chain
|
||||||
|
|
||||||
|
add_routes(app, basic_critique_revise_chain, path="/basic-critique-revise")
|
||||||
|
```
|
||||||
|
|
||||||
|
(Optional) Let's now configure LangSmith.
|
||||||
|
LangSmith will help us trace, monitor and debug LangChain applications.
|
||||||
|
LangSmith is currently in private beta, you can sign up [here](https://smith.langchain.com/).
|
||||||
|
If you don't have access, you can skip this section
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
export LANGCHAIN_TRACING_V2=true
|
||||||
|
export LANGCHAIN_API_KEY=<your-api-key>
|
||||||
|
export LANGCHAIN_PROJECT=<your-project> # if not specified, defaults to "default"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are inside this directory, then you can spin up a LangServe instance directly by:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
langchain serve
|
||||||
|
```
|
||||||
|
|
||||||
|
This will start the FastAPI app with a server is running locally at
|
||||||
|
[http://localhost:8000](http://localhost:8000)
|
||||||
|
|
||||||
|
We can see all templates at [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)
|
||||||
|
We can access the playground at [http://127.0.0.1:8000/basic-critique-revise/playground](http://127.0.0.1:8000/basic-critique-revise/playground)
|
||||||
|
|
||||||
|
We can access the template from code with:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from langserve.client import RemoteRunnable
|
||||||
|
|
||||||
|
runnable = RemoteRunnable("http://localhost:8000/basic-critique-revise")
|
||||||
|
```
|
@ -0,0 +1,3 @@
|
|||||||
|
from basic_critique_revise.chain import chain
|
||||||
|
|
||||||
|
__all__ = ["chain"]
|
143
templates/basic-critique-revise/basic_critique_revise/chain.py
Normal file
143
templates/basic-critique-revise/basic_critique_revise/chain.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from enum import Enum
|
||||||
|
from operator import itemgetter
|
||||||
|
from typing import Any, Dict, Sequence
|
||||||
|
|
||||||
|
from langchain.chains.openai_functions import convert_to_openai_function
|
||||||
|
from langchain.chat_models import ChatOpenAI
|
||||||
|
from langchain.prompts import ChatPromptTemplate
|
||||||
|
from langchain.pydantic_v1 import BaseModel, Field, ValidationError, conint
|
||||||
|
from langchain.schema.runnable import (
|
||||||
|
Runnable,
|
||||||
|
RunnableBranch,
|
||||||
|
RunnableLambda,
|
||||||
|
RunnablePassthrough,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskType(str, Enum):
|
||||||
|
call = "Call"
|
||||||
|
message = "Message"
|
||||||
|
todo = "Todo"
|
||||||
|
in_person_meeting = "In-Person Meeting"
|
||||||
|
email = "Email"
|
||||||
|
mail = "Mail"
|
||||||
|
text = "Text"
|
||||||
|
open_house = "Open House"
|
||||||
|
|
||||||
|
|
||||||
|
class Task(BaseModel):
|
||||||
|
title: str = Field(..., description="The title of the tasks, reminders and alerts")
|
||||||
|
due_date: datetime = Field(
|
||||||
|
..., description="Due date. Must be a valid ISO date string with timezone"
|
||||||
|
)
|
||||||
|
task_type: TaskType = Field(None, description="The type of task")
|
||||||
|
|
||||||
|
|
||||||
|
class Tasks(BaseModel):
|
||||||
|
"""JSON definition for creating tasks, reminders and alerts"""
|
||||||
|
|
||||||
|
tasks: Sequence[Task]
|
||||||
|
|
||||||
|
|
||||||
|
template = """Respond to the following user query to the best of your ability:
|
||||||
|
|
||||||
|
{query}"""
|
||||||
|
|
||||||
|
generate_prompt = ChatPromptTemplate.from_template(template)
|
||||||
|
|
||||||
|
function_args = {"functions": [convert_to_openai_function(Tasks)]}
|
||||||
|
|
||||||
|
task_function_call_model = ChatOpenAI(model="gpt-3.5-turbo").bind(**function_args)
|
||||||
|
|
||||||
|
output_parser = RunnableLambda(
|
||||||
|
lambda x: json.loads(
|
||||||
|
x.additional_kwargs.get("function_call", {}).get("arguments", '""')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
revise_template = """
|
||||||
|
Based on the provided context, fix the incorrect result of the original prompt
|
||||||
|
and the provided errors. Only respond with an answer that satisfies the
|
||||||
|
constraints laid out in the original prompt and fixes the Pydantic errors.
|
||||||
|
|
||||||
|
Hint: Datetime fields must be valid ISO date strings.
|
||||||
|
|
||||||
|
<context>
|
||||||
|
<original_prompt>
|
||||||
|
{original_prompt}
|
||||||
|
</original_prompt>
|
||||||
|
<incorrect_result>
|
||||||
|
{completion}
|
||||||
|
</incorrect_result>
|
||||||
|
<errors>
|
||||||
|
{error}
|
||||||
|
</errors>
|
||||||
|
</context>"""
|
||||||
|
|
||||||
|
revise_prompt = ChatPromptTemplate.from_template(revise_template)
|
||||||
|
|
||||||
|
revise_chain = revise_prompt | task_function_call_model | output_parser
|
||||||
|
|
||||||
|
|
||||||
|
def output_validator(output):
|
||||||
|
try:
|
||||||
|
Tasks.validate(output["completion"])
|
||||||
|
except ValidationError as e:
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class IntermediateType(BaseModel):
|
||||||
|
error: str
|
||||||
|
completion: Dict
|
||||||
|
original_prompt: str
|
||||||
|
max_revisions: int
|
||||||
|
|
||||||
|
|
||||||
|
validation_step = RunnablePassthrough().assign(error=RunnableLambda(output_validator))
|
||||||
|
|
||||||
|
|
||||||
|
def revise_loop(input: IntermediateType) -> IntermediateType:
|
||||||
|
revise_step = RunnablePassthrough().assign(completion=revise_chain)
|
||||||
|
|
||||||
|
else_step: Runnable[IntermediateType, IntermediateType] = RunnableBranch(
|
||||||
|
(lambda x: x["error"] is None, RunnablePassthrough()),
|
||||||
|
revise_step | validation_step,
|
||||||
|
).with_types(input_type=IntermediateType)
|
||||||
|
|
||||||
|
for _ in range(max(0, input["max_revisions"] - 1)):
|
||||||
|
else_step = RunnableBranch(
|
||||||
|
(lambda x: x["error"] is None, RunnablePassthrough()),
|
||||||
|
revise_step | validation_step | else_step,
|
||||||
|
)
|
||||||
|
return else_step
|
||||||
|
|
||||||
|
|
||||||
|
revise_lambda = RunnableLambda(revise_loop)
|
||||||
|
|
||||||
|
|
||||||
|
class InputType(BaseModel):
|
||||||
|
query: str
|
||||||
|
max_revisions: conint(ge=1, le=10) = 5
|
||||||
|
|
||||||
|
|
||||||
|
chain: Runnable[Any, Any] = (
|
||||||
|
{
|
||||||
|
"original_prompt": generate_prompt,
|
||||||
|
"max_revisions": itemgetter("max_revisions"),
|
||||||
|
}
|
||||||
|
| RunnablePassthrough().assign(
|
||||||
|
completion=(
|
||||||
|
RunnableLambda(itemgetter("original_prompt"))
|
||||||
|
| task_function_call_model
|
||||||
|
| output_parser
|
||||||
|
)
|
||||||
|
)
|
||||||
|
| validation_step
|
||||||
|
| revise_lambda
|
||||||
|
| RunnableLambda(itemgetter("completion"))
|
||||||
|
).with_types(input_type=InputType)
|
1473
templates/basic-critique-revise/poetry.lock
generated
Normal file
1473
templates/basic-critique-revise/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
templates/basic-critique-revise/pyproject.toml
Normal file
24
templates/basic-critique-revise/pyproject.toml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "basic_critique_revise"
|
||||||
|
version = "0.0.1"
|
||||||
|
description = ""
|
||||||
|
authors = []
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = ">=3.8.1,<4.0"
|
||||||
|
langchain = ">=0.0.313, <0.1"
|
||||||
|
openai = "^0.28.1"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
langchain-cli = ">=0.0.15"
|
||||||
|
fastapi = "^0.104.0"
|
||||||
|
sse-starlette = "^1.6.5"
|
||||||
|
|
||||||
|
[tool.langserve]
|
||||||
|
export_module = "basic_critique_revise"
|
||||||
|
export_attr = "chain"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
0
templates/basic-critique-revise/tests/__init__.py
Normal file
0
templates/basic-critique-revise/tests/__init__.py
Normal file
Loading…
Reference in New Issue
Block a user