当前位置:   article > 正文

书生·浦语大模型实战营之Lagent & AgentLego 智能体应用搭建

书生·浦语大模型实战营之Lagent & AgentLego 智能体应用搭建

书生·浦语大模型实战营之Lagent & AgentLego 智能体应用搭建

Lagent 简介
Lagent 是一个轻量级开源智能体框架,旨在让用户可以高效地构建基于大语言模型的智能体。同时它也提供了一些典型工具以增强大语言模型的能力。

Lagent 目前已经支持了包括 AutoGPT、ReAct 等在内的多个经典智能体范式,也支持了如下工具:

Arxiv 搜索
Bing 地图
Google 学术搜索
Google 搜索
交互式 IPython 解释器
IPython 解释器
PPT
Python 解释器
AgentLego 简介
AgentLego 是一个提供了多种开源工具 API 的多模态工具包,旨在像是乐高积木一样,让用户可以快速简便地拓展自定义工具,从而组装出自己的智能体。通过 AgentLego 算法库,不仅可以直接使用多种工具,也可以利用这些工具,在相关智能体框架(如 Lagent,Transformers Agent 等)的帮助下,快速构建可以增强大语言模型能力的智能体。

AgentLego 目前提供了如下工具:

Lagent 是一个智能体框架,而 AgentLego 与大模型智能体并不直接相关,而是作为工具包,在相关智能体的功能支持模块发挥作用。

两者之间的关系可以用下图来表示:

环境配置

在创建开发机界面选择镜像为 Cuda12.2-conda,并选择 GPU 为30% A100

创建一个用于存放 Agent 相关文件的目录

mkdir -p /root/agent

配置 conda 环境,可以输入如下指令

studio-conda -t agent -o pytorch-2.1.2

安装 Lagent 和 AgentLego
Lagent 和 AgentLego 都提供了两种安装方法,一种是通过 pip 直接进行安装,另一种则是从源码进行安装。为了方便使用 Lagent 的 Web Demo 以及 AgentLego 的 WebUI,我们选择直接从源码进行安装。 此处附上源码安装的相关帮助文档:

Lagent:https://lagent.readthedocs.io/zh-cn/latest/get_started/install.html
AgentLego:https://agentlego.readthedocs.io/zh-cn/latest/get_started.html

可以执行如下命令进行安装:

  1. cd /root/agent
  2. conda activate agent
  3. git clone https://gitee.com/internlm/lagent.git
  4. cd lagent && git checkout 581d9fb && pip install -e . && cd ..
  5. git clone https://gitee.com/internlm/agentlego.git
  6. cd agentlego && git checkout 7769e0d && pip install -e . && cd ..

安装其他依赖

安装其他将要用到的依赖库,如 LMDeploy,可以执行如下命令:

  1. conda activate agent
  2. pip install lmdeploy==0.3.0

git clone 的方法 下载 tutorial

  1. cd /root/agent
  2. git clone -b camp2 https://gitee.com/internlm/Tutorial.git

Lagent:轻量级智能体框架
在这一部分中,我们将带大家体验 Lagent 的 Web Demo,使用 Lagent 自定义工具,并体验自定义工具的效果。

详细文档可以访问:Lagent:轻量级智能体框架。

Lagent Web Demo
使用 LMDeploy 部署
由于 Lagent 的 Web Demo 需要用到 LMDeploy 所启动的 api_server,因此我们首先按照下图指示在 vscode terminal 中执行如下代码使用 LMDeploy 启动一个 api_server

  1. conda activate agent
  2. lmdeploy serve api_server /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-7b \
  3. --server-name 127.0.0.1 \
  4. --model-name internlm2-chat-7b \
  5. --cache-max-entry-count 0.1

等待 LMDeploy 的 api_server 与 Lagent Web Demo 完全启动后,在本地进行端口映射,将 LMDeploy api_server 的23333端口以及 Lagent Web Demo 的7860端口映射到本地。可以执行:

ssh -CNg -L 7860:127.0.0.1:7860 -L 23333:127.0.0.1:23333 root@ssh.intern-ai.org.cn -p   43844

