---
# System prepended metadata

title: '[LangChain] 範例－飲食敘述分類'
tags: [LangChain_samples]

---

# [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的功能，可將不具有結構的文字敘述變成結構化的輸出，如上。經過整理過的資訊，會更方便進行後續的運用。





