# [LangChain] 範例-飲食敘述分類 日期:2023/09/19 ## 敘述 - 主題:StructuredOutputParser()、ResponseSchema() - 使用情境:讓程式自行將描述的飲食種類,根據六大類食物進行分類。利用GPT模型對文字的理解能力,自行分類描述的食物,讓食物種類確認這件事變簡單。 - 輸入:飲食敘述。例如:我今天吃了兩塊巧克力、一塊pizza。 - 輸出:將輸入中提及的飲食根據食物六大類進行分類。 備註: 此篇範例將作為下一個範例的其中一個功能。 ## 目錄 - [1. 主程式](#1-主程式) - [2. 輸入輸出](#2-輸入輸出) ____________________ ## 1. 主程式 導入套件 ```python= from dotenv import load_dotenv load_dotenv() from langchain.chat_models import ChatOpenAI from langchain.prompts import ( PromptTemplate ) from langchain import LLMChain from langchain.output_parsers import StructuredOutputParser, ResponseSchema llm = ChatOpenAI(temperature=0) llm_model = "gpt-3.5-turbo" ``` 在本次的範例中,預期將輸入的飲食敘述進行處理,抓出飲食相關的描述並分類到對應的六大類食物分類中。 首先,透過以下程式碼建立希望的輸出格式。每個ResponseSchema()將對應到六大類食物的各個類別,其中name為自定義類別名稱,description為類別的敘述,model將會根據這個敘述確認應該如何分類。定義好的六個ResponseSchema()將放入一個串列中。 實際上制定類別或者說輸出架構的過程,就是在定義一個要輸入到model中的prompt。 可從本段程式碼的輸出確認定義好的prompt。 ```python= #定義輸出架構 response_schemas = [ ResponseSchema(name='CER', description='請將<五穀類>的食物放到此處。'), ResponseSchema(name='VEG', description='請將<蔬菜類>的食物放到此處。'), ResponseSchema(name='FRU', description='請將<水果類>的食物放到此處。'), ResponseSchema(name='M&L', description='請將<肉類和豆類>的食物放到此處。'), ResponseSchema(name='DAIRY', description='請將<奶製品類>的食物放到此處。'), ResponseSchema(name='F&N', description='請將<油脂和堅果類>的食物放到此處。'), ] output_parser = StructuredOutputParser.from_response_schemas(response_schemas) print(output_parser.get_format_instructions()) ``` :::success The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "\```json" and "```": \```json { "CER": string // 請將<五穀類>的食物放到此處。 "VEG": string // 請將<蔬菜類>的食物放到此處。 "FRU": string // 請將<水果類>的食物放到此處。 "M&L": string // 請將<肉類和豆類>的食物放到此處。 "DAIRY": string // 請將<奶製品類>的食物放到此處。 "F&N": string // 請將<油脂和堅果類>的食物放到此處。 } \``` ::: 除了建立輸出格式外,下一步還需要將此格式加入到PromptTemplate()中,並提供給chain。 ```python= #將前面定義好的輸出架構提供PromptTemplate(),再提供給chain format_instructions = output_parser.get_format_instructions() template="answer the users question as best as possible.\n{format_instructions}\n{question}" prompt = PromptTemplate( template=template, input_variables=["question"], partial_variables={"format_instructions": format_instructions}, output_parser=output_parser ) llm_chain = LLMChain(prompt=prompt, llm=llm) ``` ## 2. 輸入輸出 ```python= input_text = '''請判斷<>中包含的飲食或料理,根據六大類食物進行分類。 <我今天早上吃了十顆哈密瓜、兩個蘋果派,十分過癮;而下午時,吃了一片巧克力蛋糕、一個素食便當。>''' output = llm_chain.predict(question=input_text) print(output) print('-'*30) output = llm_chain.predict_and_parse(question=input_text) print('使用.predict_and_parse():') print(output) ``` :::success \```json { "CER": "", "VEG": "一個素食便當", "FRU": "十顆哈密瓜、兩個蘋果派", "M&L": "", "DAIRY": "", "F&N": "一片巧克力蛋糕" } \``` \------------------------------ 使用.predict_and_parse(): {'CER': '', 'VEG': '一個素食便當', 'FRU': '十顆哈密瓜、兩個蘋果派', 'M&L': '', 'DAIRY': '', 'F&N': '一片巧克力蛋糕'} ::: 透過LangChain中OutputParser的功能,可將不具有結構的文字敘述變成結構化的輸出,如上。經過整理過的資訊,會更方便進行後續的運用。