在本地的浏览器页面中打开 http://localhost:7860 以使用 Lagent Web Demo。首先输入模型 IP 为 127.0.0.1:23333,在输入完成后按下回车键以确认。并选择插件为 ArxivSearch,以让模型获得在 arxiv 上搜索论文的能力。

  1. 系统提示词:当开启工具以及代码时,根据需求选择合适的工具进行调用
  2. 数据分析提示词:你现在已经能够在一个有状态的 Jupyter 笔记本环境中运行 Python 代码。当你向 python 发送含有 Python 代码的消息时,它将在该环境中执行。这个工具适用于多种场景,如数据分析或处理(包括数据操作、统计分析、图表绘制),复杂的计算问题(解决数学和物理难题),编程示例(理解编程概念或特性),文本处理和分析(比如文本解析和自然语言处理),机器学习和数据科学(用于展示模型训练和数据可视化),以及文件操作和数据导入(处理CSV、JSON等格式的文件)。
  3. 插件提示词:
  4. 你可以使用如下工具:
  5. {prompt}
  6. 如果你已经获得足够信息,请直接给出答案. 避免不必要的工具调用! 同时注意你可以使用的工具,不要随意捏造!

输入“请帮我搜索 InternLM2 Technical Report” 以让模型搜索书生·浦语2的技术报告。效果如下图所示,可以看到模型正确输出了 InternLM2 技术报告的相关信息。尽管还输出了其他论文,但这是由 arxiv 搜索 API 的相关行为导致的

