iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
生成式 AI

RAG自己來系列:客服機器人系列 第 16

[Day 16] Langchain - Parsers & Memory

  • 分享至 

  • xImage
  •  

Parser

若想要將模型的輸出轉換成程式可用的資料型態,我們可以用 Langchain 的 StructuredOutputParser 的方法去幫我們達成,其實現方法也就是在打一次請求,將我們 invoke 的結果送回 LLM 幫我們轉換成 Markdown 或 Json 格式的資料

from langchain_community.chat_models import ChatOllama
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain.output_parsers import ResponseSchema, StructuredOutputParser

response_schemas = [
    ResponseSchema(name="建議", description="模型回覆的建議")
]

output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = output_parser.get_format_instructions()

prompt = PromptTemplate(
    template="請根據使用者給予的內容,給予實質的建議或者有用的回覆,回覆請使用繁體中文.\n{format_instructions}\n{question}",
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions},
)

llm = ChatOllama(
    model="gemma2",
    base_url="http://127.0.0.1:11434"
)

chain = (
    prompt
    | llm
    | output_parser
)

print(chain.invoke({"question": "我想要買一台筆電,但是不知道要選擇哪一台,可以給我一些建議嗎?"}))

可以得出以下回覆

https://ithelp.ithome.com.tw/upload/images/20240924/20146555F5bIRqMaK0.png

也可以從官方文檔中得到更多有關 Parser 的不同用法

Memory

不只輸出格式可以設定,連記憶會話的方法也有不同的選擇

如 ConversationBufferMemory、ConversationBufferWindowMemory 以及 ConversationSummaryBufferMemory 等等

不同的 Memory 方法,適用的時機也不同

ConversationBufferMemory

from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory, ConversationBufferWindowMemory, ConversationSummaryBufferMemory
from langchain_core.prompts.prompt import PromptTemplate

template = """你是一個聊天機器人,請盡根據使用者的需求進行回覆,回覆請使用繁體中文

History:
{history}
Human: {input}
AI Assistant:"""

PROMPT = PromptTemplate(input_variables=["history", "input"], template=template)

conversation = ConversationChain(
    prompt=PROMPT,
    llm=llm,
    verbose=True,
    memory=ConversationBufferMemory()
)
conversation.predict(input="你好!")
conversation.predict(input="告訴烘焙的相關知識")
conversation.predict(input="烘焙技巧和方法")

若我們想要預先初始化先前的對話,也可以直接透過 .save_context() 直接設定

memory = ConversationBufferMemory()
memory.save_context({"input": "告訴烘焙的相關知識"}, {"output": "好的,我可協助您了解烘焙相關知識。請問您想了解哪些方面呢?\n\n* **烘焙材料和方法**\n* **烘焙技巧和方法**\n* **烘焙流程**\n* **烘焙設備**\n* **烘焙常見問題**\n* **烘焙相關歷史**"})

conversation = ConversationChain(
    prompt=PROMPT,
    llm=llm,
    verbose=True,
    memory=memory
)
conversation.predict(input="烘焙技巧和方法")

ConversationBufferWindowMemory

用法與 ConversationBufferMemory 一樣,不過超過 k 所設定的歷史對話將被捨棄,其中原因包含 ConversationBufferMemory 的運作方法就是將歷史對話一起丟給 LLM 去做處理,好處當然就是可以有「對話」的感覺,缺點就是會很吃 Token,畢竟給的不只當前的輸入與輸出,還給了過往的對話紀錄,這時若使用 ChatOpenAI 去打 OpenAI 的服務,可以說,帳單跟 Token 使用量一起起飛。

# 透過 k 來設定留下多少個對話
conversation = ConversationChain(
    prompt=PROMPT,
    llm=llm,
    verbose=True,
    memory=ConversationBufferWindowMemory(k=2),
)
...

ConversationSummaryBufferMemory

我們也可以使用 Langchain 自帶的「總結」工具

memory = ConversationSummaryBufferMemory(llm=llm)
memory.save_context({"input": "告訴烘焙的相關知識"}, {"output": "好的,我可協助您了解烘焙相關知識。請問您想了解哪些方面呢?\n\n* **烘焙材料和方法**\n* **烘焙技巧和方法**\n* **烘焙流程**\n* **烘焙設備**\n* **烘焙常見問題**\n* **烘焙相關歷史**"})

conversation = ConversationChain(
    llm=llm,
    verbose=True,
    memory=memory
)

conversation.predict(input="烘焙技巧和方法")

若使用本地語言模型,則需特別注意模型的回覆效果,倘若模型本身不夠給力,總結有可能失效,或者總結的不好

然後,沒錯,能做到總結功能,也是 Langchain 偷偷幫你再多打一次 API 喔 XD

https://ithelp.ithome.com.tw/upload/images/20240924/20146555uS829z6JDP.png


上一篇
[Day 15] Langchain - Prompt & LLM
下一篇
[Day 17] [複習篇] Day10 ~ Day16 周回複習
系列文
RAG自己來系列:客服機器人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言