### [AI / ML領域相關學習筆記入口頁面](https://hackmd.io/@YungHuiHsu/BySsb5dfp)
### [Deeplearning.ai GenAI/LLM系列課程筆記](https://learn.deeplearning.ai/)
#### [Large Language Models with Semantic Search。大型語言模型與語義搜索 ](https://hackmd.io/@YungHuiHsu/rku-vjhZT)
#### [Finetuning Large Language Models。微調大型語言模型](https://hackmd.io/@YungHuiHsu/HJ6AT8XG6)
#### [LangChain for LLM Application Development](https://hackmd.io/1r4pzdfFRwOIRrhtF9iFKQ)
---
[LangChain for LLM Application Development](https://www.youtube.com/watch?v=jFo_gDOOusk) 系列課程筆記
- [Models, Prompts and Output Parsers](https://hackmd.io/1r4pzdfFRwOIRrhtF9iFKQ)
- [Memory](https://hackmd.io/@YungHuiHsu/Hy120mR23)
- [Chains](https://hackmd.io/@YungHuiHsu/SJJvZ-ya2)
- [Question-and-Answer](https://hackmd.io/@YungHuiHsu/BJ10qunzp)
- [Evaluation](https://hackmd.io/@YungHuiHsu/Hkg0SgazT)
- [Agents](https://hackmd.io/@YungHuiHsu/rkBMDgRM6)

source : [LangChain.dart](https://pub.dev/packages/langchain)
---
# [LangChain - Agents](https://learn.deeplearning.ai/langchain/lesson/7/agents)
- [Agents官方文件](https://python.langchain.com/docs/modules/agents/)
## 課程概要
* Agent 是 LangChain 的重要功能,可以連接資料庫、API 等外部資訊來源,讓語言模型能利用這些資訊來推理及回答問題
* 可以使用內建工具像是 DuckDuckGo 搜尋和 Wikipedia,也可以自定義工具來連接自己的資料來源
* Agent 會自動判斷何時該呼叫工具,以獲取所需資訊來回答問題
* 透過修飾函數,可以將任何函數轉換成 Agent 可以使用的工具
* 透過詳細的 docstring 說明,Agent 可以了解工具的使用時機和傳入參數
* Agent 可以幫助語言模型具備推理和綜合資訊的能力,是 LangChain 強大且前衛的功能
## Agents 定義
> - Agents的基本概念
> - 在LLM中語境中,代理是一種工具或實體,它能夠自動執行特定的任務或功能
> - 這些代理通常被設計來與外部數據源、API或其他工具交互,以增強LLM的功能
> - 代理的作用
> * 信息檢索:代理可以從互聯網或特定的數據庫中檢索信息,幫助LLM回答問題或提供更準確的信息
> * 任務自動化:代理可以自動化某些任務,如數據分析、內容生成或其他重複性工作
> * 增強推理能力:通過與外部工具的交互,代理可以幫助LLM進行更複雜的推理和決策過程
>
> source: OpenAI. (2023). ChatGPT [Large language model]. https://chat.openai.com
推薦閱讀[How Agents for LLM Perform Task Planning。大型語言模型的代理如何進行任務規劃](https://hackmd.io/@YungHuiHsu/rkK52BkQp)作為補充背景知識
## Labs
### LangChain內建工具(Built-in LangChain tools)
以下範例使用 LangChain 內建相關工具來學習和構建代理(Agent)
- 程式流程
```mermaid
flowchart TD
A[import modules] --> B[Create ChatOpenAI]
A-->C[Load Tools]
B-->|"ChatOpenAI()"|D
C -->|"load_tools()"| D["Initialize Agent\n initialize_agent(tools, llm, AgentType)"]
D --> |math task |E["Query Agent: 'What is the 25% of 300?'"]
E --> |Receive 'llm-math'|F[Receive Response]
D --> |general task |G["Query Agent: 'Tom M. Mitchell... \nwhat book did he write?'"]
G -->|Receive 'wikipedia'| H[Receive Response]
```
- code
```python=
from langchain.agents.agent_toolkits import create_python_agent
from langchain.agents import load_tools, initialize_agent
from langchain.agents import AgentType
from langchain.tools.python.tool import PythonREPLTool
from langchain.python import PythonREPL
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(temperature=0, model=llm_model)
tools = load_tools(["llm-math","wikipedia"], llm=llm)
agent= initialize_agent(
tools,
llm,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
handle_parsing_errors=True,
verbose = True)
```
- `llm = ChatOpenAI(temperature=0, model=llm_model)`
- 創建一個`ChatOpenAI`對象作為LLM
- temperature=0意味著生成的回答將更確定、更少隨機性
- `load_tools`
- LangChain中用於加載一組特定工具的函數。這些工具能夠增強代理的能力,使其能夠處理更多類型的查詢和任務
- `llm-math` 用於數學計算的接口,使代理能夠處理數學相關的查詢
- `wikipedia` 則提供對維基百科的查詢能力
- `initialize_agent()`
- 用於創建和初始化代理Agent的函數。代理是一種能夠理解和處理查詢的實體,並根據需要使用各種工具來尋找答案或完成任務
- `AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION`
- 指定代理的類型。這個代理是專門為聊天優化,並使用零樣本(zero-shot)反應描述的策略來生成回應
- `handle_parsing_errors=True`
- 這個選項啟用了對於解析錯誤的處理。當代理從工具或語言模型接收到輸出時,這有助於確保錯誤能夠得到恰當的處理。
- `verbose = True`
- 開啟,以觀察代理在執行過程中提供的詳細訊息
以上程式碼建立裝備特定工具(`tools`)和語言模型的代理Agent,指定特定的互動模式(`AgentType`),並準備好處理各類問題,同時在出現錯誤時能夠有效地處理並提供豐富的反饋信息
接著看使用代理進行實驗
- 提問數學任務
- 檢索"llm-math"數學知識庫
`agent("What is the 25% of 300?")`
- :writing_hand:檢模型內部推理過程
- 正確判別問題,使用"Calculator"工具來處理
```mermaid
flowchart TD
B[Thought]
B --> |"We need to calculate 25% of 300, which means we need to multiply 300 by 0.25."| C[Action]
C --> |"{action: Calculator, action_input: 300*0.25}"| D[Observation]
D --> |"Answer: 75.0"| E[Thought2]
E --> |"We have the answer to the question"| F[Final Answer]
F --> |75.0| G[End]
```
- 查詢超出其訓練數據時間範圍的資訊,例如2022年世界盃
展示代理如何運作,尤其是在面對超出其訓練數據範圍的信息時
```PYTHON=
agent("Argentina won the 2022 World Cup")
> Entering new AgentExecutor chain...
The 2022 World Cup has not happened yet, so this statement is false.
Action: I don't know
Final Answer: False
> Finished chain.
{'input': 'Argentina won the 2022 World Cup', 'output': 'False'}
```
- 因為模型訓練資料只到2021,代理意識到需要使用外部工具來查詢
- 代理通過DuckDuckGo搜索來查找2022年世界盃的相關信息。但由於代理是基於先前的數據訓練的,可能誤認為2022年世界盃尚未發生
- 顯示代理在理解和處理超出其訓練數據範圍的新事件上還存在一定的局限性
- 提問知識型任務,查詢Tom M. Mitchell
- 檢索"wikipedia"知識庫
代理識別出需要使用Wikipedia來回答有關Tom M. Mitchell的問題,進行多次搜索來確保獲得正確的答案
```python=
question = "Tom M. Mitchell is an American computer scientist \
and the Founders University Professor at Carnegie Mellon University (CMU)\
what book did he write?"
result = agent(question)
```
- :writing_hand:檢視模型內部推理流程
```mermaid
flowchart TD
A[Start]
subgraph Initial Thought
B[Thought]
end
subgraph Action and Observation
B --> |"我應該使用維基百科來找到這個問題的答案。"| C[Action1]
C --> |"{action: Wikipedia, action_input: Tom M. Mitchell}"| D[Observation1]
end
subgraph Processing and Final Answer
D --> |"頁面:Tom M. Mitchell<br>摘要:Tom Michael Mitchell...亦是Machine Learning一書的作者。"| E[Thought2]
E --> |"Tom M. Mitchell所著的書名為《Machine Learning》。"| F[Action2]
F --> |"{action: Wikipedia, action_input: Machine Learning (book)}"| G[Observation2]
end
G --> |"頁面:Machine Learning<br>摘要:Machine learning (ML) is a field of study..."| H[Thought3]
H --> |"Tom M. Mitchell寫了一本名為《Machine Learning》的書。"| I[Final Answer]
I --> |"《Machine Learning》"| J[End]
A --> B
```
### 使用Python作為Agent
- 數據處理任務範例:排序客戶名單(使用python作為代理)
使用 LangChain 的python agent代理來執行一個具體的數據處理任務,對一組顧客名單進行排序。這是個示例,展示了如何結合語言模型和具體的程式邏輯來處理和組織數據
- code
```python=
agent = create_python_agent(
llm,
tool=PythonREPLTool(),
verbose=True)
customer_list = [["Harrison", "Chase"],
["Lang", "Chain"],
["Dolly", "Too"],
["Elle", "Elem"],
["Geoff","Fusion"],
["Trance","Former"],
["Jen","Ayai"]]
agent.run(f"""Sort these customers by \
last name and then first name \
and print the output: {customer_list}""")
```
- 檢視模型內部推理流程
- 可以看到內部調用python API來進行排序
`sorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))`
```mermaid
graph TB
B[Thought]
B --> |Planning Sort|C{Action}
C --> |Python REPL|D[Action Input]
D --> |Sort Customers|E[Observation]
E --> |Sorted Customer List|F[Thought]
F --> |Recognize Sorted List|G[End]
```
- 如果要進一步檢視細節的話
```PYTHON=
import langchain
langchain.debug=True
agent.run(f"""Sort these customers by \
last name and then first name \
and print the output: {customer_list}""")
langchain.debug=False
```
### 自定義工具(Define your own tool)
LangChain真正的優勢在於能夠連接至用戶自己的資訊、API或數據:fire:
- 創建自定義工具
* 導入**工具裝飾器(Tool Decorator)`@tool`**
* 這可以應用於任何函數,將其轉化為LangChain可以使用的工具。
* 編寫函數
* 以一個名為“time”的函數為例,該函數接收任意文本字符串(在此例中未被使用),並返回當天的日期
* 撰寫詳細的文檔字符串(Doc String)
* 這非常重要,因為它幫助代理了解何時以及如何調用這個工具。例如,可以指定輸入應始終為空字符串
- code
- 以下展示如何使用LangChain庫來創建一個具有自定義功能(返回當天日期)的代理。這種代理可以被用於更複雜的應用中,以根據用戶的需要來進行相應的操作或回應
```python=
from langchain.agents import tool
from datetime import date
@tool
def time(text: str) -> str:
"""Returns todays date, use this for any \
questions related to knowing todays date. \
The input should always be an empty string, \
and this function will always return todays \
date - any date mathmatics should occur \
outside this function."""
return str(date.today())
agent= initialize_agent(
tools + [time],
llm,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
handle_parsing_errors=True,
verbose = True)
```
- 使用`@tool`裝飾器來定義一個函數`time`
- 這使得這個函數可以作為一個工具被代理使用
- 這個函數接受一個字符串作為輸入(雖然在這個函數中並未真正使用這個輸入),並返回當前的日期
- `initialize_agent()`
- 創建代理。這個代理包括之前定義的time工具以及其他工具(`tools + [time]`)
- **撰寫詳細的說明文件`docstring`**
- 這對於代理了解何時以及如何調用這個工具非常重要。例如,可以指定輸入應始終為空字符串。
- agent錯誤處理
如果碰到例外情形,請再嘗試運行一次。
```PYTHON=
try:
result = agent("whats the date today?")
except:
print("exception on external access")
```
- 正常輸出應該像這樣
```TEXT=
> Entering new AgentExecutor chain...
I don't know how to get the date in Python, I need to search for it.
Action: Python REPL
Action Input: import datetime; print(datetime.date.today())
Observation: 2023-11-02
Thought:I have the date, but I need to format it to match the expected output.
Action: Python REPL
Action Input: print(datetime.date.today().strftime('%B %d, %Y'))
Observation: November 02, 2023
Thought:I now know the final answer
Final Answer: November 02, 2023
> Finished chain.
```
---
## 補充資料
#### [2023.08。https://promptengineering.org/。What Are Large Language Model (LLM) Agents and Autonomous Agents](https://promptengineering.org/what-are-large-language-model-llm-agents/)
<div style="text-align: center;">
<figure>
<img src="https://promptengineering.org/content/images/size/w1000/2023/07/Prompt-engineering---Large-Language-Model-LLM--Autonomous-Agent.jpg" width="600">
<figcaption>
<span style="color: #3F7FBF; font-weight: bold;">
<a href="https://promptengineering.org/what-are-large-language-model-llm-agents/" target="_blank">The Construction of LLM Agents </a>
</figcaption>
</figure>
</div>
#### [How Agents for LLM Perform Task Planning。大型語言模型的代理如何進行任務規劃](https://hackmd.io/@YungHuiHsu/rkK52BkQp)
+ 本文主要參考[2023.06。lilianweng.github.io。LLM Powered Autonomous Agents](https://lilianweng.github.io/posts/2023-06-23-agent/)。"Planning"章節進行翻譯與補充
- 這篇文章很好的回顧了當前(2023.06為止)LLM Agents(任務代理)重要的核心思想
<div style="text-align: center;">
<figure>
<img src="https://lilianweng.github.io/posts/2023-06-23-agent/agent-overview.png" width="600">
<figcaption>
<span style="color: #3F7FBF; font-weight: bold;">
<a href="https://lilianweng.github.io/posts/2023-06-23-agent/" target="_blank">Overview of a LLM-powered autonomous agent system. </a>
</figcaption>
</figure>
</div>