lagent/agents/internlm2_agent.py

  1. import json
  2. import logging
  3. from copy import deepcopy
  4. from typing import Dict, List, Optional, Union
  5. from lagent.actions import ActionExecutor
  6. from lagent.agents.base_agent import BaseAgent
  7. from lagent.llms import BaseAPIModel, BaseModel
  8. from lagent.schema import ActionReturn, ActionStatusCode, AgentReturn, AgentStatusCode, ModelStatusCode # noqa: E501
  9. API_PREFIX = (
  10. "This is the subfunction for tool '{tool_name}', you can use this tool. "
  11. 'The description of this function is: \n{description}')
  12. META_CN = ('当开启工具以及代码时,根据需求选择合适的工具进行调用')
  13. INTERPRETER_CN = ('你现在已经能够在一个有状态的 Jupyter 笔记本环境中运行 Python 代码。'
  14. '当你向 python 发送含有 Python 代码的消息时,它将在该环境中执行。'
  15. '这个工具适用于多种场景,如数据分析或处理(包括数据操作、统计分析、图表绘制),'
  16. '复杂的计算问题(解决数学和物理难题),编程示例(理解编程概念或特性),'
  17. '文本处理和分析(比如文本解析和自然语言处理),'
  18. '机器学习和数据科学(用于展示模型训练和数据可视化),'
  19. '以及文件操作和数据导入(处理CSV、JSON等格式的文件)。')
  20. PLUGIN_CN = ('你可以使用如下工具:'
  21. '\n{prompt}\n'
  22. '如果你已经获得足够信息,请直接给出答案. 避免不必要的工具调用! '
  23. '同时注意你可以使用的工具,不要随意捏造!')
  24. class Internlm2Protocol:
  25. def __init__(
  26. self,
  27. meta_prompt: str = META_CN,
  28. interpreter_prompt: str = INTERPRETER_CN,
  29. plugin_prompt: str = PLUGIN_CN,
  30. few_shot: Optional[List] = None,
  31. language: Dict = dict(
  32. begin='',
  33. end='',
  34. belong='assistant',
  35. ),
  36. tool: Dict = dict(
  37. begin='{start_token}{name}\n',
  38. start_token='<|action_start|>',
  39. name_map=dict(plugin='<|plugin|>', interpreter='<|interpreter|>'),
  40. belong='assistant',
  41. end='<|action_end|>\n',
  42. ),
  43. execute: Dict = dict(
  44. role='execute', begin='', end='', fallback_role='environment'),
  45. ) -> None:
  46. self.meta_prompt = meta_prompt
  47. self.interpreter_prompt = interpreter_prompt
  48. self.plugin_prompt = plugin_prompt
  49. self.roles_cfg = dict(tool=tool, language=language)
  50. self.language = language
  51. self.execute = execute
  52. self.tool = tool
  53. self.few_shot = few_shot
  54. def format_sub_role(self, messages: List[Dict]) -> List[Dict]:
  55. def format_interpreter(message):
  56. if isinstance(message['content'], dict):
  57. # assert message['content']['name'] == 'IPythonInterpreter'
  58. return dict(
  59. role=message['role'],
  60. name=message['name'],
  61. content=message['content']['parameters']['command'])
  62. else:
  63. return message
  64. def format_plugin(message):
  65. if isinstance(message['content'], dict):
  66. return dict(
  67. role=message['role'],
  68. name=message['name'],
  69. content=json.dumps(message['content']))
  70. else:
  71. return message
  72. new_message = list()
  73. for message in messages:
  74. if message['role'] in [
  75. 'assistant', 'user', 'system', 'environment'
  76. ]:
  77. new_message.append(message)
  78. continue
  79. role_cfg = self.roles_cfg[message['role']]
  80. begin = role_cfg['begin']
  81. if message['role'] == 'tool':
  82. if message['name'] == 'interpreter':
  83. message = format_interpreter(message)
  84. elif message['name'] == 'plugin':
  85. message = format_plugin(message)
  86. else:
  87. raise NotImplementedError
  88. begin = role_cfg['begin'].format(
  89. start_token=role_cfg.get('start_token', ''),
  90. name=role_cfg.get('name_map', {}).get(message['name'], ''))
  91. new_content = begin + message['content'] + role_cfg['end']
  92. if role_cfg.get('fallback_role'):
  93. new_message.append(
  94. dict(role=role_cfg['fallback_role'], content=new_content))
  95. elif role_cfg.get('belong'):
  96. if new_message[-1]['role'] != role_cfg.get('belong'):
  97. new_message.append(
  98. dict(role=role_cfg.get('belong'), content=new_content))
  99. else:
  100. new_message[-1]['content'] += new_content
  101. else:
  102. new_message.append(
  103. dict(role=message['role'], content=new_content))
  104. return new_message
  105. def format(self,
  106. inner_step: List[Dict],
  107. plugin_executor: ActionExecutor = None,
  108. interpreter_executor: ActionExecutor = None,
  109. **kwargs) -> list:
  110. formatted = []
  111. if self.meta_prompt:
  112. formatted.append(dict(role='system', content=self.meta_prompt))
  113. if interpreter_executor and self.interpreter_prompt:
  114. interpreter_info = interpreter_executor.get_actions_info()[0]
  115. interpreter_prompt = self.interpreter_prompt.format(
  116. code_prompt=interpreter_info['description'])
  117. formatted.append(
  118. dict(
  119. role='system',
  120. content=interpreter_prompt,
  121. name='interpreter'))
  122. if plugin_executor and plugin_executor.actions and self.plugin_prompt:
  123. plugin_descriptions = []
  124. for api_info in plugin_executor.get_actions_info():
  125. plugin = deepcopy(api_info)
  126. if isinstance(api_info, dict):
  127. tool_name = api_info['name'].split('.')[0]
  128. plugin['description'] = API_PREFIX.format(
  129. tool_name=tool_name, description=plugin['description'])
  130. # only keep required parameters
  131. required_parameters = [
  132. param for param in plugin['parameters']
  133. if param['name'] in plugin['required']
  134. ]
  135. plugin['parameters'] = required_parameters
  136. plugin_descriptions.append(plugin)
  137. plugin_prompt = self.plugin_prompt.format(
  138. prompt=json.dumps(
  139. plugin_descriptions, ensure_ascii=False, indent=4))
  140. formatted.append(
  141. dict(role='system', content=plugin_prompt, name='plugin'))
  142. if self.few_shot:
  143. for few_shot in self.few_shot:
  144. formatted += self.format_sub_role(few_shot)
  145. formatted += self.format_sub_role(inner_step)
  146. return formatted
  147. def parse(self, message, plugin_executor: ActionExecutor,
  148. interpreter_executor: ActionExecutor):
  149. if self.language['begin']:
  150. message = message.split(self.language['begin'])[-1]
  151. if self.tool['name_map']['plugin'] in message:
  152. message, action = message.split(
  153. f"{self.tool['start_token']}{self.tool['name_map']['plugin']}")
  154. action = action.split(self.tool['end'].strip())[0]
  155. return 'plugin', message, action
  156. if self.tool['name_map']['interpreter'] in message:
  157. message, code = message.split(
  158. f"{self.tool['start_token']}"
  159. f"{self.tool['name_map']['interpreter']}")
  160. code = code.split(self.tool['end'].strip())[0].strip()
  161. return 'interpreter', message, dict(
  162. name=interpreter_executor.action_names()[0],
  163. parameters=dict(
  164. command=code)) if interpreter_executor else None
  165. return None, message.split(self.tool['start_token'])[0], None
  166. def format_response(self, action_return, name) -> dict:
  167. if action_return.state == ActionStatusCode.SUCCESS:
  168. response = action_return.format_result()
  169. else:
  170. response = str(action_return.errmsg)
  171. content = self.execute['begin'] + response + self.execute['end']
  172. if self.execute.get('fallback_role'):
  173. return dict(
  174. role=self.execute['fallback_role'], content=content, name=name)
  175. elif self.execute.get('belong'):
  176. return dict(
  177. role=self.execute['belong'], content=content, name=name)
  178. return dict(role=self.execute['role'], content=response, name=name)
  179. class Internlm2Agent(BaseAgent):
  180. def __init__(self,
  181. llm: Union[BaseModel, BaseAPIModel],
  182. plugin_executor: ActionExecutor = None,
  183. interpreter_executor: ActionExecutor = None,
  184. protocol=Internlm2Protocol(),
  185. max_turn: int = 3) -> None:
  186. self.max_turn = max_turn
  187. self._interpreter_executor = interpreter_executor
  188. super().__init__(
  189. llm=llm, action_executor=plugin_executor, protocol=protocol)
  190. def chat(self, message: Union[str, Dict], **kwargs) -> AgentReturn:
  191. if isinstance(message, str):
  192. message = dict(role='user', content=message)
  193. if isinstance(message, dict):
  194. message = [message]
  195. inner_history = message[:]
  196. offset = len(inner_history)
  197. agent_return = AgentReturn()
  198. for _ in range(self.max_turn):
  199. # list of dict
  200. prompt = self._protocol.format(
  201. inner_step=inner_history,
  202. plugin_executor=self._action_executor,
  203. interpreter_executor=self._interpreter_executor,
  204. )
  205. response = self._llm.chat(prompt, **kwargs)
  206. name, language, action = self._protocol.parse(
  207. message=response,
  208. plugin_executor=self._action_executor,
  209. interpreter_executor=self._interpreter_executor,
  210. )
  211. if name:
  212. if name == 'plugin':
  213. if self._action_executor:
  214. executor = self._action_executor
  215. else:
  216. logging.info(msg='No plugin is instantiated!')
  217. continue
  218. try:
  219. action = json.loads(action)
  220. except Exception as e:
  221. logging.info(msg=f'Invaild action {e}')
  222. continue
  223. elif name == 'interpreter':
  224. if self._interpreter_executor:
  225. executor = self._interpreter_executor
  226. else:
  227. logging.info(msg='No interpreter is instantiated!')
  228. continue
  229. else:
  230. logging.info(
  231. msg=(f"Invalid name '{name}'. Currently only 'plugin' "
  232. "and 'interpreter' are supported."))
  233. continue
  234. action_return: ActionReturn = executor(action['name'],
  235. action['parameters'])
  236. action_return.thought = language
  237. agent_return.actions.append(action_return)
  238. inner_history.append(dict(role='language', content=language))
  239. if not name or action_return.type == executor.finish_action.name:
  240. agent_return.response = language
  241. agent_return.state = AgentStatusCode.END
  242. break
  243. else:
  244. inner_history.append(
  245. dict(role='tool', content=action, name=name))
  246. inner_history.append(
  247. self._protocol.format_response(action_return, name=name))
  248. agent_return.inner_steps = inner_history[offset:]
  249. return agent_return
  250. def stream_chat(self, message: List[dict], **kwargs) -> AgentReturn:
  251. if isinstance(message, str):
  252. message = dict(role='user', content=message)
  253. if isinstance(message, dict):
  254. message = [message]
  255. inner_history = message[:]
  256. offset = len(inner_history)
  257. agent_return = AgentReturn()
  258. last_agent_state = AgentStatusCode.SESSION_READY
  259. for _ in range(self.max_turn):
  260. # list of dict
  261. prompt = self._protocol.format(
  262. inner_step=inner_history,
  263. plugin_executor=self._action_executor,
  264. interpreter_executor=self._interpreter_executor,
  265. )
  266. response = ''
  267. for model_state, res, _ in self._llm.stream_chat(prompt, **kwargs):
  268. model_state: ModelStatusCode
  269. response = res
  270. if model_state.value < 0:
  271. agent_return.state = getattr(AgentStatusCode,
  272. model_state.name)
  273. yield deepcopy(agent_return)
  274. return
  275. else:
  276. name, language, action = self._protocol.parse(
  277. message=response,
  278. plugin_executor=self._action_executor,
  279. interpreter_executor=self._interpreter_executor,
  280. )
  281. if name:
  282. if model_state == ModelStatusCode.END:
  283. agent_state = last_agent_state + 1
  284. if name == 'plugin':
  285. if self._action_executor:
  286. executor = self._action_executor
  287. else:
  288. logging.info(
  289. msg='No plugin is instantiated!')
  290. continue
  291. try:
  292. action = json.loads(action)
  293. except Exception as e:
  294. logging.info(msg=f'Invaild action {e}')
  295. continue
  296. elif name == 'interpreter':
  297. if self._interpreter_executor:
  298. executor = self._interpreter_executor
  299. else:
  300. logging.info(
  301. msg='No interpreter is instantiated!')
  302. continue
  303. agent_return.state = agent_state
  304. agent_return.response = action
  305. else:
  306. agent_state = (
  307. AgentStatusCode.PLUGIN_START if name
  308. == 'plugin' else AgentStatusCode.CODING)
  309. if agent_state != last_agent_state:
  310. # agent_return.state = agent_state
  311. agent_return.response = language
  312. yield deepcopy(agent_return)
  313. agent_return.state = agent_state
  314. agent_return.response = action
  315. else:
  316. agent_state = AgentStatusCode.STREAM_ING
  317. agent_return.state = agent_state
  318. agent_return.response = language
  319. last_agent_state = agent_state
  320. yield deepcopy(agent_return)
  321. if name:
  322. action_return: ActionReturn = executor(action['name'],
  323. action['parameters'])
  324. action_return.thought = language
  325. agent_return.actions.append(action_return)
  326. inner_history.append(dict(role='language', content=language))
  327. if not name:
  328. agent_return.response = language
  329. break
  330. elif action_return.type == executor.finish_action.name:
  331. try:
  332. response = action_return.args['text']['response']
  333. except Exception:
  334. logging.info(msg='Unable to parse FinishAction.')
  335. response = ''
  336. agent_return.response = response
  337. break
  338. else:
  339. inner_history.append(
  340. dict(role='tool', content=action, name=name))
  341. inner_history.append(
  342. self._protocol.format_response(action_return, name=name))
  343. agent_state += 1
  344. agent_return.state = agent_state
  345. yield agent_return
  346. agent_return.inner_steps = deepcopy(inner_history[offset:])
  347. agent_return.state = AgentStatusCode.END
  348. yield agent_return

