From 930d87559f0e10db25ea9b6cf36d860f50422d1f Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Tue, 31 Dec 2024 09:38:19 +0800 Subject: [PATCH 01/11] fix state node --- .../executor/recipe_executor/executor.py | 36 +++++++++++++++---- .../executor/recipe_executor/parser.py | 13 +------ .../executor/recipe_executor/state.py | 16 ++++++++- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index fd3befb6e..412d85541 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -104,9 +104,19 @@ class AgentExecutor(): action.input[key] = value return action + @staticmethod + def get_leaves_result(state): + summary = "" + for name in state.leaves_tasks: + content = state.sop_graph.get("description", name) + res = state.variable_space.get(name, "") + summary += f"content: {content}\n" + summary += f"result: {res}\n" + return summary + def get_executable_actions(self, executor_state): done_actions = executor_state.done_tasks - graph = executor_state.sop_graph.actions + graph = executor_state.sop_graph activated = executor_state.activated_tasks independent_actions = [] for task_name in executor_state.remaining_tasks: @@ -142,7 +152,7 @@ class AgentExecutor(): return pending_actions def run_task(self, action, executor_state, llm): - graph = executor_state.sop_graph.actions + graph = executor_state.sop_graph sop_handler = self.operation_handler mommt = datetime.now(tz=timezone.utc) logger.debug(f'{action.name} start: {mommt.strftime("%Y-%m-%d %H:%M:%S")}') @@ -177,7 +187,8 @@ class AgentExecutor(): for future in as_completed(thread_list): with self.lock: self.update_history(future.result(), executor_state) - return executor_state.workspace.get_last_result() + # return executor_state.workspace.get_last_result() # 这个worksapce什么东西啊留在这没用 + return self.get_leaves_result(executor_state) # 而此处的写法不关注next,关注dependency def run(self, content): @@ -238,13 +249,26 @@ class AgentExecutor(): execute_state = ExecutorState() workspace = WorkSpace(operation_history=[], variable_space={}) - graph = ActionGraph(operations) execute_state.workspace = workspace - execute_state.sop_graph = graph - execute_state.remaining_tasks = {k for k, _ in graph.actions.items()} + execute_state.sop_graph = operations + execute_state.start_node_id = operations[next(iter(operations))] + execute_state.remaining_tasks = {k for k, _ in operations.items()} + execute_state.leaves_tasks = self.get_leaves_node(operations) return execute_state + def get_leaves_node(self, nodes): + leaves = [] + for node in nodes: + is_leaf = True + for other_node in nodes: + if node["step"] in other_node.get("dependency", []): + is_leaf = False + break + if is_leaf: + leaves.append(node["name"]) + return leaves + def fetch_str_content(content): start_identify = "```yaml" diff --git a/mxAgent/agent_sdk/executor/recipe_executor/parser.py b/mxAgent/agent_sdk/executor/recipe_executor/parser.py index ee4ac0895..1cf89a531 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/parser.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/parser.py @@ -57,7 +57,7 @@ class Parser: node = { "step": None, "name": None, - "goal": None, + "description": None, "input": None, # 输入 "prompt": None, # llm的prompt "activate": None, # 执行引擎,表达式验证规则 @@ -104,14 +104,3 @@ class Parser: else: raise TypeError("Invalid inputs type") return output - - - - -class ActionGraph: - def __init__(self, actions) -> None: - self.actions = actions - if len(actions) == 0: - self.start_node_id = 0 - else: - self.start_node_id = actions[next(iter(actions))] diff --git a/mxAgent/agent_sdk/executor/recipe_executor/state.py b/mxAgent/agent_sdk/executor/recipe_executor/state.py index eeae064e7..c015b09b6 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/state.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/state.py @@ -48,6 +48,8 @@ class ExecutorState: self.activated_tasks = set() self.done_tasks = set() self.activate_actions = [] + self.leaves_tasks = [] # 图中所有的叶子节点 + self.start_node_id = None # 开始节点 # for sop planning type self.init_query = "" @@ -73,7 +75,7 @@ class WorkSpace: operation_history, variable_space): self.operation_history = operation_history - self.variable_space = variable_space + self.variable_space = variable_space # 记录执行结果,workspace[node_name]的值正常是一个json,由[out_param]指定某一个具体的参数值 self.last_operation = "" def update(self, history): @@ -118,3 +120,15 @@ class WorkSpace: if value is not None and len(value) > 0: ans += f"{key}: {str(value)}\n" return ans + + def get_leaves_result(self, state): + summary = "" + for name in state.leaves_tasks: + content = state.sop_graph.get("description", name) + res = self.variable_space.get(name, "") + summary += f"content: {content}\n" + summary += f"result: {res}\n" + return summary + + + -- Gitee From 92c46955c3bdb9e5d9cb6408e66958cdda5f914c Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Tue, 31 Dec 2024 10:37:21 +0800 Subject: [PATCH 02/11] fix web summary --- .../tools/tool_query_accommodations.py | 21 ++++++++------- .../samples/tools/tool_query_attractions.py | 27 ++++++++++--------- .../samples/tools/tool_query_transports.py | 16 ++++++----- mxAgent/samples/tools/web_summary_api.py | 2 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/mxAgent/samples/tools/tool_query_accommodations.py b/mxAgent/samples/tools/tool_query_accommodations.py index 8c1edfdb1..5326b3537 100644 --- a/mxAgent/samples/tools/tool_query_accommodations.py +++ b/mxAgent/samples/tools/tool_query_accommodations.py @@ -50,16 +50,17 @@ class QueryAccommodations(API): logger.debug(f"search accommodation key words: {','.join(keys)}") prompt = """你是一个擅长文字处理和信息总结的智能助手,你的任务是将提供的网页信息进行总结,并以精简的文本的形式进行返回, - 请添加适当的词语,使得语句内容连贯,通顺。提供的信息是为用户推荐的酒店的网页数据, - 请总结网页信息,要求从以下几个方面考虑: - 1. 酒店的地理位置,星级、评分,评价,品牌信息 - 2. 不同的户型对应的价格、房间情况,对入住用户的要求等 - 并给出一到两个例子介绍这些情况 - 若输入的内容没有包含有效的酒店和住宿信息,请统一返回:【无】 - 下面是网页的输入: - {input} - 请生成总结: - """ +请添加适当的词语,使得语句内容连贯,通顺。提供的信息是为用户推荐的酒店的网页数据, +请总结网页信息,要求从以下几个方面考虑: +1. 酒店的地理位置,星级、评分,评价,品牌信息 +2. 不同的户型对应的价格、房间情况,对入住用户的要求等 +并给出一到两个例子介绍这些情况。 +必须注意下面这个要求: +若输入的内容没有包含相关的酒店和住宿信息,请统一返回:【无】 +下面是网页的输入: +{input} +请生成总结: +""" try: filtered = filter_website_keywords(keys) filtered.append("住宿") diff --git a/mxAgent/samples/tools/tool_query_attractions.py b/mxAgent/samples/tools/tool_query_attractions.py index b590d9542..ff16f98a0 100644 --- a/mxAgent/samples/tools/tool_query_attractions.py +++ b/mxAgent/samples/tools/tool_query_attractions.py @@ -54,19 +54,20 @@ class QueryAttractions(API): keys = [destination, scene, scene_type, requirement] summary_prompt = """你是一个擅长于网页信息总结的智能助手,提供的网页是关于旅游规划的信息,现在已经从网页中获取到了相关的文字内容信息,你需要从网页中找到与**景区**介绍相关的内容,并进行提取, - 你务必保证提取的内容都来自所提供的文本,保证结果的客观性,真实性。 - 网页中可能包含多个景点的介绍,你需要以YAML文件的格式返回,每个景点的返回的参数和格式如下: - **输出格式**: - - name: xx - introduction: xx - **参数介绍**: - name:景点名称 - introduction:精简的景区介绍,可以从以下这些方面阐述:景点的基本情况、历史文化等信息、景区门票信息、景区开放时间、景区的联系方式、预约方式以及链接,景区对游客的要求等。 - **注意** - 请注意:不要添加任何解释或注释,且严格遵循YAML格式 - 下面是提供的网页文本信息: - {input} - 请开始生成: +你务必保证提取的内容都来自所提供的文本,保证结果的客观性,真实性。 +网页中可能包含多个景点的介绍,你需要以YAML文件的格式返回,每个景点的返回的参数和格式如下: +**输出格式**: +- name: xx +introduction: xx +**参数介绍**: +name:景点名称 +introduction:精简的景区介绍,可以从以下这些方面阐述:景点的基本情况、历史文化等信息、景区门票信息、景区开放时间、景区的联系方式、预约方式以及链接,景区对游客的要求等。 +**注意** +1. 请注意:不要添加任何解释或注释,且严格遵循YAML格式 +2. 若输入的内容没有包含旅游和景点相关信息,请统一返回:【无】 +下面是提供的网页文本信息: +{input} +请开始生成: """ try: filtered = filter_website_keywords(keys) diff --git a/mxAgent/samples/tools/tool_query_transports.py b/mxAgent/samples/tools/tool_query_transports.py index bf048f822..367aab9e9 100644 --- a/mxAgent/samples/tools/tool_query_transports.py +++ b/mxAgent/samples/tools/tool_query_transports.py @@ -55,13 +55,15 @@ class QueryTransports(API): keys = [prefix, req, travel_mode] prompt = """你的任务是将提供的网页信息进行总结,并以精简的文本的形式进行返回, - 请添加适当的词语,使得语句内容连贯,通顺。输入是为用户查询的航班、高铁等交通数据,请将这些信息总结 - 请总结网页信息,要求从以下几个方面考虑: - 总结出航班或者高铁的价格区间、需要时长区间、并给出2-3例子,介绍车次、时间、时长、价格等 - 下面是网页的输入: - {input} - 请生成总结: - """ +请添加适当的词语,使得语句内容连贯,通顺。输入是为用户查询的航班、高铁等交通数据,请将这些信息总结 +请总结网页信息,要求从以下几个方面考虑: +总结出航班或者高铁的价格区间、需要时长区间、并给出2-3例子,介绍车次、时间、时长、价格等 +请特别注意: +若输入的内容没有包含相关的酒店和住宿信息,请统一返回:【无】 +下面是网页的输入: +{input} +请生成总结: +""" filtered = filter_website_keywords(keys) webs = WebSummary.web_summary( filtered, search_num=3, summary_num=3, summary_prompt=prompt, llm=llm) diff --git a/mxAgent/samples/tools/web_summary_api.py b/mxAgent/samples/tools/web_summary_api.py index c4e040dd3..39fcecebe 100644 --- a/mxAgent/samples/tools/web_summary_api.py +++ b/mxAgent/samples/tools/web_summary_api.py @@ -115,7 +115,7 @@ class WebSummary: content, err = asyncio.run(cls.get_details(url, summary_prompt)) except Exception as e: logger.error(e) - if not isinstance(content, str) or len(content) == 0: + if not isinstance(content, str) or len(content) == 0 or "【无】" in content: web_summary['snippet'] = snippet else: web_summary['content'] = content -- Gitee From 5ec3bb3986401372e6713883687e3623fa901f1e Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Tue, 31 Dec 2024 10:50:12 +0800 Subject: [PATCH 03/11] fix weather --- mxAgent/samples/tools/tool_query_weather.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mxAgent/samples/tools/tool_query_weather.py b/mxAgent/samples/tools/tool_query_weather.py index 2df61a1db..03d877a28 100644 --- a/mxAgent/samples/tools/tool_query_weather.py +++ b/mxAgent/samples/tools/tool_query_weather.py @@ -88,7 +88,7 @@ class QueryWeather(API): # 精简输入 key_keeps = [ 'day_weather', 'day_wind_direction', 'day_wind_power', - 'max_degree', 'min_degree', 'night_weather', 'night_wind_direction', 'night_wind_power' + 'max_degree', 'min_degree', 'night_weather' ] summary_copy = [] for key, info in weekly_weather.items(): @@ -98,7 +98,7 @@ class QueryWeather(API): info_keeps = {k: info[k] for k in key_keeps if k in info} daily[time] = info_keeps summary_copy.append(daily) - return summary_copy + return summary_copy[:5] def format_request_param(self, data, weather_type): for key, value in data.items(): @@ -164,7 +164,7 @@ class QueryWeather(API): weather_summary = summary_copy[gaps + 1:] if len(weather_summary) == 0: - weather_summary = "**抱歉,我最多只能查询最近7天的天气情况,例如下面是我将为你提供最近的天气预报**:\n" + \ + weather_summary = "**抱歉,我最多只能查询最近5天的天气情况,例如下面是我将为你提供最近的天气预报**:\n" + \ json.dumps(summary_copy, ensure_ascii=False, indent=4) res = { 'forecast': weather_summary -- Gitee From 66a02aa8988275a371bad1b93d530e1218161d52 Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Tue, 31 Dec 2024 11:13:34 +0800 Subject: [PATCH 04/11] fix node state --- .../executor/recipe_executor/executor.py | 16 ++++++++-------- .../agent_sdk/executor/recipe_executor/parser.py | 7 +++++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index 412d85541..ba85531b6 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -15,7 +15,7 @@ import yaml from loguru import logger from agent_sdk.executor.recipe_executor.state import ExecutorState, WorkSpace -from agent_sdk.executor.recipe_executor.parser import Node, Parser, ActionGraph +from agent_sdk.executor.recipe_executor.parser import Node, Parser from agent_sdk.executor.recipe_executor.sop import SopHandler from agent_sdk.executor.common import ERROR_MAP, ErrorType, PlanStrategyType @@ -108,10 +108,10 @@ class AgentExecutor(): def get_leaves_result(state): summary = "" for name in state.leaves_tasks: - content = state.sop_graph.get("description", name) - res = state.variable_space.get(name, "") + content = state.sop_graph.description + res = state.workspace.variable_space.get(name, "") summary += f"content: {content}\n" - summary += f"result: {res}\n" + summary += f"result: {json.dumps(res, ensure_ascii=False)}\n" return summary def get_executable_actions(self, executor_state): @@ -259,14 +259,14 @@ class AgentExecutor(): def get_leaves_node(self, nodes): leaves = [] - for node in nodes: + for key, _ in nodes.items(): is_leaf = True - for other_node in nodes: - if node["step"] in other_node.get("dependency", []): + for _, other_node in nodes.items(): + if key in other_node.dependency: is_leaf = False break if is_leaf: - leaves.append(node["name"]) + leaves.append(key) return leaves diff --git a/mxAgent/agent_sdk/executor/recipe_executor/parser.py b/mxAgent/agent_sdk/executor/recipe_executor/parser.py index 1cf89a531..40a19999c 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/parser.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/parser.py @@ -9,6 +9,7 @@ from loguru import logger class Node: def __init__(self, name, + description, content, prompt, step, @@ -22,6 +23,7 @@ class Node: ): self.step = step self.name = name + self.description = description self.input = content self.prompt = prompt self.activate = activate @@ -39,7 +41,8 @@ class Parser: def construct_graph(nodes): graph = OrderedDict() for operation in nodes: - operation = Node(name=operation['name'], + node = Node(name=operation['name'], + description=operation["description"], step=operation['step'], content=operation['input'], prompt=operation['prompt'], @@ -48,7 +51,7 @@ class Parser: output=operation["output"], strategy=operation["strategy"], activate=operation["activate"]) - graph[operation.name] = operation + graph[node.name] = node return graph def parse(self, raw_dict): -- Gitee From 136da7255049d13ff5f027ec877f09727160d54a Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Tue, 31 Dec 2024 11:17:18 +0800 Subject: [PATCH 05/11] fix node desc --- mxAgent/agent_sdk/executor/recipe_executor/executor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index ba85531b6..53b08d09a 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -108,7 +108,7 @@ class AgentExecutor(): def get_leaves_result(state): summary = "" for name in state.leaves_tasks: - content = state.sop_graph.description + content = state.sop_graph[name].description res = state.workspace.variable_space.get(name, "") summary += f"content: {content}\n" summary += f"result: {json.dumps(res, ensure_ascii=False)}\n" -- Gitee From e4bd6e9f16eb14db6dfa9c4174b3d7635d2248af Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Tue, 31 Dec 2024 14:13:05 +0800 Subject: [PATCH 06/11] fix final prompt --- mxAgent/agent_sdk/agentchain/recipe_agent.py | 12 ++++++------ .../agent_sdk/executor/recipe_executor/executor.py | 9 +++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/mxAgent/agent_sdk/agentchain/recipe_agent.py b/mxAgent/agent_sdk/agentchain/recipe_agent.py index c12a1d6f0..d9adc71f0 100644 --- a/mxAgent/agent_sdk/agentchain/recipe_agent.py +++ b/mxAgent/agent_sdk/agentchain/recipe_agent.py @@ -82,17 +82,17 @@ class RecipeAgent(BaseAgent, ABC): def get_tool_usage(self): return self.tool_desc_for_agent - def _build_final_prompt(self, text, **kwargs) -> Union[List, str]: - if self.final_prompt is None: + def _build_final_prompt(self, recipe_out, **kwargs) -> Union[List, str]: + if self.final_prompt is None or len(recipe_out) == 0: raise Exception("final prompt is None error") else: max_input_token_num = self.max_token_number input_token_len = len(self.encoding.encode(text)) prompt_len = len(self.encoding.encode(self.final_prompt)) - clip_text_index = int( - len(text) * (max_input_token_num - prompt_len) / input_token_len) - clip_text = text[:clip_text_index] - pmt = self.final_prompt.format(text=clip_text) + # 每个token平均可能包含1.5-1.8个汉字 + element_len = 1.5 * (max_input_token_num-prompt_len) / len(recipe_out) + text = "".join([item[:element_len] for item in recipe_out]) + pmt = self.final_prompt.format(text=text) return pmt def _execute_recipe(self, recipefile, llm): diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index 53b08d09a..481b09739 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -106,13 +106,14 @@ class AgentExecutor(): @staticmethod def get_leaves_result(state): - summary = "" + summary = [] for name in state.leaves_tasks: + item = "" content = state.sop_graph[name].description res = state.workspace.variable_space.get(name, "") - summary += f"content: {content}\n" - summary += f"result: {json.dumps(res, ensure_ascii=False)}\n" - return summary + item += f"content: {content}\n" + item += f"result: {json.dumps(res, ensure_ascii=False)}\n" + return summary.append(item) # 每个叶子节点都有一个结束的结果 def get_executable_actions(self, executor_state): done_actions = executor_state.done_tasks -- Gitee From c8bead7323ec7aa51ef49c8948f6d481329d964c Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Thu, 2 Jan 2025 09:58:14 +0800 Subject: [PATCH 07/11] fix duck duck search --- mxAgent/samples/tools/duck_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxAgent/samples/tools/duck_search.py b/mxAgent/samples/tools/duck_search.py index f99a79129..f6bc1cd0b 100644 --- a/mxAgent/samples/tools/duck_search.py +++ b/mxAgent/samples/tools/duck_search.py @@ -56,7 +56,7 @@ def call_duck_duck_go_search(query: str, count: int) -> List[str]: while retry <= 3: try: logger.debug(f"search DuckDuckGo({query}, {count})") - results = DDGS().text(query, backend="html", max_results=count) + results = DDGS().text(query, max_results=count) return results except Exception as e: retry += 1 -- Gitee From c9388b19350cf22c842d6dce2c67d8a860dd4fb4 Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Thu, 2 Jan 2025 10:13:23 +0800 Subject: [PATCH 08/11] fix executor --- mxAgent/agent_sdk/executor/recipe_executor/executor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index 481b09739..d2cb7aaaf 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -113,7 +113,8 @@ class AgentExecutor(): res = state.workspace.variable_space.get(name, "") item += f"content: {content}\n" item += f"result: {json.dumps(res, ensure_ascii=False)}\n" - return summary.append(item) # 每个叶子节点都有一个结束的结果 + summary.append(item) # 每个叶子节点都有一个结束的结果 + return summary def get_executable_actions(self, executor_state): done_actions = executor_state.done_tasks @@ -188,7 +189,6 @@ class AgentExecutor(): for future in as_completed(thread_list): with self.lock: self.update_history(future.result(), executor_state) - # return executor_state.workspace.get_last_result() # 这个worksapce什么东西啊留在这没用 return self.get_leaves_result(executor_state) # 而此处的写法不关注next,关注dependency -- Gitee From d71302422c4f0ec09efeec359065b2d8c4901579 Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Thu, 2 Jan 2025 15:21:08 +0800 Subject: [PATCH 09/11] fix cution --- mxAgent/agent_sdk/agentchain/recipe_agent.py | 5 ++--- mxAgent/agent_sdk/executor/recipe_executor/executor.py | 8 +++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/mxAgent/agent_sdk/agentchain/recipe_agent.py b/mxAgent/agent_sdk/agentchain/recipe_agent.py index d9adc71f0..f37a3bfd6 100644 --- a/mxAgent/agent_sdk/agentchain/recipe_agent.py +++ b/mxAgent/agent_sdk/agentchain/recipe_agent.py @@ -87,11 +87,10 @@ class RecipeAgent(BaseAgent, ABC): raise Exception("final prompt is None error") else: max_input_token_num = self.max_token_number - input_token_len = len(self.encoding.encode(text)) prompt_len = len(self.encoding.encode(self.final_prompt)) # 每个token平均可能包含1.5-1.8个汉字 - element_len = 1.5 * (max_input_token_num-prompt_len) / len(recipe_out) - text = "".join([item[:element_len] for item in recipe_out]) + element_len = 1.5 * (max_input_token_num-prompt_len) + text = recipe_out[:element_len] pmt = self.final_prompt.format(text=text) return pmt diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index d2cb7aaaf..2380f780a 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -106,14 +106,12 @@ class AgentExecutor(): @staticmethod def get_leaves_result(state): - summary = [] + summary = "" for name in state.leaves_tasks: - item = "" content = state.sop_graph[name].description res = state.workspace.variable_space.get(name, "") - item += f"content: {content}\n" - item += f"result: {json.dumps(res, ensure_ascii=False)}\n" - summary.append(item) # 每个叶子节点都有一个结束的结果 + summary += f"content: {content}\n" + summary += f"result: {json.dumps(res, ensure_ascii=False)}\n" return summary def get_executable_actions(self, executor_state): -- Gitee From 317a15d18fa7b5871c926a847eb3c523c5414969 Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Thu, 2 Jan 2025 16:46:07 +0800 Subject: [PATCH 10/11] clean code --- mxAgent/agent_sdk/agentchain/recipe_agent.py | 13 +++++----- .../executor/recipe_executor/executor.py | 25 ++++++++++--------- mxAgent/samples/tools/duck_search.py | 2 +- .../samples/tools/tool_query_transports.py | 2 +- mxAgent/samples/tools/web_summary_api.py | 6 +++-- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/mxAgent/agent_sdk/agentchain/recipe_agent.py b/mxAgent/agent_sdk/agentchain/recipe_agent.py index f37a3bfd6..c12a1d6f0 100644 --- a/mxAgent/agent_sdk/agentchain/recipe_agent.py +++ b/mxAgent/agent_sdk/agentchain/recipe_agent.py @@ -82,16 +82,17 @@ class RecipeAgent(BaseAgent, ABC): def get_tool_usage(self): return self.tool_desc_for_agent - def _build_final_prompt(self, recipe_out, **kwargs) -> Union[List, str]: - if self.final_prompt is None or len(recipe_out) == 0: + def _build_final_prompt(self, text, **kwargs) -> Union[List, str]: + if self.final_prompt is None: raise Exception("final prompt is None error") else: max_input_token_num = self.max_token_number + input_token_len = len(self.encoding.encode(text)) prompt_len = len(self.encoding.encode(self.final_prompt)) - # 每个token平均可能包含1.5-1.8个汉字 - element_len = 1.5 * (max_input_token_num-prompt_len) - text = recipe_out[:element_len] - pmt = self.final_prompt.format(text=text) + clip_text_index = int( + len(text) * (max_input_token_num - prompt_len) / input_token_len) + clip_text = text[:clip_text_index] + pmt = self.final_prompt.format(text=clip_text) return pmt def _execute_recipe(self, recipefile, llm): diff --git a/mxAgent/agent_sdk/executor/recipe_executor/executor.py b/mxAgent/agent_sdk/executor/recipe_executor/executor.py index 2380f780a..ee8ca765b 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/executor.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/executor.py @@ -113,6 +113,19 @@ class AgentExecutor(): summary += f"content: {content}\n" summary += f"result: {json.dumps(res, ensure_ascii=False)}\n" return summary + + @staticmethod + def get_leaves_node(nodes): + leaves = [] + for key, _ in nodes.items(): + is_leaf = True + for _, other_node in nodes.items(): + if key in other_node.dependency: + is_leaf = False + break + if is_leaf: + leaves.append(key) + return leaves def get_executable_actions(self, executor_state): done_actions = executor_state.done_tasks @@ -256,18 +269,6 @@ class AgentExecutor(): execute_state.leaves_tasks = self.get_leaves_node(operations) return execute_state - def get_leaves_node(self, nodes): - leaves = [] - for key, _ in nodes.items(): - is_leaf = True - for _, other_node in nodes.items(): - if key in other_node.dependency: - is_leaf = False - break - if is_leaf: - leaves.append(key) - return leaves - def fetch_str_content(content): start_identify = "```yaml" diff --git a/mxAgent/samples/tools/duck_search.py b/mxAgent/samples/tools/duck_search.py index f6bc1cd0b..f99a79129 100644 --- a/mxAgent/samples/tools/duck_search.py +++ b/mxAgent/samples/tools/duck_search.py @@ -56,7 +56,7 @@ def call_duck_duck_go_search(query: str, count: int) -> List[str]: while retry <= 3: try: logger.debug(f"search DuckDuckGo({query}, {count})") - results = DDGS().text(query, max_results=count) + results = DDGS().text(query, backend="html", max_results=count) return results except Exception as e: retry += 1 diff --git a/mxAgent/samples/tools/tool_query_transports.py b/mxAgent/samples/tools/tool_query_transports.py index 367aab9e9..8a6a383eb 100644 --- a/mxAgent/samples/tools/tool_query_transports.py +++ b/mxAgent/samples/tools/tool_query_transports.py @@ -59,7 +59,7 @@ class QueryTransports(API): 请总结网页信息,要求从以下几个方面考虑: 总结出航班或者高铁的价格区间、需要时长区间、并给出2-3例子,介绍车次、时间、时长、价格等 请特别注意: -若输入的内容没有包含相关的酒店和住宿信息,请统一返回:【无】 +若输入的内容没有包含相关的交通信息,请统一返回:【无】 下面是网页的输入: {input} 请生成总结: diff --git a/mxAgent/samples/tools/web_summary_api.py b/mxAgent/samples/tools/web_summary_api.py index 39fcecebe..a91c69f56 100644 --- a/mxAgent/samples/tools/web_summary_api.py +++ b/mxAgent/samples/tools/web_summary_api.py @@ -91,6 +91,8 @@ class WebSummary: if 'PleaseenableJSanddisableanyadblocker' in text: text = "" except Exception as e: + if len(str(e)) == 0: + e = Exception(f"error type: {type(e)}, when request the url: {url}") logger.error(e) return '', e if len(text) == 0: @@ -115,7 +117,7 @@ class WebSummary: content, err = asyncio.run(cls.get_details(url, summary_prompt)) except Exception as e: logger.error(e) - if not isinstance(content, str) or len(content) == 0 or "【无】" in content: + if not isinstance(content, str) or len(content) == 0 or content == "【无】": web_summary['snippet'] = snippet else: web_summary['content'] = content @@ -130,7 +132,7 @@ class WebSummary: mommt = datetime.now(tz=timezone.utc) logger.debug(f"start duck duck go search: {mommt.strftime('%Y-%m-%d %H:%M:%S')}") if isinstance(keys, list): - keys = ",".join(keys) + keys = " ".join(keys) search_result = call_duck_duck_go_search(keys, search_num) mommt = datetime.now(tz=timezone.utc) logger.debug(f"finish duck duck go search: {mommt.strftime('%Y-%m-%d %H:%M:%S')}") -- Gitee From 918e985ccfee347602d96eacd2070f99b512227e Mon Sep 17 00:00:00 2001 From: hu-xinjia Date: Thu, 2 Jan 2025 17:35:19 +0800 Subject: [PATCH 11/11] clean code --- mxAgent/agent_sdk/executor/recipe_executor/state.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/mxAgent/agent_sdk/executor/recipe_executor/state.py b/mxAgent/agent_sdk/executor/recipe_executor/state.py index c015b09b6..d0e916507 100644 --- a/mxAgent/agent_sdk/executor/recipe_executor/state.py +++ b/mxAgent/agent_sdk/executor/recipe_executor/state.py @@ -120,15 +120,3 @@ class WorkSpace: if value is not None and len(value) > 0: ans += f"{key}: {str(value)}\n" return ans - - def get_leaves_result(self, state): - summary = "" - for name in state.leaves_tasks: - content = state.sop_graph.get("description", name) - res = self.variable_space.get(name, "") - summary += f"content: {content}\n" - summary += f"result: {res}\n" - return summary - - - -- Gitee