1. 學習背景
在LangChain for LLM應用程序開發中課程中,學習了LangChain框架擴展應用程序開發中語言模型的用例和功能的基本技能,遂做整理為后面的應用做準備。視頻地址:基于LangChain的大語言模型應用開發+構建和評估高
2. 先準備嘗試調用OpenAI API
本實驗基于jupyternotebook進行。
2.1先安裝openai包、langchain包
!pip install openai
!pip install langchain
2.2 嘗試調用openai包
import openai# 此處需要提前準備好可使用的openai KEY
openai.api_key = "XXXX"
openai.base_url = "XXXX"def get_completion(prompt, model = "gpt-3.5-turbo"):messages = [{"role": "user", "content": prompt}]response = openai.chat.completions.create(model = model,messages = messages,temperature = 0,)return response.choices[0].message.content
get_completion("What is 1+1?")
輸出結果:
'1 + 1 equals 2.'
3.嘗試用API解決郵件對話問題
3.1 郵件內容和風格
customer_email = """
Arrr, I be fuming that me blender lid \
flew off and splattered me kitchen walls \
with smoothie! And to make matters worse,\
the warranty don't cover the cost of \
cleaning up me kitchen. I need yer help \
right now, matey!
"""style = """American English \
in a calm and respectful tone
"""
3.2 構造成prompt
prompt = f"""Translate the text \
that is delimited by triple backticks \
into a style that is {style}.
text: ```{customer_email}```
"""
prompt
輸出如下:
"Translate the text that is delimited by triple backticks into a style that is American English in a calm and respectful tone\n. \ntext: ```\nArrr, I be fuming that me blender lid flew off and splattered me kitchen walls with smoothie! And to make matters worse,the warranty don't cover the cost of cleaning up me kitchen. I need yer help right now, matey!\n```\n"
3.3 使用上述prompt得到答案
response = get_completion(prompt)
response
輸出如下:
'I must express my frustration that my blender lid unexpectedly came off and caused my kitchen walls to be covered in smoothie splatters! And unfortunately, the warranty does not cover the cleaning costs of my kitchen. I kindly request your immediate assistance, my friend.'
4. 嘗試用langchain解決
4.1 用langchain調用API
from langchain.chat_models import ChatOpenAI
chat = ChatOpenAI(api_key = "XXXX",base_url = "XXXX",temperature=0.0)
print(chat)
輸出如下:
ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x7f362ab4f340>,
async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x7f362aba9d80>,
temperature=0.0, openai_api_key='sk-gGSeHiJn09Ydl6Q1655eCf128b3a42XXXXXXXXXXXXXX',
openai_api_base='XXXX', openai_proxy='')
4.2 構造prompt模板
注意和3.2的區別,一個用了f"“”“”“,一個直接”“”“”"。
template_string = """Translate the text \
that is delimited by triple backticks \
into a style that is {style}. \
text: ```{text}```
"""customer_style = """American English in a calm and respectful tone"""customer_email = """
Arrr, I be fuming that me blender lid \
flew off and splattered me kitchen walls \
with smoothie! And to make matters worse, \
the warranty don't cover the cost of \
cleaning up me kitchen. I need yer help \
right now, matey!
"""
4.3 調用ChatPromptTemplate
from langchain.prompts import ChatPromptTemplate
# 將構造的prompt模板化
prompt_template = ChatPromptTemplate.from_template(template_string)
# 模板中的占位符填充的參數
customer_messages = prompt_template.format_messages(style = customer_style,text = customer_email
)
print(type(customer_messages))
print(customer_messages[0])
輸出如下:
<class 'list'>
content="Translate the text that is delimited by triple backticks into a style that is American English in a calm and respectful tone\n. text: ```\nArrr, I be fuming that me blender lid flew off and splattered me kitchen walls with smoothie! And to make matters worse, the warranty don't cover the cost of cleaning up me kitchen. I need yer help right now, matey!\n```\n"
4.4 使用LLM解決問題
# Call the LLM to translate to the style of the customer message
customer_response = chat(customer_messages)
print(customer_response.content)
輸出如下:
Oh man, I 'm really frustrated that my blender lid flew off and made a mess of my kitchen walls with smoothie! And on top of that, the warranty doesn't cover the cost of cleaning up my kitchen. I could really use your help right now, buddy!
5. 調用langchain對郵件回復
5.1定義回復的prompt
service_reply = """Hey there customer, \
the warranty does not cover \
cleaning expenses for your kitchen \
because it's your fault that \
you misused your blender \
by forgetting to put the lid on before \
starting the blender. \
Tough luck! See ya!
"""service_style_pirate = """\
a polite tone \
that speaks in English Pirate\
"""# 繼續使用前面定義的prompt_template,占位符用參數填充
service_messages = prompt_template.format_messages(style = service_style_pirate,text = service_reply)print(service_messages[0].content)
輸出如下:
Translate the text that is delimited by triple backticks into a style that is a polite tone that speaks in English Pirate.
text: ```
Hey there customer, the warranty does not cover cleaning expenses for your kitchen because it's your fault that you misused your blender by forgetting to put the lid on before starting the blender. Tough luck! See ya!```
5.2 使用LLM解決問題
service_response = chat(service_messages)
print(service_response.content)
輸出如下:
Ahoy there, me heartie! Unfortunately, the warranty be not coverin' the cost of cleanin' yer kitchen, as tis yer own fault for misusin' yer blender by forgettin' to put on the lid afore startin' the blendin'. Aye, 'tis a tough break indeed! Fare thee well, matey!
至此我們就完成了使用langchain去實現prompt的構造、轉換和調用。
6. 用langchain轉化回答為JSON格式
6.1 構造模板
# 顧客對產品的評論
customer_review = """\
This leaf blower is pretty amazing. It has four settings:\
candle blower, gentle breeze, windy city, and tornado. \
It arrived in two days, just in time for my wife's \
anniversary present. \
I think my wife liked it so much she was speechless. \
So far I've been the only one using it, and I've been \
using it every other morning to clear the leaves on our lawn. \
It's slightly more expensive than the other leaf blowers \
out there, but I think it's worth it for the extra features.
"""# 顧客意見形成模板
review_template = """\
For the following text, extract the following information:gift: Was the item purchased as a gift for someone else? \
Answer True if yes, False if not or unknown.delivery_days: How many days did it take for the product \
to arrive? If this information is not found, output -1.price_value: Extract any sentences about the value or price,\
and output them as a comma separated Python list.Format the output as JSON with the following keys:
gift
delivery_days
price_valuetext: {text}
"""from langchain.prompts import ChatPromptTemplate
# 構造模板,占位符信息用prompt填充
prompt_template = ChatPromptTemplate.from_template(review_template)
messages = prompt_template.format_messages(text=customer_review)
# 調用LLM,輸入為prompt
response = chat(messages)
print(response.content)
輸出如下:
{"gift": true,"delivery_days": 2,"price_value": "It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features."
}
6.2 構造合適的prompt
print(type(response.content))
輸出如下:
str
可以看到輸出內容是字符串類型的,為了方便處理數據,我們需要的是JSON格式,因此還需要進行轉化。
from langchain.output_parsers import ResponseSchema
from langchain.output_parsers import StructuredOutputParsergift_schema = ResponseSchema(name="gift", description="Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.")
delivery_days_schema = ResponseSchema(name="delivery_days", description="How many days did it take for the product to arrive? If this information \is not found, output -1.")
price_value_schema = ResponseSchema(name="price_value", description="Extract any sentences about the value or price, and output them as a comma \separated Python list.")response_schemas = [gift_schema, delivery_days_schema,price_value_schema]
# 構造轉換器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = output_parser.get_format_instructions()
print(format_instructions)
輸出如下:
The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":```json
{"gift": string // Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown."delivery_days": string // How many days did it take for the product to arrive? If this information is not found, output -1."price_value": string // Extract any sentences about the value or price, and output them as a comma separated Python list.
}```
LLM會根據構造的prompt進行回答,生成最終的回答結果。接著構造完整的prompt:
review_template_2 = """\
For the following text, extract the following information:gift: Was the item purchased as a gift for someone else? \
Answer True if yes, False if not or unknown.delivery_days: How many days did it take for the product\
to arrive? If this information is not found, output -1.price_value: Extract any sentences about the value or price,\
and output them as a comma separated Python list.text: {text}{format_instructions}
"""prompt = ChatPromptTemplate.from_template(template=review_template_2)
messages = prompt.format_messages(text=customer_review, format_instructions=format_instructions)
print(messages[0].content)
輸出如下:
For the following text, extract the following information:gift: Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.delivery_days: How many days did it take for the productto arrive? If this information is not found, output -1.price_value: Extract any sentences about the value or price,and output them as a comma separated Python list.text: This leaf blower is pretty amazing. It has four settings:candle blower, gentle breeze, windy city, and tornado. It arrived in two days, just in time for my wife's anniversary present. I think my wife liked it so much she was speechless. So far I've been the only one using it, and I've been using it every other morning to clear the leaves on our lawn. It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features.The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":```json
{"gift": string // Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown."delivery_days": string // How many days did it take for the product to arrive? If this information is not found, output -1."price_value": string // Extract any sentences about the value or price, and output them as a comma separated Python list.
}```
6.3 使用LLM解決問題
response = chat(messages)
print(response.content)
輸出如下:
```json
{"gift": "True","delivery_days": "2","price_value": "It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features."
}```
進行格式轉換
output_dict = output_parser.parse(response.content)
print(output_dict)
輸出如下:
{'gift': 'True', 'delivery_days': '2', 'price_value': "It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features."}
接下來查看輸出類型:
type(output_dict)
輸出如下:
dict
接下來就可以愉快的使用輸出數據了。
總的來說,langchain對于格式化輸出和prompt構造擁有較好的效果,可以很好使用。