lagent/actions/arxiv_search.py 代码

  1. from typing import Optional, Type
  2. from lagent.actions.base_action import BaseAction, tool_api
  3. from lagent.actions.parser import BaseParser, JsonParser
  4. from lagent.schema import ActionReturn, ActionStatusCode
  5. class ArxivSearch(BaseAction):
  6. """Search information from Arxiv.org. \
  7. Useful for when you need to answer questions about Physics, Mathematics, \
  8. Computer Science, Quantitative Biology, Quantitative Finance, Statistics, \
  9. Electrical Engineering, and Economics from scientific articles on arxiv.org.
  10. """
  11. def __init__(self,
  12. top_k_results: int = 3,
  13. max_query_len: int = 300,
  14. doc_content_chars_max: int = 1500,
  15. description: Optional[dict] = None,
  16. parser: Type[BaseParser] = JsonParser,
  17. enable: bool = True):
  18. super().__init__(description, parser, enable)
  19. self.top_k_results = top_k_results
  20. self.max_query_len = max_query_len
  21. self.doc_content_chars_max = doc_content_chars_max
  22. @tool_api(explode_return=True)
  23. def get_arxiv_article_information(self, query: str) -> dict:
  24. """Run Arxiv search and get the article meta information.
  25. Args:
  26. query (:class:`str`): the content of search query
  27. Returns:
  28. :class:`dict`: article information
  29. * content (str): a list of 3 arxiv search papers
  30. """
  31. import arxiv
  32. try:
  33. results = arxiv.Search( # type: ignore
  34. query[:self.max_query_len],
  35. max_results=self.top_k_results).results()
  36. except Exception as exc:
  37. return ActionReturn(
  38. errmsg=f'Arxiv exception: {exc}',
  39. state=ActionStatusCode.HTTP_ERROR)
  40. docs = [
  41. f'Published: {result.updated.date()}\nTitle: {result.title}\n'
  42. f'Authors: {", ".join(a.name for a in result.authors)}\n'
  43. f'Summary: {result.summary[:self.doc_content_chars_max]}'
  44. for result in results
  45. ]
  46. if docs:
  47. return {'content': '\n\n'.join(docs)}
  48. return {'content': 'No good Arxiv Result was found'}

