結論速遞
TinyAgent項目實現了一個簡單的Agent智能體,主要是實現了ReAct策略(推理+調用工具的能力),及封裝了一個Tool。
項目實現有一定的疏漏。為了正確運行代碼,本次對代碼Agent部分進行了簡單修改(完善ReAct prompt及LLM的多次循環調用)。
前情回顧
- TinyRAG
目錄
- 結論速遞
- 前情回顧
- 1 緒論
- 1.1 LLM Agent
- 1.2 ReAct
- 1.3 如何手搓Agent
- 2 TinyAgent
- 2.1 項目結構
- 2.2 代碼閱讀
- 2.2.1 Agent
- 2.2.2 Tool
- 2.2.3 LLM
- 2.3 運行案例
- 2.3.1 代碼修改
- 2.3.2 運行結果
- 參考閱讀
1 緒論
1.1 LLM Agent
Agent是人工智能中一個廣為人知的概念,指代理人類完成部分工作的AI程序。
LLM Agent是利用LLM構建Agent,比較受到廣泛認可的方式是使用LLM作為Agent的大腦,讓其自主規劃、利用工具來完成人類指定的任務。如下圖所示,圖片出自The Rise and Potential of Large Language Model Based Agents: A Survey。
關于Agent有很多有名的項目,除了單Agent之外,Multi-agent也是目前一個比較流行的研究方向(simulated agent society)。
- AI小鎮
- ChatDev
- MetaGPT
- …
1.2 ReAct
ReAct是一種prompt策略,它將CoT(思維鏈策略)和action(操作工具)結合,使LLM能夠實時規劃和調整操作工具的策略,從而完成較復雜的任務。下圖出自ReAct project。
1.3 如何手搓Agent
之前簡單玩過Langchain和CrewAI的agent,都是ReAct策略的agent,簡單理解agent是prompt-based的role+tool use,其中tool use借助ReAct實現
所以,手搓Agent需要完成
- 定義Agent的prompt構建:
- 角色
- 任務
- ReAct策略
- tool:
- input處理:把agent的動作處理為API的輸入
- 調用API
2 TinyAgent
2.1 項目結構
項目由三大部分構成
- Agent:集成了prompt模板,其中agent的動作的截取也在此實現
- Tool:實現了tool的封裝
- LLM:實現LLM的調用
2.2 代碼閱讀
2.2.1 Agent
代碼詳見tinyAgent/Agent.py,下為筆記
有兩大部分組成
- prompt:分為兩塊,一塊是tool描述的模板,一塊是ReAct的模板
- tool描述:由三個部分組成,tool唯一名
name_for_model
,tool描述(name_for_human
工具人類名,description_for_model
工具功能),調用tool所需要生成的格式及參數(JSON
格式,指定parameters
)。
其中tool唯一名 和 調用tool所需要生成的格式及參數 是decode LLM的回復時需要的,tool描述是方便LLM理解這個工具是干什么的(這個在多工具時很重要)
{name_for_model}: Call this tool to interact with the {name_for_human} API. What is the {name_for_human} API useful for? {description_for_model} Parameters: {parameters} Format the arguments as a JSON object.
- ReAct策略:規定了由Question,Thought,Action,Action Input, Observation構成,并且從思考動作到觀測這個步驟可以重復多次。這個是ReAct的核心。
- tool描述:由三個部分組成,tool唯一名
- Agent:
- LLM調用:
build_system_input
構建調用LLM所需的prompt,text_completion
調用LLM生成回復。只執行了兩次調用 - 工具調用:
parse_latest_plugin_call
解析/解碼LLM回復中關于調用工具的部分,確定調用的tool唯一名 和 調用tool的參數;call_plugin
調用工具得到結果。
疑問:parse_latest_plugin_call
沒有用正則,而使用的字符串遍歷,是出于什么考慮呢?
- LLM調用:
class Agent:def __init__(self, path: str = '') -> None:passdef build_system_input(self):# 構造上文中所說的系統提示詞passdef parse_latest_plugin_call(self, text):# 解析第一次大模型返回選擇的工具和工具參數passdef call_plugin(self, plugin_name, plugin_args):# 調用選擇的工具passdef text_completion(self, text, history=[]):# 整合兩次調用pass
Agent的一次回答(解決問題)是LLM多次回復的結果,這是和先前的ChatLLM顯著不同的地方。
疑問:是不是應該有action回合數控制?以實現多次調用
2.2.2 Tool
代碼詳見tinyAgent/tool.py,下為筆記
實現了Tools類,其實應該是寫成abstract類及繼承子類的形式會比較合理,但是因為這里只有一個tool,所以就混在了一起。
- 內部方法_tools,包含了構建tool描述prompt的四大基本信息:
name_for_model
,name_for_human
,description_for_model
,parameters
。 - 調用API的功能方法:這里是Google search所以是
google_search
的調用google搜索的http POST。
2.2.3 LLM
代碼詳見tinyAgent/LLM.py,下為筆記
abstract類+繼承子類的形式,就是LLM的調用封裝(因為這里是開源模型調用),兩個核心功能
- 加載模型
- 推理
如果改調用API的話,可以參考TinyRAG的實現。
2.3 運行案例
2.3.1 代碼修改
用Colab跑的,開源模型調用的是internlm/internlm2-chat-1_8b
,把所有中文描述都改成了英文。
internlm/internlm2-chat-1_8b
會編造工具,所以修改了system_prompt,要求它不能使用其他工具。
完整的prompt:
Answer the following questions as best you can. You have access to the following tools:google_search: Call this tool to interact with the Google Search API. What is the Google Search API useful for? Google Search is a general search engine that can be used to access the internet, consult encyclopedias, learn about current news, and more. Parameters: [{'name': 'search_query', 'description': 'Search for a keyword or phrase', 'required': True, 'schema': {'type': 'string'}}] Format the arguments as a JSON object.Do not use other tools!Use the following format:Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [google_search]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input questionBegin!
修改了Agent類的兩個函數,使其:
- 在調用其他工具時返回
Wrong input
的提示、 - 多次調用LLM,直到獲得
Final Answer
或者達到調用上限(設為5)
class Agent:...def call_plugin(self, plugin_name, plugin_args):plugin_args = json5.loads(plugin_args)if plugin_name == 'google_search':return '\nObservation:' + self.tool.google_search(**plugin_args)else:return '\nWrong input!'def text_completion(self, text, history=[]):response = "\nQuestion:" + textfor i in range(5):response, history = self.model.chat(response, history, self.system_prompt)if response.rfind('\nFinal Answer:') > 0:breakplugin_name, plugin_args, response = self.parse_latest_plugin_call(response)if plugin_name:response += self.call_plugin(plugin_name, plugin_args)print(response)return response, history
2.3.2 運行結果
運行示例如下,可以正確解決問題
- 周杰倫哪年生
response, _ = agent.text_completion(text='Which year was Jay Chou born?', history=_)
print(response)
Thought: To answer this question, I need to search for information about Jay Chou's birth year. I will use the Google Search API to find relevant search results.
Action: google_search
Action Input: {"search_query": "Jay Chou birth year"}
Observation:Overview · Born. January 18, 1979 · New Taipei, Taiwan · Birth name. Chieh-Lun Chou · Nicknames. President Chou; Director Chou · Height. 5′ 8″ (1.73 m) ...
Thought: Jay Chou was born on January 18, 1979. He is a Taiwanese singer, songwriter, and actor. He is known for his contributions to the Taiwanese music industry and has released numerous hit songs throughout his career. Chou has also acted in Taiwanese television dramas and films. He is considered one of the most successful and influential Taiwanese artists of all time.
Final Answer: Jay Chou was born on January 18, 1979. He is a Taiwanese singer, songwriter, and actor. He is known for his contributions to the Taiwanese music industry and has released numerous hit songs throughout his career. Chou has also acted in Taiwanese television dramas and films. He is considered one of the most successful and influential Taiwanese artists of all time.
- 第一張專輯什么時候發的
response, _ = agent.text_completion(text='What was his first album?', history=_)
print(response)
Thought: To answer this question, I need to search for information about Jay Chou's first album. I will use the Google Search API to find relevant search results.
Action: google_search
Action Input: {"search_query": "Jay Chou first album"}
Observation:Jay is the debut studio album by Taiwanese singer Jay Chou. It was released on November 7, 2000, by BMG Taiwan. It was entirely produced and composed by ...
Thought: Jay Chou's first album is titled \"Jay\" and was released on November 7, 2000. It was entirely produced and composed by Jay Chou himself. The album features a mix of pop, rock, and electronic music and includes popular tracks such as \"Jay\" and \"Jay, Jay, Jay\".
Final Answer: Jay Chou's first album is titled \"Jay\" and was released on November 7, 2000. It was entirely produced and composed by Jay Chou himself. The album features a mix of pop, rock, and electronic music and includes popular tracks such as \"Jay\" and \"Jay, Jay, Jay\".
參考閱讀
- TinyAgent