diff --git a/agentuniverse/agent/plan/planner/doe_planner/__init__.py b/agentuniverse/agent/plan/planner/doe_planner/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/agentuniverse/agent/plan/planner/doe_planner/doe_planner.py b/agentuniverse/agent/plan/planner/doe_planner/doe_planner.py new file mode 100644 index 00000000..af13e3ff --- /dev/null +++ b/agentuniverse/agent/plan/planner/doe_planner/doe_planner.py @@ -0,0 +1,54 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: doe_planner.py +"""DOE planner module.""" +from agentuniverse.agent.agent_manager import AgentManager +from agentuniverse.agent.agent_model import AgentModel +from agentuniverse.agent.input_object import InputObject +from agentuniverse.agent.plan.planner.planner import Planner +from agentuniverse.base.util.logging.logging_util import LOGGER + + +class DOEPlanner(Planner): + """Executing planner class.""" + + def invoke(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject) -> dict: + """Invoke the planner. + + Args: + agent_model (AgentModel): Agent model object. + planner_input (dict): Planner input object. + input_object (InputObject): The input parameters passed by the user. + Returns: + dict: The planner result. + """ + + data_fining_agent = agent_model.plan.get('planner').get('data_fining_agent') + opinion_inject_agent = agent_model.plan.get('planner').get('opinion_inject_agent') + expressing_agent = agent_model.plan.get('planner').get('expressing_agent') + + # 数据加工 + LOGGER.info("Start data fining...") + data_fining_output = AgentManager().get_instance_obj(data_fining_agent).run(**planner_input) + LOGGER.info(f"Finished data fining, Data fining result: {data_fining_output.to_dict()}") + self.stream_output(input_object, data_fining_output.to_dict()) + planner_input.update(data_fining_output.to_dict()) + + # 观点注入 + LOGGER.info("Start opinion inject...") + opinion_inject_output = AgentManager().get_instance_obj(opinion_inject_agent).run(**planner_input) + LOGGER.info(f"Finished opinion inject, Opinion inject result: {opinion_inject_output.to_dict()}") + self.stream_output(input_object, opinion_inject_output.to_dict()) + planner_input.update(opinion_inject_output.to_dict()) + + # 表达 + LOGGER.info("Start expressing...") + expressing_agent_result = AgentManager().get_instance_obj(expressing_agent).run(**planner_input) + LOGGER.info(f"Finished expressing,Expressing result: {expressing_agent_result.to_dict()}") + self.stream_output(input_object, expressing_agent_result.to_dict()) + + return expressing_agent_result.to_dict() diff --git a/agentuniverse/agent/plan/planner/doe_planner/doe_planner.yaml b/agentuniverse/agent/plan/planner/doe_planner/doe_planner.yaml new file mode 100644 index 00000000..7e519902 --- /dev/null +++ b/agentuniverse/agent/plan/planner/doe_planner/doe_planner.yaml @@ -0,0 +1,6 @@ +name: 'doe_planner' +description: 'doe planner' +metadata: + type: 'PLANNER' + module: 'agentuniverse.agent.plan.planner.doe_planner.doe_planner' + class: 'DOEPlanner' \ No newline at end of file diff --git a/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml index 58bb4c9d..97c44f4e 100644 --- a/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml +++ b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml @@ -1,3 +1,4 @@ + name: 'rag_planner' description: 'rag planner' metadata: diff --git a/agentuniverse/agent/plan/planner/serial_planner/__init__.py b/agentuniverse/agent/plan/planner/serial_planner/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/agentuniverse/agent/plan/planner/serial_planner/serial_planner.py b/agentuniverse/agent/plan/planner/serial_planner/serial_planner.py new file mode 100644 index 00000000..1e4e705c --- /dev/null +++ b/agentuniverse/agent/plan/planner/serial_planner/serial_planner.py @@ -0,0 +1,103 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: serial_planner.py + +from agentuniverse.agent.action.tool.tool import Tool +from agentuniverse.agent.action.tool.tool_manager import ToolManager +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.agent_manager import AgentManager +from agentuniverse.agent.agent_model import AgentModel +from agentuniverse.agent.input_object import InputObject +from agentuniverse.agent.output_object import OutputObject +from agentuniverse.agent.plan.planner.planner import Planner +from agentuniverse.base.util.logging.logging_util import LOGGER + + +def execute_tool_or_agent(name: str, manager_class, planner_input: dict, + runtime_params: dict): + instance = manager_class.get_instance_obj(name) + input_params = dict() + input_params.update(runtime_params) + + if isinstance(instance, Tool): + input_keys = instance.input_keys + elif isinstance(instance, Agent): + input_keys = instance.input_keys() + else: + raise ValueError(f"Unsupported instance type: {instance}") + + for key in input_keys: + if key in input_params: + continue + if key not in planner_input: + raise Exception(f"{key} is not in planner input") + input_params[key] = planner_input.get(key) + + try: + result = instance.run(**input_params) + if isinstance(result, dict): + planner_input.update(result) + elif isinstance(result, OutputObject): + planner_input.update(result.to_dict()) + else: + planner_input[name] = result + return result + except Exception as e: + raise Exception(f"Error executing {name}: {e}") + + +class SerialPlanner(Planner): + """Executing planner class.""" + + def invoke(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject) -> dict: + """Invoke the planner. + + Args: + agent_model (AgentModel): Agent model object. + planner_input (dict): Planner input object. + input_object (InputObject): The input parameters passed by the user. + Returns: + dict: The planner result. + """ + output_stream = input_object.get_data('output_stream') + if output_stream: + planner_input.update({'output_stream': output_stream}) + return self.run_all_actions(agent_model, planner_input, input_object) + + def run_all_actions(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject): + if not isinstance(planner_input, dict): + raise TypeError("planner_input must be a dictionary") + + serials: dict = agent_model.plan.get('planner') + for key in serials: + if key == 'name': + continue + tool = serials.get(key) + tool_name = tool.get('name') + runtime_params = tool.get('runtime_params') or dict() + tool_type = tool.get('type') or 'tool' + if tool_type == 'tool': + LOGGER.info(f"start Executing tool: {tool_name}") + res = execute_tool_or_agent(tool_name, ToolManager(), planner_input, runtime_params) + self.stream_output(input_object, { + 'data': res, + "type": "tool", + "agent_info": agent_model.info + }) + LOGGER.info(f"finished execute tool {tool_name},execute result {res}") + elif tool_type == 'agent': + LOGGER.info(f"start Executing Agent: {tool_name}") + res = execute_tool_or_agent(tool_name, AgentManager(), planner_input, runtime_params) + self.stream_output(input_object, { + 'data': res.to_dict(), + "type": "agent", + "agent_info": agent_model.info + }) + LOGGER.info(f"finished execute agent {tool_name},execute result {res.to_dict()}") + else: + raise ValueError(f"Unsupported tool type: {tool_type}") + return planner_input diff --git a/agentuniverse/agent/plan/planner/serial_planner/serial_planner.yaml b/agentuniverse/agent/plan/planner/serial_planner/serial_planner.yaml new file mode 100644 index 00000000..0206c1c9 --- /dev/null +++ b/agentuniverse/agent/plan/planner/serial_planner/serial_planner.yaml @@ -0,0 +1,6 @@ +name: 'serial_planner' +description: 'serial planner' +metadata: + type: 'PLANNER' + module: 'agentuniverse.agent.plan.planner.serial_planner.serial_planner' + class: 'SerialPlanner' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index ec5c24ee..d0ef2b91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ pymilvus = { version = "^2.4.3", optional = true} googleapis-common-protos = "^1.63.0" myst-parser = "^2.0.0" qianfan = "^0.3.12" -dashscope = "^1.19.1" +dashscope = "1.19.1" anthropic = "^0.26.0" ollama = '^0.2.1' langchain-anthropic = '^0.1.13' diff --git a/sample_standard_app/app/core/agent/doe_agent_case/__init__.py b/sample_standard_app/app/core/agent/doe_agent_case/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sample_standard_app/app/core/agent/doe_agent_case/data_fining_agent.py b/sample_standard_app/app/core/agent/doe_agent_case/data_fining_agent.py new file mode 100644 index 00000000..5984ffad --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/data_fining_agent.py @@ -0,0 +1,29 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: data_fining_agent.py + + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class DataFiningAgent(Agent): + def input_keys(self) -> list[str]: + return ['input'] + + def output_keys(self) -> list[str]: + return ['data_fining_result'] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in input_object.to_dict(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + return { + 'data_fining_result': planner_result.get('data_processing_result') + } diff --git a/sample_standard_app/app/core/agent/doe_agent_case/data_fining_agent.yaml b/sample_standard_app/app/core/agent/doe_agent_case/data_fining_agent.yaml new file mode 100644 index 00000000..5705ea99 --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/data_fining_agent.yaml @@ -0,0 +1,22 @@ +info: + name: 'data_fining_agent' + description: 'data fining agent' +profile: + llm_model: + name: 'deep_seek_llm' + temperature: 0.6 +plan: + planner: + name: 'serial_planner' + data_loader: + name: 'load_fund_tool' + type: 'tool' + data_processing: +# name: 'data_processing_agent' +# type: 'agent' + name: 'fund_data_processing_agent' + type: 'agent' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.data_fining_agent' + class: 'DataFiningAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/agent/doe_agent_case/data_processing_agent.py b/sample_standard_app/app/core/agent/doe_agent_case/data_processing_agent.py new file mode 100644 index 00000000..de46bcfd --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/data_processing_agent.py @@ -0,0 +1,30 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: data_processing_agent.py + +from langchain_core.utils.json import parse_json_markdown + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class DataProcessingAgent(Agent): + def input_keys(self) -> list[str]: + return ['input','init_data'] + + def output_keys(self) -> list[str]: + return ['data_processing_result'] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in input_object.to_dict(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + return { + 'data_processing_result': parse_json_markdown(planner_result.get('output')) + } diff --git a/sample_standard_app/app/core/agent/doe_agent_case/data_processing_agent.yaml b/sample_standard_app/app/core/agent/doe_agent_case/data_processing_agent.yaml new file mode 100644 index 00000000..ed065939 --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/data_processing_agent.yaml @@ -0,0 +1,15 @@ +info: + name: 'data_processing_agent' + description: 'data processing agent' +profile: + prompt_version: data_processing_agent.cn + llm_model: + name: 'deep_seek_llm' + temperature: 0.6 +plan: + planner: + name: 'rag_planner' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.data_processing_agent' + class: 'DataProcessingAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/agent/doe_agent_case/doe_agent_case.py b/sample_standard_app/app/core/agent/doe_agent_case/doe_agent_case.py new file mode 100644 index 00000000..e8600e3c --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/doe_agent_case.py @@ -0,0 +1,26 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: doe_agent.py + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class DOEAgent(Agent): + def input_keys(self) -> list[str]: + return ['input'] + + def output_keys(self) -> list[str]: + return [] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in input_object.to_dict(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + return planner_result diff --git a/sample_standard_app/app/core/agent/doe_agent_case/doe_agent_case.yaml b/sample_standard_app/app/core/agent/doe_agent_case/doe_agent_case.yaml new file mode 100644 index 00000000..07cf5a3a --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/doe_agent_case.yaml @@ -0,0 +1,15 @@ +info: + name: 'doe_agent_case' + description: 'DOE agent case' +profile: +action: +plan: + planner: + name: 'doe_planner' + data_fining_agent: 'data_fining_agent' + opinion_inject_agent: 'opinion_inject_agent' + expressing_agent: 'doe_expressing_agent_case' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.doe_agent_case' + class: 'DOEAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/agent/doe_agent_case/doe_expressing_agent_case.py b/sample_standard_app/app/core/agent/doe_agent_case/doe_expressing_agent_case.py new file mode 100644 index 00000000..19f854ad --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/doe_expressing_agent_case.py @@ -0,0 +1,26 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: doe_expressing_agent.py + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class DOEExpressingAgent(Agent): + def input_keys(self) -> list[str]: + return ['input','data_fining_result','matched_opinions'] + + def output_keys(self) -> list[str]: + return [] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in self.input_keys(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + return planner_result diff --git a/sample_standard_app/app/core/agent/doe_agent_case/doe_expressing_agent_case.yaml b/sample_standard_app/app/core/agent/doe_agent_case/doe_expressing_agent_case.yaml new file mode 100644 index 00000000..b8903f52 --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/doe_expressing_agent_case.yaml @@ -0,0 +1,16 @@ +info: + name: 'doe_expressing_agent_case' + description: 'DOE expressing agent case' +profile: + prompt_version: doe_expressing_agent_case.cn + llm_model: + name: 'deep_seek_llm' + temperature: 0.6 +action: +plan: + planner: + name: 'rag_planner' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.doe_expressing_agent_case' + class: 'DOEExpressingAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/agent/doe_agent_case/fund_data_processing_agent.yaml b/sample_standard_app/app/core/agent/doe_agent_case/fund_data_processing_agent.yaml new file mode 100644 index 00000000..b69f50dd --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/fund_data_processing_agent.yaml @@ -0,0 +1,15 @@ +info: + name: 'fund_data_processing_agent' + description: 'fund data processing agent' +profile: + prompt_version: fund_data_fining_agent.cn + llm_model: + name: 'deep_seek_llm' + temperature: 0.6 +plan: + planner: + name: 'rag_planner' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.data_processing_agent' + class: 'DataProcessingAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/agent/doe_agent_case/opinion_generate_agent.py b/sample_standard_app/app/core/agent/doe_agent_case/opinion_generate_agent.py new file mode 100644 index 00000000..af18ec7e --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/opinion_generate_agent.py @@ -0,0 +1,30 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: opinion_generate_agent.py + +from langchain_core.utils.json import parse_json_markdown + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class OpinionGenerateAgent(Agent): + def input_keys(self) -> list[str]: + return ['input','business_scene'] + + def output_keys(self) -> list[str]: + return [] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in input_object.to_dict(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + return { + 'opinions': parse_json_markdown(planner_result.get('output')) + } diff --git a/sample_standard_app/app/core/agent/doe_agent_case/opinion_generate_agent.yaml b/sample_standard_app/app/core/agent/doe_agent_case/opinion_generate_agent.yaml new file mode 100644 index 00000000..d5eda56d --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/opinion_generate_agent.yaml @@ -0,0 +1,15 @@ +info: + name: 'opinion_generate_agent' + description: 'opinion generate agent' +profile: + prompt_version: 'opinion_generate.cn' + llm_model: + name: 'deep_seek_llm' + temperature: 0.6 +plan: + planner: + name: 'rag_planner' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.opinion_generate_agent' + class: 'OpinionGenerateAgent' diff --git a/sample_standard_app/app/core/agent/doe_agent_case/opinion_inject_agent.py b/sample_standard_app/app/core/agent/doe_agent_case/opinion_inject_agent.py new file mode 100644 index 00000000..8d2f772e --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/opinion_inject_agent.py @@ -0,0 +1,36 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: opinion_inject_agent.py + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class OpinionInjectAgent(Agent): + """ + An agent that injects opinions into the input. + """ + + def input_keys(self) -> list[str]: + return ['data_fining_result'] + + def output_keys(self) -> list[str]: + return ['matched_opinions'] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in input_object.to_dict(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + matched_opinions = [ + { + "opinion": opinion["opinion"], + "type": opinion["type"], + } for opinion in planner_result.get('matched_opinions') + ] + return {"matched_opinions": matched_opinions} diff --git a/sample_standard_app/app/core/agent/doe_agent_case/opinion_inject_agent.yaml b/sample_standard_app/app/core/agent/doe_agent_case/opinion_inject_agent.yaml new file mode 100644 index 00000000..743851ae --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/opinion_inject_agent.yaml @@ -0,0 +1,21 @@ +info: + name: 'opinion_inject_agent' + description: 'opinion inject agent' +profile: +plan: + planner: + name: 'serial_planner' + opinion_generate: +# name: 'opinion_generate_agent' +# type: 'agent' + name: 'load_opinion_tool' + type: 'tool' + opinion_verify: + name: 'opinion_verify_agent' + type: 'agent' +# name: 'opinion_verify_tool' +# type: 'tool' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.opinion_inject_agent' + class: 'OpinionInjectAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/agent/doe_agent_case/opinion_verify_agent.py b/sample_standard_app/app/core/agent/doe_agent_case/opinion_verify_agent.py new file mode 100644 index 00000000..b8900db6 --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/opinion_verify_agent.py @@ -0,0 +1,30 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: opinion_verify_agent.py + +from langchain_core.utils.json import parse_json_markdown + +from agentuniverse.agent.agent import Agent +from agentuniverse.agent.input_object import InputObject + + +class OpinionVerifyAgent(Agent): + def input_keys(self) -> list[str]: + return ['input', 'data_fining_result', 'opinions'] + + def output_keys(self) -> list[str]: + return [] + + def parse_input(self, input_object: InputObject, agent_input: dict) -> dict: + for key in input_object.to_dict(): + agent_input[key] = input_object.get_data(key) + return agent_input + + def parse_result(self, planner_result: dict) -> dict: + return { + "matched_opinions":parse_json_markdown(planner_result.get('output')).get('matched_opinions') + } diff --git a/sample_standard_app/app/core/agent/doe_agent_case/opinion_verify_agent.yaml b/sample_standard_app/app/core/agent/doe_agent_case/opinion_verify_agent.yaml new file mode 100644 index 00000000..048efb08 --- /dev/null +++ b/sample_standard_app/app/core/agent/doe_agent_case/opinion_verify_agent.yaml @@ -0,0 +1,16 @@ +info: + name: 'opinion_verify_agent' + description: 'opinion verify agent' +profile: + prompt_version: opinion_generate_agent.cn + llm_model: + name: 'deep_seek_llm' + temperature: 0.6 +action: +plan: + planner: + name: 'rag_planner' +metadata: + type: 'AGENT' + module: 'sample_standard_app.app.core.agent.doe_agent_case.opinion_verify_agent' + class: 'OpinionVerifyAgent' \ No newline at end of file diff --git a/sample_standard_app/app/core/prompt/doe_prompt/data_processing_agent_cn.yaml b/sample_standard_app/app/core/prompt/doe_prompt/data_processing_agent_cn.yaml new file mode 100644 index 00000000..5bb14cd2 --- /dev/null +++ b/sample_standard_app/app/core/prompt/doe_prompt/data_processing_agent_cn.yaml @@ -0,0 +1,59 @@ +introduction: 你是一位数据分析专家。 +target: 你的目标是从提供的背景信息中提取回答用户问题可能用到的所有信息,并将这些信息格式化为一个JSON对象。请确保最终的JSON对象是有效的,并且符合用户的需求。 +instruction: | + 当前用户的需求是: {input} + ================================================================ + 当前的背景信息是: + {init_data} + ================================================================ + 数据提取要求如下: + 1. **识别关键数据点**: + - 从提供的背景信息中识别与用户需求相关的关键数据点,包括但不限于: + - 日期 + - 数值 + - 百分比 + - 其他相关文本信息 + + 2. **格式化数据**: + - 日期应使用 `yyyy-mm-dd` 格式。 + - 数值和百分比应使用数值类型(例如,`100` 而不是 `"100"` 或 `"100%"`)。 + + 3. **构建JSON对象**: + - 使用适当的键名来组织提取的信息。 + - 确保最终的 JSON 对象是有效的,并且符合用户需求。 + - 为每个数据点添加一个 `description` 字段,描述该数据的具体含义。 + + 4. **不允许回答背景信息中不存在的数据点** + + 5. **严格限制**: + - 不允许对背景信息进行任何总结或直接回答用户的问题。只需提取并格式化数据信息。 + + ### 输出示例 + ```json + {{ + "date_1": {{ + "value": "2023-10-01", + "description": "报告发布日期" + }}, + "number_1": {{ + "value": 100, + "description": "总销售额" + }}, + "percentage_1": {{ + "value": 10, + "description": "增长率" + }}, + "text_1": {{ + "value": "基金经理是xxxx", + "description": "基金经理信息" + }}, + "trend": {{ + "value": [10,20,30,40], + "description": "1-4月收益" + }} + }}``` + ================================================================= + +metadata: + type: 'PROMPT' + version: 'data_processing_agent.cn' diff --git a/sample_standard_app/app/core/prompt/doe_prompt/doe_expressing_agent_cn.yaml b/sample_standard_app/app/core/prompt/doe_prompt/doe_expressing_agent_cn.yaml new file mode 100644 index 00000000..f497bb03 --- /dev/null +++ b/sample_standard_app/app/core/prompt/doe_prompt/doe_expressing_agent_cn.yaml @@ -0,0 +1,27 @@ +introduction: 你是一位内容撰写专家。 +target: 你的任务是根据用户的请求、提供的数据资料及特定的业务场景来创作高质量的内容。 +instruction: | + ### 提供的数据信息 + {data_fining_result} + + ### 专家观点 + {matched_opinions} + + ### 生成要求 + 1. **理解用户需求** - 仔细阅读用户的需求描述,确定他们期望得到什么样的成果。 + 2. **收集与分析信息** - 浏览所提供的文档或链接,从中抽取与主题相关的重要细节。 + 3. **考虑上下文** - 结合所讨论领域的最新动态和发展方向来进行更深层次的思考。 + 4. **集成专家意见** - 如果提供了专家的意见,则要将这些观点合理地嵌入到你的写作之中。 + 5. **构建输出** - 综合前面几个步骤的结果,开始起草最终的作品。记得针对指定受众调整语气和复杂度。 + 6. **校验与优化** - 完成初稿后,进行全面审查以保证内容质量达到最佳状态。 + + ### 写作风格 + - **清晰性**:确保报告语言清晰易懂,避免使用过于复杂的专业术语。 + - **准确性**:所有陈述都必须基于提供的数据和专家观点,不得包含未经验证的信息。 + - **结构化**:按照上述报告要求的结构组织内容,确保每个部分都有明确的标题和子标题。 + - **客观性**:在分析过程中保持客观,不要引入个人偏见。 + + ### 当前用户的生成需求是: {input} +metadata: + type: 'PROMPT' + version: 'doe_expressing_agent_case.cn' diff --git a/sample_standard_app/app/core/prompt/doe_prompt/fund_data_fining_agent_cn.yaml b/sample_standard_app/app/core/prompt/doe_prompt/fund_data_fining_agent_cn.yaml new file mode 100644 index 00000000..d59f5718 --- /dev/null +++ b/sample_standard_app/app/core/prompt/doe_prompt/fund_data_fining_agent_cn.yaml @@ -0,0 +1,98 @@ +introduction: 你是一位数据分析专家。 +target: 你的目标是从提供的背景信息中提取回答用户问题可能用到的所有信息,并将这些信息格式化为一个JSON对象。请确保最终的JSON对象是有效的,并且符合用户的需求。 +instruction: | + 当前的html页面信息是: + ================================================================ + {init_data} + ================================================================ + + 需要填充下面的JSON中的信息: + ```json {{ + "name":"基金名称", + "date": "数据日期", + "EPTWU": "万份收益", + "seven_day_annualized":"七日年化收益率", + "since_founding":"成立以来收益率", + "manager_year": int,基金经理的工作年限, + "last_six_month": float64 近六个月的收益, + "base_income_info":{{ + "last_week": "近一周收益率", + "last_month": "近一月收益率", + "last_three_moth":"近三个月收益率", + "last_six_moth": "近了六个月收益率", + "this_year":"今年以来收益率", + "last_year": "近一年收益率" + }}, + "peer_income_info":{{ + "last_week": "同类近一周收益率", + "last_month": "同类平均近一月收益率", + "last_three_moth":"同类平均近三个月收益率", + "last_six_moth": "同类平均近了六个月收益率", + "this_year":"同类平均今年以来收益率", + "last_year": "同类平均近一年的收益率" + }}, + "CSI_300":{{ + "last_week": "沪深300近一周收益率", + "last_month": "沪深300平均近一月收益率", + "last_three_moth":"沪深300平均近三个月收益率", + "last_six_moth": "沪深300平均近了六个月收益率", + "this_year":"沪深300平均今年以来收益率", + "last_year": "沪深300平均近一年的收益率" + }}, + "ranker":{{ + "last_week": "同类近一周排名", + "last_month": "同类平均近两周排名", + "last_three_moth":"同类平均近三周排名", + "last_six_moth": "同类平均近了六个月排名", + "this_year":"同类平均今年以来排名", + "last_year": "同类平均近一年排名" + }}, + "manager_info": {{ + "name": "基金经理姓名", + "date": "基金经理的入职时间", + "description": "基金经理简介" + }}, + "risk_rating":"风险等级,值应该是:low,middle,high之一", + "investment_scope":"基金的投资范围", + "risk_return_profile":"风险收益特征", + "funding_time": "成立时间,格式:2022-03-04", + "funding_rating":{{ + "manage_rating":"管理费率", + "custodial_fee": "托管费率", + "annual_sales_service_fee":"销售服务费率", + "subscription_fee":"申购费率", + "redemption_fee":"赎回费率" + }}, + "asset_allocation": {{ + "stocks":"股票资产比例", + "fund_investment":"基金投资比例", + "fixed_income_investment": "固定收益投资投资比例", + "precious_metals_investment": "贵金属投资比例", + "financial_derivatives_investment": "金融衍生品投资比例", + "repurchase_agreements": "买入返售金融资产比例", + "bank_deposits": "银行存款比例", + "settlement_reserve":"结算备付金比例", + "others": "其他比例" + }}, + "net_asset_value":[ + {{ + "date": "收益日期", + "EPTWU": "万份收益", + "seven_day_annualized": "七日年化收益率", + }}, + {{ + "date": "收益日期", + "EPTWU": "万份收益", + "seven_day_annualized": "七日年化收益率", + }} + ] + + }}``` + 填充时必须遵守以下规则: + 1. 输出的json必须包含以上所有字段,且字段名不能修改。 + 2. 收益率,费率都必须使用小数表示 + 3. 所有的日期格式必须是:yyyy-mm-dd + 4. net_asset_value代表近10天的基金净值 +metadata: + type: 'PROMPT' + version: 'fund_data_fining_agent.cn' diff --git a/sample_standard_app/app/core/prompt/doe_prompt/opinion_generate_cn.yaml b/sample_standard_app/app/core/prompt/doe_prompt/opinion_generate_cn.yaml new file mode 100644 index 00000000..b50ce3d0 --- /dev/null +++ b/sample_standard_app/app/core/prompt/doe_prompt/opinion_generate_cn.yaml @@ -0,0 +1,30 @@ +introduction: 你是一位专业的分析师。 +target: 你的目标是据给定的[业务场景]和[具体需求],提出6-10个正负向分析视角。 +instruction: | + 【输入信息】 + - 业务场景: {business_scene} + - 具体需求: {input} + + 【输出要求】 + 1. 明确性:每个观点必须清楚地表达一个独立的想法或论据。 + 2. 客观性:基于事实和数据进行分析,尽量减少主观臆断。 + 3. 全面性:考虑多方面因素,包括但不限于市场趋势、竞争对手情况、内部资源能力等。 + 4. 实用性:提出的建议或结论应具有实际操作性,能够为企业决策提供参考。 + 5. 结构化:每个观点都应条理清晰,便于理解和对比。 + 6. 每个正面观点和对应的负向观点建议控制在50-100字之间,使用正式、专业的语言风格,避免口语化表达。确保所有观点之间没有自相矛盾的地方,整体上保持一致性和连贯性。 + 7. 生成的观点中不要携带时间,数据等信息。 + 8. 返回的结果需要是JSON格式,包含如下结构: + {{ + "points": [ + {{ + "point": "[独立的观点]", + "type": "positive" 或 "negative" + }}, + ... + ] + }} + + 请严格按照上述格式输出。 +metadata: + type: 'PROMPT' + version: 'opinion_generate.cn' diff --git a/sample_standard_app/app/core/prompt/doe_prompt/opinion_verify_cn.yaml b/sample_standard_app/app/core/prompt/doe_prompt/opinion_verify_cn.yaml new file mode 100644 index 00000000..d5e91e53 --- /dev/null +++ b/sample_standard_app/app/core/prompt/doe_prompt/opinion_verify_cn.yaml @@ -0,0 +1,32 @@ +introduction: 你是一位观点分析专家。 +target: 你的目标根据数据,以及用户的需求,从所有观点中,匹配出一个最符合数据的观点。 +instruction: | + ================================================================ + ### 已知数据信息 + {data_fining_result} + ================================================================ + ### 可供选择的观点列表 + {opinions} + ================================================================ + 填充时必须遵守以下规则: + 1. **论据方向选择**:根据数据信息选择出最适合当前数据特性的方向。如果存在多条可能的方向,请选择与用户需求最匹配的一条或者几条。 + 2. **表达方式**:请确保最终选择的观点不仅与所提供的数据紧密相关,而且其表述风格也应符合所选产品或服务领域的通用语言习惯。 + 3. **决策依据**:明确指出你是如何基于数据做出最终决定的,包括但不限于关键数据点、趋势分析等。 + 4. **透明度**:在整个过程中保持高度透明,解释每一步的选择理由及其背后的逻辑。 + 5. **匹配度**: 观点与数据必须完全匹配,无法完全匹配的观点,直接忽略。 + 5. **输出规则**:请确保最终输出是一个有效的JSON对象,结构如下: + {{ + "matched_opinions": [ + {{ + "opinion_id": 观点ID, + "opinion": "观点内容", + "thought": "匹配理由", + "type": "Positive or Negative" + }}, + ... + ] + }} + +metadata: + type: 'PROMPT' + version: 'opinion_generate_agent.cn' \ No newline at end of file diff --git a/sample_standard_app/app/core/tool/doe_tool/__init__.py b/sample_standard_app/app/core/tool/doe_tool/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sample_standard_app/app/core/tool/doe_tool/json_output_parser_tool.py b/sample_standard_app/app/core/tool/doe_tool/json_output_parser_tool.py new file mode 100644 index 00000000..064459b3 --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/json_output_parser_tool.py @@ -0,0 +1,12 @@ +from langchain_core.utils.json import parse_json_markdown + +from agentuniverse.agent.action.tool.tool import Tool, ToolInput + + +class JsonOutputParser(Tool): + def execute(self, tool_input: ToolInput): + json_str = tool_input.get_data("output") + res = parse_json_markdown(json_str) + return { + "output": res + } diff --git a/sample_standard_app/app/core/tool/doe_tool/json_output_parser_tool.yaml b/sample_standard_app/app/core/tool/doe_tool/json_output_parser_tool.yaml new file mode 100644 index 00000000..0511bcbe --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/json_output_parser_tool.yaml @@ -0,0 +1,8 @@ +name: 'json_output_parser_tool' +description: '' +tool_type: 'api' +input_keys: ['output'] +metadata: + type: 'TOOL' + module: 'sample_standard_app.app.core.tool.doe_tool.json_output_parser_tool' + class: 'JsonOutputParser' \ No newline at end of file diff --git a/sample_standard_app/app/core/tool/doe_tool/load_fund_tool.py b/sample_standard_app/app/core/tool/doe_tool/load_fund_tool.py new file mode 100644 index 00000000..c854d652 --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/load_fund_tool.py @@ -0,0 +1,32 @@ +from typing import Optional + +import requests +from bs4 import BeautifulSoup + +from agentuniverse.agent.action.tool.tool import Tool, ToolInput + + +class LoadFundInfoTool(Tool): + fund_info_url: Optional[str] = "https://fund.pingan.com/main/peanutFinance/yingPeanut/fundDetailV2/" + + fund_rate_info_url: Optional[str] = "https://fund.eastmoney.com/" + + def execute(self, tool_input: ToolInput): + fund_id = tool_input.get_data("fund_id") + fund_info_url = f"{self.fund_info_url}{fund_id}.shtml" + # 爬取页面中基金的信息 + response = requests.get(fund_info_url) + response.encoding = "utf-8" + html_content = response.text + + rate_info_url = f"{self.fund_rate_info_url}{fund_id}.html" + + response = requests.get(rate_info_url) + response.encoding = "utf-8" + rate_html_content = response.text + soup = BeautifulSoup(rate_html_content, "html.parser") + elem = soup.find("li", id="increaseAmount_stage").find("table", class_="ui-table-hover") + html_content = html_content + "\n========================================\n" + str(elem.contents) + return { + "init_data": html_content + } \ No newline at end of file diff --git a/sample_standard_app/app/core/tool/doe_tool/load_fund_tool.yaml b/sample_standard_app/app/core/tool/doe_tool/load_fund_tool.yaml new file mode 100644 index 00000000..2234c221 --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/load_fund_tool.yaml @@ -0,0 +1,8 @@ +name: 'load_fund_tool' +description: '' +tool_type: 'api' +input_keys: ['fund_id'] +metadata: + type: 'TOOL' + module: 'sample_standard_app.app.core.tool.doe_tool.load_fund_tool' + class: 'LoadFundInfoTool' \ No newline at end of file diff --git a/sample_standard_app/app/core/tool/doe_tool/load_opinion_tool.yaml b/sample_standard_app/app/core/tool/doe_tool/load_opinion_tool.yaml new file mode 100644 index 00000000..32a7a6b1 --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/load_opinion_tool.yaml @@ -0,0 +1,8 @@ +name: 'load_opinion_tool' +description: 'load opinion' +tool_type: 'api' +input_keys: ['opinions_path'] +metadata: + type: 'TOOL' + module: 'sample_standard_app.app.core.tool.doe_tool.opinion_tool' + class: 'LoadOpinionTool' \ No newline at end of file diff --git a/sample_standard_app/app/core/tool/doe_tool/opinion_tool.py b/sample_standard_app/app/core/tool/doe_tool/opinion_tool.py new file mode 100644 index 00000000..9f0e9966 --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/opinion_tool.py @@ -0,0 +1,44 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/14 14:59 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: opinions_verify_tool.py + +from agentuniverse.agent.action.tool.tool import Tool, ToolInput +import pandas as pd + + +class LoadOpinionTool(Tool): + def execute(self, tool_input: ToolInput): + opinions_path = tool_input.get_data("opinions_path") + + # 从csv文件中读取信息 + df = pd.read_csv(opinions_path,header=None) + values = df.values.tolist() + keys = values[0] + opinions = [] + for index,row in enumerate(values[1:]): + + temp = { + keys[i]:row[i] for i in range(len(row)) + } + temp['opinion_id'] = index + opinions.append(temp) + + return {"opinions": opinions} + + +class OpinionMatchingTool(Tool): + def execute(self, tool_input: ToolInput): + matched_opinions =[] + opinions = tool_input.get_data("opinions") + data = tool_input.get_data("data_fining_result") + for opinion in opinions: + matching_conditions = opinion["rule"] + if eval(matching_conditions,data): + matched_opinions.append(opinion) + return { + "matched_opinions": matched_opinions + } \ No newline at end of file diff --git a/sample_standard_app/app/core/tool/doe_tool/opinion_verify_tool.yaml b/sample_standard_app/app/core/tool/doe_tool/opinion_verify_tool.yaml new file mode 100644 index 00000000..01abf5d6 --- /dev/null +++ b/sample_standard_app/app/core/tool/doe_tool/opinion_verify_tool.yaml @@ -0,0 +1,8 @@ +name: 'opinion_verify_tool' +description: 'opinion verify' +tool_type: 'api' +input_keys: ['opinions','data_fining_result'] +metadata: + type: 'TOOL' + module: 'sample_standard_app.app.core.tool.doe_tool.opinion_tool' + class: 'OpinionMatchingTool' \ No newline at end of file diff --git a/sample_standard_app/app/test/doe_data/opinions.csv b/sample_standard_app/app/test/doe_data/opinions.csv new file mode 100644 index 00000000..ed65ad46 --- /dev/null +++ b/sample_standard_app/app/test/doe_data/opinions.csv @@ -0,0 +1,5 @@ +thought,type,opinion,rule +持续超额营收能力,positive,"持续超额能力强,风控能力较强",last_six_month>0 +持续超额营收能力,negative,"持续超额不稳定,风控能力较弱",last_six_month<=0 +投资风格,positive,投资风格稳定,manager_year>3 +投资风格,negative,"投资风格不稳定,基金经理投资经验过短,基金经理任职经验过短",manager_year<=3 diff --git a/sample_standard_app/app/test/test_doe_agent.py b/sample_standard_app/app/test/test_doe_agent.py new file mode 100644 index 00000000..1cc5ce25 --- /dev/null +++ b/sample_standard_app/app/test/test_doe_agent.py @@ -0,0 +1,86 @@ +# !/usr/bin/env python3 +# -*- coding:utf-8 -*- + +# @Time : 2024/10/18 15:25 +# @Author : weizjajj +# @Email : weizhongjie.wzj@antgroup.com +# @FileName: test_doe_agent.py + +import unittest + +from agentuniverse.agent.agent_manager import AgentManager +from agentuniverse.base.agentuniverse import AgentUniverse + + +class DOEAgentTestCase(unittest.TestCase): + def setUp(self) -> None: + AgentUniverse().start(config_path='../../config/config.toml') + + # def test_data_fining_agent(self): + # agent_instance = AgentManager().get_instance_obj('data_fining_agent') + # res = agent_instance.run(fund_id="000759",input="请帮我总结基金表现") + # print(json.dumps(res.to_dict(),ensure_ascii=False)) + + # def test_framework_matching_agent(self): + # # agent_instance = AgentManager().get_instance_obj('data_fining_agent') + # # res = agent_instance.run(fund_id="000759") + # + # + # fund_info_str = """ + # {"name": "平安财富宝货币 A", "date": "2024-10-13", "EPTWU": "0.4884", "seven_day_annualized": "1.789%", "since_founding": "35.88%", "base_income_info": {"last_week": "0.05%", "last_month": "0.15%", "last_three_moth": "0.46%", "last_six_moth": "0.96%", "this_year": "1.61%", "last_year": "2.13%"}, "peer_income_info": {"last_week": "0.04%", "last_month": "0.10%", "last_three_moth": "0.23%", "last_six_moth": "0.57%", "this_year": "1.24%", "last_year": "1.73%"}, "CSI_300": {"last_week": "-3.25%", "last_month": "22.00%", "last_three_moth": "12.08%", "last_six_moth": "10.93%", "this_year": "13.29%", "last_year": "5.99%"}, "ranker": {"last_week": "82 | 895", "last_month": "52 | 894", "last_three_moth": "24 | 886", "last_six_moth": "27 | 878", "this_year": "25 | 855", "last_year": "26 | 834"}, "manager_info": {"name": "罗薇", "date": "2020-11-01", "description": "罗薇女士,新南威尔士大学金融会计学专业硕士,曾任红塔红土基金管理有限公司固定收益交易员、基金经理助理、基金经理。2020年11月加入平安基金管理有限公司,现任平安交易型货币市场基金(2022-05-24至今)、平安日增利货币市场基金(2022-06-13至今)、平安合丰定期开放纯债债券型发起式证券投资基金(2022-06-17至今)、平安惠鸿纯债债券型证券投资基金(2022-07-01至今)、平安合慧定期开放纯债债券型发起式证券投资基金(2022-07-01至今)、平安惠隆纯债债券型证券投资基金(2022-07-01至今)、平安惠兴纯债债券型证券投资基金(2022-07-01至今)、平安财富宝货币市场基金(2022-07-01至今)、平安惠信3个月定期开放债券型证券投资基金(2022-11-07至今)基金经理。"}, "risk_rating": "low", "investment_scope": "本基金投资于法律法规及监管机构允许投资的金融工具,包括现金,通知存款,短期融资券,一年以内(含一年)的银行定期存款、大额存单,期限在一年以内(含一年)的债券回购,期限在一年以内(含一年)的中央银行票据,剩余期限在397天以内(含397天)的债券、资产支持证券、中期票据,中国证监会及/或中国人民银行认可的其他具有良好流动性的金融工具。", "risk_return_profile": "本基金为货币市场基金,是证券投资基金中的低风险品种。本基金的风险和预期收益低于股票型基金、混合型基金、债券型基金。", "funding_time": "2014-08-21", "funding_rating": {"manage_rating": "0.0015", "custodial_fee": "0.0005", "annual_sales_service_fee": "0.0001", "subscription_fee": "0", "redemption_fee": "0"}, "asset_allocation": {"stocks": "0.00%", "fund_investment": "0.00%", "fixed_income_investment": "40.18%", "precious_metals_investment": "0.00%", "financial_derivatives_investment": "0.00%", "repurchase_agreements": "16.13%", "bank_deposits": "43.46%", "settlement_reserve": "0.00%", "others": "0.24%"}, "net_asset_value": [{"date": "2024-10-13", "EPTWU": "0.4884", "seven_day_annualized": "1.789%"}]} + # """ + # + # fund_info = json.loads(fund_info_str) + # + # # print(json.dumps(fund_info,ensure_ascii=False)) + # + # + # tool:Tool = ToolManager().get_instance_obj('load_framework_tool') + # + # frameworks = tool.run(framework_path = "./doe_data/framework.csv") + # print(frameworks) + # + # agent_instance:Agent = AgentManager().get_instance_obj('framework_matching_agent') + # + # res = agent_instance.run(fund_info=fund_info, frameworks=frameworks) + # print(res.to_dict().get('output')) + + # def test_json_output_parser_tool(self): + # data = """ + # ```json + # { + # "thought": "平安财富宝货币 A 是一款货币市场基金,其主要投资于低风险的金融工具,如银行存款、短期债券等。其风险评级为低,表明其风险和预期收益都较低。基金的收益率和同类基金相比表现较好,且基金经理具有丰富的固定收益投资经验,投资风格稳定。", + # "product_track": "均衡风格", + # "interpret_latitude": "持续超额收益能力", + # "argument_direction": "正", + # "argument_direction_list": ["持续超额能力强", "风控能力较强"], + # "expression_techniques": "持续超额收益能力强" + # } + # ``` + # """ + # + # tool = ToolManager().get_instance_obj('json_output_parser_tool') + # res = tool.run(output=data) + # print(res) + + # def test_opinion_inject_agent(self): + # fund_info_str = """ + # {"name": "平安财富宝货币 A", "last_six_month": 0.02, "manager_year":3, "date": "2024-10-13", "EPTWU": "0.4884", "seven_day_annualized": "1.789%", "since_founding": "35.88%", "base_income_info": {"last_week": "0.05%", "last_month": "0.15%", "last_three_moth": "0.46%", "last_six_moth": "0.96%", "this_year": "1.61%", "last_year": "2.13%"}, "peer_income_info": {"last_week": "0.04%", "last_month": "0.10%", "last_three_moth": "0.23%", "last_six_moth": "0.57%", "this_year": "1.24%", "last_year": "1.73%"}, "CSI_300": {"last_week": "-3.25%", "last_month": "22.00%", "last_three_moth": "12.08%", "last_six_moth": "10.93%", "this_year": "13.29%", "last_year": "5.99%"}, "ranker": {"last_week": "82 | 895", "last_month": "52 | 894", "last_three_moth": "24 | 886", "last_six_moth": "27 | 878", "this_year": "25 | 855", "last_year": "26 | 834"}, "manager_info": {"name": "罗薇", "date": "2020-11-01", "description": "罗薇女士,新南威尔士大学金融会计学专业硕士,曾任红塔红土基金管理有限公司固定收益交易员、基金经理助理、基金经理。2020年11月加入平安基金管理有限公司,现任平安交易型货币市场基金(2022-05-24至今)、平安日增利货币市场基金(2022-06-13至今)、平安合丰定期开放纯债债券型发起式证券投资基金(2022-06-17至今)、平安惠鸿纯债债券型证券投资基金(2022-07-01至今)、平安合慧定期开放纯债债券型发起式证券投资基金(2022-07-01至今)、平安惠隆纯债债券型证券投资基金(2022-07-01至今)、平安惠兴纯债债券型证券投资基金(2022-07-01至今)、平安财富宝货币市场基金(2022-07-01至今)、平安惠信3个月定期开放债券型证券投资基金(2022-11-07至今)基金经理。"}, "risk_rating": "low", "investment_scope": "本基金投资于法律法规及监管机构允许投资的金融工具,包括现金,通知存款,短期融资券,一年以内(含一年)的银行定期存款、大额存单,期限在一年以内(含一年)的债券回购,期限在一年以内(含一年)的中央银行票据,剩余期限在397天以内(含397天)的债券、资产支持证券、中期票据,中国证监会及/或中国人民银行认可的其他具有良好流动性的金融工具。", "risk_return_profile": "本基金为货币市场基金,是证券投资基金中的低风险品种。本基金的风险和预期收益低于股票型基金、混合型基金、债券型基金。", "funding_time": "2014-08-21", "funding_rating": {"manage_rating": "0.0015", "custodial_fee": "0.0005", "annual_sales_service_fee": "0.0001", "subscription_fee": "0", "redemption_fee": "0"}, "asset_allocation": {"stocks": "0.00%", "fund_investment": "0.00%", "fixed_income_investment": "40.18%", "precious_metals_investment": "0.00%", "financial_derivatives_investment": "0.00%", "repurchase_agreements": "16.13%", "bank_deposits": "43.46%", "settlement_reserve": "0.00%", "others": "0.24%"}, "net_asset_value": [{"date": "2024-10-13", "EPTWU": "0.4884", "seven_day_annualized": "1.789%"}]} + # """ + # fund_info = json.loads(fund_info_str) + # framework_path = "./doe_data/opinions.csv" + # agent_instance: Agent = AgentManager().get_instance_obj('opinion_inject_agent') + # res = agent_instance.run(input="请帮我生成一个基金解读报告", data_fining_result=fund_info, + # opinions_path=framework_path) + # print(res.to_dict()) + + def test_doe_agent(self): + fund_id = "009008" + framework_path = "./doe_data/opinions.csv" + agent = AgentManager().get_instance_obj('doe_agent_case') + res = agent.run(fund_id=fund_id, opinions_path=framework_path,input="请给出基金近期表现的研究报告",business_scene="基金分析") + print(res.to_dict().get('output')) + + +if __name__ == '__main__': + unittest.main()