用 Lagent 自定义工具
在本节中,我们将基于 Lagent 自定义一个工具。Lagent 中关于工具部分的介绍文档位于 https://lagent.readthedocs.io/zh-cn/latest/tutorials/action.html 。使用 Lagent 自定义工具主要分为以下几步:

继承 BaseAction 类
实现简单工具的 run 方法;或者实现工具包内每个子工具的功能
简单工具的 run 方法可选被 tool_api 装饰;工具包内每个子工具的功能都需要被 tool_api 装饰
下面我们将实现一个调用和风天气 API 的工具以完成实时天气查询的功能。

创建工具文件
首先通过 touch /root/agent/lagent/lagent/actions/weather.py 新建工具文件,该文件内容如下

vim /root/agent/lagent/lagent/actions/weather.py

  1. import json
  2. import os
  3. import requests
  4. from typing import Optional, Type
  5. from lagent.actions.base_action import BaseAction, tool_api
  6. from lagent.actions.parser import BaseParser, JsonParser
  7. from lagent.schema import ActionReturn, ActionStatusCode
  8. class WeatherQuery(BaseAction):
  9. """Weather plugin for querying weather information."""
  10. def __init__(self,
  11. key: Optional[str] = None,
  12. description: Optional[dict] = None,
  13. parser: Type[BaseParser] = JsonParser,
  14. enable: bool = True) -> None:
  15. super().__init__(description, parser, enable)
  16. key = os.environ.get('WEATHER_API_KEY', key)
  17. if key is None:
  18. raise ValueError(
  19. 'Please set Weather API key either in the environment '
  20. 'as WEATHER_API_KEY or pass it as `key`')
  21. self.key = key
  22. self.location_query_url = 'https://geoapi.qweather.com/v2/city/lookup'
  23. self.weather_query_url = 'https://devapi.qweather.com/v7/weather/now'
  24. @tool_api
  25. def run(self, query: str) -> ActionReturn:
  26. """一个天气查询API。可以根据城市名查询天气信息。
  27. Args:
  28. query (:class:`str`): The city name to query.
  29. """
  30. tool_return = ActionReturn(type=self.name)
  31. status_code, response = self._search(query)
  32. if status_code == -1:
  33. tool_return.errmsg = response
  34. tool_return.state = ActionStatusCode.HTTP_ERROR
  35. elif status_code == 200:
  36. parsed_res = self._parse_results(response)
  37. tool_return.result = [dict(type='text', content=str(parsed_res))]
  38. tool_return.state = ActionStatusCode.SUCCESS
  39. else:
  40. tool_return.errmsg = str(status_code)
  41. tool_return.state = ActionStatusCode.API_ERROR
  42. return tool_return
  43. def _parse_results(self, results: dict) -> str:
  44. """Parse the weather results from QWeather API.
  45. Args:
  46. results (dict): The weather content from QWeather API
  47. in json format.
  48. Returns:
  49. str: The parsed weather results.
  50. """
  51. now = results['now']
  52. data = [
  53. f'数据观测时间: {now["obsTime"]}',
  54. f'温度: {now["temp"]}°C',
  55. f'体感温度: {now["feelsLike"]}°C',
  56. f'天气: {now["text"]}',
  57. f'风向: {now["windDir"]},角度为 {now["wind360"]}°',
  58. f'风力等级: {now["windScale"]},风速为 {now["windSpeed"]} km/h',
  59. f'相对湿度: {now["humidity"]}',
  60. f'当前小时累计降水量: {now["precip"]} mm',
  61. f'大气压强: {now["pressure"]} 百帕',
  62. f'能见度: {now["vis"]} km',
  63. ]
  64. return '\n'.join(data)
  65. def _search(self, query: str):
  66. # get city_code
  67. try:
  68. city_code_response = requests.get(
  69. self.location_query_url,
  70. params={'key': self.key, 'location': query}
  71. )
  72. except Exception as e:
  73. return -1, str(e)
  74. if city_code_response.status_code != 200:
  75. return city_code_response.status_code, city_code_response.json()
  76. city_code_response = city_code_response.json()
  77. if len(city_code_response['location']) == 0:
  78. return -1, '未查询到城市'
  79. city_code = city_code_response['location'][0]['id']
  80. # get weather
  81. try:
  82. weather_response = requests.get(
  83. self.weather_query_url,
  84. params={'key': self.key, 'location': city_code}
  85. )
  86. except Exception as e:
  87. return -1, str(e)
  88. return weather_response.status_code, weather_response.json()

