### [AI / ML領域相關學習筆記入口頁面](https://hackmd.io/@YungHuiHsu/BySsb5dfp) #### [Deeplearning.ai GenAI/LLM系列課程筆記](https://learn.deeplearning.ai/) ##### GenAI - [Large Language Models with Semantic Search。大型語言模型與語義搜索 ](https://hackmd.io/@YungHuiHsu/rku-vjhZT) - [LangChain for LLM Application Development。使用LangChain進行LLM應用開發](https://hackmd.io/1r4pzdfFRwOIRrhtF9iFKQ) - [Finetuning Large Language Models。微調大型語言模型](https://hackmd.io/@YungHuiHsu/HJ6AT8XG6) ##### RAG - [Preprocessing Unstructured Data for LLM Applications。大型語言模型(LLM)應用的非結構化資料前處理](https://hackmd.io/@YungHuiHsu/BJDAbgpgR) - [Building and Evaluating Advanced RAG。建立與評估進階RAG](https://hackmd.io/@YungHuiHsu/rkqGpCDca) - [[GenAI][RAG] Multi-Modal Retrieval-Augmented Generation and Evaluaion。多模態的RAG與評估 ](https://hackmd.io/@YungHuiHsu/B1LJcOlfA) ##### AI Agents 原理可參考這篇綜論: [How Agents for LLM Perform Task Planning。大型語言模型的代理如何進行任務規劃](https://hackmd.io/@YungHuiHsu/rkK52BkQp) 相關framework選擇 - [AI Agents in LangGraph](https://hackmd.io/@YungHuiHsu/BJTKpkEHC) - [Building Agentic RAG with LlamaIndex](https://learn.deeplearning.ai/courses/building-agentic-rag-with-llamaindex/lesson/1/introduction) - [Multi AI Agent Systems with crewAI](https://learn.deeplearning.ai/courses/multi-ai-agent-systems-with-crewai/lesson/1/introduction) - [Functions, Tools and Agents with LangChain](https://learn.deeplearning.ai/courses/functions-tools-agents-langchain/lesson/1/introduction) - [2024.06。reddit。Langchain vs LlamaIndex vs CrewAI vs Custom? Which framework to use to build Multi-Agents application?](https://www.reddit.com/r/LocalLLaMA/comments/1chkl62/langchain_vs_llamaindex_vs_crewai_vs_custom_which/) > - :pencil2:**The only libraries you need to build LLM apps are: the LLM API - OpenAI API library, liteLLM** (provides an OpenAI compatible interface for nearly all other APIs, ollama included) > - OpenAI API and Qdrant are well documented and rarely have issues. Its easier to track down and fix bugs, compared to dealing with langchain. :::info 現在建構LLM應用的框架五花八門,到底該自己打造到什程度? 可以參考這篇討論 Deeplearning.ai GenAI系列短課程很大程度是各AI新創來推銷自家產品,比較重要的理論跟觀念部分、各家LIB API是其次 ::: --- # [AI Agents in LangGraph](https://learn.deeplearning.ai/courses/ai-agents-in-langgraph/lesson/1/introduction) * [Build an Agent from Scratch。從零開始建立AI代理](https://hackmd.io/@YungHuiHsu/BJTKpkEHC) * [LangGraph Components](https://hackmd.io/@YungHuiHsu/BySTFuhSC) * Agentic Search Tools * Persistence and Streaming * Human in the loop * Essay Writer --- ## [Build an Agent from Scratch。 從零開始建立AI代理](https://hackmd.io/@YungHuiHsu/BJTKpkEHC) #### REACT(偕同的理解+行動)實作 - [REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS](https://arxiv.org/abs/2210.03629) - [Prompt Engineering Guide。ReAct Prompting](https://www.promptingguide.ai/techniques/react) ![image](https://hackmd.io/_uploads/HJX6pG2S0.png) - ReAct 框架概念主要包含下列三個元素: - **Reasoning Traces(推理軌跡):** 模型在處理任務時所經歷的內部思考過程和步驟 - **Actions(行動):** 模型與外部環境互動的步驟,如檢索信息或執行特定任務 - **Observations(觀察):** 執行行動後從環境中獲得的回饋或資料 Chain-of-thought(CoT)提示展示了 LLM 執行推理軌跡以生成涉及算術和常識推理等任務的回答的能力。但其缺乏訪問外部世界的能力或無法更新知識,會導致事實幻覺和錯誤傳播等問題。 ReAct 是一種將推理和行動結合起來的通用範式。ReAct 提示 LLM 生成任務的口頭推理軌跡和行動。這使系統能夠執行動態推理,以創建、維護和調整行動計劃,同時還能與外部環境(如維基百科)進行互動,將額外的信息納入推理過程。 ![image](https://hackmd.io/_uploads/H1iKsG3HR.png =600x) > - 分析 > * **推理過程(Thoughts)**:每一步的思考都反映了如何逐步接近答案,首先是了解Apple Remote的設計初衷,接著找出相關的控制軟體,再尋找這些軟體的具體控制設備。 > * **行為(Acts)**:每一步的行為是根據思考所進行的具體操作,這些操作包括在知識庫中搜索相關信息。 > * **觀察(Observations)**:每一步行為後的觀察記錄了從環境(知識庫)中獲得的反饋信息,這些信息進一步指引了下一步的思考和行為。 > * 結果 > * 最終的答案是鍵盤功能鍵(keyboard function keys),因為經過多步推理和行為,發現Front Row(軟體)可以由Apple Remote或鍵盤功能鍵控制。這張圖展示了ReAct方法如何有效結合推理和行為來解決問題,並找到正確答案。 ### code ![image](https://hackmd.io/_uploads/rkF7j_nHC.png =800x) - 簡單的`class Agent` 實作 - 在def __call__中, - 每次 Agent得到使用者的message後 - 就調用self.execute(),調用llm完成一次推理(Thoughts)/行為(Acts)動,返回對話結果/觀察(Observations) - 再將上次的結果/觀察(Observations)作為下次丟給Agent的訊息 ```python= class Agent: def __init__(self, system=""): self.system = system self.messages = [] if self.system: self.messages.append({"role": "system", "content": system}) def __call__(self, message): self.messages.append({"role": "user", "content": message}) result = self.execute() self.messages.append({"role": "assistant", "content": result}) return result def execute(self): completion = client.chat.completions.create( # model="gpt-35-turb temperature=0, messages=self.messages) return completion.choices[0].message.content ``` - prompt - 告訴LLM在 T**hought, Action, PAUSE, Observation**的循環中 - 在loop結果中要輸出: **Answer** - 使用**Thought**描述對問題的看法 - **使用Action**執行可用的操作,然後返回 **PAUSE** - 明確指定actions的類別:`calculate`、 `average_dog_weight` - 相對於應於openai的tool/[Function calling] - 有趣的是**Action**後的**PAUSE**,用提示就能讓LLM真的停下來?(https://platform.openai.com/docs/guides/function-calling) - **Observation**即是執行上述行動的結果 - :pencil2: 注意這邊的狀態是用字首大寫 ```python= prompt = """ You run in a loop of Thought, Action, PAUSE, Observation. At the end of the loop you output an Answer Use Thought to describe your thoughts about the question you have been asked. Use Action to run one of the actions available to you - then return PAUSE. Observation will be the result of running those actions. Your available actions are: calculate: e.g. calculate: 4 * 7 / 3 Runs a calculation and returns the number - uses Python so be sure to use floating point syntax if necessary average_dog_weight: e.g. average_dog_weight: Collie returns average weight of a dog when given the breed Example session: Question: How much does a Bulldog weigh? Thought: I should look the dogs weight using average_dog_weight Action: average_dog_weight: Bulldog PAUSE You will be called again with this: Observation: A Bulldog weights 51 lbs You then output: Answer: A bulldog weights 51 lbs """.strip() ``` - 給定的行動方案/工具選擇 ```python= def calculate(what): return eval(what) def average_dog_weight(name): if name in "Scottish Terrier": return("Scottish Terriers average 20 lbs") elif name in "Border Collie": return("a Border Collies average weight is 37 lbs") elif name in "Toy Poodle": return("a toy poodles average weight is 7 lbs") else: return("An average dog weights 50 lbs") known_actions = { "calculate": calculate, "average_dog_weight": average_dog_weight ``` - 建立任務循環loop - 從回應結果中抽取出有關action的部分 - `actions = [action_re.match(a) for a in result.split('\n') if action_re.match(a)]` - 觀察動作後的狀態 - `observation = known_actions[action](action_input)` - ```python= action_re = re.compile('^Action: (\w+): (.*)$') # python regular expression to selection action def query(question, max_turns=5): i = 0 bot = Agent(prompt) next_prompt = question while i < max_turns: i += 1 result = bot(next_prompt) print(result) actions = [ action_re.match(a) for a in result.split('\n') if action_re.match(a) ] if actions: # There is an action to run action, action_input = actions[0].groups() if action not in known_actions: raise Exception("Unknown action: {}: {}".format(action, action_input)) print(" -- running {} {}".format(action, action_input)) observation = known_actions[action](action_input) print("Observation:", observation) next_prompt = "Observation: {}".format(observation) else: return ``` - 測試提問結果 - 第一輪Thought會先分析問題、決定後面採取的動作 - 接下來幾輪會重複執行Thought-Action-PAUSE-Observation-Thought,直到獲得答案 - 某種角度來看,是在LLM內部的參數空間及透過MESSAGE容器儲存檢索/生成結果來避免幻覺 ```python= question = """I have 2 dogs, a border collie and a scottish terrier. \ What is their combined weight""" query(question) ``` ```python=! # Thought: To find the combined weight of the two dogs, I need to use the average_dog_weight action for each breed and then add the results together. # Action: average_dog_weight: Border Collie # PAUSE # -- running average_dog_weight Border Collie # Observation: a Border Collies average weight is 37 lbs # Thought: Now that I have the average weight of a Border Collie, I can use the average_dog_weight action for the Scottish Terrier. # Action: average_dog_weight: Scottish Terrier # PAUSE # -- running average_dog_weight Scottish Terrier # Observation: Scottish Terriers average 20 lbs # Thought: Now that I have the average weight of both the Border Collie and the Scottish Terrier, I can calculate their combined weight by adding the two values together. # Action: calculate: 37 + 20 # PAUSE # -- running calculate 37 + 20 # Observation: 57 # Answer: The combined weight of a Border Collie and a Scottish Terrier is 57 lbs. ```