为了获得稳定的天气查询服务, 首先要获取 API KEY。打开 开发文档 | 和风天气开发服务

体验自定义工具效果

在两个 terminal 中分别启动 LMDeploy 服务和 Tutorial 已经写好的用于这部分的 Web Demo

  1. conda activate agent
  2. lmdeploy serve api_server /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-7b \
  3. --server-name 127.0.0.1 \
  4. --model-name internlm2-chat-7b \
  5. --cache-max-entry-count 0.1

  1. export WEATHER_API_KEY=在2.2节获取的API KEY
  2. # 比如 export WEATHER_API_KEY=1234567890abcdef
  3. conda activate agent
  4. cd /root/agent/Tutorial/agent
  5. streamlit run internlm2_weather_web_demo.py --server.address 127.0.0.1 --server.port 7860

在本地执行如下操作以进行端口映射

在输入模型地址并选择好工具后,就可以开始体验了

读者可以关注大模型返回的工具名称及参数。query参数解析为上海

  1. {
  2. "name": "WeatherQuery",
  3. "parameters": {
  4. "query": "上海"
  5. }
  6. }

AgentLego:组装智能体“乐高”
使用 AgentLego 工具,体验 AgentLego 的 WebUI,以及基于 AgentLego 自定义工具并体验自定义工具的效果。

https://github.com/InternLM/Tutorial/tree/camp2/agent

Tutorial/agent/lagent.md at camp2 · InternLM/Tutorial · GitHub

https://github.com/InternLM/Tutorial/blob/camp2/agent/agentlego.md

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/541651
推荐阅读
相关标签
  

闽ICP备14008679号