From 91c5c7208936bacfbeac5938b0a01e1f7ee47c12 Mon Sep 17 00:00:00 2001 From: Arnaud Gelas Date: Mon, 22 Jan 2024 20:10:11 +0100 Subject: [PATCH 01/35] Fix prompt logic when defining to who the message should be sent. With the previous logic, it was possible to reach an undefined state where it was not meant to be sent to Engineer, QaEngineer, nor NoOne. --- metagpt/actions/run_code.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metagpt/actions/run_code.py b/metagpt/actions/run_code.py index 30b06f1a6..885f4e12c 100644 --- a/metagpt/actions/run_code.py +++ b/metagpt/actions/run_code.py @@ -42,8 +42,8 @@ Determine the ONE file to rewrite in order to fix the error, for example, xyz.py Determine if all of the code works fine, if so write PASS, else FAIL, WRITE ONLY ONE WORD, PASS OR FAIL, IN THIS SECTION ## Send To: -Please write Engineer if the errors are due to problematic development codes, and QaEngineer to problematic test codes, and NoOne if there are no errors, -WRITE ONLY ONE WORD, Engineer OR QaEngineer OR NoOne, IN THIS SECTION. +Please write NoOne if there are no errors, Engineer if the errors are due to problematic development codes, else QaEngineer, +WRITE ONLY ONE WORD, NoOne OR Engineer OR QaEngineer, IN THIS SECTION. --- You should fill in necessary instruction, status, send to, and finally return all content between the --- segment line. """ From ed54f6b86a7000de1487472a8900138933ac6c42 Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Fri, 26 Jan 2024 22:59:10 +0800 Subject: [PATCH 02/35] To avoid JSONDecodeError: Remove comments in output json str, after json value content, maybe start with #, maybe start with //, particularly, it is not inside the string value Addtionly, if you do not want JSONDecodeError to occur, you can add 'Delete comments in json' after FORMAT_CONSTRAINT in action_node.py --- metagpt/actions/action_node.py | 2 ++ metagpt/utils/repair_llm_raw_output.py | 31 ++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/metagpt/actions/action_node.py b/metagpt/actions/action_node.py index 6c65b33ef..0f441cfee 100644 --- a/metagpt/actions/action_node.py +++ b/metagpt/actions/action_node.py @@ -24,6 +24,8 @@ TAG = "CONTENT" LANGUAGE_CONSTRAINT = "Language: Please use the same language as Human INPUT." FORMAT_CONSTRAINT = f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else." +# Delete comments in json +# If you don't want JSONDecodeError to occur, you can add Delete comments in json after FORMAT_CONSTRAINT SIMPLE_TEMPLATE = """ diff --git a/metagpt/utils/repair_llm_raw_output.py b/metagpt/utils/repair_llm_raw_output.py index b71def136..4995918c2 100644 --- a/metagpt/utils/repair_llm_raw_output.py +++ b/metagpt/utils/repair_llm_raw_output.py @@ -120,13 +120,21 @@ def repair_json_format(output: str) -> str: elif output.startswith("{") and output.endswith("]"): output = output[:-1] + "}" - # remove `#` in output json str, usually appeared in `glm-4` + # remove comments in output json str, after json value content, maybe start with #, maybe start with // arr = output.split("\n") new_arr = [] for line in arr: - idx = line.find("#") - if idx >= 0: - line = line[:idx] + # look for # or // comments and make sure they are not inside the string value + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + # if comments, then delete them + if comment_index != -1: + line = line[:comment_index].rstrip() new_arr.append(line) output = "\n".join(new_arr) return output @@ -198,6 +206,21 @@ def repair_invalid_json(output: str, error: str) -> str: new_line = line.replace("}", "") elif line.endswith("},") and output.endswith("},"): new_line = line[:-1] + # remove comments in output json str, after json value content, maybe start with #, maybe start with // + elif rline[col_no] == "#" or rline[col_no] == "/": + new_line = rline[:col_no] + for i in range(line_no + 1, len(arr)): + # look for # or // comments and make sure they are not inside the string value + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + # if comments, then delete them + if comment_index != -1: + arr[i] = arr[i][:comment_index].rstrip() elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: # problem, `"""` or `'''` without `,` new_line = f",{line}" From 43b069f453d0ea351ba31b918b4fcb8bae5863e0 Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Fri, 26 Jan 2024 23:20:16 +0800 Subject: [PATCH 03/35] Addtionly, if you do not want JSONDecodeError to occur, you can add 'Delete comments in json' after FORMAT_CONSTRAINT in action_node.py --- metagpt/actions/action_node.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metagpt/actions/action_node.py b/metagpt/actions/action_node.py index 0f441cfee..ed0e27869 100644 --- a/metagpt/actions/action_node.py +++ b/metagpt/actions/action_node.py @@ -23,7 +23,8 @@ from metagpt.utils.common import OutputParser, general_after_log TAG = "CONTENT" LANGUAGE_CONSTRAINT = "Language: Please use the same language as Human INPUT." -FORMAT_CONSTRAINT = f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else." +FORMAT_CONSTRAINT = (f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else. " + f"Delete comments in json") # Delete comments in json # If you don't want JSONDecodeError to occur, you can add Delete comments in json after FORMAT_CONSTRAINT From f16b24758692bd10d89069c13a1260f9d15c968c Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Sat, 27 Jan 2024 15:32:12 +0800 Subject: [PATCH 04/35] merge code with similar logic to avoid duplication --- ...move comments in output json str, after js | 12 + PR/action_node.py | 351 ++++++++++++++++++ PR/repair_llm_raw_output.py | 351 ++++++++++++++++++ metagpt/utils/repair_llm_raw_output.py | 43 ++- 4 files changed, 735 insertions(+), 22 deletions(-) create mode 100644 PR/# remove comments in output json str, after js create mode 100644 PR/action_node.py create mode 100644 PR/repair_llm_raw_output.py diff --git a/PR/# remove comments in output json str, after js b/PR/# remove comments in output json str, after js new file mode 100644 index 000000000..f795fefdb --- /dev/null +++ b/PR/# remove comments in output json str, after js @@ -0,0 +1,12 @@ + +git commit -m "To avoid JSONDecodeError: " -m "Remove comments in output json str, after json value content, maybe start with #, maybe start with //, particularly, it is not inside the string value" -m "Addtionly, if you do not want JSONDecodeError to occur, you can add 'Delete comments in json' after FORMAT_CONSTRAINT in action_node.py" + + + +git commit -m "Addtionly, if you do not want JSONDecodeError to occur, you can add 'Delete comments in json' after FORMAT_CONSTRAINT in action_node.py" + + + + + + diff --git a/PR/action_node.py b/PR/action_node.py new file mode 100644 index 000000000..0f441cfee --- /dev/null +++ b/PR/action_node.py @@ -0,0 +1,351 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2023/12/11 18:45 +@Author : alexanderwu +@File : action_node.py + +NOTE: You should use typing.List instead of list to do type annotation. Because in the markdown extraction process, + we can use typing to extract the type of the node, but we cannot use built-in list to extract. +""" +import json +from typing import Any, Dict, List, Optional, Tuple, Type + +from pydantic import BaseModel, create_model, model_validator +from tenacity import retry, stop_after_attempt, wait_random_exponential + +from metagpt.config import CONFIG +from metagpt.llm import BaseLLM +from metagpt.logs import logger +from metagpt.provider.postprocess.llm_output_postprocess import llm_output_postprocess +from metagpt.utils.common import OutputParser, general_after_log + +TAG = "CONTENT" + +LANGUAGE_CONSTRAINT = "Language: Please use the same language as Human INPUT." +FORMAT_CONSTRAINT = f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else." +# Delete comments in json +# If you don't want JSONDecodeError to occur, you can add Delete comments in json after FORMAT_CONSTRAINT + + +SIMPLE_TEMPLATE = """ +## context +{context} + +----- + +## format example +{example} + +## nodes: ": # " +{instruction} + +## constraint +{constraint} + +## action +Follow instructions of nodes, generate output and make sure it follows the format example. +""" + + +def dict_to_markdown(d, prefix="- ", kv_sep="\n", postfix="\n"): + markdown_str = "" + for key, value in d.items(): + markdown_str += f"{prefix}{key}{kv_sep}{value}{postfix}" + return markdown_str + + +class ActionNode: + """ActionNode is a tree of nodes.""" + + schema: str # raw/json/markdown, default: "" + + # Action Context + context: str # all the context, including all necessary info + llm: BaseLLM # LLM with aask interface + children: dict[str, "ActionNode"] + + # Action Input + key: str # Product Requirement / File list / Code + expected_type: Type # such as str / int / float etc. + # context: str # everything in the history. + instruction: str # the instructions should be followed. + example: Any # example for In Context-Learning. + + # Action Output + content: str + instruct_content: BaseModel + + def __init__( + self, + key: str, + expected_type: Type, + instruction: str, + example: Any, + content: str = "", + children: dict[str, "ActionNode"] = None, + schema: str = "", + ): + self.key = key + self.expected_type = expected_type + self.instruction = instruction + self.example = example + self.content = content + self.children = children if children is not None else {} + self.schema = schema + + def __str__(self): + return ( + f"{self.key}, {repr(self.expected_type)}, {self.instruction}, {self.example}" + f", {self.content}, {self.children}" + ) + + def __repr__(self): + return self.__str__() + + def add_child(self, node: "ActionNode"): + """增加子ActionNode""" + self.children[node.key] = node + + def add_children(self, nodes: List["ActionNode"]): + """批量增加子ActionNode""" + for node in nodes: + self.add_child(node) + + @classmethod + def from_children(cls, key, nodes: List["ActionNode"]): + """直接从一系列的子nodes初始化""" + obj = cls(key, str, "", "") + obj.add_children(nodes) + return obj + + def get_children_mapping(self, exclude=None) -> Dict[str, Tuple[Type, Any]]: + """获得子ActionNode的字典,以key索引""" + exclude = exclude or [] + return {k: (v.expected_type, ...) for k, v in self.children.items() if k not in exclude} + + def get_self_mapping(self) -> Dict[str, Tuple[Type, Any]]: + """get self key: type mapping""" + return {self.key: (self.expected_type, ...)} + + def get_mapping(self, mode="children", exclude=None) -> Dict[str, Tuple[Type, Any]]: + """get key: type mapping under mode""" + if mode == "children" or (mode == "auto" and self.children): + return self.get_children_mapping(exclude=exclude) + return {} if exclude and self.key in exclude else self.get_self_mapping() + + @classmethod + def create_model_class(cls, class_name: str, mapping: Dict[str, Tuple[Type, Any]]): + """基于pydantic v1的模型动态生成,用来检验结果类型正确性""" + + def check_fields(cls, values): + required_fields = set(mapping.keys()) + missing_fields = required_fields - set(values.keys()) + if missing_fields: + raise ValueError(f"Missing fields: {missing_fields}") + + unrecognized_fields = set(values.keys()) - required_fields + if unrecognized_fields: + logger.warning(f"Unrecognized fields: {unrecognized_fields}") + return values + + validators = {"check_missing_fields_validator": model_validator(mode="before")(check_fields)} + + new_class = create_model(class_name, __validators__=validators, **mapping) + return new_class + + def create_children_class(self, exclude=None): + """使用object内有的字段直接生成model_class""" + class_name = f"{self.key}_AN" + mapping = self.get_children_mapping(exclude=exclude) + return self.create_model_class(class_name, mapping) + + def to_dict(self, format_func=None, mode="auto", exclude=None) -> Dict: + """将当前节点与子节点都按照node: format的格式组织成字典""" + + # 如果没有提供格式化函数,使用默认的格式化方式 + if format_func is None: + format_func = lambda node: f"{node.instruction}" + + # 使用提供的格式化函数来格式化当前节点的值 + formatted_value = format_func(self) + + # 创建当前节点的键值对 + if mode == "children" or (mode == "auto" and self.children): + node_dict = {} + else: + node_dict = {self.key: formatted_value} + + if mode == "root": + return node_dict + + # 遍历子节点并递归调用 to_dict 方法 + exclude = exclude or [] + for _, child_node in self.children.items(): + if child_node.key in exclude: + continue + node_dict.update(child_node.to_dict(format_func)) + + return node_dict + + def compile_to(self, i: Dict, schema, kv_sep) -> str: + if schema == "json": + return json.dumps(i, indent=4) + elif schema == "markdown": + return dict_to_markdown(i, kv_sep=kv_sep) + else: + return str(i) + + def tagging(self, text, schema, tag="") -> str: + if not tag: + return text + if schema == "json": + return f"[{tag}]\n" + text + f"\n[/{tag}]" + else: # markdown + return f"[{tag}]\n" + text + f"\n[/{tag}]" + + def _compile_f(self, schema, mode, tag, format_func, kv_sep, exclude=None) -> str: + nodes = self.to_dict(format_func=format_func, mode=mode, exclude=exclude) + text = self.compile_to(nodes, schema, kv_sep) + return self.tagging(text, schema, tag) + + def compile_instruction(self, schema="markdown", mode="children", tag="", exclude=None) -> str: + """compile to raw/json/markdown template with all/root/children nodes""" + format_func = lambda i: f"{i.expected_type} # {i.instruction}" + return self._compile_f(schema, mode, tag, format_func, kv_sep=": ", exclude=exclude) + + def compile_example(self, schema="json", mode="children", tag="", exclude=None) -> str: + """compile to raw/json/markdown examples with all/root/children nodes""" + + # 这里不能使用f-string,因为转译为str后再json.dumps会额外加上引号,无法作为有效的example + # 错误示例:"File list": "['main.py', 'const.py', 'game.py']", 注意这里值不是list,而是str + format_func = lambda i: i.example + return self._compile_f(schema, mode, tag, format_func, kv_sep="\n", exclude=exclude) + + def compile(self, context, schema="json", mode="children", template=SIMPLE_TEMPLATE, exclude=[]) -> str: + """ + mode: all/root/children + mode="children": 编译所有子节点为一个统一模板,包括instruction与example + mode="all": NotImplemented + mode="root": NotImplemented + schmea: raw/json/markdown + schema="raw": 不编译,context, lang_constaint, instruction + schema="json":编译context, example(json), instruction(markdown), constraint, action + schema="markdown": 编译context, example(markdown), instruction(markdown), constraint, action + """ + if schema == "raw": + return context + "\n\n## Actions\n" + LANGUAGE_CONSTRAINT + "\n" + self.instruction + + # FIXME: json instruction会带来格式问题,如:"Project name": "web_2048 # 项目名称使用下划线", + # compile example暂时不支持markdown + instruction = self.compile_instruction(schema="markdown", mode=mode, exclude=exclude) + example = self.compile_example(schema=schema, tag=TAG, mode=mode, exclude=exclude) + # nodes = ", ".join(self.to_dict(mode=mode).keys()) + constraints = [LANGUAGE_CONSTRAINT, FORMAT_CONSTRAINT] + constraint = "\n".join(constraints) + + prompt = template.format( + context=context, + example=example, + instruction=instruction, + constraint=constraint, + ) + return prompt + + @retry( + wait=wait_random_exponential(min=1, max=20), + stop=stop_after_attempt(6), + after=general_after_log(logger), + ) + async def _aask_v1( + self, + prompt: str, + output_class_name: str, + output_data_mapping: dict, + system_msgs: Optional[list[str]] = None, + schema="markdown", # compatible to original format + timeout=CONFIG.timeout, + ) -> (str, BaseModel): + """Use ActionOutput to wrap the output of aask""" + content = await self.llm.aask(prompt, system_msgs, timeout=timeout) + logger.debug(f"llm raw output:\n{content}") + output_class = self.create_model_class(output_class_name, output_data_mapping) + + if schema == "json": + parsed_data = llm_output_postprocess( + output=content, schema=output_class.model_json_schema(), req_key=f"[/{TAG}]" + ) + else: # using markdown parser + parsed_data = OutputParser.parse_data_with_mapping(content, output_data_mapping) + + logger.debug(f"parsed_data:\n{parsed_data}") + instruct_content = output_class(**parsed_data) + return content, instruct_content + + def get(self, key): + return self.instruct_content.model_dump()[key] + + def set_recursive(self, name, value): + setattr(self, name, value) + for _, i in self.children.items(): + i.set_recursive(name, value) + + def set_llm(self, llm): + self.set_recursive("llm", llm) + + def set_context(self, context): + self.set_recursive("context", context) + + async def simple_fill(self, schema, mode, timeout=CONFIG.timeout, exclude=None): + prompt = self.compile(context=self.context, schema=schema, mode=mode, exclude=exclude) + + if schema != "raw": + mapping = self.get_mapping(mode, exclude=exclude) + class_name = f"{self.key}_AN" + content, scontent = await self._aask_v1(prompt, class_name, mapping, schema=schema, timeout=timeout) + self.content = content + self.instruct_content = scontent + else: + self.content = await self.llm.aask(prompt) + self.instruct_content = None + + return self + + async def fill(self, context, llm, schema="json", mode="auto", strgy="simple", timeout=CONFIG.timeout, exclude=[]): + """Fill the node(s) with mode. + + :param context: Everything we should know when filling node. + :param llm: Large Language Model with pre-defined system message. + :param schema: json/markdown, determine example and output format. + - raw: free form text + - json: it's easy to open source LLM with json format + - markdown: when generating code, markdown is always better + :param mode: auto/children/root + - auto: automated fill children's nodes and gather outputs, if no children, fill itself + - children: fill children's nodes and gather outputs + - root: fill root's node and gather output + :param strgy: simple/complex + - simple: run only once + - complex: run each node + :param timeout: Timeout for llm invocation. + :param exclude: The keys of ActionNode to exclude. + :return: self + """ + self.set_llm(llm) + self.set_context(context) + if self.schema: + schema = self.schema + + if strgy == "simple": + return await self.simple_fill(schema=schema, mode=mode, timeout=timeout, exclude=exclude) + elif strgy == "complex": + # 这里隐式假设了拥有children + tmp = {} + for _, i in self.children.items(): + if exclude and i.key in exclude: + continue + child = await i.simple_fill(schema=schema, mode=mode, timeout=timeout, exclude=exclude) + tmp.update(child.instruct_content.dict()) + cls = self.create_children_class() + self.instruct_content = cls(**tmp) + return self diff --git a/PR/repair_llm_raw_output.py b/PR/repair_llm_raw_output.py new file mode 100644 index 000000000..4995918c2 --- /dev/null +++ b/PR/repair_llm_raw_output.py @@ -0,0 +1,351 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Desc : repair llm raw output with particular conditions + +import copy +from enum import Enum +from typing import Callable, Union + +import regex as re +from tenacity import RetryCallState, retry, stop_after_attempt, wait_fixed + +from metagpt.config import CONFIG +from metagpt.logs import logger +from metagpt.utils.custom_decoder import CustomDecoder + + +class RepairType(Enum): + CS = "case sensitivity" + RKPM = "required key pair missing" # condition like `[key] xx` which lacks `[/key]` + SCM = "special character missing" # Usually the req_key appear in pairs like `[key] xx [/key]` + JSON = "json format" + + +def repair_case_sensitivity(output: str, req_key: str) -> str: + """ + usually, req_key is the key name of expected json or markdown content, it won't appear in the value part. + fix target string `"Shared Knowledge": ""` but `"Shared knowledge": ""` actually + """ + if req_key in output: + return output + + output_lower = output.lower() + req_key_lower = req_key.lower() + if req_key_lower in output_lower: + # find the sub-part index, and replace it with raw req_key + lidx = output_lower.find(req_key_lower) + source = output[lidx : lidx + len(req_key_lower)] + output = output.replace(source, req_key) + logger.info(f"repair_case_sensitivity: {req_key}") + + return output + + +def repair_special_character_missing(output: str, req_key: str = "[/CONTENT]") -> str: + """ + fix + 1. target string `[CONTENT] xx [CONTENT] xxx [CONTENT]` lacks `/` in the last `[CONTENT]` + 2. target string `xx [CONTENT] xxx [CONTENT] xxxx` lacks `/` in the last `[CONTENT]` + """ + sc_arr = ["/"] + + if req_key in output: + return output + + for sc in sc_arr: + req_key_pure = req_key.replace(sc, "") + appear_cnt = output.count(req_key_pure) + if req_key_pure in output and appear_cnt > 1: + # req_key with special_character usually in the tail side + ridx = output.rfind(req_key_pure) + output = f"{output[:ridx]}{req_key}{output[ridx + len(req_key_pure):]}" + logger.info(f"repair_special_character_missing: {sc} in {req_key_pure} as position {ridx}") + + return output + + +def repair_required_key_pair_missing(output: str, req_key: str = "[/CONTENT]") -> str: + """ + implement the req_key pair in the begin or end of the content + req_key format + 1. `[req_key]`, and its pair `[/req_key]` + 2. `[/req_key]`, and its pair `[req_key]` + """ + sc = "/" # special char + if req_key.startswith("[") and req_key.endswith("]"): + if sc in req_key: + left_key = req_key.replace(sc, "") # `[/req_key]` -> `[req_key]` + right_key = req_key + else: + left_key = req_key + right_key = f"{req_key[0]}{sc}{req_key[1:]}" # `[req_key]` -> `[/req_key]` + + if left_key not in output: + output = left_key + "\n" + output + if right_key not in output: + + def judge_potential_json(routput: str, left_key: str) -> Union[str, None]: + ridx = routput.rfind(left_key) + if ridx < 0: + return None + sub_output = routput[ridx:] + idx1 = sub_output.rfind("}") + idx2 = sub_output.rindex("]") + idx = idx1 if idx1 >= idx2 else idx2 + sub_output = sub_output[: idx + 1] + return sub_output + + if output.strip().endswith("}") or (output.strip().endswith("]") and not output.strip().endswith(left_key)): + # # avoid [req_key]xx[req_key] case to append [/req_key] + output = output + "\n" + right_key + elif judge_potential_json(output, left_key) and (not output.strip().endswith(left_key)): + sub_content = judge_potential_json(output, left_key) + output = sub_content + "\n" + right_key + + return output + + +def repair_json_format(output: str) -> str: + """ + fix extra `[` or `}` in the end + """ + output = output.strip() + + if output.startswith("[{"): + output = output[1:] + logger.info(f"repair_json_format: {'[{'}") + elif output.endswith("}]"): + output = output[:-1] + logger.info(f"repair_json_format: {'}]'}") + elif output.startswith("{") and output.endswith("]"): + output = output[:-1] + "}" + + # remove comments in output json str, after json value content, maybe start with #, maybe start with // + arr = output.split("\n") + new_arr = [] + for line in arr: + # look for # or // comments and make sure they are not inside the string value + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + # if comments, then delete them + if comment_index != -1: + line = line[:comment_index].rstrip() + new_arr.append(line) + output = "\n".join(new_arr) + return output + + +def _repair_llm_raw_output(output: str, req_key: str, repair_type: RepairType = None) -> str: + repair_types = [repair_type] if repair_type else [item for item in RepairType if item not in [RepairType.JSON]] + for repair_type in repair_types: + if repair_type == RepairType.CS: + output = repair_case_sensitivity(output, req_key) + elif repair_type == RepairType.RKPM: + output = repair_required_key_pair_missing(output, req_key) + elif repair_type == RepairType.SCM: + output = repair_special_character_missing(output, req_key) + elif repair_type == RepairType.JSON: + output = repair_json_format(output) + return output + + +def repair_llm_raw_output(output: str, req_keys: list[str], repair_type: RepairType = None) -> str: + """ + in open-source llm model, it usually can't follow the instruction well, the output may be incomplete, + so here we try to repair it and use all repair methods by default. + typical case + 1. case sensitivity + target: "Original Requirements" + output: "Original requirements" + 2. special character missing + target: [/CONTENT] + output: [CONTENT] + 3. json format + target: { xxx } + output: { xxx }] + """ + if not CONFIG.repair_llm_output: + return output + + # do the repairation usually for non-openai models + for req_key in req_keys: + output = _repair_llm_raw_output(output=output, req_key=req_key, repair_type=repair_type) + return output + + +def repair_invalid_json(output: str, error: str) -> str: + """ + repair the situation like there are extra chars like + error examples + example 1. json.decoder.JSONDecodeError: Expecting ',' delimiter: line 154 column 1 (char 2765) + example 2. xxx.JSONDecodeError: Expecting property name enclosed in double quotes: line 14 column 1 (char 266) + """ + pattern = r"line ([0-9]+) column ([0-9]+)" + + matches = re.findall(pattern, error, re.DOTALL) + if len(matches) > 0: + line_no = int(matches[0][0]) - 1 + col_no = int(matches[0][1]) - 1 + + # due to CustomDecoder can handle `"": ''` or `'': ""`, so convert `"""` -> `"`, `'''` -> `'` + output = output.replace('"""', '"').replace("'''", '"') + arr = output.split("\n") + rline = arr[line_no] # raw line + line = arr[line_no].strip() + # different general problems + if line.endswith("],"): + # problem, redundant char `]` + new_line = line.replace("]", "") + elif line.endswith("},") and not output.endswith("},"): + # problem, redundant char `}` + new_line = line.replace("}", "") + elif line.endswith("},") and output.endswith("},"): + new_line = line[:-1] + # remove comments in output json str, after json value content, maybe start with #, maybe start with // + elif rline[col_no] == "#" or rline[col_no] == "/": + new_line = rline[:col_no] + for i in range(line_no + 1, len(arr)): + # look for # or // comments and make sure they are not inside the string value + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + # if comments, then delete them + if comment_index != -1: + arr[i] = arr[i][:comment_index].rstrip() + elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: + # problem, `"""` or `'''` without `,` + new_line = f",{line}" + elif '",' not in line and "," not in line and '"' not in line: + new_line = f'{line}",' + elif not line.endswith(","): + # problem, miss char `,` at the end. + new_line = f"{line}," + elif "," in line and len(line) == 1: + new_line = f'"{line}' + elif '",' in line: + new_line = line[:-2] + "'," + else: + new_line = line + + arr[line_no] = new_line + output = "\n".join(arr) + logger.info(f"repair_invalid_json, raw error: {error}") + + return output + + +def run_after_exp_and_passon_next_retry(logger: "loguru.Logger") -> Callable[["RetryCallState"], None]: + def run_and_passon(retry_state: RetryCallState) -> None: + """ + RetryCallState example + { + "start_time":143.098322024, + "retry_object":")>", + "fn":"", + "args":"(\"tag:[/CONTENT]\",)", # function input args + "kwargs":{}, # function input kwargs + "attempt_number":1, # retry number + "outcome":"", # type(outcome.result()) = "str", type(outcome.exception()) = "class" + "outcome_timestamp":143.098416904, + "idle_for":0, + "next_action":"None" + } + """ + if retry_state.outcome.failed: + if retry_state.args: + # # can't be used as args=retry_state.args + func_param_output = retry_state.args[0] + elif retry_state.kwargs: + func_param_output = retry_state.kwargs.get("output", "") + exp_str = str(retry_state.outcome.exception()) + + fix_str = "try to fix it, " if CONFIG.repair_llm_output else "" + logger.warning( + f"parse json from content inside [CONTENT][/CONTENT] failed at retry " + f"{retry_state.attempt_number}, {fix_str}exp: {exp_str}" + ) + + repaired_output = repair_invalid_json(func_param_output, exp_str) + retry_state.kwargs["output"] = repaired_output + + return run_and_passon + + +@retry( + stop=stop_after_attempt(3 if CONFIG.repair_llm_output else 0), + wait=wait_fixed(1), + after=run_after_exp_and_passon_next_retry(logger), +) +def retry_parse_json_text(output: str) -> Union[list, dict]: + """ + repair the json-text situation like there are extra chars like [']', '}'] + + Warning + if CONFIG.repair_llm_output is False, retry _aask_v1 {x=3} times, and the retry_parse_json_text's retry not work + if CONFIG.repair_llm_output is True, the _aask_v1 and the retry_parse_json_text will loop for {x=3*3} times. + it's a two-layer retry cycle + """ + # logger.debug(f"output to json decode:\n{output}") + + # if CONFIG.repair_llm_output is True, it will try to fix output until the retry break + parsed_data = CustomDecoder(strict=False).decode(output) + + return parsed_data + + +def extract_content_from_output(content: str, right_key: str = "[/CONTENT]"): + """extract xxx from [CONTENT](xxx)[/CONTENT] using regex pattern""" + + def re_extract_content(cont: str, pattern: str) -> str: + matches = re.findall(pattern, cont, re.DOTALL) + for match in matches: + if match: + cont = match + break + return cont.strip() + + # TODO construct the extract pattern with the `right_key` + raw_content = copy.deepcopy(content) + pattern = r"\[CONTENT\]([\s\S]*)\[/CONTENT\]" + new_content = re_extract_content(raw_content, pattern) + + if not new_content.startswith("{"): + # TODO find a more general pattern + # # for `[CONTENT]xxx[CONTENT]xxxx[/CONTENT] situation + logger.warning(f"extract_content try another pattern: {pattern}") + if right_key not in new_content: + raw_content = copy.deepcopy(new_content + "\n" + right_key) + # # pattern = r"\[CONTENT\](\s*\{.*?\}\s*)\[/CONTENT\]" + new_content = re_extract_content(raw_content, pattern) + else: + if right_key in new_content: + idx = new_content.find(right_key) + new_content = new_content[:idx] + new_content = new_content.strip() + + return new_content + + +def extract_state_value_from_output(content: str) -> str: + """ + For openai models, they will always return state number. But for open llm models, the instruction result maybe a + long text contain target number, so here add a extraction to improve success rate. + + Args: + content (str): llm's output from `Role._think` + """ + content = content.strip() # deal the output cases like " 0", "0\n" and so on. + pattern = r"([0-9])" # TODO find the number using a more proper method not just extract from content using pattern + matches = re.findall(pattern, content, re.DOTALL) + matches = list(set(matches)) + state = matches[0] if len(matches) > 0 else "-1" + return state diff --git a/metagpt/utils/repair_llm_raw_output.py b/metagpt/utils/repair_llm_raw_output.py index 4995918c2..ef3580750 100644 --- a/metagpt/utils/repair_llm_raw_output.py +++ b/metagpt/utils/repair_llm_raw_output.py @@ -105,6 +105,23 @@ def repair_required_key_pair_missing(output: str, req_key: str = "[/CONTENT]") - return output +def remove_comments_from_line(line): + """ + Remove comments from a single line of string. + Comments are assumed to start with '#' or '//' and are not inside string values. + """ + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + if comment_index != -1: # if comments, then delete them + return line[:comment_index].rstrip() + return line + + def repair_json_format(output: str) -> str: """ fix extra `[` or `}` in the end @@ -125,17 +142,8 @@ def repair_json_format(output: str) -> str: new_arr = [] for line in arr: # look for # or // comments and make sure they are not inside the string value - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - # if comments, then delete them - if comment_index != -1: - line = line[:comment_index].rstrip() - new_arr.append(line) + new_line = remove_comments_from_line(line) + new_arr.append(new_line) output = "\n".join(new_arr) return output @@ -209,18 +217,9 @@ def repair_invalid_json(output: str, error: str) -> str: # remove comments in output json str, after json value content, maybe start with #, maybe start with // elif rline[col_no] == "#" or rline[col_no] == "/": new_line = rline[:col_no] + # check the next line and remove the comments for i in range(line_no + 1, len(arr)): - # look for # or // comments and make sure they are not inside the string value - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - # if comments, then delete them - if comment_index != -1: - arr[i] = arr[i][:comment_index].rstrip() + arr[i] = remove_comments_from_line(arr[i]) elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: # problem, `"""` or `'''` without `,` new_line = f",{line}" From 8b5f7848fa6aa8c9e0703dcdbf6760ef1efa87eb Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Sat, 27 Jan 2024 17:00:59 +0800 Subject: [PATCH 05/35] delete PR dir --- metagpt/utils/repair_llm_raw_output.py | 43 +++++++++++++------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/metagpt/utils/repair_llm_raw_output.py b/metagpt/utils/repair_llm_raw_output.py index 4995918c2..ef3580750 100644 --- a/metagpt/utils/repair_llm_raw_output.py +++ b/metagpt/utils/repair_llm_raw_output.py @@ -105,6 +105,23 @@ def repair_required_key_pair_missing(output: str, req_key: str = "[/CONTENT]") - return output +def remove_comments_from_line(line): + """ + Remove comments from a single line of string. + Comments are assumed to start with '#' or '//' and are not inside string values. + """ + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + if comment_index != -1: # if comments, then delete them + return line[:comment_index].rstrip() + return line + + def repair_json_format(output: str) -> str: """ fix extra `[` or `}` in the end @@ -125,17 +142,8 @@ def repair_json_format(output: str) -> str: new_arr = [] for line in arr: # look for # or // comments and make sure they are not inside the string value - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - # if comments, then delete them - if comment_index != -1: - line = line[:comment_index].rstrip() - new_arr.append(line) + new_line = remove_comments_from_line(line) + new_arr.append(new_line) output = "\n".join(new_arr) return output @@ -209,18 +217,9 @@ def repair_invalid_json(output: str, error: str) -> str: # remove comments in output json str, after json value content, maybe start with #, maybe start with // elif rline[col_no] == "#" or rline[col_no] == "/": new_line = rline[:col_no] + # check the next line and remove the comments for i in range(line_no + 1, len(arr)): - # look for # or // comments and make sure they are not inside the string value - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - # if comments, then delete them - if comment_index != -1: - arr[i] = arr[i][:comment_index].rstrip() + arr[i] = remove_comments_from_line(arr[i]) elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: # problem, `"""` or `'''` without `,` new_line = f",{line}" From 2361c7e8aa2df55bd3562243e95b4d5f538188ff Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Sat, 27 Jan 2024 17:07:21 +0800 Subject: [PATCH 06/35] delete PR dir --- ...move comments in output json str, after js | 12 - PR/action_node.py | 351 ------------------ PR/repair_llm_raw_output.py | 351 ------------------ 3 files changed, 714 deletions(-) delete mode 100644 PR/# remove comments in output json str, after js delete mode 100644 PR/action_node.py delete mode 100644 PR/repair_llm_raw_output.py diff --git a/PR/# remove comments in output json str, after js b/PR/# remove comments in output json str, after js deleted file mode 100644 index f795fefdb..000000000 --- a/PR/# remove comments in output json str, after js +++ /dev/null @@ -1,12 +0,0 @@ - -git commit -m "To avoid JSONDecodeError: " -m "Remove comments in output json str, after json value content, maybe start with #, maybe start with //, particularly, it is not inside the string value" -m "Addtionly, if you do not want JSONDecodeError to occur, you can add 'Delete comments in json' after FORMAT_CONSTRAINT in action_node.py" - - - -git commit -m "Addtionly, if you do not want JSONDecodeError to occur, you can add 'Delete comments in json' after FORMAT_CONSTRAINT in action_node.py" - - - - - - diff --git a/PR/action_node.py b/PR/action_node.py deleted file mode 100644 index 0f441cfee..000000000 --- a/PR/action_node.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -@Time : 2023/12/11 18:45 -@Author : alexanderwu -@File : action_node.py - -NOTE: You should use typing.List instead of list to do type annotation. Because in the markdown extraction process, - we can use typing to extract the type of the node, but we cannot use built-in list to extract. -""" -import json -from typing import Any, Dict, List, Optional, Tuple, Type - -from pydantic import BaseModel, create_model, model_validator -from tenacity import retry, stop_after_attempt, wait_random_exponential - -from metagpt.config import CONFIG -from metagpt.llm import BaseLLM -from metagpt.logs import logger -from metagpt.provider.postprocess.llm_output_postprocess import llm_output_postprocess -from metagpt.utils.common import OutputParser, general_after_log - -TAG = "CONTENT" - -LANGUAGE_CONSTRAINT = "Language: Please use the same language as Human INPUT." -FORMAT_CONSTRAINT = f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else." -# Delete comments in json -# If you don't want JSONDecodeError to occur, you can add Delete comments in json after FORMAT_CONSTRAINT - - -SIMPLE_TEMPLATE = """ -## context -{context} - ------ - -## format example -{example} - -## nodes: ": # " -{instruction} - -## constraint -{constraint} - -## action -Follow instructions of nodes, generate output and make sure it follows the format example. -""" - - -def dict_to_markdown(d, prefix="- ", kv_sep="\n", postfix="\n"): - markdown_str = "" - for key, value in d.items(): - markdown_str += f"{prefix}{key}{kv_sep}{value}{postfix}" - return markdown_str - - -class ActionNode: - """ActionNode is a tree of nodes.""" - - schema: str # raw/json/markdown, default: "" - - # Action Context - context: str # all the context, including all necessary info - llm: BaseLLM # LLM with aask interface - children: dict[str, "ActionNode"] - - # Action Input - key: str # Product Requirement / File list / Code - expected_type: Type # such as str / int / float etc. - # context: str # everything in the history. - instruction: str # the instructions should be followed. - example: Any # example for In Context-Learning. - - # Action Output - content: str - instruct_content: BaseModel - - def __init__( - self, - key: str, - expected_type: Type, - instruction: str, - example: Any, - content: str = "", - children: dict[str, "ActionNode"] = None, - schema: str = "", - ): - self.key = key - self.expected_type = expected_type - self.instruction = instruction - self.example = example - self.content = content - self.children = children if children is not None else {} - self.schema = schema - - def __str__(self): - return ( - f"{self.key}, {repr(self.expected_type)}, {self.instruction}, {self.example}" - f", {self.content}, {self.children}" - ) - - def __repr__(self): - return self.__str__() - - def add_child(self, node: "ActionNode"): - """增加子ActionNode""" - self.children[node.key] = node - - def add_children(self, nodes: List["ActionNode"]): - """批量增加子ActionNode""" - for node in nodes: - self.add_child(node) - - @classmethod - def from_children(cls, key, nodes: List["ActionNode"]): - """直接从一系列的子nodes初始化""" - obj = cls(key, str, "", "") - obj.add_children(nodes) - return obj - - def get_children_mapping(self, exclude=None) -> Dict[str, Tuple[Type, Any]]: - """获得子ActionNode的字典,以key索引""" - exclude = exclude or [] - return {k: (v.expected_type, ...) for k, v in self.children.items() if k not in exclude} - - def get_self_mapping(self) -> Dict[str, Tuple[Type, Any]]: - """get self key: type mapping""" - return {self.key: (self.expected_type, ...)} - - def get_mapping(self, mode="children", exclude=None) -> Dict[str, Tuple[Type, Any]]: - """get key: type mapping under mode""" - if mode == "children" or (mode == "auto" and self.children): - return self.get_children_mapping(exclude=exclude) - return {} if exclude and self.key in exclude else self.get_self_mapping() - - @classmethod - def create_model_class(cls, class_name: str, mapping: Dict[str, Tuple[Type, Any]]): - """基于pydantic v1的模型动态生成,用来检验结果类型正确性""" - - def check_fields(cls, values): - required_fields = set(mapping.keys()) - missing_fields = required_fields - set(values.keys()) - if missing_fields: - raise ValueError(f"Missing fields: {missing_fields}") - - unrecognized_fields = set(values.keys()) - required_fields - if unrecognized_fields: - logger.warning(f"Unrecognized fields: {unrecognized_fields}") - return values - - validators = {"check_missing_fields_validator": model_validator(mode="before")(check_fields)} - - new_class = create_model(class_name, __validators__=validators, **mapping) - return new_class - - def create_children_class(self, exclude=None): - """使用object内有的字段直接生成model_class""" - class_name = f"{self.key}_AN" - mapping = self.get_children_mapping(exclude=exclude) - return self.create_model_class(class_name, mapping) - - def to_dict(self, format_func=None, mode="auto", exclude=None) -> Dict: - """将当前节点与子节点都按照node: format的格式组织成字典""" - - # 如果没有提供格式化函数,使用默认的格式化方式 - if format_func is None: - format_func = lambda node: f"{node.instruction}" - - # 使用提供的格式化函数来格式化当前节点的值 - formatted_value = format_func(self) - - # 创建当前节点的键值对 - if mode == "children" or (mode == "auto" and self.children): - node_dict = {} - else: - node_dict = {self.key: formatted_value} - - if mode == "root": - return node_dict - - # 遍历子节点并递归调用 to_dict 方法 - exclude = exclude or [] - for _, child_node in self.children.items(): - if child_node.key in exclude: - continue - node_dict.update(child_node.to_dict(format_func)) - - return node_dict - - def compile_to(self, i: Dict, schema, kv_sep) -> str: - if schema == "json": - return json.dumps(i, indent=4) - elif schema == "markdown": - return dict_to_markdown(i, kv_sep=kv_sep) - else: - return str(i) - - def tagging(self, text, schema, tag="") -> str: - if not tag: - return text - if schema == "json": - return f"[{tag}]\n" + text + f"\n[/{tag}]" - else: # markdown - return f"[{tag}]\n" + text + f"\n[/{tag}]" - - def _compile_f(self, schema, mode, tag, format_func, kv_sep, exclude=None) -> str: - nodes = self.to_dict(format_func=format_func, mode=mode, exclude=exclude) - text = self.compile_to(nodes, schema, kv_sep) - return self.tagging(text, schema, tag) - - def compile_instruction(self, schema="markdown", mode="children", tag="", exclude=None) -> str: - """compile to raw/json/markdown template with all/root/children nodes""" - format_func = lambda i: f"{i.expected_type} # {i.instruction}" - return self._compile_f(schema, mode, tag, format_func, kv_sep=": ", exclude=exclude) - - def compile_example(self, schema="json", mode="children", tag="", exclude=None) -> str: - """compile to raw/json/markdown examples with all/root/children nodes""" - - # 这里不能使用f-string,因为转译为str后再json.dumps会额外加上引号,无法作为有效的example - # 错误示例:"File list": "['main.py', 'const.py', 'game.py']", 注意这里值不是list,而是str - format_func = lambda i: i.example - return self._compile_f(schema, mode, tag, format_func, kv_sep="\n", exclude=exclude) - - def compile(self, context, schema="json", mode="children", template=SIMPLE_TEMPLATE, exclude=[]) -> str: - """ - mode: all/root/children - mode="children": 编译所有子节点为一个统一模板,包括instruction与example - mode="all": NotImplemented - mode="root": NotImplemented - schmea: raw/json/markdown - schema="raw": 不编译,context, lang_constaint, instruction - schema="json":编译context, example(json), instruction(markdown), constraint, action - schema="markdown": 编译context, example(markdown), instruction(markdown), constraint, action - """ - if schema == "raw": - return context + "\n\n## Actions\n" + LANGUAGE_CONSTRAINT + "\n" + self.instruction - - # FIXME: json instruction会带来格式问题,如:"Project name": "web_2048 # 项目名称使用下划线", - # compile example暂时不支持markdown - instruction = self.compile_instruction(schema="markdown", mode=mode, exclude=exclude) - example = self.compile_example(schema=schema, tag=TAG, mode=mode, exclude=exclude) - # nodes = ", ".join(self.to_dict(mode=mode).keys()) - constraints = [LANGUAGE_CONSTRAINT, FORMAT_CONSTRAINT] - constraint = "\n".join(constraints) - - prompt = template.format( - context=context, - example=example, - instruction=instruction, - constraint=constraint, - ) - return prompt - - @retry( - wait=wait_random_exponential(min=1, max=20), - stop=stop_after_attempt(6), - after=general_after_log(logger), - ) - async def _aask_v1( - self, - prompt: str, - output_class_name: str, - output_data_mapping: dict, - system_msgs: Optional[list[str]] = None, - schema="markdown", # compatible to original format - timeout=CONFIG.timeout, - ) -> (str, BaseModel): - """Use ActionOutput to wrap the output of aask""" - content = await self.llm.aask(prompt, system_msgs, timeout=timeout) - logger.debug(f"llm raw output:\n{content}") - output_class = self.create_model_class(output_class_name, output_data_mapping) - - if schema == "json": - parsed_data = llm_output_postprocess( - output=content, schema=output_class.model_json_schema(), req_key=f"[/{TAG}]" - ) - else: # using markdown parser - parsed_data = OutputParser.parse_data_with_mapping(content, output_data_mapping) - - logger.debug(f"parsed_data:\n{parsed_data}") - instruct_content = output_class(**parsed_data) - return content, instruct_content - - def get(self, key): - return self.instruct_content.model_dump()[key] - - def set_recursive(self, name, value): - setattr(self, name, value) - for _, i in self.children.items(): - i.set_recursive(name, value) - - def set_llm(self, llm): - self.set_recursive("llm", llm) - - def set_context(self, context): - self.set_recursive("context", context) - - async def simple_fill(self, schema, mode, timeout=CONFIG.timeout, exclude=None): - prompt = self.compile(context=self.context, schema=schema, mode=mode, exclude=exclude) - - if schema != "raw": - mapping = self.get_mapping(mode, exclude=exclude) - class_name = f"{self.key}_AN" - content, scontent = await self._aask_v1(prompt, class_name, mapping, schema=schema, timeout=timeout) - self.content = content - self.instruct_content = scontent - else: - self.content = await self.llm.aask(prompt) - self.instruct_content = None - - return self - - async def fill(self, context, llm, schema="json", mode="auto", strgy="simple", timeout=CONFIG.timeout, exclude=[]): - """Fill the node(s) with mode. - - :param context: Everything we should know when filling node. - :param llm: Large Language Model with pre-defined system message. - :param schema: json/markdown, determine example and output format. - - raw: free form text - - json: it's easy to open source LLM with json format - - markdown: when generating code, markdown is always better - :param mode: auto/children/root - - auto: automated fill children's nodes and gather outputs, if no children, fill itself - - children: fill children's nodes and gather outputs - - root: fill root's node and gather output - :param strgy: simple/complex - - simple: run only once - - complex: run each node - :param timeout: Timeout for llm invocation. - :param exclude: The keys of ActionNode to exclude. - :return: self - """ - self.set_llm(llm) - self.set_context(context) - if self.schema: - schema = self.schema - - if strgy == "simple": - return await self.simple_fill(schema=schema, mode=mode, timeout=timeout, exclude=exclude) - elif strgy == "complex": - # 这里隐式假设了拥有children - tmp = {} - for _, i in self.children.items(): - if exclude and i.key in exclude: - continue - child = await i.simple_fill(schema=schema, mode=mode, timeout=timeout, exclude=exclude) - tmp.update(child.instruct_content.dict()) - cls = self.create_children_class() - self.instruct_content = cls(**tmp) - return self diff --git a/PR/repair_llm_raw_output.py b/PR/repair_llm_raw_output.py deleted file mode 100644 index 4995918c2..000000000 --- a/PR/repair_llm_raw_output.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Desc : repair llm raw output with particular conditions - -import copy -from enum import Enum -from typing import Callable, Union - -import regex as re -from tenacity import RetryCallState, retry, stop_after_attempt, wait_fixed - -from metagpt.config import CONFIG -from metagpt.logs import logger -from metagpt.utils.custom_decoder import CustomDecoder - - -class RepairType(Enum): - CS = "case sensitivity" - RKPM = "required key pair missing" # condition like `[key] xx` which lacks `[/key]` - SCM = "special character missing" # Usually the req_key appear in pairs like `[key] xx [/key]` - JSON = "json format" - - -def repair_case_sensitivity(output: str, req_key: str) -> str: - """ - usually, req_key is the key name of expected json or markdown content, it won't appear in the value part. - fix target string `"Shared Knowledge": ""` but `"Shared knowledge": ""` actually - """ - if req_key in output: - return output - - output_lower = output.lower() - req_key_lower = req_key.lower() - if req_key_lower in output_lower: - # find the sub-part index, and replace it with raw req_key - lidx = output_lower.find(req_key_lower) - source = output[lidx : lidx + len(req_key_lower)] - output = output.replace(source, req_key) - logger.info(f"repair_case_sensitivity: {req_key}") - - return output - - -def repair_special_character_missing(output: str, req_key: str = "[/CONTENT]") -> str: - """ - fix - 1. target string `[CONTENT] xx [CONTENT] xxx [CONTENT]` lacks `/` in the last `[CONTENT]` - 2. target string `xx [CONTENT] xxx [CONTENT] xxxx` lacks `/` in the last `[CONTENT]` - """ - sc_arr = ["/"] - - if req_key in output: - return output - - for sc in sc_arr: - req_key_pure = req_key.replace(sc, "") - appear_cnt = output.count(req_key_pure) - if req_key_pure in output and appear_cnt > 1: - # req_key with special_character usually in the tail side - ridx = output.rfind(req_key_pure) - output = f"{output[:ridx]}{req_key}{output[ridx + len(req_key_pure):]}" - logger.info(f"repair_special_character_missing: {sc} in {req_key_pure} as position {ridx}") - - return output - - -def repair_required_key_pair_missing(output: str, req_key: str = "[/CONTENT]") -> str: - """ - implement the req_key pair in the begin or end of the content - req_key format - 1. `[req_key]`, and its pair `[/req_key]` - 2. `[/req_key]`, and its pair `[req_key]` - """ - sc = "/" # special char - if req_key.startswith("[") and req_key.endswith("]"): - if sc in req_key: - left_key = req_key.replace(sc, "") # `[/req_key]` -> `[req_key]` - right_key = req_key - else: - left_key = req_key - right_key = f"{req_key[0]}{sc}{req_key[1:]}" # `[req_key]` -> `[/req_key]` - - if left_key not in output: - output = left_key + "\n" + output - if right_key not in output: - - def judge_potential_json(routput: str, left_key: str) -> Union[str, None]: - ridx = routput.rfind(left_key) - if ridx < 0: - return None - sub_output = routput[ridx:] - idx1 = sub_output.rfind("}") - idx2 = sub_output.rindex("]") - idx = idx1 if idx1 >= idx2 else idx2 - sub_output = sub_output[: idx + 1] - return sub_output - - if output.strip().endswith("}") or (output.strip().endswith("]") and not output.strip().endswith(left_key)): - # # avoid [req_key]xx[req_key] case to append [/req_key] - output = output + "\n" + right_key - elif judge_potential_json(output, left_key) and (not output.strip().endswith(left_key)): - sub_content = judge_potential_json(output, left_key) - output = sub_content + "\n" + right_key - - return output - - -def repair_json_format(output: str) -> str: - """ - fix extra `[` or `}` in the end - """ - output = output.strip() - - if output.startswith("[{"): - output = output[1:] - logger.info(f"repair_json_format: {'[{'}") - elif output.endswith("}]"): - output = output[:-1] - logger.info(f"repair_json_format: {'}]'}") - elif output.startswith("{") and output.endswith("]"): - output = output[:-1] + "}" - - # remove comments in output json str, after json value content, maybe start with #, maybe start with // - arr = output.split("\n") - new_arr = [] - for line in arr: - # look for # or // comments and make sure they are not inside the string value - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - # if comments, then delete them - if comment_index != -1: - line = line[:comment_index].rstrip() - new_arr.append(line) - output = "\n".join(new_arr) - return output - - -def _repair_llm_raw_output(output: str, req_key: str, repair_type: RepairType = None) -> str: - repair_types = [repair_type] if repair_type else [item for item in RepairType if item not in [RepairType.JSON]] - for repair_type in repair_types: - if repair_type == RepairType.CS: - output = repair_case_sensitivity(output, req_key) - elif repair_type == RepairType.RKPM: - output = repair_required_key_pair_missing(output, req_key) - elif repair_type == RepairType.SCM: - output = repair_special_character_missing(output, req_key) - elif repair_type == RepairType.JSON: - output = repair_json_format(output) - return output - - -def repair_llm_raw_output(output: str, req_keys: list[str], repair_type: RepairType = None) -> str: - """ - in open-source llm model, it usually can't follow the instruction well, the output may be incomplete, - so here we try to repair it and use all repair methods by default. - typical case - 1. case sensitivity - target: "Original Requirements" - output: "Original requirements" - 2. special character missing - target: [/CONTENT] - output: [CONTENT] - 3. json format - target: { xxx } - output: { xxx }] - """ - if not CONFIG.repair_llm_output: - return output - - # do the repairation usually for non-openai models - for req_key in req_keys: - output = _repair_llm_raw_output(output=output, req_key=req_key, repair_type=repair_type) - return output - - -def repair_invalid_json(output: str, error: str) -> str: - """ - repair the situation like there are extra chars like - error examples - example 1. json.decoder.JSONDecodeError: Expecting ',' delimiter: line 154 column 1 (char 2765) - example 2. xxx.JSONDecodeError: Expecting property name enclosed in double quotes: line 14 column 1 (char 266) - """ - pattern = r"line ([0-9]+) column ([0-9]+)" - - matches = re.findall(pattern, error, re.DOTALL) - if len(matches) > 0: - line_no = int(matches[0][0]) - 1 - col_no = int(matches[0][1]) - 1 - - # due to CustomDecoder can handle `"": ''` or `'': ""`, so convert `"""` -> `"`, `'''` -> `'` - output = output.replace('"""', '"').replace("'''", '"') - arr = output.split("\n") - rline = arr[line_no] # raw line - line = arr[line_no].strip() - # different general problems - if line.endswith("],"): - # problem, redundant char `]` - new_line = line.replace("]", "") - elif line.endswith("},") and not output.endswith("},"): - # problem, redundant char `}` - new_line = line.replace("}", "") - elif line.endswith("},") and output.endswith("},"): - new_line = line[:-1] - # remove comments in output json str, after json value content, maybe start with #, maybe start with // - elif rline[col_no] == "#" or rline[col_no] == "/": - new_line = rline[:col_no] - for i in range(line_no + 1, len(arr)): - # look for # or // comments and make sure they are not inside the string value - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - # if comments, then delete them - if comment_index != -1: - arr[i] = arr[i][:comment_index].rstrip() - elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: - # problem, `"""` or `'''` without `,` - new_line = f",{line}" - elif '",' not in line and "," not in line and '"' not in line: - new_line = f'{line}",' - elif not line.endswith(","): - # problem, miss char `,` at the end. - new_line = f"{line}," - elif "," in line and len(line) == 1: - new_line = f'"{line}' - elif '",' in line: - new_line = line[:-2] + "'," - else: - new_line = line - - arr[line_no] = new_line - output = "\n".join(arr) - logger.info(f"repair_invalid_json, raw error: {error}") - - return output - - -def run_after_exp_and_passon_next_retry(logger: "loguru.Logger") -> Callable[["RetryCallState"], None]: - def run_and_passon(retry_state: RetryCallState) -> None: - """ - RetryCallState example - { - "start_time":143.098322024, - "retry_object":")>", - "fn":"", - "args":"(\"tag:[/CONTENT]\",)", # function input args - "kwargs":{}, # function input kwargs - "attempt_number":1, # retry number - "outcome":"", # type(outcome.result()) = "str", type(outcome.exception()) = "class" - "outcome_timestamp":143.098416904, - "idle_for":0, - "next_action":"None" - } - """ - if retry_state.outcome.failed: - if retry_state.args: - # # can't be used as args=retry_state.args - func_param_output = retry_state.args[0] - elif retry_state.kwargs: - func_param_output = retry_state.kwargs.get("output", "") - exp_str = str(retry_state.outcome.exception()) - - fix_str = "try to fix it, " if CONFIG.repair_llm_output else "" - logger.warning( - f"parse json from content inside [CONTENT][/CONTENT] failed at retry " - f"{retry_state.attempt_number}, {fix_str}exp: {exp_str}" - ) - - repaired_output = repair_invalid_json(func_param_output, exp_str) - retry_state.kwargs["output"] = repaired_output - - return run_and_passon - - -@retry( - stop=stop_after_attempt(3 if CONFIG.repair_llm_output else 0), - wait=wait_fixed(1), - after=run_after_exp_and_passon_next_retry(logger), -) -def retry_parse_json_text(output: str) -> Union[list, dict]: - """ - repair the json-text situation like there are extra chars like [']', '}'] - - Warning - if CONFIG.repair_llm_output is False, retry _aask_v1 {x=3} times, and the retry_parse_json_text's retry not work - if CONFIG.repair_llm_output is True, the _aask_v1 and the retry_parse_json_text will loop for {x=3*3} times. - it's a two-layer retry cycle - """ - # logger.debug(f"output to json decode:\n{output}") - - # if CONFIG.repair_llm_output is True, it will try to fix output until the retry break - parsed_data = CustomDecoder(strict=False).decode(output) - - return parsed_data - - -def extract_content_from_output(content: str, right_key: str = "[/CONTENT]"): - """extract xxx from [CONTENT](xxx)[/CONTENT] using regex pattern""" - - def re_extract_content(cont: str, pattern: str) -> str: - matches = re.findall(pattern, cont, re.DOTALL) - for match in matches: - if match: - cont = match - break - return cont.strip() - - # TODO construct the extract pattern with the `right_key` - raw_content = copy.deepcopy(content) - pattern = r"\[CONTENT\]([\s\S]*)\[/CONTENT\]" - new_content = re_extract_content(raw_content, pattern) - - if not new_content.startswith("{"): - # TODO find a more general pattern - # # for `[CONTENT]xxx[CONTENT]xxxx[/CONTENT] situation - logger.warning(f"extract_content try another pattern: {pattern}") - if right_key not in new_content: - raw_content = copy.deepcopy(new_content + "\n" + right_key) - # # pattern = r"\[CONTENT\](\s*\{.*?\}\s*)\[/CONTENT\]" - new_content = re_extract_content(raw_content, pattern) - else: - if right_key in new_content: - idx = new_content.find(right_key) - new_content = new_content[:idx] - new_content = new_content.strip() - - return new_content - - -def extract_state_value_from_output(content: str) -> str: - """ - For openai models, they will always return state number. But for open llm models, the instruction result maybe a - long text contain target number, so here add a extraction to improve success rate. - - Args: - content (str): llm's output from `Role._think` - """ - content = content.strip() # deal the output cases like " 0", "0\n" and so on. - pattern = r"([0-9])" # TODO find the number using a more proper method not just extract from content using pattern - matches = re.findall(pattern, content, re.DOTALL) - matches = list(set(matches)) - state = matches[0] if len(matches) > 0 else "-1" - return state From 11f70ca9b1714dc312a847505c9940f0c60a24b1 Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Sat, 27 Jan 2024 18:06:52 +0800 Subject: [PATCH 07/35] modify code based on feedback of action_node.py and repair_llm_raw_output.py, add code in test_repair_llm_raw_output.py --- metagpt/actions/action_node.py | 5 +--- metagpt/utils/repair_llm_raw_output.py | 9 +------ .../utils/test_repair_llm_raw_output.py | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/metagpt/actions/action_node.py b/metagpt/actions/action_node.py index ed0e27869..6c65b33ef 100644 --- a/metagpt/actions/action_node.py +++ b/metagpt/actions/action_node.py @@ -23,10 +23,7 @@ from metagpt.utils.common import OutputParser, general_after_log TAG = "CONTENT" LANGUAGE_CONSTRAINT = "Language: Please use the same language as Human INPUT." -FORMAT_CONSTRAINT = (f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else. " - f"Delete comments in json") -# Delete comments in json -# If you don't want JSONDecodeError to occur, you can add Delete comments in json after FORMAT_CONSTRAINT +FORMAT_CONSTRAINT = f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else." SIMPLE_TEMPLATE = """ diff --git a/metagpt/utils/repair_llm_raw_output.py b/metagpt/utils/repair_llm_raw_output.py index ef3580750..973cffb8a 100644 --- a/metagpt/utils/repair_llm_raw_output.py +++ b/metagpt/utils/repair_llm_raw_output.py @@ -137,11 +137,10 @@ def repair_json_format(output: str) -> str: elif output.startswith("{") and output.endswith("]"): output = output[:-1] + "}" - # remove comments in output json str, after json value content, maybe start with #, maybe start with // + # remove comments in output json string arr = output.split("\n") new_arr = [] for line in arr: - # look for # or // comments and make sure they are not inside the string value new_line = remove_comments_from_line(line) new_arr.append(new_line) output = "\n".join(new_arr) @@ -214,12 +213,6 @@ def repair_invalid_json(output: str, error: str) -> str: new_line = line.replace("}", "") elif line.endswith("},") and output.endswith("},"): new_line = line[:-1] - # remove comments in output json str, after json value content, maybe start with #, maybe start with // - elif rline[col_no] == "#" or rline[col_no] == "/": - new_line = rline[:col_no] - # check the next line and remove the comments - for i in range(line_no + 1, len(arr)): - arr[i] = remove_comments_from_line(arr[i]) elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: # problem, `"""` or `'''` without `,` new_line = f",{line}" diff --git a/tests/metagpt/utils/test_repair_llm_raw_output.py b/tests/metagpt/utils/test_repair_llm_raw_output.py index 1f809a081..9d53b8243 100644 --- a/tests/metagpt/utils/test_repair_llm_raw_output.py +++ b/tests/metagpt/utils/test_repair_llm_raw_output.py @@ -141,6 +141,32 @@ def test_repair_json_format(): output = repair_llm_raw_output(output=raw_output, req_keys=[None], repair_type=RepairType.JSON) assert output == target_output + raw_output = """ +{ + "Language": "en_us", // define language + "Programming Language": "Python" # define code language +} +""" + target_output = """{ + "Language": "en_us", + "Programming Language": "Python" +}""" + output = repair_llm_raw_output(output=raw_output, req_keys=[None], repair_type=RepairType.JSON) + assert output == target_output + + raw_output = """ + { + "Language": "#en_us#", // define language + "Programming Language": "//Python # Code // Language//" # define code language + } + """ + target_output = """{ + "Language": "#en_us#", + "Programming Language": "//Python # Code // Language//" + }""" + output = repair_llm_raw_output(output=raw_output, req_keys=[None], repair_type=RepairType.JSON) + assert output == target_output + def test_repair_invalid_json(): from metagpt.utils.repair_llm_raw_output import repair_invalid_json From c3b4c698d80cba70e446cd6a97f375459c8c5595 Mon Sep 17 00:00:00 2001 From: huzixia <528543747@qq.com> Date: Sat, 27 Jan 2024 18:23:57 +0800 Subject: [PATCH 08/35] update repair_llm_raw_output.py --- metagpt/utils/repair_llm_raw_output.py | 36 ++++++++++---------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/metagpt/utils/repair_llm_raw_output.py b/metagpt/utils/repair_llm_raw_output.py index 973cffb8a..6da974d96 100644 --- a/metagpt/utils/repair_llm_raw_output.py +++ b/metagpt/utils/repair_llm_raw_output.py @@ -105,23 +105,6 @@ def repair_required_key_pair_missing(output: str, req_key: str = "[/CONTENT]") - return output -def remove_comments_from_line(line): - """ - Remove comments from a single line of string. - Comments are assumed to start with '#' or '//' and are not inside string values. - """ - comment_index = -1 - for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", line): - if match.group(1): # if the string value - continue - if match.group(2): # if comments - comment_index = match.start(2) - break - if comment_index != -1: # if comments, then delete them - return line[:comment_index].rstrip() - return line - - def repair_json_format(output: str) -> str: """ fix extra `[` or `}` in the end @@ -136,13 +119,22 @@ def repair_json_format(output: str) -> str: logger.info(f"repair_json_format: {'}]'}") elif output.startswith("{") and output.endswith("]"): output = output[:-1] + "}" - - # remove comments in output json string + # remove comments in output json string, after json value content, maybe start with #, maybe start with // arr = output.split("\n") new_arr = [] - for line in arr: - new_line = remove_comments_from_line(line) - new_arr.append(new_line) + for json_line in arr: + # look for # or // comments and make sure they are not inside the string value + comment_index = -1 + for match in re.finditer(r"(\".*?\"|\'.*?\')|(#|//)", json_line): + if match.group(1): # if the string value + continue + if match.group(2): # if comments + comment_index = match.start(2) + break + # if comments, then delete them + if comment_index != -1: + json_line = json_line[:comment_index].rstrip() + new_arr.append(json_line) output = "\n".join(new_arr) return output From a68c3442bcff09864409ed47a02bbcc476657d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=85=81=E6=9D=83?= Date: Sun, 28 Jan 2024 10:39:00 +0800 Subject: [PATCH 09/35] Refactor get_choice_delta_text for safer dict access --- metagpt/provider/base_llm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagpt/provider/base_llm.py b/metagpt/provider/base_llm.py index a50cdacd9..47c527b97 100644 --- a/metagpt/provider/base_llm.py +++ b/metagpt/provider/base_llm.py @@ -91,7 +91,7 @@ class BaseLLM(ABC): def get_choice_delta_text(self, rsp: dict) -> str: """Required to provide the first text of stream choice""" - return rsp.get("choices")[0]["delta"]["content"] + return rsp.get("choices", [{}])[0].get("delta", {}).get("content", "") def get_choice_function(self, rsp: dict) -> dict: """Required to provide the first function of choice From 06b4e4767a9ab7a74d8f293b215d644d1cda71a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Mon, 29 Jan 2024 10:14:09 +0800 Subject: [PATCH 10/35] feat: generate_repo return ProjectRepo --- metagpt/startup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/metagpt/startup.py b/metagpt/startup.py index 000b3c5d4..4a077cab7 100644 --- a/metagpt/startup.py +++ b/metagpt/startup.py @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- + import asyncio import shutil from pathlib import Path @@ -9,6 +10,7 @@ import typer from metagpt.config2 import config from metagpt.const import CONFIG_ROOT, METAGPT_ROOT from metagpt.context import Context +from metagpt.utils.project_repo import ProjectRepo app = typer.Typer(add_completion=False, pretty_exceptions_show_locals=False) @@ -26,7 +28,7 @@ def generate_repo( reqa_file, max_auto_summarize_code, recover_path, -): +) -> ProjectRepo: """Run the startup logic. Can be called from CLI or other Python scripts.""" from metagpt.roles import ( Architect, @@ -67,6 +69,8 @@ def generate_repo( company.run_project(idea) asyncio.run(company.run(n_round=n_round)) + return ctx.repo + @app.command("", help="Start a new project.") def startup( From 41907b1fe332906c542168d2f04fd93ef91bf122 Mon Sep 17 00:00:00 2001 From: geekan Date: Wed, 31 Jan 2024 13:57:32 +0800 Subject: [PATCH 11/35] add action graph, solver, search space. --- metagpt/actions/action_graph.py | 58 ++++++++ metagpt/actions/action_node.py | 159 ++++++++++++---------- metagpt/strategy/search_space.py | 20 +++ metagpt/strategy/solver.py | 77 +++++++++++ tests/data/rsp_cache.json | 37 ++++- tests/metagpt/actions/test_action_node.py | 43 +++++- tests/metagpt/strategy/test_solver.py | 47 +++++++ 7 files changed, 366 insertions(+), 75 deletions(-) create mode 100644 metagpt/actions/action_graph.py create mode 100644 metagpt/strategy/search_space.py create mode 100644 metagpt/strategy/solver.py create mode 100644 tests/metagpt/strategy/test_solver.py diff --git a/metagpt/actions/action_graph.py b/metagpt/actions/action_graph.py new file mode 100644 index 000000000..8570778c7 --- /dev/null +++ b/metagpt/actions/action_graph.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2024/1/30 13:52 +@Author : alexanderwu +@File : action_graph.py +""" +from __future__ import annotations + +# from metagpt.actions.action_node import ActionNode + + +class ActionGraph: + """ActionGraph: 用于定义一个图,图中的节点是 ActionNode 实例,节点间的依赖关系是有向边。""" + + def __init__(self): + self.nodes = {} + self.edges = {} + self.execution_order = [] + + def add_node(self, node): + """ + 添加一个节点到图中。 + :param node: ActionNode 实例 + """ + self.nodes[node.key] = node + + def add_edge(self, from_node: "ActionNode", to_node: "ActionNode"): + """ + 定义节点间的依赖关系。 + :param from_node: 节点标识 + :param to_node: 节点标识 + """ + if from_node.key not in self.edges: + self.edges[from_node.key] = [] + self.edges[from_node.key].append(to_node.key) + from_node.add_next(to_node) + to_node.add_prev(from_node) + + def topological_sort(self): + """ + 实现拓扑排序来确定执行顺序。 + """ + visited = set() + stack = [] + + def visit(k): + if k not in visited: + visited.add(k) + if k in self.edges: + for next_node in self.edges[k]: + visit(next_node) + stack.insert(0, k) + + for key in self.nodes: + visit(key) + + self.execution_order = stack diff --git a/metagpt/actions/action_node.py b/metagpt/actions/action_node.py index 162ab90eb..a3efb214e 100644 --- a/metagpt/actions/action_node.py +++ b/metagpt/actions/action_node.py @@ -9,6 +9,7 @@ NOTE: You should use typing.List instead of list to do type annotation. Because we can use typing to extract the type of the node, but we cannot use built-in list to extract. """ import json +import typing from enum import Enum from typing import Any, Dict, List, Optional, Tuple, Type, Union @@ -39,7 +40,6 @@ TAG = "CONTENT" LANGUAGE_CONSTRAINT = "Language: Please use the same language as Human INPUT." FORMAT_CONSTRAINT = f"Format: output wrapped inside [{TAG}][/{TAG}] like format example, nothing else." - SIMPLE_TEMPLATE = """ ## context {context} @@ -131,6 +131,8 @@ class ActionNode: # Action Input key: str # Product Requirement / File list / Code + func: typing.Callable # 与节点相关联的函数或LLM调用 + params: Dict[str, Type] # 输入参数的字典,键为参数名,值为参数类型 expected_type: Type # such as str / int / float etc. # context: str # everything in the history. instruction: str # the instructions should be followed. @@ -140,6 +142,10 @@ class ActionNode: content: str instruct_content: BaseModel + # For ActionGraph + prevs: List["ActionNode"] # previous nodes + nexts: List["ActionNode"] # next nodes + def __init__( self, key: str, @@ -157,6 +163,8 @@ class ActionNode: self.content = content self.children = children if children is not None else {} self.schema = schema + self.prevs = [] + self.nexts = [] def __str__(self): return ( @@ -167,6 +175,14 @@ class ActionNode: def __repr__(self): return self.__str__() + def add_prev(self, node: "ActionNode"): + """增加前置ActionNode""" + self.prevs.append(node) + + def add_next(self, node: "ActionNode"): + """增加后置ActionNode""" + self.nexts.append(node) + def add_child(self, node: "ActionNode"): """增加子ActionNode""" self.children[node.key] = node @@ -186,41 +202,38 @@ class ActionNode: obj.add_children(nodes) return obj - def get_children_mapping_old(self, exclude=None) -> Dict[str, Tuple[Type, Any]]: - """获得子ActionNode的字典,以key索引""" + def _get_children_mapping(self, exclude=None) -> Dict[str, Any]: + """获得子ActionNode的字典,以key索引,支持多级结构。""" exclude = exclude or [] - return {k: (v.expected_type, ...) for k, v in self.children.items() if k not in exclude} - def get_children_mapping(self, exclude=None) -> Dict[str, Tuple[Type, Any]]: - """获得子ActionNode的字典,以key索引,支持多级结构""" - exclude = exclude or [] - mapping = {} - - def _get_mapping(node: "ActionNode", prefix: str = ""): + def _get_mapping(node: "ActionNode") -> Dict[str, Any]: + mapping = {} for key, child in node.children.items(): if key in exclude: continue - full_key = f"{prefix}{key}" - mapping[full_key] = (child.expected_type, ...) - _get_mapping(child, prefix=f"{full_key}.") + # 对于嵌套的子节点,递归调用 _get_mapping + if child.children: + mapping[key] = _get_mapping(child) + else: + mapping[key] = (child.expected_type, Field(default=child.example, description=child.instruction)) + return mapping - _get_mapping(self) - return mapping + return _get_mapping(self) - def get_self_mapping(self) -> Dict[str, Tuple[Type, Any]]: + def _get_self_mapping(self) -> Dict[str, Tuple[Type, Any]]: """get self key: type mapping""" return {self.key: (self.expected_type, ...)} def get_mapping(self, mode="children", exclude=None) -> Dict[str, Tuple[Type, Any]]: """get key: type mapping under mode""" if mode == "children" or (mode == "auto" and self.children): - return self.get_children_mapping(exclude=exclude) - return {} if exclude and self.key in exclude else self.get_self_mapping() + return self._get_children_mapping(exclude=exclude) + return {} if exclude and self.key in exclude else self._get_self_mapping() @classmethod @register_action_outcls def create_model_class(cls, class_name: str, mapping: Dict[str, Tuple[Type, Any]]): - """基于pydantic v1的模型动态生成,用来检验结果类型正确性""" + """基于pydantic v2的模型动态生成,用来检验结果类型正确性""" def check_fields(cls, values): required_fields = set(mapping.keys()) @@ -235,7 +248,17 @@ class ActionNode: validators = {"check_missing_fields_validator": model_validator(mode="before")(check_fields)} - new_class = create_model(class_name, __validators__=validators, **mapping) + new_fields = {} + for field_name, field_value in mapping.items(): + if isinstance(field_value, dict): + # 对于嵌套结构,递归创建模型类 + nested_class_name = f"{class_name}_{field_name}" + nested_class = cls.create_model_class(nested_class_name, field_value) + new_fields[field_name] = (nested_class, ...) + else: + new_fields[field_name] = field_value + + new_class = create_model(class_name, __validators__=validators, **new_fields) return new_class def create_class(self, mode: str = "auto", class_name: str = None, exclude=None): @@ -243,39 +266,48 @@ class ActionNode: mapping = self.get_mapping(mode=mode, exclude=exclude) return self.create_model_class(class_name, mapping) - def create_children_class(self, exclude=None): + def _create_children_class(self, exclude=None): """使用object内有的字段直接生成model_class""" class_name = f"{self.key}_AN" - mapping = self.get_children_mapping(exclude=exclude) + mapping = self._get_children_mapping(exclude=exclude) return self.create_model_class(class_name, mapping) def to_dict(self, format_func=None, mode="auto", exclude=None) -> Dict: """将当前节点与子节点都按照node: format的格式组织成字典""" + nodes = self._to_dict(format_func=format_func, mode=mode, exclude=exclude) + if not isinstance(nodes, dict): + nodes = {self.key: nodes} + return nodes - # 如果没有提供格式化函数,使用默认的格式化方式 + def _to_dict(self, format_func=None, mode="auto", exclude=None) -> Dict: + """将当前节点与子节点都按照node: format的格式组织成字典""" + + # 如果没有提供格式化函数,则使用默认的格式化函数 if format_func is None: - format_func = lambda node: f"{node.instruction}" + format_func = lambda node: node.instruction # 使用提供的格式化函数来格式化当前节点的值 formatted_value = format_func(self) # 创建当前节点的键值对 - if mode == "children" or (mode == "auto" and self.children): - node_dict = {} + if (mode == "children" or mode == "auto") and self.children: + node_value = {} else: - node_dict = {self.key: formatted_value} + node_value = formatted_value if mode == "root": - return node_dict + return {self.key: node_value} - # 遍历子节点并递归调用 to_dict 方法 + # 递归处理子节点 exclude = exclude or [] - for _, child_node in self.children.items(): - if child_node.key in exclude: + for child_key, child_node in self.children.items(): + if child_key in exclude: continue - node_dict.update(child_node.to_dict(format_func)) + # 递归调用 to_dict 方法并更新节点字典 + child_dict = child_node._to_dict(format_func, mode, exclude) + node_value[child_key] = child_dict - return node_dict + return node_value def update_instruct_content(self, incre_data: dict[str, Any]): assert self.instruct_content @@ -344,6 +376,17 @@ class ActionNode: if schema == "raw": return context + "\n\n## Actions\n" + LANGUAGE_CONSTRAINT + "\n" + self.instruction + ### 直接使用 pydantic BaseModel 生成 instruction 与 example,仅限 JSON + # child_class = self._create_children_class() + # node_schema = child_class.model_json_schema() + # defaults = { + # k: str(v) + # for k, v in child_class.model_fields.items() + # if k not in exclude + # } + # instruction = node_schema + # example = json.dumps(defaults, indent=4) + # FIXME: json instruction会带来格式问题,如:"Project name": "web_2048 # 项目名称使用下划线", # compile example暂时不支持markdown instruction = self.compile_instruction(schema="markdown", mode=mode, exclude=exclude) @@ -454,7 +497,7 @@ class ActionNode: continue child = await i.simple_fill(schema=schema, mode=mode, timeout=timeout, exclude=exclude) tmp.update(child.instruct_content.model_dump()) - cls = self.create_children_class() + cls = self._create_children_class() self.instruct_content = cls(**tmp) return self @@ -645,49 +688,19 @@ class ActionNode: ActionNode: The root node of the created ActionNode tree. """ key = key or model.__name__ - root_node = cls(key=model.__name__, expected_type=Type[model], instruction="", example="") + root_node = cls(key=key, expected_type=Type[model], instruction="", example="") - for field_name, field_model in model.model_fields.items(): - # Extracting field details - expected_type = field_model.annotation - instruction = field_model.description or "" - example = field_model.default + for field_name, field_info in model.model_fields.items(): + field_type = field_info.annotation + description = field_info.description + default = field_info.default - # Check if the field is a Pydantic model itself. - # Use isinstance to avoid typing.List, typing.Dict, etc. (they are instances of type, not subclasses) - if isinstance(expected_type, type) and issubclass(expected_type, BaseModel): - # Recursively process the nested model - child_node = cls.from_pydantic(expected_type, key=field_name) + # Recursively handle nested models if needed + if not isinstance(field_type, typing._GenericAlias) and issubclass(field_type, BaseModel): + child_node = cls.from_pydantic(field_type, key=field_name) else: - child_node = cls(key=field_name, expected_type=expected_type, instruction=instruction, example=example) + child_node = cls(key=field_name, expected_type=field_type, instruction=description, example=default) root_node.add_child(child_node) return root_node - - -class ToolUse(BaseModel): - tool_name: str = Field(default="a", description="tool name", examples=[]) - - -class Task(BaseModel): - task_id: int = Field(default="1", description="task id", examples=[1, 2, 3]) - name: str = Field(default="Get data from ...", description="task name", examples=[]) - dependent_task_ids: List[int] = Field(default=[], description="dependent task ids", examples=[1, 2, 3]) - tool: ToolUse = Field(default=ToolUse(), description="tool use", examples=[]) - - -class Tasks(BaseModel): - tasks: List[Task] = Field(default=[], description="tasks", examples=[]) - - -if __name__ == "__main__": - node = ActionNode.from_pydantic(Tasks) - print("Tasks") - print(Tasks.model_json_schema()) - print("Task") - print(Task.model_json_schema()) - print(node) - prompt = node.compile(context="") - node.create_children_class() - print(prompt) diff --git a/metagpt/strategy/search_space.py b/metagpt/strategy/search_space.py new file mode 100644 index 000000000..c643a2f11 --- /dev/null +++ b/metagpt/strategy/search_space.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2024/1/30 17:15 +@Author : alexanderwu +@File : search_space.py +""" + + +class SearchSpace: + """SearchSpace: 用于定义一个搜索空间,搜索空间中的节点是 ActionNode 类。""" + + def __init__(self): + self.search_space = {} + + def add_node(self, node): + self.search_space[node.key] = node + + def get_node(self, key): + return self.search_space[key] diff --git a/metagpt/strategy/solver.py b/metagpt/strategy/solver.py new file mode 100644 index 000000000..bd21dda3e --- /dev/null +++ b/metagpt/strategy/solver.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2024/1/30 17:13 +@Author : alexanderwu +@File : solver.py +""" +from abc import abstractmethod + +from metagpt.actions.action_graph import ActionGraph +from metagpt.provider.base_llm import BaseLLM +from metagpt.strategy.search_space import SearchSpace + + +class BaseSolver: + """AbstractSolver: 用于定义一个抽象求解器,求解器中的搜索空间是 SearchSpace 实例,图是 ActionGraph 实例。""" + + def __init__(self, graph: ActionGraph, search_space: SearchSpace, llm: BaseLLM, context): + """ + :param graph: ActionGraph 实例 + :param search_space: SearchSpace 实例 + :param llm: BaseLLM + :param context: Context + """ + self.graph = graph + self.search_space = search_space + self.llm = llm + self.context = context + + @abstractmethod + async def solve(self): + """求解器的求解方法。""" + + +class NaiveSolver(BaseSolver): + """NaiveSolver: 直接循序执行给定的 graph""" + + async def solve(self): + self.graph.topological_sort() + for key in self.graph.execution_order: + op = self.graph.nodes[key] + await op.fill(self.context, self.llm, mode="root") + + +class TOTSolver(BaseSolver): + """TOTSolver: 通过拓扑排序执行给定的 graph""" + + async def solve(self): + raise NotImplementedError + + +class CodeInterpreterSolver(BaseSolver): + """CodeInterpreterSolver: 通过代码解释器执行给定的 graph""" + + async def solve(self): + raise NotImplementedError + + +class ReActSolver(BaseSolver): + """ReActSolver: 通过 ReAct 执行给定的 graph""" + + async def solve(self): + raise NotImplementedError + + +class IOSolver(BaseSolver): + """IOSolver: 通过 IO 执行给定的 graph""" + + async def solve(self): + raise NotImplementedError + + +class COTSolver(BaseSolver): + """COTSolver: 通过cot执行给定的 graph""" + + async def solve(self): + raise NotImplementedError diff --git a/tests/data/rsp_cache.json b/tests/data/rsp_cache.json index 92a600b67..998eb714f 100644 --- a/tests/data/rsp_cache.json +++ b/tests/data/rsp_cache.json @@ -277,5 +277,40 @@ "Given an instruction and several choices, decide which choice is most promising. Analyze each choice in detail, then conclude in the last line \"The best choice is {s}\", where s the integer id of the choice.\nChoice 3:\nEnsure there is enough space around you to avoid any obstacles.\n": "Choice 3: \n\nAnalyzing this choice, ensuring there is enough space around you to avoid any obstacles is a crucial step in maintaining safety and preventing accidents. By creating a buffer zone, you can react to unexpected obstacles or changes in the environment without risking collisions or other hazards.\n\nThe best choice is 3.", "Given an instruction and several choices, decide which choice is most promising. Analyze each choice in detail, then conclude in the last line \"The best choice is {s}\", where s the integer id of the choice.\nChoice 2:\nConsider a flat and stable surface, such as a grassy field or a gym mat.\n": "Choice 2: Considering a flat and stable surface, such as a grassy field or a gym mat, is the most promising option. This choice provides a safe and secure environment for the activity, reducing the risk of injury. A grassy field offers a natural and soft surface, while a gym mat provides cushioning and stability. Both options allow for comfortable movement and can accommodate various physical activities.\n\nThe best choice is 2.", "Given an instruction and several choices, decide which choice is most promising. Analyze each choice in detail, then conclude in the last line \"The best choice is {s}\", where s the integer id of the choice.\nChoice 4:\nPractice near a wall or with a spotter for safety.\n": "Choice 4: \n\nPractice near a wall or with a spotter for safety.\n\nAnalyzing this choice, practicing near a wall or with a spotter provides a safety measure to prevent accidents or injuries. When practicing a new skill or exercise, having a wall nearby can provide support and stability, reducing the risk of falling or losing balance. Similarly, having a spotter can offer assistance and guidance, ensuring that the practice is done safely and effectively.\n\nThe best choice is 4.", - "### Requirements\n1. Please summarize the latest dialogue based on the reference information (secondary) and dialogue history (primary). Do not include text that is irrelevant to the conversation.\n- The context is for reference only. If it is irrelevant to the user's search request history, please reduce its reference and usage.\n2. If there are citable links in the context, annotate them in the main text in the format [main text](citation link). If there are none in the context, do not write links.\n3. The reply should be graceful, clear, non-repetitive, smoothly written, and of moderate length, in {LANG}.\n\n### Dialogue History (For example)\nA: MLOps competitors\n\n### Current Question (For example)\nA: MLOps competitors\n\n### Current Reply (For example)\n1. Alteryx Designer: etc. if any\n2. Matlab: ditto\n3. IBM SPSS Statistics\n4. RapidMiner Studio\n5. DataRobot AI Platform\n6. Databricks Lakehouse Platform\n7. Amazon SageMaker\n8. Dataiku\n#SYSTEM_MSG_END#\n### Reference Information\nABC cleanser is preferred by many with oily skin.\nL'Oreal is a popular brand with many positive reviews.\n\n### Dialogue History\n\nuser: Which facial cleanser is good for oily skin?\n\n### Current Question\nuser: Which facial cleanser is good for oily skin?\n\n### Current Reply: Based on the information, please write the reply to the Question\n\n\n": "Based on the information provided, ABC cleanser is preferred by many with oily skin. It is a popular choice for individuals with oily skin due to its effectiveness. Additionally, L'Oreal is a well-known brand with many positive reviews, and they offer a range of products suitable for oily skin. Both of these options could be good choices for individuals with oily skin." + "### Requirements\n1. Please summarize the latest dialogue based on the reference information (secondary) and dialogue history (primary). Do not include text that is irrelevant to the conversation.\n- The context is for reference only. If it is irrelevant to the user's search request history, please reduce its reference and usage.\n2. If there are citable links in the context, annotate them in the main text in the format [main text](citation link). If there are none in the context, do not write links.\n3. The reply should be graceful, clear, non-repetitive, smoothly written, and of moderate length, in {LANG}.\n\n### Dialogue History (For example)\nA: MLOps competitors\n\n### Current Question (For example)\nA: MLOps competitors\n\n### Current Reply (For example)\n1. Alteryx Designer: etc. if any\n2. Matlab: ditto\n3. IBM SPSS Statistics\n4. RapidMiner Studio\n5. DataRobot AI Platform\n6. Databricks Lakehouse Platform\n7. Amazon SageMaker\n8. Dataiku\n#SYSTEM_MSG_END#\n### Reference Information\nABC cleanser is preferred by many with oily skin.\nL'Oreal is a popular brand with many positive reviews.\n\n### Dialogue History\n\nuser: Which facial cleanser is good for oily skin?\n\n### Current Question\nuser: Which facial cleanser is good for oily skin?\n\n### Current Reply: Based on the information, please write the reply to the Question\n\n\n": "Based on the information provided, ABC cleanser is preferred by many with oily skin. It is a popular choice for individuals with oily skin due to its effectiveness. Additionally, L'Oreal is a well-known brand with many positive reviews, and they offer a range of products suitable for oily skin. Both of these options could be good choices for individuals with oily skin.", + "\n## context\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Required Python packages\": [\n \"flask==1.1.2\",\n \"bcrypt==3.2.0\"\n ],\n \"Required Other language third-party packages\": [\n \"No third-party dependencies required\"\n ],\n \"Logic Analysis\": [\n [\n \"game.py\",\n \"Contains Game class and ... functions\"\n ],\n [\n \"main.py\",\n \"Contains main function, from game import Game\"\n ]\n ],\n \"Task list\": [\n \"game.py\",\n \"main.py\"\n ],\n \"Full API spec\": \"openapi: 3.0.0 ...\",\n \"Shared Knowledge\": \"`game.py` contains functions shared across the project.\",\n \"Anything UNCLEAR\": \"Clarification needed on how to start and initialize third-party libraries.\"\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Required Python packages: typing.List[str] # Provide required Python packages in requirements.txt format.\n- Required Other language third-party packages: typing.List[str] # List down the required packages for languages other than Python.\n- Logic Analysis: typing.List[typing.List[str]] # Provide a list of files with the classes/methods/functions to be implemented, including dependency analysis and imports.\n- Task list: typing.List[str] # Break down the tasks into a list of filenames, prioritized by dependency order.\n- Full API spec: # Describe all APIs using OpenAPI 3.0 spec that may be used by both frontend and backend. If front-end and back-end communication is not required, leave it blank.\n- Shared Knowledge: # Detail any shared knowledge, like common utility functions or configuration variables.\n- Anything UNCLEAR: # Mention any unclear aspects in the project management context and try to clarify them.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Required Python packages\": [\n \"pygame==2.0.1\"\n ],\n \"Required Other language third-party packages\": [\n \"No third-party dependencies required\"\n ],\n \"Logic Analysis\": [\n [\n \"game.py\",\n \"Contains Game class and ... functions\"\n ],\n [\n \"main.py\",\n \"Contains main function, from game import Game\"\n ]\n ],\n \"Task list\": [\n \"game.py\",\n \"main.py\"\n ],\n \"Full API spec\": \"\",\n \"Shared Knowledge\": \"`game.py` contains functions shared across the project.\",\n \"Anything UNCLEAR\": \"Clarification needed on the scoring system and how the game over condition will be handled.\"\n}\n[/CONTENT]", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Task\n{\"Required Python packages\":[\"pygame==2.0.1\"],\"Required Other language third-party packages\":[\"No third-party dependencies required\"],\"Logic Analysis\":[[\"game.py\",\"Contains Game class and ... functions\"],[\"main.py\",\"Contains main function, from game import Game\"]],\"Task list\":[\"game.py\",\"main.py\"],\"Full API spec\":\"\",\"Shared Knowledge\":\"`game.py` contains functions shared across the project.\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: game.py\n```python\n## game.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: game.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## game.py\n\nimport pygame\nimport random\n\nclass Snake:\n def __init__(self, start_pos: tuple, length: int, direction: str):\n self.body = [start_pos]\n self.direction = direction\n self.length = length\n\n def move(self):\n head = self.body[0]\n x, y = head\n if self.direction == 'UP':\n new_head = (x, y - 10)\n elif self.direction == 'DOWN':\n new_head = (x, y + 10)\n elif self.direction == 'LEFT':\n new_head = (x - 10, y)\n elif self.direction == 'RIGHT':\n new_head = (x + 10, y)\n self.body = [new_head] + self.body[:-1]\n\n def change_direction(self, new_direction: str):\n if new_direction in ['UP', 'DOWN', 'LEFT', 'RIGHT']:\n self.direction = new_direction\n\n def grow(self):\n self.length += 1\n self.body.append((0, 0)) # Set default value\n\nclass Game:\n def __init__(self):\n self.snake = Snake((100, 50), 1, 'RIGHT') # Set default value\n self.food = (200, 200) # Set default value\n self.score = 0 # Set default value\n\n def update(self):\n self.snake.move()\n if self.snake.body[0] == self.food:\n self.snake.grow()\n self.food = (random.randrange(0, 400, 10), random.randrange(0, 400, 10)) # Set default value\n\n def draw(self):\n pass # Set default value\n\n def handle_input(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n pygame.quit()\n quit()\n if event.type == pygame.KEYDOWN:\n if event.key == pygame.K_UP:\n self.snake.change_direction('UP')\n elif event.key == pygame.K_DOWN:\n self.snake.change_direction('DOWN')\n elif event.key == pygame.K_LEFT:\n self.snake.change_direction('LEFT')\n elif event.key == pygame.K_RIGHT:\n self.snake.change_direction('RIGHT')\n\n def restart(self):\n self.snake = Snake((100, 50), 1, 'RIGHT') # Set default value\n self.food = (200, 200) # Set default value\n self.score = 0 # Set default value\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Task\n{\"Required Python packages\":[\"pygame==2.0.1\"],\"Required Other language third-party packages\":[\"No third-party dependencies required\"],\"Logic Analysis\":[[\"game.py\",\"Contains Game class and ... functions\"],[\"main.py\",\"Contains main function, from game import Game\"]],\"Task list\":[\"game.py\",\"main.py\"],\"Full API spec\":\"\",\"Shared Knowledge\":\"`game.py` contains functions shared across the project.\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Code Files\n\n\n\n## Code to be Reviewed: game.py\n```Code\n## game.py\n\nimport pygame\nimport random\n\nclass Snake:\n def __init__(self, start_pos: tuple, length: int, direction: str):\n self.body = [start_pos]\n self.direction = direction\n self.length = length\n\n def move(self):\n head = self.body[0]\n x, y = head\n if self.direction == 'UP':\n new_head = (x, y - 10)\n elif self.direction == 'DOWN':\n new_head = (x, y + 10)\n elif self.direction == 'LEFT':\n new_head = (x - 10, y)\n elif self.direction == 'RIGHT':\n new_head = (x + 10, y)\n self.body = [new_head] + self.body[:-1]\n\n def change_direction(self, new_direction: str):\n if new_direction in ['UP', 'DOWN', 'LEFT', 'RIGHT']:\n self.direction = new_direction\n\n def grow(self):\n self.length += 1\n self.body.append((0, 0)) # Set default value\n\nclass Game:\n def __init__(self):\n self.snake = Snake((100, 50), 1, 'RIGHT') # Set default value\n self.food = (200, 200) # Set default value\n self.score = 0 # Set default value\n\n def update(self):\n self.snake.move()\n if self.snake.body[0] == self.food:\n self.snake.grow()\n self.food = (random.randrange(0, 400, 10), random.randrange(0, 400, 10)) # Set default value\n\n def draw(self):\n pass # Set default value\n\n def handle_input(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n pygame.quit()\n quit()\n if event.type == pygame.KEYDOWN:\n if event.key == pygame.K_UP:\n self.snake.change_direction('UP')\n elif event.key == pygame.K_DOWN:\n self.snake.change_direction('DOWN')\n elif event.key == pygame.K_LEFT:\n self.snake.change_direction('LEFT')\n elif event.key == pygame.K_RIGHT:\n self.snake.change_direction('RIGHT')\n\n def restart(self):\n self.snake = Snake((100, 50), 1, 'RIGHT') # Set default value\n self.food = (200, 200) # Set default value\n self.score = 0 # Set default value\n\n```\n\n\n\n# Format example 1\n## Code Review: game.py\n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: game.py\n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: game.py\n1. The code is implemented as per the requirements. The Snake and Game classes are defined, and the necessary methods for updating, drawing, handling input, and restarting the game are implemented.\n2. The code logic is correct. The Snake class methods for moving, changing direction, and growing the snake are implemented properly. The Game class methods for updating the game state, handling input, and restarting the game are also correctly implemented.\n3. The existing code follows the defined \"Data structures and interfaces\" with the Snake and Game classes and their respective methods.\n4. All necessary functions are implemented as per the requirements.\n5. The necessary pre-dependencies, including the pygame package, are imported.\n6. The methods from other files are not being reused in the current code.\n\n## Actions\nNo actions required.\n\n## Code Review Result\nLGTM", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Task\n{\"Required Python packages\":[\"pygame==2.0.1\"],\"Required Other language third-party packages\":[\"No third-party dependencies required\"],\"Logic Analysis\":[[\"game.py\",\"Contains Game class and ... functions\"],[\"main.py\",\"Contains main function, from game import Game\"]],\"Task list\":[\"game.py\",\"main.py\"],\"Full API spec\":\"\",\"Shared Knowledge\":\"`game.py` contains functions shared across the project.\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: main.py\n```python\n## main.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: main.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## main.py\n\nfrom game import Game\n\ndef main():\n game = Game()\n running = True\n\n while running:\n game.update()\n game.draw()\n game.handle_input()\n\n if game.game_over:\n game.restart()\n\nif __name__ == \"__main__\":\n main()\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Task\n{\"Required Python packages\":[\"pygame==2.0.1\"],\"Required Other language third-party packages\":[\"No third-party dependencies required\"],\"Logic Analysis\":[[\"game.py\",\"Contains Game class and ... functions\"],[\"main.py\",\"Contains main function, from game import Game\"]],\"Task list\":[\"game.py\",\"main.py\"],\"Full API spec\":\"\",\"Shared Knowledge\":\"`game.py` contains functions shared across the project.\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Code Files\n\n\n\n## Code to be Reviewed: main.py\n```Code\n## main.py\n\nfrom game import Game\n\ndef main():\n game = Game()\n running = True\n\n while running:\n game.update()\n game.draw()\n game.handle_input()\n\n if game.game_over:\n game.restart()\n\nif __name__ == \"__main__\":\n main()\n\n```\n\n\n\n# Format example 1\n## Code Review: main.py\n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: main.py\n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: main.py\n1. Yes, the code is implemented as per the requirements.\n2. Yes, the code logic is completely correct.\n3. Yes, the existing code follows the \"Data structures and interfaces\".\n4. No, the `game_over` condition is not handled in the code. To achieve it, we need to add the implementation of the `game_over` condition in the `Game` class.\n5. Yes, all necessary pre-dependencies have been imported.\n6. Yes, methods from other files are being reused correctly.\n\n## Actions\n4. Implement the `game_over` condition in the `Game` class to handle the game over scenario.\n\n## Code Review Result\nLBTM", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Task\n{\"Required Python packages\":[\"pygame==2.0.1\"],\"Required Other language third-party packages\":[\"No third-party dependencies required\"],\"Logic Analysis\":[[\"game.py\",\"Contains Game class and ... functions\"],[\"main.py\",\"Contains main function, from game import Game\"]],\"Task list\":[\"game.py\",\"main.py\"],\"Full API spec\":\"\",\"Shared Knowledge\":\"`game.py` contains functions shared across the project.\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Code Files\n\n\n\n## Code to be Reviewed: main.py\n```Code\n## main.py\n\nfrom game import Game\n\ndef main():\n game = Game()\n running = True\n\n while running:\n game.update()\n game.draw()\n game.handle_input()\n\n if game.game_over:\n game.restart()\n\nif __name__ == \"__main__\":\n main()\n\n```\n\n## Code Review: main.py\n1. Yes, the code is implemented as per the requirements.\n2. Yes, the code logic is completely correct.\n3. Yes, the existing code follows the \"Data structures and interfaces\".\n4. No, the `game_over` condition is not handled in the code. To achieve it, we need to add the implementation of the `game_over` condition in the `Game` class.\n5. Yes, all necessary pre-dependencies have been imported.\n6. Yes, methods from other files are being reused correctly.\n\n## Actions\n4. Implement the `game_over` condition in the `Game` class to handle the game over scenario.\n\n## Code Review Result\nLBTM\n\n# Instruction: rewrite code based on the Code Review and Actions\n## Rewrite Code: CodeBlock. If it still has some bugs, rewrite main.py with triple quotes. Do your utmost to optimize THIS SINGLE FILE. Return all completed codes and prohibit the return of unfinished codes.\n```Code\n## main.py\n...\n```\n": "```Code\n## main.py\n\nfrom game import Game\n\ndef main():\n game = Game()\n running = True\n\n while running:\n game.update()\n game.draw()\n game.handle_input()\n\n if game.game_over():\n game.restart()\n\nif __name__ == \"__main__\":\n main()\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n{\"Implementation approach\":\"We will use the Pygame library to create the game and handle user input. The game logic will be implemented using Python classes and functions.\",\"File list\":[\"main.py\",\"game.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Game {\\n -snake: list\\n -food: tuple\\n -score: int\\n +__init__()\\n +update()\\n +draw()\\n +handle_input()\\n +restart()\\n }\\n class Snake {\\n -body: list\\n -direction: str\\n +__init__(start_pos: tuple, length: int, direction: str)\\n +move()\\n +change_direction(new_direction: str)\\n +grow()\\n }\\n Game --> Snake\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: initialize game\\n G->>G: update game state\\n G->>G: draw game\\n G->>G: handle user input\\n G->>G: restart game\\n\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Task\n{\"Required Python packages\":[\"pygame==2.0.1\"],\"Required Other language third-party packages\":[\"No third-party dependencies required\"],\"Logic Analysis\":[[\"game.py\",\"Contains Game class and ... functions\"],[\"main.py\",\"Contains main function, from game import Game\"]],\"Task list\":[\"game.py\",\"main.py\"],\"Full API spec\":\"\",\"Shared Knowledge\":\"`game.py` contains functions shared across the project.\",\"Anything UNCLEAR\":\"Clarification needed on the scoring system and how the game over condition will be handled.\"}\n\n## Code Files\n\n\n\n## Code to be Reviewed: main.py\n```Code\n## main.py\n\nfrom game import Game\n\ndef main():\n game = Game()\n running = True\n\n while running:\n game.update()\n game.draw()\n game.handle_input()\n\n if game.game_over():\n game.restart()\n\nif __name__ == \"__main__\":\n main()\n\n```\n\n\n\n# Format example 1\n## Code Review: main.py\n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: main.py\n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: main.py\n1. The code is implemented as per the requirements. It initializes the game, updates the game state, draws the game, handles user input, and restarts the game when it's over.\n2. The code logic is correct, and it follows the expected flow of the game.\n3. The existing code follows the \"Data structures and interfaces\" as it uses classes and methods as described in the class diagram.\n4. All necessary functions are implemented as per the requirements.\n5. The necessary pre-dependencies have been imported, as the `pygame` package is imported.\n6. The methods from other files are being reused correctly.\n\n## Actions\npass\n\n## Code Review Result\nLGTM", + "\n## context\n{'Implementation approach': '我们将使用Python编程语言,并选择合适的开源框架来实现贪吃蛇游戏。我们将分析需求中的难点,并选择合适的开源框架来简化开发流程。', 'File list': ['main.py', 'game.py'], 'Data structures and interfaces': '\\nclassDiagram\\n class Game {\\n -int width\\n -int height\\n -int score\\n -int speed\\n -List snake\\n -Point food\\n +__init__(width: int, height: int, speed: int)\\n +start_game()\\n +change_direction(direction: str)\\n +game_over()\\n +update_snake()\\n +update_food()\\n +check_collision()\\n }\\n class Point {\\n -int x\\n -int y\\n +__init__(x: int, y: int)\\n }\\n Game --> Point\\n', 'Program call flow': '\\nsequenceDiagram\\n participant M as Main\\n participant G as Game\\n M->>G: start_game()\\n M->>G: change_direction(direction)\\n G->>G: update_snake()\\n G->>G: update_food()\\n G->>G: check_collision()\\n G-->>G: game_over()\\n', 'Anything UNCLEAR': ''}\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Required Python packages\": [\n \"flask==1.1.2\",\n \"bcrypt==3.2.0\"\n ],\n \"Required Other language third-party packages\": [\n \"No third-party dependencies required\"\n ],\n \"Logic Analysis\": [\n [\n \"game.py\",\n \"Contains Game class and ... functions\"\n ],\n [\n \"main.py\",\n \"Contains main function, from game import Game\"\n ]\n ],\n \"Task list\": [\n \"game.py\",\n \"main.py\"\n ],\n \"Full API spec\": \"openapi: 3.0.0 ...\",\n \"Shared Knowledge\": \"`game.py` contains functions shared across the project.\",\n \"Anything UNCLEAR\": \"Clarification needed on how to start and initialize third-party libraries.\"\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Required Python packages: typing.List[str] # Provide required Python packages in requirements.txt format.\n- Required Other language third-party packages: typing.List[str] # List down the required packages for languages other than Python.\n- Logic Analysis: typing.List[typing.List[str]] # Provide a list of files with the classes/methods/functions to be implemented, including dependency analysis and imports.\n- Task list: typing.List[str] # Break down the tasks into a list of filenames, prioritized by dependency order.\n- Full API spec: # Describe all APIs using OpenAPI 3.0 spec that may be used by both frontend and backend. If front-end and back-end communication is not required, leave it blank.\n- Shared Knowledge: # Detail any shared knowledge, like common utility functions or configuration variables.\n- Anything UNCLEAR: # Mention any unclear aspects in the project management context and try to clarify them.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Required Python packages\": [\n \"pygame==2.0.1\"\n ],\n \"Required Other language third-party packages\": [\n \"No third-party dependencies required\"\n ],\n \"Logic Analysis\": [\n [\n \"game.py\",\n \"Contains Game class and related functions\"\n ],\n [\n \"main.py\",\n \"Contains the main function and imports Game from game.py\"\n ]\n ],\n \"Task list\": [\n \"game.py\",\n \"main.py\"\n ],\n \"Full API spec\": \"\",\n \"Shared Knowledge\": \"`game.py` contains functions shared across the project.\",\n \"Anything UNCLEAR\": \"\"\n}\n[/CONTENT]", + "\nNOTICE\nRole: You are a professional software engineer, and your main task is to review the code.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n-----\n# System Design\n```text\n\n{\"Implementation approach\": \"To develop this snake game, we will use the Python language and choose the Pygame library. Pygame is an open-source Python module collection specifically designed for writing video games. It provides functionalities such as displaying images and playing sounds, making it suitable for creating intuitive and responsive user interfaces. We will ensure efficient game logic to prevent any delays during gameplay. The scoring system will be simple, with the snake gaining points for each food it eats. We will use Pygame's event handling system to implement pause and resume functionality, as well as high-score tracking. The difficulty will increase by speeding up the snake's movement. In the initial version, we will focus on single-player mode and consider adding multiplayer mode and customizable skins in future updates. Based on the new requirement, we will also add a moving obstacle that appears randomly. If the snake eats this obstacle, the game will end. If the snake does not eat the obstacle, it will disappear after 5 seconds. For this, we need to add mechanisms for obstacle generation, movement, and disappearance in the game logic.\", \"Project_name\": \"snake_game\", \"File list\": [\"main.py\", \"game.py\", \"snake.py\", \"food.py\", \"obstacle.py\", \"scoreboard.py\", \"constants.py\", \"assets/styles.css\", \"assets/index.html\"], \"Data structures and interfaces\": \"```mermaid\n classDiagram\n class Game{\n +int score\n +int speed\n +bool game_over\n +bool paused\n +Snake snake\n +Food food\n +Obstacle obstacle\n +Scoreboard scoreboard\n +start_game() void\n +pause_game() void\n +resume_game() void\n +end_game() void\n +increase_difficulty() void\n +update() void\n +render() void\n Game()\n }\n class Snake{\n +list body_parts\n +str direction\n +bool grow\n +move() void\n +grow() void\n +check_collision() bool\n Snake()\n }\n class Food{\n +tuple position\n +spawn() void\n Food()\n }\n class Obstacle{\n +tuple position\n +int lifetime\n +bool active\n +spawn() void\n +move() void\n +check_collision() bool\n +disappear() void\n Obstacle()\n }\n class Scoreboard{\n +int high_score\n +update_score(int) void\n +reset_score() void\n +load_high_score() void\n +save_high_score() void\n Scoreboard()\n }\n class Constants{\n }\n Game \"1\" -- \"1\" Snake: has\n Game \"1\" -- \"1\" Food: has\n Game \"1\" -- \"1\" Obstacle: has\n Game \"1\" -- \"1\" Scoreboard: has\n ```\", \"Program call flow\": \"```sequenceDiagram\n participant M as Main\n participant G as Game\n participant S as Snake\n participant F as Food\n participant O as Obstacle\n participant SB as Scoreboard\n M->>G: start_game()\n loop game loop\n G->>S: move()\n G->>S: check_collision()\n G->>F: spawn()\n G->>O: spawn()\n G->>O: move()\n G->>O: check_collision()\n G->>O: disappear()\n G->>SB: update_score(score)\n G->>G: update()\n G->>G: render()\n alt if paused\n M->>G: pause_game()\n M->>G: resume_game()\n end\n alt if game_over\n G->>M: end_game()\n end\n end\n```\", \"Anything UNCLEAR\": \"There is no need for further clarification as the requirements are already clear.\"}\n\n```\n-----\n# Task\n```text\n\n{\"Required Python third-party packages\": [\"pygame==2.0.1\"], \"Required Other language third-party packages\": [\"No third-party packages required for other languages.\"], \"Full API spec\": \"\n openapi: 3.0.0\n info:\n title: Snake Game API\n version: \"1.0.0\"\n paths:\n /start:\n get:\n summary: Start the game\n responses:\n '200':\n description: Game started successfully\n /pause:\n get:\n summary: Pause the game\n responses:\n '200':\n description: Game paused successfully\n /resume:\n get:\n summary: Resume the game\n responses:\n '200':\n description: Game resumed successfully\n /end:\n get:\n summary: End the game\n responses:\n '200':\n description: Game ended successfully\n /score:\n get:\n summary: Get the current score\n responses:\n '200':\n description: Current score retrieved successfully\n /highscore:\n get:\n summary: Get the high score\n responses:\n '200':\n description: High score retrieved successfully\n components: {}\n \", \"Logic Analysis\": [[\"constants.py\", \"Contains all the constant values like screen size, colors, game speeds, etc. This should be implemented first as it provides the base values for other components.\"], [\"snake.py\", \"Contains the Snake class with methods for movement, growth, and collision detection. It is dependent on constants.py for configuration values.\"], [\"food.py\", \"Contains the Food class responsible for spawning food items on the screen. It is dependent on constants.py for configuration values.\"], [\"obstacle.py\", \"Contains the Obstacle class with methods for spawning, moving, and disappearing of obstacles, as well as collision detection with the snake. It is dependent on constants.py for configuration values.\"], [\"scoreboard.py\", \"Contains the Scoreboard class for updating, resetting, loading, and saving high scores. It may use constants.py for configuration values and depends on the game's scoring logic.\"], [\"game.py\", \"Contains the main Game class which includes the game loop and methods for starting, pausing, resuming, and ending the game. It is dependent on snake.py, food.py, obstacle.py, and scoreboard.py.\"], [\"main.py\", \"The entry point of the game that initializes the game and starts the game loop. It is dependent on game.py.\"]], \"Task list\": [\"constants.py\", \"snake.py\", \"food.py\", \"obstacle.py\", \"scoreboard.py\", \"game.py\", \"main.py\"], \"Shared Knowledge\": \"\n 'constants.py' should contain all the necessary configurations for the game, such as screen dimensions, color definitions, and speed settings. These constants will be used across multiple files, ensuring consistency and ease of updates. Ensure that the Pygame library is initialized correctly in 'main.py' before starting the game loop. Also, make sure that the game's state is managed properly when pausing and resuming the game.\n \", \"Anything UNCLEAR\": \"The interaction between the 'obstacle.py' and the game loop needs to be clearly defined to ensure obstacles appear and disappear correctly. The lifetime of the obstacle and its random movement should be implemented in a way that does not interfere with the game's performance.\"}\n\n```\n-----\n```python\n\n## game.py\nimport pygame\nfrom snake import Snake\nfrom food import Food\n\nclass Game:\n def __init__(self):\n self.score = 0\n self.level = 1\n self.snake = Snake()\n self.food = Food()\n\n def start_game(self):\n pygame.init()\n self.initialize_game()\n self.game_loop()\n\n def initialize_game(self):\n self.score = 0\n self.level = 1\n self.snake.reset()\n self.food.generate()\n\n def game_loop(self):\n game_over = False\n\n while not game_over:\n self.update()\n self.draw()\n self.handle_events()\n self.check_collision()\n self.increase_score()\n self.increase_level()\n\n if self.snake.is_collision():\n game_over = True\n self.game_over()\n\n def update(self):\n self.snake.move()\n\n def draw(self):\n self.snake.draw()\n self.food.draw()\n\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n pygame.quit()\n quit()\n elif event.type == pygame.KEYDOWN:\n if event.key == pygame.K_UP:\n self.snake.change_direction(\"UP\")\n elif event.key == pygame.K_DOWN:\n self.snake.change_direction(\"DOWN\")\n elif event.key == pygame.K_LEFT:\n self.snake.change_direction(\"LEFT\")\n elif event.key == pygame.K_RIGHT:\n self.snake.change_direction(\"RIGHT\")\n\n def check_collision(self):\n if self.snake.get_head() == self.food.get_position():\n self.snake.grow()\n self.food.generate()\n\n def increase_score(self):\n self.score += 1\n\n def increase_level(self):\n if self.score % 10 == 0:\n self.level += 1\n\n def game_over(self):\n print(\"Game Over\")\n self.initialize_game()\n\n\n```\n-----\n```python\n\n## snake.py\nimport pygame\n\nclass Snake:\n def __init__(self):\n self.body = [(0, 0)]\n self.direction = (1, 0)\n\n def move(self):\n head = self.body[0]\n dx, dy = self.direction\n new_head = (head[0] + dx, head[1] + dy)\n self.body.insert(0, new_head)\n self.body.pop()\n\n def change_direction(self, direction):\n if direction == \"UP\":\n self.direction = (0, -1)\n elif direction == \"DOWN\":\n self.direction = (0, 1)\n elif direction == \"LEFT\":\n self.direction = (-1, 0)\n elif direction == \"RIGHT\":\n self.direction = (1, 0)\n\n def grow(self):\n tail = self.body[-1]\n dx, dy = self.direction\n new_tail = (tail[0] - dx, tail[1] - dy)\n self.body.append(new_tail)\n\n def get_head(self):\n return self.body[0]\n\n def get_body(self):\n return self.body[1:]\n\n\n```\n-----\n```python\n\n## main.py\nimport pygame\nfrom game import Game\n\ndef main():\n pygame.init()\n game = Game()\n game.start_game()\n\nif __name__ == \"__main__\":\n main()\n\n\n```\n-----\n```python\n\n## food.py\nimport random\n\nclass Food:\n def __init__(self):\n self.position = (0, 0)\n\n def generate(self):\n x = random.randint(0, 9)\n y = random.randint(0, 9)\n self.position = (x, y)\n\n def get_position(self):\n return self.position\n\n\n```\n-----\n\n## Code Review All: Please read all historical files and find possible bugs in the files, such as unimplemented functions, calling errors, unreferences, etc.\n\n## Call flow: mermaid code, based on the implemented function, use mermaid to draw a complete call chain\n\n## Summary: Summary based on the implementation of historical files\n\n## TODOs: Python dict[str, str], write down the list of files that need to be modified and the reasons. We will modify them later.\n\n": "```mermaid\nclassDiagram\n class Game{\n +int score\n +int level\n +Snake snake\n +Food food\n +start_game() void\n +initialize_game() void\n +game_loop() void\n +update() void\n +draw() void\n +handle_events() void\n +check_collision() void\n +increase_score() void\n +increase_level() void\n +game_over() void\n Game()\n }\n class Snake{\n +list body\n +tuple direction\n +move() void\n +change_direction(direction: str) void\n +grow() void\n +get_head() tuple\n +get_body() list\n Snake()\n }\n class Food{\n +tuple position\n +generate() void\n +get_position() tuple\n Food()\n }\n Game \"1\" -- \"1\" Snake: has\n Game \"1\" -- \"1\" Food: has\n```\n\n```sequenceDiagram\nparticipant M as Main\nparticipant G as Game\nparticipant S as Snake\nparticipant F as Food\nM->>G: start_game()\nG->>G: initialize_game()\nG->>G: game_loop()\nG->>S: move()\nG->>S: change_direction()\nG->>S: grow()\nG->>F: generate()\nS->>S: move()\nS->>S: change_direction()\nS->>S: grow()\nF->>F: generate()\n```\n\n## Summary\nThe code consists of the main game logic, including the Game, Snake, and Food classes. The game loop is responsible for updating and drawing the game elements, handling events, checking collisions, and managing the game state. The Snake class handles the movement, growth, and direction changes of the snake, while the Food class is responsible for generating and tracking the position of food items.\n\n## TODOs\n- Modify 'game.py' to add the implementation of obstacle handling and interaction with the game loop.\n- Implement 'obstacle.py' to include the methods for spawning, moving, and disappearing of obstacles, as well as collision detection with the snake.\n- Update 'main.py' to initialize the obstacle and incorporate it into the game loop.\n- Update the mermaid call flow diagram to include the interaction with the obstacle.\n\n```python\n{\n \"files_to_modify\": {\n \"game.py\": \"Add obstacle handling and interaction with the game loop\",\n \"obstacle.py\": \"Implement obstacle class with necessary methods\",\n \"main.py\": \"Initialize the obstacle and incorporate it into the game loop\"\n }\n}\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n设计一个名为'add'的函数,该函数接受两个整数作为输入,并返回它们的和。\n\n## Task\n\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: \n```python\n## \n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: . Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "## Code: \n```python\n## Design a function called 'add' that takes two integers as input and returns their sum.\n\ndef add(num1: int, num2: int) -> int:\n \"\"\"\n Add two integers and return the sum.\n \n Args:\n num1: An integer.\n num2: An integer.\n \n Returns:\n The sum of num1 and num2 as an integer.\n \"\"\"\n return num1 + num2\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n{\"Implementation approach\": \"We will use the Pygame library to create the game interface and handle user input. The game logic will be implemented using Python classes and data structures.\", \"File list\": [\"main.py\", \"game.py\"], \"Data structures and interfaces\": \"classDiagram\\n class Game {\\n -grid: List[List[int]]\\n -score: int\\n -game_over: bool\\n +__init__()\\n +reset_game()\\n +move(direction: str)\\n +is_game_over() bool\\n +get_empty_cells() List[Tuple[int, int]]\\n +add_new_tile()\\n +get_score() int\\n }\\n class UI {\\n -game: Game\\n +__init__(game: Game)\\n +draw_grid()\\n +draw_score()\\n +draw_game_over()\\n +handle_input()\\n }\\n Game --> UI\", \"Program call flow\": \"sequenceDiagram\\n participant M as Main\\n participant G as Game\\n participant U as UI\\n M->>G: reset_game()\\n M->>U: draw_grid()\\n M->>U: draw_score()\\n M->>U: handle_input()\\n U->>G: move(direction)\\n G->>G: add_new_tile()\\n G->>U: draw_grid()\\n G->>U: draw_score()\\n G->>U: draw_game_over()\\n G->>G: is_game_over()\\n G->>G: get_empty_cells()\\n G->>G: get_score()\", \"Anything UNCLEAR\": \"...\"}\n\n## Task\n{\"Required Python packages\": [\"pygame==2.0.1\"], \"Required Other language third-party packages\": [\"No third-party dependencies required\"], \"Logic Analysis\": [[\"game.py\", \"Contains Game class and related functions for game logic\"], [\"main.py\", \"Contains main function, initializes the game and UI\"]], \"Task list\": [\"game.py\", \"main.py\"], \"Full API spec\": \"\", \"Shared Knowledge\": \"The game logic will be implemented using Python classes and data structures. The Pygame library will be used to create the game interface and handle user input.\", \"Anything UNCLEAR\": \"...\"}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\nE.......F\n======================================================================\nERROR: test_add_new_tile (__main__.TestGame)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n File \"/Users/xx/tests/test_game.py\", line 104, in test_add_new_tile\n self.assertIn(self.game.grid[empty_cells[0][0]][empty_cells[0][1]], [2, 4])\nIndexError: list index out of range\n\n======================================================================\nFAIL: test_reset_game (__main__.TestGame)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n File \"/Users/xx/tests/test_game.py\", line 13, in test_reset_game\n self.assertEqual(self.game.grid, [[0 for _ in range(4)] for _ in range(4)])\nAssertionError: Lists differ: [[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 2], [0, 0, 0, 0]] != [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]\n\nFirst differing element 1:\n[0, 2, 0, 0]\n[0, 0, 0, 0]\n\n- [[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 2], [0, 0, 0, 0]]\n? --- ^\n\n+ [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]\n? +++ ^\n\n\n----------------------------------------------------------------------\nRan 9 tests in 0.002s\n\nFAILED (failures=1, errors=1)\n\n\n{\"design_filename\": \"docs/system_design/20231221155954.json\", \"task_filename\": \"docs/tasks/20231221155954.json\", \"codes_filenames\": [\"game.py\", \"main.py\"], \"reason\": \"```json\\n{\\n \\\"game.py\\\": \\\"Add handling for no empty cells in add_new_tile function, Update score in move function\\\",\\n \\\"main.py\\\": \\\"Handle game over condition in the game loop\\\"\\n}\\n```\"}\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: game.py\n```python\n## game.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: game.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "## Code: game.py\n```python\n## game.py\n\nfrom typing import List, Tuple\nimport random\n\nclass Game:\n def __init__(self):\n self.grid: List[List[int]] = [[0 for _ in range(4)] for _ in range(4)]\n self.score: int = 0\n self.game_over: bool = False\n\n def reset_game(self):\n self.grid = [[0 for _ in range(4)] for _ in range(4)]\n self.score = 0\n self.game_over = False\n\n def move(self, direction: str):\n # Implement the move logic based on the direction\n pass\n\n def is_game_over(self) -> bool:\n # Check if the game is over\n return self.game_over\n\n def get_empty_cells(self) -> List[Tuple[int, int]]:\n empty_cells = []\n for i in range(4):\n for j in range(4):\n if self.grid[i][j] == 0:\n empty_cells.append((i, j))\n return empty_cells\n\n def add_new_tile(self):\n empty_cells = self.get_empty_cells()\n if empty_cells:\n cell = random.choice(empty_cells)\n self.grid[cell[0]][cell[1]] = random.choice([2, 4])\n else:\n # Handle the case when there are no empty cells\n pass\n\n def get_score(self) -> int:\n return self.score\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n编写一个从a加b的函数,返回a+b\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\n\ndef add(a, b):\n return a + \n\n```\n\n\n\n# Format example 1\n## Code Review: \n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: \n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: \n1. No, the code is not implemented as per the requirements. The function 'add' is incomplete and does not return the sum of 'a' and 'b'.\n2. No, the code logic is not completely correct. The return statement in the 'add' function is incomplete.\n3. N/A\n4. N/A\n5. N/A\n6. N/A\n\n## Actions\n1. Complete the 'add' function to return the sum of 'a' and 'b'.\n ```python\n def add(a, b):\n return a + b\n ```\n\n## Code Review Result\nLBTM", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n编写一个从a加b的函数,返回a+b\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\n\ndef add(a, b):\n return a + \n\n```\n\n## Code Review: \n1. No, the code is not implemented as per the requirements. The function 'add' is incomplete and does not return the sum of 'a' and 'b'.\n2. No, the code logic is not completely correct. The return statement in the 'add' function is incomplete.\n3. N/A\n4. N/A\n5. N/A\n6. N/A\n\n## Actions\n1. Complete the 'add' function to return the sum of 'a' and 'b'.\n ```python\n def add(a, b):\n return a + b\n ```\n\n## Code Review Result\nLBTM\n\n# Instruction: rewrite code based on the Code Review and Actions\n## Rewrite Code: CodeBlock. If it still has some bugs, rewrite with triple quotes. Do your utmost to optimize THIS SINGLE FILE. Return all completed codes and prohibit the return of unfinished codes.\n```Code\n## \n...\n```\n": "```python\ndef add(a, b):\n return a + b\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\n编写一个从a加b的函数,返回a+b\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\ndef add(a, b):\n return a + b\n\n```\n\n\n\n# Format example 1\n## Code Review: \n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: \n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: \n1. Yes, the code is implemented as per the requirements.\n2. Yes, the code logic is completely correct.\n3. Yes, the existing code follows the \"Data structures and interfaces\".\n4. Yes, the function is implemented.\n5. Yes, all necessary pre-dependencies have been imported.\n6. N/A\n\n## Code Review Result\nLGTM", + "\n## context\n\n### Legacy Content\n{\"Implementation approach\":\"We will analyze the difficult points of the requirements and select the appropriate open-source framework to develop the search engine. We will also integrate a large language model to provide intelligent summarization of search results.\",\"File list\":[\"main.py\",\"search_engine.py\",\"index.py\",\"ranking.py\",\"summary.py\",\"knowledge_base.py\"],\"Data structures and interfaces\":\"\\nclassDiagram\\n class Main {\\n -SearchEngine search_engine\\n +main() str\\n }\\n class SearchEngine {\\n -Index index\\n -Ranking ranking\\n -Summary summary\\n +search(query: str) str\\n }\\n class Index {\\n -KnowledgeBase knowledge_base\\n +create_index(data: dict)\\n +query_index(query: str) list\\n }\\n class Ranking {\\n +rank_results(results: list) list\\n }\\n class Summary {\\n +summarize_results(results: list) str\\n }\\n class KnowledgeBase {\\n +update(data: dict)\\n +fetch_data(query: str) dict\\n }\\n Main --> SearchEngine\\n SearchEngine --> Index\\n SearchEngine --> Ranking\\n SearchEngine --> Summary\\n Index --> KnowledgeBase\\n\",\"Program call flow\":\"\\nsequenceDiagram\\n participant M as Main\\n participant SE as SearchEngine\\n participant I as Index\\n participant R as Ranking\\n participant S as Summary\\n participant KB as KnowledgeBase\\n M->>SE: search(query)\\n SE->>I: query_index(query)\\n I->>KB: fetch_data(query)\\n KB-->>I: return data\\n I-->>SE: return results\\n SE->>R: rank_results(results)\\n R-->>SE: return ranked_results\\n SE->>S: summarize_results(ranked_results)\\n S-->>SE: return summary\\n SE-->>M: return summary\\n\",\"Anything UNCLEAR\":\"Clarification needed on third-party API integration, optimization techniques, and security measures.\"}\n\n### New Requirements\n## 原始需求\n```python\n\"\"\"\n我们希望开发一个基于大语言模型与私有知识库的搜索引擎。该搜索引擎应当能根据用户输入的查询进行智能搜索,并基于大语言模型对搜索结果进行总结,以便用户能够快速获取他们所需要的信息。该搜索引擎应当能够处理大规模的数据,同时保持搜索结果的准确性和相关性。我们希望这个产品能够降低用户在查找、筛选和理解信息时的工作负担,提高他们的工作效率。\n\"\"\"\n```\n\n## 产品目标\n```python\n[\n \"提供高准确性、高相关性的搜索结果,满足用户的查询需求\",\n \"基于大语言模型对搜索结果进行智能总结,帮助用户快速获取所需信息\",\n \"处理大规模数据,保证搜索的速度和效率,提高用户的工作效率\"\n]\n```\n\n## 用户故事\n```python\n[\n \"假设用户是一名研究员,他正在为一项关于全球气候变化的报告做研究。他输入了'全球气候变化的最新研究',我们的搜索引擎快速返回了相关的文章、报告、数据集等。并且基于大语言模型对这些信息进行了智能总结,研究员可以快速了解到最新的研究趋势和发现。\",\n \"用户是一名学生,正在为即将到来的历史考试复习。他输入了'二战的主要战役',搜索引擎返回了相关的资料,大语言模型总结出主要战役的时间、地点、结果等关键信息,帮助学生快速记忆。\",\n \"用户是一名企业家,他正在寻找关于最新的市场趋势信息。他输入了'2023年人工智能市场趋势',搜索引擎返回了各种报告、新闻和分析文章。大语言模型对这些信息进行了总结,用户能够快速了解到市场的最新动态和趋势。\"\n]\n```\n\n## 竞品分析\n```python\n[\n \"Google Search:Google搜索是市场上最主要的搜索引擎,它能够提供海量的搜索结果。但Google搜索并不提供搜索结果的总结功能,用户需要自己去阅读和理解搜索结果。\",\n \"Microsoft Bing:Bing搜索也能提供丰富的搜索结果,同样没有提供搜索结果的总结功能。\",\n \"Wolfram Alpha:Wolfram Alpha是一个基于知识库的计算型搜索引擎,能够针对某些特定类型的查询提供直接的答案和总结,但它的知识库覆盖范围有限,无法处理大规模的数据。\"\n]\n```\n\n## 开发需求池\n```python\n[\n (\"开发基于大语言模型的智能总结功能\", 5),\n (\"开发搜索引擎核心算法,包括索引构建、查询处理、结果排序等\", 7),\n (\"设计和实现用户界面,包括查询输入、搜索结果展示、总结结果展示等\", 3),\n (\"构建和维护私有知识库,包括数据采集、清洗、更新等\", 7),\n (\"优化搜索引擎性能,包括搜索速度、准确性、相关性等\", 6),\n (\"开发用户反馈机制,包括反馈界面、反馈处理等\", 2),\n (\"开发安全防护机制,防止恶意查询和攻击\", 3),\n (\"集成大语言模型,包括模型选择、优化、更新等\", 5),\n (\"进行大规模的测试,包括功能测试、性能测试、压力测试等\", 5),\n (\"开发数据监控和日志系统,用于监控搜索引擎的运行状态和性能\", 4)\n]\n```\n\n\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Refined Implementation Approach\": \"We will refine ...\",\n \"Refined File list\": [\n \"main.py\",\n \"game.py\",\n \"new_feature.py\"\n ],\n \"Refined Data structures and interfaces\": \"\\nclassDiagram\\n class Main {\\n -SearchEngine search_engine\\n +main() str\\n }\\n class SearchEngine {\\n -Index index\\n -Ranking ranking\\n -Summary summary\\n +search(query: str) str\\n }\\n class Index {\\n -KnowledgeBase knowledge_base\\n +create_index(data: dict)\\n +query_index(query: str) list\\n }\\n class Ranking {\\n +rank_results(results: list) list\\n }\\n class Summary {\\n +summarize_results(results: list) str\\n }\\n class KnowledgeBase {\\n +update(data: dict)\\n +fetch_data(query: str) dict\\n }\\n Main --> SearchEngine\\n SearchEngine --> Index\\n SearchEngine --> Ranking\\n SearchEngine --> Summary\\n Index --> KnowledgeBase\\n\",\n \"Refined Program call flow\": \"\\nsequenceDiagram\\n participant M as Main\\n participant SE as SearchEngine\\n participant I as Index\\n participant R as Ranking\\n participant S as Summary\\n participant KB as KnowledgeBase\\n M->>SE: search(query)\\n SE->>I: query_index(query)\\n I->>KB: fetch_data(query)\\n KB-->>I: return data\\n I-->>SE: return results\\n SE->>R: rank_results(results)\\n R-->>SE: return ranked_results\\n SE->>S: summarize_results(ranked_results)\\n S-->>SE: return summary\\n SE-->>M: return summary\\n\",\n \"Anything UNCLEAR\": \"Clarification needed on third-party API integration, ...\"\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Refined Implementation Approach: # Update and extend the original implementation approach to reflect the evolving challenges and requirements due to incremental development. Outline the steps involved in the implementation process with the detailed strategies.\n- Refined File list: typing.List[str] # Update and expand the original file list including only relative paths. Up to 2 files can be added.Ensure that the refined file list reflects the evolving structure of the project.\n- Refined Data structures and interfaces: # Update and extend the existing mermaid classDiagram code syntax to incorporate new classes, methods (including __init__), and functions with precise type annotations. Delineate additional relationships between classes, ensuring clarity and adherence to PEP8 standards.Retain content that is not related to incremental development but important for consistency and clarity.\n- Refined Program call flow: # Extend the existing sequenceDiagram code syntax with detailed information, accurately covering theCRUD and initialization of each object. Ensure correct syntax usage and reflect the incremental changes introducedin the classes and API defined above. Retain content that is not related to incremental development but important for consistency and clarity.\n- Anything UNCLEAR: # Mention unclear project aspects, then try to clarify it.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Refined Implementation Approach\": \"We will refine the existing implementation approach to incorporate the new requirements for developing a search engine based on a large language model and a private knowledge base. We will update and extend the original implementation approach to reflect the evolving challenges and requirements due to incremental development. We will outline the steps involved in the implementation process with detailed strategies to ensure the search engine meets the new goals of providing high-accuracy and high-relevance search results, intelligent summarization of search results, and efficient handling of large-scale data.\",\n \"Refined File list\": [\n \"main.py\",\n \"search_engine.py\",\n \"index.py\",\n \"ranking.py\",\n \"summary.py\",\n \"knowledge_base.py\",\n \"user_interface.py\"\n ],\n \"Refined Data structures and interfaces\": \"\\nclassDiagram\\n class Main {\\n -SearchEngine search_engine\\n -UserInterface user_interface\\n +main() str\\n }\\n class SearchEngine {\\n -Index index\\n -Ranking ranking\\n -Summary summary\\n -KnowledgeBase knowledge_base\\n +search(query: str) str\\n }\\n class Index {\\n +create_index(data: dict)\\n +query_index(query: str) list\\n }\\n class Ranking {\\n +rank_results(results: list) list\\n }\\n class Summary {\\n +summarize_results(results: list) str\\n }\\n class KnowledgeBase {\\n +update(data: dict)\\n +fetch_data(query: str) dict\\n }\\n class UserInterface {\\n +display_search_results(results: str)\\n +display_summary(summary: str)\\n }\\n Main --> SearchEngine\\n Main --> UserInterface\\n SearchEngine --> Index\\n SearchEngine --> Ranking\\n SearchEngine --> Summary\\n SearchEngine --> KnowledgeBase\\n\",\n \"Refined Program call flow\": \"\\nsequenceDiagram\\n participant M as Main\\n participant SE as SearchEngine\\n participant UI as UserInterface\\n participant I as Index\\n participant R as Ranking\\n participant S as Summary\\n participant KB as KnowledgeBase\\n M->>UI: main()\\n UI->>M: return results\\n M->>SE: search(query)\\n SE->>I: query_index(query)\\n I->>KB: fetch_data(query)\\n KB-->>I: return data\\n I-->>SE: return results\\n SE->>R: rank_results(results)\\n R-->>SE: return ranked_results\\n SE->>S: summarize_results(ranked_results)\\n S-->>SE: return summary\\n SE->>UI: display_search_results(results)\\n UI->>SE: display_summary(summary)\\n\",\n \"Anything UNCLEAR\": \"Clarification needed on third-party API integration, optimization techniques, and security measures.\"\n}\n[/CONTENT]", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/knowledge_base.py\n```python\n## smart_search_engine/knowledge_base.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/knowledge_base.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/knowledge_base.py\n\nclass KnowledgeBase:\n def __init__(self, data={}):\n self.data = data\n\n def update(self, data: dict):\n \"\"\"\n Update the knowledge base with new data.\n \n Args:\n data (dict): The new data to be added to the knowledge base.\n \"\"\"\n self.data.update(data)\n\n def fetch_data(self, query: str) -> dict:\n \"\"\"\n Fetch data from the knowledge base based on the query.\n \n Args:\n query (str): The query to search for in the knowledge base.\n \n Returns:\n dict: The data fetched from the knowledge base based on the query.\n \"\"\"\n return self.data.get(query, {})\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/index.py\n```python\n## smart_search_engine/index.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/index.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/index.py\n\nfrom smart_search_engine.knowledge_base import KnowledgeBase\n\nclass Index:\n def __init__(self, knowledge_base: KnowledgeBase):\n self.knowledge_base = knowledge_base\n self.index_data = {}\n\n def create_index(self, data: dict):\n self.index_data = data\n\n def query_index(self, query: str) -> list:\n if query in self.index_data:\n return self.index_data[query]\n else:\n return []\n\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/ranking.py\n```python\n## smart_search_engine/ranking.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/ranking.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/ranking.py\n\nclass Ranking:\n def __init__(self):\n pass\n\n def rank_results(self, results: list) -> list:\n \"\"\"\n Rank the search results based on relevance.\n\n Args:\n results (list): List of search results.\n\n Returns:\n list: Ranked list of search results.\n \"\"\"\n # Implement ranking algorithm here\n ranked_results = self._custom_ranking_algorithm(results)\n return ranked_results\n\n def _custom_ranking_algorithm(self, results: list) -> list:\n \"\"\"\n Custom ranking algorithm to rank search results.\n\n Args:\n results (list): List of search results.\n\n Returns:\n list: Ranked list of search results.\n \"\"\"\n # Implement custom ranking algorithm here\n return results\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/summary.py\n```python\n## smart_search_engine/summary.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/summary.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/summary.py\n\nclass Summary:\n def __init__(self):\n pass\n\n def summarize_results(self, results: list) -> str:\n \"\"\"\n Summarize the search results.\n\n Args:\n - results (list): List of search results.\n\n Returns:\n - str: Summarized results.\n \"\"\"\n summary = \"\"\n for result in results:\n summary += result + \"\\n\"\n return summary\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/search.py\n```python\n## smart_search_engine/search.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/search.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/search.py\n\nfrom smart_search_engine.index import Index\nfrom smart_search_engine.ranking import Ranking\nfrom smart_search_engine.summary import Summary\n\nclass SearchEngine:\n def __init__(self):\n self.index = Index()\n self.ranking = Ranking()\n self.summary = Summary()\n\n def search(self, query: str) -> str:\n results = self.index.query_index(query)\n ranked_results = self.ranking.rank_results(results)\n summary = self.summary.summarize_results(ranked_results)\n return summary\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/main.py\n```python\n## smart_search_engine/main.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/main.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/main.py\n\nfrom smart_search_engine.search import SearchEngine\n\nclass Main:\n def __init__(self):\n self.search_engine = SearchEngine()\n\n def main(self) -> str:\n query = input(\"Enter your search query: \")\n result = self.search_engine.search(query)\n return result\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/interface.py\n```python\n## smart_search_engine/interface.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/interface.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/interface.py\n\nfrom .search import SearchEngine\n\nclass UserInterface:\n def __init__(self):\n self.search_engine = SearchEngine()\n\n def get_user_input(self) -> str:\n # Get user input from the interface\n user_input = input(\"Enter your search query: \")\n return user_input\n\n def display_results(self, results: list):\n # Display search results to the user\n for result in results:\n print(result)\n\n# Ensure to follow the design and import necessary modules as needed.\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/user_feedback.py\n```python\n## smart_search_engine/user_feedback.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/user_feedback.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/user_feedback.py\n\nclass UserFeedback:\n def __init__(self):\n self.feedback_data = {}\n\n def collect_feedback(self, feedback: str):\n self.feedback_data['feedback'] = feedback\n\n def get_feedback(self):\n return self.feedback_data.get('feedback', 'No feedback provided')\n\n# Code details:\n# - Created a class UserFeedback to handle user feedback.\n# - Initialized feedback_data as an empty dictionary in the constructor.\n# - Implemented collect_feedback method to store user feedback in the feedback_data dictionary.\n# - Implemented get_feedback method to retrieve the stored feedback, with a default message if no feedback is provided.\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/security.py\n```python\n## smart_search_engine/security.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/security.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/security.py\n\nclass Security:\n def __init__(self, api_key: str = \"default_api_key\"):\n self.api_key = api_key\n\n def validate_api_key(self, api_key: str) -> bool:\n \"\"\"\n Validate the API key.\n Args:\n api_key (str): The API key to be validated.\n\n Returns:\n bool: True if the API key is valid, False otherwise.\n \"\"\"\n if api_key == self.api_key:\n return True\n else:\n return False\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/testing.py\n```python\n## smart_search_engine/testing.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/testing.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/testing.py\n\nclass Testing:\n def __init__(self, test_data: dict = {}):\n self.test_data = test_data\n\n def run_tests(self):\n # Write code to run tests based on the test_data\n pass\n```", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\n## Project name\n```python\n\"smart_search_engine\"\n```\n\n## Task list:\n```python\n[\n \"smart_search_engine/__init__.py\",\n \"smart_search_engine/main.py\",\n \"smart_search_engine/search.py\",\n \"smart_search_engine/index.py\",\n \"smart_search_engine/ranking.py\",\n \"smart_search_engine/summary.py\",\n \"smart_search_engine/knowledge_base.py\",\n \"smart_search_engine/interface.py\",\n \"smart_search_engine/user_feedback.py\",\n \"smart_search_engine/security.py\",\n \"smart_search_engine/testing.py\",\n \"smart_search_engine/monitoring.py\"\n]\n```\n\n## Data structures and interfaces\n```mermaid\nclassDiagram\n class Main {\n -SearchEngine search_engine\n +main() str\n }\n class SearchEngine {\n -Index index\n -Ranking ranking\n -Summary summary\n +search(query: str) str\n }\n class Index {\n -KnowledgeBase knowledge_base\n +create_index(data: dict)\n +query_index(query: str) list\n }\n class Ranking {\n +rank_results(results: list) list\n }\n class Summary {\n +summarize_results(results: list) str\n }\n class KnowledgeBase {\n +update(data: dict)\n +fetch_data(query: str) dict\n }\n Main --> SearchEngine\n SearchEngine --> Index\n SearchEngine --> Ranking\n SearchEngine --> Summary\n Index --> KnowledgeBase\n```\n\n## Program call flow\n```mermaid\nsequenceDiagram\n participant M as Main\n participant SE as SearchEngine\n participant I as Index\n participant R as Ranking\n participant S as Summary\n participant KB as KnowledgeBase\n M->>SE: search(query)\n SE->>I: query_index(query)\n I->>KB: fetch_data(query)\n KB-->>I: return data\n I-->>SE: return results\n SE->>R: rank_results(results)\n R-->>SE: return ranked_results\n SE->>S: summarize_results(ranked_results)\n S-->>SE: return summary\n SE-->>M: return summary\n```\n\n\n## Task\n{\"Logic Analysis\": \"\\n 在这个项目中,所有的模块都依赖于“SearchEngine”类,这是主入口,其他的模块(Index、Ranking和Summary)都通过它交互。另外,\\\"Index\\\"类又依赖于\\\"KnowledgeBase\\\"类,因为它需要从知识库中获取数据。\\n\\n- \\\"main.py\\\"包含\\\"Main\\\"类,是程序的入口点,它调用\\\"SearchEngine\\\"进行搜索操作,所以在其他任何模块之前,\\\"SearchEngine\\\"必须首先被定义。\\n- \\\"search.py\\\"定义了\\\"SearchEngine\\\"类,它依赖于\\\"Index\\\"、\\\"Ranking\\\"和\\\"Summary\\\",因此,这些模块需要在\\\"search.py\\\"之前定义。\\n- \\\"index.py\\\"定义了\\\"Index\\\"类,它从\\\"knowledge_base.py\\\"获取数据来创建索引,所以\\\"knowledge_base.py\\\"需要在\\\"index.py\\\"之前定义。\\n- \\\"ranking.py\\\"和\\\"summary.py\\\"相对独立,只需确保在\\\"search.py\\\"之前定义。\\n- \\\"knowledge_base.py\\\"是独立的模块,可以优先开发。\\n- \\\"interface.py\\\"、\\\"user_feedback.py\\\"、\\\"security.py\\\"、\\\"testing.py\\\"和\\\"monitoring.py\\\"看起来像是功能辅助模块,可以在主要功能模块开发完成后并行开发。\\n \", \"Task list\": [\"smart_search_engine/knowledge_base.py\", \"smart_search_engine/index.py\", \"smart_search_engine/ranking.py\", \"smart_search_engine/summary.py\", \"smart_search_engine/search.py\", \"smart_search_engine/main.py\", \"smart_search_engine/interface.py\", \"smart_search_engine/user_feedback.py\", \"smart_search_engine/security.py\", \"smart_search_engine/testing.py\", \"smart_search_engine/monitoring.py\"]}\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: smart_search_engine/monitoring.py\n```python\n## smart_search_engine/monitoring.py\n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: smart_search_engine/monitoring.py. Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "```python\n## smart_search_engine/monitoring.py\n\nclass Monitoring:\n def __init__(self, log_file: str = \"search_log.txt\"):\n self.log_file = log_file\n\n def log_search(self, query: str, results: list, summary: str):\n with open(self.log_file, \"a\") as file:\n file.write(f\"Query: {query}\\n\")\n file.write(\"Results:\\n\")\n for result in results:\n file.write(f\"- {result}\\n\")\n file.write(f\"Summary: {summary}\\n\")\n file.write(\"\\n\")\n```\n", + "\nNOTICE\nRole: You are a professional engineer; the main goal is to write google-style, elegant, modular, easy to read and maintain code\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## Design\nwrite add function to calculate two numbers\n\n## Task\n\n\n## Legacy Code\n```Code\n\n```\n\n## Debug logs\n```text\n\n\n\n```\n\n## Bug Feedback logs\n```text\n\n```\n\n# Format example\n## Code: \n```python\n## \n...\n```\n\n# Instruction: Based on the context, follow \"Format example\", write code.\n\n## Code: . Write code with triple quoto, based on the following attentions and context.\n1. Only One file: do your best to implement THIS ONLY ONE FILE.\n2. COMPLETE CODE: Your code will be part of the entire project, so please implement complete, reliable, reusable code snippets.\n3. Set default value: If there is any setting, ALWAYS SET A DEFAULT VALUE, ALWAYS USE STRONG TYPE AND EXPLICIT VARIABLE. AVOID circular import.\n4. Follow design: YOU MUST FOLLOW \"Data structures and interfaces\". DONT CHANGE ANY DESIGN. Do not use public member functions that do not exist in your design.\n5. CAREFULLY CHECK THAT YOU DONT MISS ANY NECESSARY CLASS/FUNCTION IN THIS FILE.\n6. Before using a external variable/module, make sure you import it first.\n7. Write out EVERY CODE DETAIL, DON'T LEAVE TODO.\n\n": "## Code:\n\n```python\ndef add(num1: int, num2: int) -> int:\n \"\"\"\n Add two numbers and return the result.\n\n Args:\n num1 (int): The first number to be added.\n num2 (int): The second number to be added.\n\n Returns:\n int: The sum of num1 and num2.\n \"\"\"\n return num1 + num2\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\ndivide two numbers\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\n\ndef div(a: int, b: int = 0):\n return a / b\n\n```\n\n\n\n# Format example 1\n## Code Review: \n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: \n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: \n1. No, the code does not handle the case where the divisor 'b' is 0, which would result in a division by zero error. This should be addressed to handle this edge case.\n2. No, the code logic is not completely correct as it does not handle the division by zero scenario.\n3. Yes, the code follows the basic function implementation.\n4. Yes, the function is implemented.\n5. No, the code does not handle the necessary pre-dependencies for error handling when 'b' is 0.\n6. No, there are no methods from other files being reused in this code.\n\n## Actions\n1. Implement error handling to check if the divisor 'b' is 0 before performing the division operation.\n2. Import the necessary pre-dependencies for error handling when 'b' is 0.\n\n## Code Review Result\nLBTM", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\ndivide two numbers\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\n\ndef div(a: int, b: int = 0):\n return a / b\n\n```\n\n## Code Review: \n1. No, the code does not handle the case where the divisor 'b' is 0, which would result in a division by zero error. This should be addressed to handle this edge case.\n2. No, the code logic is not completely correct as it does not handle the division by zero scenario.\n3. Yes, the code follows the basic function implementation.\n4. Yes, the function is implemented.\n5. No, the code does not handle the necessary pre-dependencies for error handling when 'b' is 0.\n6. No, there are no methods from other files being reused in this code.\n\n## Actions\n1. Implement error handling to check if the divisor 'b' is 0 before performing the division operation.\n2. Import the necessary pre-dependencies for error handling when 'b' is 0.\n\n## Code Review Result\nLBTM\n\n# Instruction: rewrite code based on the Code Review and Actions\n## Rewrite Code: CodeBlock. If it still has some bugs, rewrite with triple quotes. Do your utmost to optimize THIS SINGLE FILE. Return all completed codes and prohibit the return of unfinished codes.\n```Code\n## \n...\n```\n": "```python\ndef div(a: int, b: int = 0):\n if b == 0:\n raise ValueError(\"Cannot divide by zero\")\n return a / b\n```", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\ndivide two numbers\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\ndef div(a: int, b: int = 0):\n if b == 0:\n raise ValueError(\"Cannot divide by zero\")\n return a / b\n\n```\n\n\n\n# Format example 1\n## Code Review: \n1. No, we should fix the logic of class A due to ...\n2. ...\n3. ...\n4. No, function B is not implemented, ...\n5. ...\n6. ...\n\n## Actions\n1. Fix the `handle_events` method to update the game state only if a move is successful.\n ```python\n def handle_events(self):\n for event in pygame.event.get():\n if event.type == pygame.QUIT:\n return False\n if event.type == pygame.KEYDOWN:\n moved = False\n if event.key == pygame.K_UP:\n moved = self.game.move('UP')\n elif event.key == pygame.K_DOWN:\n moved = self.game.move('DOWN')\n elif event.key == pygame.K_LEFT:\n moved = self.game.move('LEFT')\n elif event.key == pygame.K_RIGHT:\n moved = self.game.move('RIGHT')\n if moved:\n # Update the game state only if a move was successful\n self.render()\n return True\n ```\n2. Implement function B\n\n## Code Review Result\nLBTM\n\n# Format example 2\n## Code Review: \n1. Yes.\n2. Yes.\n3. Yes.\n4. Yes.\n5. Yes.\n6. Yes.\n\n## Actions\npass\n\n## Code Review Result\nLGTM\n\n\n\n# Instruction: Based on the actual code situation, follow one of the \"Format example\". Return only 1 file under review.\n\n## Code Review: Ordered List. Based on the \"Code to be Reviewed\", provide key, clear, concise, and specific answer. If any answer is no, explain how to fix it step by step.\n1. Is the code implemented as per the requirements? If not, how to achieve it? Analyse it step by step.\n2. Is the code logic completely correct? If there are errors, please indicate how to correct them.\n3. Does the existing code follow the \"Data structures and interfaces\"?\n4. Are all functions implemented? If there is no implementation, please indicate how to achieve it step by step.\n5. Have all necessary pre-dependencies been imported? If not, indicate which ones need to be imported\n6. Are methods from other files being reused correctly?\n\n## Actions: Ordered List. Things that should be done after CR, such as implementing class A and function B\n\n## Code Review Result: str. If the code doesn't have bugs, we don't need to rewrite it, so answer LGTM and stop. ONLY ANSWER LGTM/LBTM.\nLGTM/LBTM\n\n": "## Code Review: \n1. The code does not fully conform to the requirements. The function signature should be updated to follow the Google style standards, and the division by zero check should be handled differently.\n2. The code logic is correct, but the exception handling for division by zero should be improved.\n3. The existing code follows the basic data structures and interfaces.\n4. The function is implemented, but the exception handling for division by zero should be added.\n5. The necessary pre-dependencies have been imported.\n6. There are no methods from other files being reused in this code.\n\n## Actions\n1. Update the function signature to follow the Google style standards and improve the division by zero check as follows:\n ```python\n def divide_numbers(dividend: int, divisor: int) -> float:\n if divisor == 0:\n raise ValueError(\"Cannot divide by zero\")\n return dividend / divisor\n ```\n2. No further action is required.\n\n## Code Review Result\nLBTM", + "\n# System\nRole: You are a professional software engineer, and your main task is to review and revise the code. You need to ensure that the code conforms to the google-style standards, is elegantly designed and modularized, easy to read and maintain.\nLanguage: Please use the same language as the user requirement, but the title and code should be still in English. For example, if the user speaks Chinese, the specific text of your answer should also be in Chinese.\nATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".\n\n# Context\n## System Design\ndivide two numbers\n\n## Task\n\n\n## Code Files\n\n\n\n## Code to be Reviewed: \n```Code\ndef div(a: int, b: int = 0):\n if b == 0:\n raise ValueError(\"Cannot divide by zero\")\n return a / b\n\n```\n\n## Code Review: \n1. The code does not fully conform to the requirements. The function signature should be updated to follow the Google style standards, and the division by zero check should be handled differently.\n2. The code logic is correct, but the exception handling for division by zero should be improved.\n3. The existing code follows the basic data structures and interfaces.\n4. The function is implemented, but the exception handling for division by zero should be added.\n5. The necessary pre-dependencies have been imported.\n6. There are no methods from other files being reused in this code.\n\n## Actions\n1. Update the function signature to follow the Google style standards and improve the division by zero check as follows:\n ```python\n def divide_numbers(dividend: int, divisor: int) -> float:\n if divisor == 0:\n raise ValueError(\"Cannot divide by zero\")\n return dividend / divisor\n ```\n2. No further action is required.\n\n## Code Review Result\nLBTM\n\n# Instruction: rewrite code based on the Code Review and Actions\n## Rewrite Code: CodeBlock. If it still has some bugs, rewrite with triple quotes. Do your utmost to optimize THIS SINGLE FILE. Return all completed codes and prohibit the return of unfinished codes.\n```Code\n## \n...\n```\n": "```python\ndef divide_numbers(dividend: int, divisor: int) -> float:\n if divisor == 0:\n raise ValueError(\"Cannot divide by zero\")\n return dividend / divisor\n```", + "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"issue_type\": \"BUG\"\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- issue_type: # Answer BUG/REQUIREMENT. If it is a bugfix, answer BUG, otherwise answer Requirement\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"issue_type\": \"REQUIREMENT\"\n}\n[/CONTENT]", + "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Product Goals\": [\n \"Create an engaging user experience\",\n \"Improve accessibility, be responsive\",\n \"More beautiful UI\"\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Product Goals: typing.List[str] # Provide up to three clear, orthogonal product goals.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Product Goals\": [\n \"Create a challenging and addictive gameplay\",\n \"Enhance accessibility and responsiveness for all users\",\n \"Implement visually appealing UI design\"\n ]\n}\n[/CONTENT]", + "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Competitive Analysis\": [\n \"2048 Game A: Simple interface, lacks responsive features\",\n \"play2048.co: Beautiful and responsive UI with my best score shown\",\n \"2048game.com: Responsive UI with my best score shown, but many ads\"\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Competitive Analysis: typing.List[str] # Provide 5 to 7 competitive products.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Competitive Analysis\": [\n \"2048 Game A: Simple interface, lacks responsive features\",\n \"play2048.co: Beautiful and responsive UI with my best score shown\",\n \"2048game.com: Responsive UI with my best score shown, but many ads\"\n ]\n}\n[/CONTENT]", + "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Requirement Pool\": [\n [\n \"P0\",\n \"The main code ...\"\n ],\n [\n \"P0\",\n \"The game algorithm ...\"\n ]\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Requirement Pool: typing.List[typing.List[str]] # List down the top-5 requirements with their priority (P0, P1, P2).\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Requirement Pool\": [\n [\n \"P0\",\n \"The main code should handle user input and update the game board accordingly.\"\n ],\n [\n \"P0\",\n \"The game algorithm should handle the merging of tiles and the generation of new tiles with values of 2 or 4.\"\n ],\n [\n \"P1\",\n \"The game should end when the player achieves the 2048 tile or when there are no possible moves left.\"\n ],\n [\n \"P1\",\n \"The game should display the current score and the highest tile achieved by the player.\"\n ],\n [\n \"P2\",\n \"The game should have a smooth and visually appealing user interface.\"\n ]\n ]\n}\n[/CONTENT]" } \ No newline at end of file diff --git a/tests/metagpt/actions/test_action_node.py b/tests/metagpt/actions/test_action_node.py index 53de9cc75..1ec9f4f8d 100644 --- a/tests/metagpt/actions/test_action_node.py +++ b/tests/metagpt/actions/test_action_node.py @@ -8,7 +8,7 @@ from typing import List, Tuple import pytest -from pydantic import ValidationError +from pydantic import BaseModel, Field, ValidationError from metagpt.actions import Action from metagpt.actions.action_node import ActionNode, ReviewMode, ReviseMode @@ -241,6 +241,47 @@ def test_create_model_class_with_mapping(): assert value == ["game.py", "app.py", "static/css/styles.css", "static/js/script.js", "templates/index.html"] +class ToolDef(BaseModel): + tool_name: str = Field(default="a", description="tool name", examples=[]) + description: str = Field(default="b", description="tool description", examples=[]) + + +class Task(BaseModel): + task_id: int = Field(default=1, description="task id", examples=[1, 2, 3]) + name: str = Field(default="Get data from ...", description="task name", examples=[]) + dependent_task_ids: List[int] = Field(default=[], description="dependent task ids", examples=[1, 2, 3]) + tool: ToolDef = Field(default=ToolDef(), description="tool use", examples=[]) + + +class Tasks(BaseModel): + tasks: List[Task] = Field(default=[], description="tasks", examples=[]) + + +def test_action_node_from_pydantic_and_print_everything(): + node = ActionNode.from_pydantic(Task) + print("1. Tasks") + print(Task().model_dump_json(indent=4)) + print(Tasks.model_json_schema()) + print("2. Task") + print(Task.model_json_schema()) + print("3. ActionNode") + print(node) + print("4. node.compile prompt") + prompt = node.compile(context="") + assert "tool_name" in prompt, "tool_name should be in prompt" + print(prompt) + print("5. node.get_children_mapping") + print(node._get_children_mapping()) + print("6. node.create_children_class") + children_class = node._create_children_class() + print(children_class) + import inspect + + code = inspect.getsource(Tasks) + print(code) + assert "tasks" in code, "tasks should be in code" + + if __name__ == "__main__": test_create_model_class() test_create_model_class_with_mapping() diff --git a/tests/metagpt/strategy/test_solver.py b/tests/metagpt/strategy/test_solver.py new file mode 100644 index 000000000..eae4a5a2a --- /dev/null +++ b/tests/metagpt/strategy/test_solver.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2024/1/31 13:54 +@Author : alexanderwu +@File : test_solver.py +""" +import pytest + +from metagpt.actions.action_graph import ActionGraph +from metagpt.llm import LLM +from metagpt.strategy.search_space import SearchSpace +from metagpt.strategy.solver import NaiveSolver + + +@pytest.mark.asyncio +async def test_solver(): + from metagpt.actions.write_prd_an import ( + COMPETITIVE_ANALYSIS, + ISSUE_TYPE, + PRODUCT_GOALS, + REQUIREMENT_POOL, + ) + + graph = ActionGraph() + graph.add_node(ISSUE_TYPE) + graph.add_node(PRODUCT_GOALS) + graph.add_node(COMPETITIVE_ANALYSIS) + graph.add_node(REQUIREMENT_POOL) + graph.add_edge(ISSUE_TYPE, PRODUCT_GOALS) + graph.add_edge(PRODUCT_GOALS, COMPETITIVE_ANALYSIS) + graph.add_edge(PRODUCT_GOALS, REQUIREMENT_POOL) + graph.add_edge(COMPETITIVE_ANALYSIS, REQUIREMENT_POOL) + search_space = SearchSpace() + llm = LLM() + context = "Create a 2048 game" + solver = NaiveSolver(graph, search_space, llm, context) + await solver.solve() + + print("## graph.nodes") + print(graph.nodes) + for k, v in graph.nodes.items(): + print(f"{v.key} | prevs: {[i.key for i in v.prevs]} | nexts: {[i.key for i in v.nexts]}") + + assert len(graph.nodes) == 4 + assert len(graph.execution_order) == 4 + assert graph.execution_order == [ISSUE_TYPE.key, PRODUCT_GOALS.key, COMPETITIVE_ANALYSIS.key, REQUIREMENT_POOL.key] From 16f54abb3df52a1fb19e96f15a7938aec7ffc1c9 Mon Sep 17 00:00:00 2001 From: geekan Date: Wed, 31 Jan 2024 14:01:25 +0800 Subject: [PATCH 12/35] use gpt-4-turbo-preview as default --- config/config2.yaml | 2 +- config/config2.yaml.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config2.yaml b/config/config2.yaml index 5e7f34809..2c4ca636f 100644 --- a/config/config2.yaml +++ b/config/config2.yaml @@ -1,3 +1,3 @@ llm: api_key: "YOUR_API_KEY" - model: "gpt-3.5-turbo-1106" \ No newline at end of file + model: "gpt-4-turbo-preview" # or gpt-3.5-turbo-1106 / gpt-4-1106-preview \ No newline at end of file diff --git a/config/config2.yaml.example b/config/config2.yaml.example index 35575e5a5..1a406e756 100644 --- a/config/config2.yaml.example +++ b/config/config2.yaml.example @@ -2,7 +2,7 @@ llm: api_type: "openai" base_url: "YOUR_BASE_URL" api_key: "YOUR_API_KEY" - model: "gpt-3.5-turbo-1106" # or gpt-4-1106-preview + model: "gpt-4-turbo-preview" # or gpt-3.5-turbo-1106 / gpt-4-1106-preview proxy: "YOUR_PROXY" From fc412e55a3ebd58ab5e79ca98b37d700b0994f36 Mon Sep 17 00:00:00 2001 From: shenchucheng Date: Wed, 31 Jan 2024 15:58:26 +0800 Subject: [PATCH 13/35] fix tests/metagpt/learn/test_google_search.py error --- metagpt/learn/google_search.py | 2 +- metagpt/tools/search_engine_serpapi.py | 2 + metagpt/tools/search_engine_serper.py | 2 + tests/data/search_rsp_cache.json | 118 +++++++++++++++++++++- tests/metagpt/learn/test_google_search.py | 24 ++--- tests/mock/mock_aiohttp.py | 4 + 6 files changed, 135 insertions(+), 17 deletions(-) diff --git a/metagpt/learn/google_search.py b/metagpt/learn/google_search.py index 3f356f7dd..399c14de4 100644 --- a/metagpt/learn/google_search.py +++ b/metagpt/learn/google_search.py @@ -8,5 +8,5 @@ async def google_search(query: str, max_results: int = 6, **kwargs): :param max_results: The number of search results to retrieve :return: The web search results in markdown format. """ - results = await SearchEngine().run(query, max_results=max_results, as_string=False) + results = await SearchEngine(**kwargs).run(query, max_results=max_results, as_string=False) return "\n".join(f"{i}. [{j['title']}]({j['link']}): {j['snippet']}" for i, j in enumerate(results, 1)) diff --git a/metagpt/tools/search_engine_serpapi.py b/metagpt/tools/search_engine_serpapi.py index a8d5b49d0..8d27d493d 100644 --- a/metagpt/tools/search_engine_serpapi.py +++ b/metagpt/tools/search_engine_serpapi.py @@ -61,9 +61,11 @@ class SerpAPIWrapper(BaseModel): if not self.aiosession: async with aiohttp.ClientSession() as session: async with session.get(url, params=params) as response: + response.raise_for_status() res = await response.json() else: async with self.aiosession.get(url, params=params) as response: + response.raise_for_status() res = await response.json() return res diff --git a/metagpt/tools/search_engine_serper.py b/metagpt/tools/search_engine_serper.py index 39cb936b8..71ee2f4f9 100644 --- a/metagpt/tools/search_engine_serper.py +++ b/metagpt/tools/search_engine_serper.py @@ -55,9 +55,11 @@ class SerperWrapper(BaseModel): if not self.aiosession: async with aiohttp.ClientSession() as session: async with session.post(url, data=payloads, headers=headers) as response: + response.raise_for_status() res = await response.json() else: async with self.aiosession.get.post(url, data=payloads, headers=headers) as response: + response.raise_for_status() res = await response.json() return res diff --git a/tests/data/search_rsp_cache.json b/tests/data/search_rsp_cache.json index 822fb2069..7b4cc583c 100644 --- a/tests/data/search_rsp_cache.json +++ b/tests/data/search_rsp_cache.json @@ -875,5 +875,121 @@ "curl-cffi-POST-https://duckduckgo.com-{\"data\": {\"q\": \"Dataiku vs DataRobot features\"}}": "Dataiku vs DataRobot features at DuckDuckGo
", "curl-cffi-GET-https://links.duckduckgo.com/d.js-{\"params\": {\"bing_market\": \"wt-WT\", \"df\": null, \"ex\": \"-1\", \"kl\": \"wt-wt\", \"l\": \"wt-wt\", \"q\": \"Dataiku vs DataRobot features\", \"s\": \"0\", \"sp\": \"0\", \"vqd\": \"4-334935250614046875026454141242803242982\"}}": "if (DDG.deep && DDG.deep.setUpstream) DDG.deep.setUpstream(\"bingv7aa\");DDG.deep.bn={'ivc':1};if (DDG.pageLayout) DDG.pageLayout.load('a',[{\"a\":\"\\u9ad8\\u7cbe\\u5ea6\\u306a\\u6a5f\\u68b0\\u5b66\\u7fd2\\u30e2\\u30c7\\u30eb\\u3092\\u69cb\\u7bc9\\u3001\\u5b9f\\u88c5\\u3001\\u904b\\u7528\\u3002DataRobot\\u306f\\u793e\\u5185\\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u65b0\\u3057\\u3044\\u4fa1\\u5024\\u3092\\u5275\\u9020\\u3057\\u307e\\u3059. DataRobot\\u306f\\u4f01\\u696d\\u306e\\u8ab2\\u984c\\u89e3\\u6c7a\\u306b\\u7279\\u5316\\u3002\\u610f\\u601d\\u6c7a\\u5b9a\\u306e\\u81ea\\u52d5\\u5316\\u304b\\u3089\\u9700\\u8981\\u4e88\\u6e2c\\u3001\\u8981\\u56e0\\u5206\\u6790\\u307e\\u3067\\u3053\\u306a\\u3059AI\\u30c4\\u30fc\\u30eb\",\"adext\":{\"callout\":{\"t\":\"Data Science Guardrails \\u00b7 Applied AI Expertise \\u00b7 Trusted by Fortune 50\",\"tid\":\"6\"},\"filterlinks\":{\"l\":[],\"tid\":\"\"},\"sitelinks\":{\"l\":[{\"snippet\":\"Explore the DataRobot AI Platform Get Started With a 30-Day Trial\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=uchwI3Eul8XsE%2DSUlPqxXg%3D%3D&rut=2381550f96a087800d427735905717264a1a708643136f2736a970e740068621&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8BGV0WifLHqlNArHdJt3WDTVUCUzDyrVI_ULomBTgn_xk1MKGRFElGY7vQ8fpE4l__S3CnH6%2D2cXlBQayeIz9CbLU7C4XEu8BgG6oZNQ6EtjG6vrYe5hjw1GZN7VBIkj6nn%2DsoUXy14mVbvkM5ojXVf8oeoz8pwdOc4ANH2TiL9vqJe6Lud2IZXvxJf1I%2DA935XcPQobPZKQaFNFMyygI3Y4TW8k%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnRyaWFsJTJmJTNmdXRtX21lZGl1bSUzZHNlYXJjaCUyNnV0bV9zb3VyY2UlM2RiaW5nJTI2dXRtX2NhbXBhaWduJTNkRnJlZVRyaWFsMjAyM1dXMDgxNkdQU2FkZXh0JTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDFmMzU0ODE0ODNmMTEyM2Y5NGMzMmRiNzdjZjk5OWFm%26rlid%3D1f35481483f1123f94c32db77cf999af&vqd=4-25671318592048362755712261648304518289&iurl=%7B1%7DIG%3D3EB403B8C4EA42F4B7FF0CE90CB46EF0%26CID%3D2F20CB6F269D6DD02331DF69279D6C12%26ID%3DDevEx%2C5064.1\",\"text\":\"DataRobot Free Trial\"},{\"snippet\":\"Unlock Your AI Success in 2023 Tips on the Path of Value-Driven AI\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=uchwI3Eul8XsE%2DSUlPqxXg%3D%3D&rut=08def2477dd7311fbcffe4c409d28fcdbe68925a50cd2894a7502f8a11785352&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8lYdQlfjG0%2Dh77MMyzT0CuDVUCUyAuuZDH6K8NWyD2XSLoABvrUNVChVbIVOVgzl4xdT3EEUvHgd9P_FWLUDT2My42qKUP3iV87B7hLXXHLdGf7yjst8tWjp%2DcaQz3uiI0c5oom%2DRo8D7A4nohZAtS9199RQLYbNcbOpJnrNMCFmz6EiWk7JqMQ9DE1t9AjaMUWEkEV%2D3W2e8XmBq5bKtRsWnT0E%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnJlc291cmNlcyUyZmFpc3VjY2VzczIwMjMlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RDb250ZW50MTBLZXlzdG9BSVN1Y2Nlc3MyMDIzV1cwNTIyR1BTYWRleHQlMjZ1dG1fdGVybSUzZGRhdGFyb2JvdCUyNnV0bV9jb250ZW50JTNkYWRfZXh0JTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDI5Zjc0NWY1MzNiNzE2NDU5ZGY0MjA1NmNjYmYyYWU0%26rlid%3D29f745f533b716459df42056ccbf2ae4&vqd=4-333465595216651803104351585568313334233&iurl=%7B1%7DIG%3D3EB403B8C4EA42F4B7FF0CE90CB46EF0%26CID%3D2F20CB6F269D6DD02331DF69279D6C12%26ID%3DDevEx%2C5066.1\",\"text\":\"10 Keys to AI Success\"},{\"snippet\":\"Our Platform Includes Four Fully Integrated Products. Read More.\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=uchwI3Eul8XsE%2DSUlPqxXg%3D%3D&rut=fbe7591a97a4b400635f8cfafd71893553c70fc90218355b7d5622310d9567db&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8cB2vIW6%2D5rxeC5vl08jFZjVUCUw2oN7vfXdo8rlxVmZIfw2bF94_ya9lvPQwUYXJFtTGXBslf_XCcVTiFtj2KJzp9yzLPOdWafvxxwBzn2iwextOSL%2Daq20iQ8nZNktMLYBD1xp3WjThLdejbBCFrR_RvD1YZcHcKf5y5auyV04F_V6x_D6nUwdRYFDmdyciLcpT7JO12EZkmM%2D1buahlzuiBmw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnByb2R1Y3QlMmYlM2ZjYW1wYWlnbmlkJTNkNTMwNzA4MDk5JTI2YWRncm91cGlkJTNkMTM1MDIwMjc3NDIxNzY5OCUyNmFkaWQlM2QlMjZtc2Nsa2lkJTNkMGZhOTg4ZjJkYWU2MWE3MGJhOTVlZDUxMjVlZWFlNDA%26rlid%3D0fa988f2dae61a70ba95ed5125eeae40&vqd=4-211419575679328898707892660118042825990&iurl=%7B1%7DIG%3D3EB403B8C4EA42F4B7FF0CE90CB46EF0%26CID%3D2F20CB6F269D6DD02331DF69279D6C12%26ID%3DDevEx%2C5068.1\",\"text\":\"Product Overview\"}],\"tid\":\"7\\t9[8]\\t11[10]\\t13[12]\",\"type\":\"EnhancedSiteLink\"},\"tid\":\"1\"},\"ae\":{\"callout\":[\"Data Science Guardrails \\u00b7 Applied AI Expertise \\u00b7 Trusted by Fortune 50\"]},\"c\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=uchwI3Eul8XsE%2DSUlPqxXg%3D%3D&rut=94a279ed1549c0107c5c13f21161fd5aaa0d3f08d19e7afd2ed4a19463b69d7d&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8XX6qufLbIkEZRIFo_zgmlDVUCUwOnCSpTtxK0dn2QInSfOGU5eU24GjiRwhmSr89Qa92PcEtK2h6KVoghC%2DNwNrkANG4L6sVirCfv5kl7GPWO9gqgcdw8x5ELjGH7N2HWgbdtH%2D7TWKtxZVdVIFwYJUQDUgM_ODwTspzwBbKKLHD4EPAO5U3RDO3R_igFUlsxkeFXA%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZmpwJTJmbHAlMmZhaS1mb3ItYnVzaW5lc3MlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RERU1PMjAyM0FsbFByb2R1Y3RzSlAwNjI2QlBTJTI2dXRtX3Rlcm0lM2RkYXRhcm9ib3QlMjZ1dG1fY29udGVudCUzZERSX2JyYW5kZWRfcnNhJTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZGQxMGY4ZjY4ZDYxZjFiOTg2NTc1ZWFjYjI5MTczYTQ1%26rlid%3Dd10f8f68d61f1b986575eacb29173a45&vqd=4-152568096679810917558416500867559274982&iurl=%7B1%7DIG%3D3EB403B8C4EA42F4B7FF0CE90CB46EF0%26CID%3D2F20CB6F269D6DD02331DF69279D6C12%26ID%3DDevEx%2C5059.1\",\"d\":\"datarobot.com\",\"h\":0,\"i\":\"\",\"k\":0,\"m\":0,\"o\":\"\",\"p\":1,\"relevancy\":{\"abstract\":\"%E9%AB%98%E7%B2%BE%E5%BA%A6%E3%81%AA%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E6%A7%8B%E7%AF%89%E3%80%81%E5%AE%9F%E8%A3%85%E3%80%81%E9%81%8B%E7%94%A8%E3%80%82%3Cb%3EDataRobot%3C%2Fb%3E%E3%81%AF%E7%A4%BE%E5%86%85%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E6%96%B0%E3%81%97%E3%81%84%E4%BE%A1%E5%80%A4%E3%82%92%E5%89%B5%E9%80%A0%E3%81%97%E3%81%BE%E3%81%99.%20DataRobot%E3%81%AF%E4%BC%81%E6%A5%AD%E3%81%AE%E8%AA%B2%E9%A1%8C%E8%A7%A3%E6%B1%BA%E3%81%AB%E7%89%B9%E5%8C%96%E3%80%82%E6%84%8F%E6%80%9D%E6%B1%BA%E5%AE%9A%E3%81%AE%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%8B%E3%82%89%E9%9C%80%E8%A6%81%E4%BA%88%E6%B8%AC%E3%80%81%E8%A6%81%E5%9B%A0%E5%88%86%E6%9E%90%E3%81%BE%E3%81%A7%E3%81%93%E3%81%AA%E3%81%99AI%E3%83%84%E3%83%BC%E3%83%AB\",\"adx_name\":\"none\",\"is_good_v10\":0,\"q\":\"Dataiku%20vs%20DataRobot%20features\",\"q_words\":4,\"q_words_fuzzy\":0.25,\"q_words_in_ad\":1,\"root_domain\":\"datarobot.com\",\"start\":\"0\",\"title\":\"%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E6%96%B0%E3%81%97%E3%81%84%E4%BE%A1%E5%80%A4%E3%82%92%20%2D%20%E7%A4%BE%E5%86%85%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E4%BE%A1%E5%80%A4%E5%89%B5%E5%87%BA\"},\"s\":\"bingv7aa\",\"t\":\"\\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u65b0\\u3057\\u3044\\u4fa1\\u5024\\u3092 - \\u793e\\u5185\\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u4fa1\\u5024\\u5275\\u51fa\",\"tid\":\"1,6,7,9[8],11[10],13[12]\",\"u\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=uchwI3Eul8XsE%2DSUlPqxXg%3D%3D&rut=94a279ed1549c0107c5c13f21161fd5aaa0d3f08d19e7afd2ed4a19463b69d7d&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8XX6qufLbIkEZRIFo_zgmlDVUCUwOnCSpTtxK0dn2QInSfOGU5eU24GjiRwhmSr89Qa92PcEtK2h6KVoghC%2DNwNrkANG4L6sVirCfv5kl7GPWO9gqgcdw8x5ELjGH7N2HWgbdtH%2D7TWKtxZVdVIFwYJUQDUgM_ODwTspzwBbKKLHD4EPAO5U3RDO3R_igFUlsxkeFXA%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZmpwJTJmbHAlMmZhaS1mb3ItYnVzaW5lc3MlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RERU1PMjAyM0FsbFByb2R1Y3RzSlAwNjI2QlBTJTI2dXRtX3Rlcm0lM2RkYXRhcm9ib3QlMjZ1dG1fY29udGVudCUzZERSX2JyYW5kZWRfcnNhJTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZGQxMGY4ZjY4ZDYxZjFiOTg2NTc1ZWFjYjI5MTczYTQ1%26rlid%3Dd10f8f68d61f1b986575eacb29173a45&vqd=4-152568096679810917558416500867559274982&iurl=%7B1%7DIG%3D3EB403B8C4EA42F4B7FF0CE90CB46EF0%26CID%3D2F20CB6F269D6DD02331DF69279D6C12%26ID%3DDevEx%2C5059.1\"}], {\"page_load_url\":\"https://duckduckgo.com/y.js?ifu=%7B3%7Dappid%3D055AAD1BA669BEB8B048128DC89A107C678B527B%26rguid%3D280881b97b9245e6a74bddebc1a6cbda&iurl=%7B2%7DIG%3D3EB403B8C4EA42F4B7FF0CE90CB46EF0%26CID%3D2F20CB6F269D6DD02331DF69279D6C12%26Type%3DEvent.CPT%26DATA%3D0\",\"visibility_url\":\"https://duckduckgo.com/y.js?ivu=%7B4%7Dtype%3Dmv%26reqver%3D1.0%26rg%3D280881b97b9245e6a74bddebc1a6cbda\"});DDG.deep.signalSummary = \"\";DDG.inject('DDG.Data.languages.resultLanguages', {\"en\":[\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\",\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"https://comparisons.financesonline.com/datarobot-vs-dataiku-dss\",\"https://slashdot.org/software/comparison/DataRobot-vs-Dataiku-DSS/\",\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"https://www.gartner.com/reviews/market/dsml-engineering-platforms/compare/dataiku-vs-datarobot\",\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"https://www.trustradius.com/products/datarobot/reviews?qs=pros-and-cons\",\"https://www.getapp.com/emerging-technology-software/a/dataiku-dss/compare/datarobot/\",\"https://www.softwarereviews.com/categories/machine-learning-platforms/compare/dataiku-vs-datarobot-ai-platform\",\"https://slashdot.org/software/comparison/Alteryx-vs-DataRobot-vs-Dataiku-DSS/\",\"https://slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS/\",\"https://valohai.com/mlops-platforms-compared/\",\"https://www.dataiku.com/product/plans-and-features/\",\"https://slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS-vs-datagym/\",\"https://sourceforge.net/software/compare/C3-AI-Suite-vs-DataRobot-vs-Dataiku-DSS/\",\"https://www.softwarereviews.com/categories/machine-learning-platforms/compare/datarobot-ai-platform-vs-dataiku\",\"https://slashdot.org/software/comparison/Amazon-SageMaker-vs-DataRobot-vs-Dataiku-DSS/\",\"https://sourceforge.net/software/compare/Analance-vs-DataRobot-vs-Dataiku-DSS/\"]});DDG.deep.pageLayoutSummary = \"a1w23r1,e1\";DDG.inject('DDG.Data.languages.adLanguages', {});if (DDG.pageLayout) DDG.pageLayout.load('d',[{\"a\":\"1 Star 0% Ratings breakdown Overall Capability Score Overall Rating 4.7 ( 504 reviews) 4.7 (20) Data Access and Manipulation 4.5 (224) Data Exploration and Visualization 4.7\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"d\":\"www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku vs DataRobot 2024 | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\"},{\"a\":\"Path to AI Success Compare Dataiku DSS vs DataRobot. 103 verified user reviews and ratings of features, pros, cons, pricing, support and more.\",\"ae\":null,\"c\":\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"d\":\"www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.trustradius.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku DSS vs DataRobot | TrustRadius\",\"u\":\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\"},{\"a\":\"General Discussion Dataiku vs DataRobot Solved! Raja Level 2 08-22-2020 03:16 AM Please enlighten me, What distinguishes Dataiku from tools like DataRobot? They appear to be similar, trying to know how dataiku has an upper hand, would make it easy for placing option to customers. 1 Reply 2 Solutions Solutions shown first - Read whole discussion\",\"ae\":null,\"c\":\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"d\":\"community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"da\":\"\",\"h\":0,\"i\":\"community.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Solved: Dataiku vs DataRobot - Dataiku Community\",\"u\":\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\"},{\"a\":\"DataRobot vs Dataiku DSS When assessing the two solutions, reviewers found Dataiku DSS easier to use and administer. However, reviewers preferred the ease of set up, and doing business with DataRobot overall. Reviewers felt that DataRobot meets the needs of their business better than Dataiku DSS.\",\"ae\":null,\"c\":\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\",\"d\":\"www.g2.com/compare/datarobot-vs-dataiku-dss\",\"da\":\"\",\"h\":0,\"i\":\"www.g2.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare DataRobot vs. Dataiku DSS | G2\",\"u\":\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\"},{\"a\":\"Quick overview Before we get into a detailed comparison, here's a quick overview of each platform. Dataiku is a cross-platform desktop application that includes a broad range of tools, such as notebooks (similar to Jupyter Notebook), workflow management (similar to Apache Airflow), and automated machine learning.\",\"ae\":null,\"c\":\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"d\":\"www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"da\":\"\",\"h\":0,\"i\":\"www.datarevenue.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"ML Platforms: Dataiku vs. Alteryx vs. Sagemaker vs. Datarobot\",\"u\":\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\"},{\"a\":\"Home Predictive Analysis Software DataRobot Dataiku DSS Why is FinancesOnline free Compare DataRobot vs Dataiku DSS What is better DataRobot or Dataiku DSS? Examining products to find the best Predictive Analysis Software does not always have to be tough.\",\"ae\":null,\"c\":\"https://comparisons.financesonline.com/datarobot-vs-dataiku-dss\",\"d\":\"comparisons.financesonline.com/datarobot-vs-dataiku-dss\",\"da\":\"\",\"h\":0,\"i\":\"comparisons.financesonline.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"DataRobot vs Dataiku DSS 2024 Comparison | FinancesOnline\",\"u\":\"https://comparisons.financesonline.com/datarobot-vs-dataiku-dss\"},{\"a\":\"Machine Learning Software Dataiku vs DataRobot Dataiku vs DataRobot Share How Capterra Verifies Reviews Pricing Best for Screenshots Features Reviews Pros & Cons Deployment & Support Alternatives Company Details Dataiku VISIT PROFILE DataRobot VISIT PROFILE Pricing Starting from $ 0.01 /Year Pricing Model: Not provided by vendor Free Trial\",\"ae\":null,\"c\":\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"d\":\"www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"da\":\"translations\",\"h\":0,\"i\":\"www.capterra.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare Dataiku vs DataRobot 2024 | Capterra\",\"u\":\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\"},{\"a\":\"What's the difference between DataRobot and Dataiku DSS? Compare DataRobot vs. Dataiku DSS in 2023 by cost, reviews, features, integrations, deployment, target market, support options, trial offers, training options, years in business, region, and more using the chart below.\",\"ae\":null,\"b\":\"/.\\tSlashdot\\tslashdot.org\",\"c\":\"https://slashdot.org/software/comparison/DataRobot-vs-Dataiku-DSS/\",\"d\":\"slashdot.org/software/comparison/DataRobot-vs-Dataiku-DSS/\",\"da\":\"\",\"h\":0,\"i\":\"slashdot.org\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare DataRobot vs. Dataiku DSS in 2023 - Slashdot\",\"u\":\"https://slashdot.org/software/comparison/DataRobot-vs-Dataiku-DSS/\"},{\"a\":\"1 Star 0% Distribution based on 504 ratings Customer Experience Evaluation & Contracting 4.6 Integration & Deployment 4.7 Service & Support 4.8 Product Capabilities 4.8 FREE View and Download Peer Insights About Dataiku\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"d\":\"www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku Reviews, Ratings & Features 2024 | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\"},{\"a\":\"1329 reviews on 16 vendors. chevron_right. Yard Management. 25 reviews on 28 vendors. chevron_right. Zero Trust Network Access. 733 reviews on 47 vendors. chevron_right. Read the latest Gartner-verified reviews covering over 500+ software categories and find the best enterprise software or services for your organization.\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/dsml-engineering-platforms/compare/dataiku-vs-datarobot\",\"d\":\"www.gartner.com/reviews/market/dsml-engineering-platforms/compare/dataiku-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Explore Enterprise Software Categories | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/dsml-engineering-platforms/compare/dataiku-vs-datarobot\"},{\"a\":\"1. Dataiku is a versatile desktop application comprised of a wide range of tools, including automated machine learning, notebooks, and workflow management. It aims to replace pre-existing tools...\",\"ae\":null,\"b\":\"li\\tLinkedIn\\twww.linkedin.com\",\"c\":\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"d\":\"www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"da\":\"\",\"e\":\"2023-08-11T00:00:00.0000000\",\"h\":0,\"i\":\"www.linkedin.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Managed Machine Learning Platforms: A Comparative Analysis - LinkedIn\",\"u\":\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\"},{\"a\":\"Dataiku DSS, H2O, and Google Cloud AI are common alternatives for DataRobot. What is DataRobot's best feature? Reviewers rate Automated Machine Learning highest, with a score of 9.3. Who uses DataRobot? The most common users of DataRobot are from Mid-sized Companies (51-1,000 employees).\",\"ae\":null,\"c\":\"https://www.trustradius.com/products/datarobot/reviews?qs=pros-and-cons\",\"d\":\"www.trustradius.com/products/datarobot/reviews?qs=pros-and-cons\",\"da\":\"\",\"h\":0,\"i\":\"www.trustradius.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Pros and Cons of DataRobot 2024 - TrustRadius\",\"u\":\"https://www.trustradius.com/products/datarobot/reviews?qs=pros-and-cons\"},{\"a\":\"Compare Dataiku and DataRobot based on features, pricing, verified reviews, integrations & more. Find out which software is best for your business today. 0. App comparison. Add up to 4 apps below to see how they compare. You can also use the "Compare" buttons while browsing.\",\"ae\":null,\"c\":\"https://www.getapp.com/emerging-technology-software/a/dataiku-dss/compare/datarobot/\",\"d\":\"www.getapp.com/emerging-technology-software/a/dataiku-dss/compare/datarobot/\",\"da\":\"\",\"h\":0,\"i\":\"www.getapp.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku vs DataRobot Comparison | GetApp\",\"u\":\"https://www.getapp.com/emerging-technology-software/a/dataiku-dss/compare/datarobot/\"},{\"a\":\"Dataiku vs DataRobot AI Platform Compare Dataiku and DataRobot AI Platform using real user data focused on features, satisfaction, business value, and the vendor relationship. What is Machine Learning Platforms (ML) Software?\",\"ae\":null,\"c\":\"https://www.softwarereviews.com/categories/machine-learning-platforms/compare/dataiku-vs-datarobot-ai-platform\",\"d\":\"www.softwarereviews.com/categories/machine-learning-platforms/compare/dataiku-vs-datarobot-ai-platform\",\"da\":\"\",\"h\":0,\"i\":\"www.softwarereviews.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku vs DataRobot AI Platform - Machine Learning Platforms\",\"u\":\"https://www.softwarereviews.com/categories/machine-learning-platforms/compare/dataiku-vs-datarobot-ai-platform\"},{\"a\":\"What's the difference between Alteryx, DataRobot, and Dataiku DSS? Compare Alteryx vs. DataRobot vs. Dataiku DSS in 2024 by cost, reviews, features, integrations, deployment, target market, support options, trial offers, training options, years in business, region, and more using the chart below. Alteryx View Product DataRobot View Product\",\"ae\":null,\"b\":\"/.\\tSlashdot\\tslashdot.org\",\"c\":\"https://slashdot.org/software/comparison/Alteryx-vs-DataRobot-vs-Dataiku-DSS/\",\"d\":\"slashdot.org/software/comparison/Alteryx-vs-DataRobot-vs-Dataiku-DSS/\",\"da\":\"\",\"h\":0,\"i\":\"slashdot.org\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare Alteryx vs. DataRobot vs. Dataiku DSS in 2023 - Slashdot\",\"u\":\"https://slashdot.org/software/comparison/Alteryx-vs-DataRobot-vs-Dataiku-DSS/\"},{\"a\":\"What's the difference between DataRobot, Databricks Lakehouse, and Dataiku DSS? Compare DataRobot vs. Databricks Lakehouse vs. Dataiku DSS in 2023 by cost, reviews, features, integrations, deployment, target market, support options, trial offers, training options, years in business, region, and more using the chart below.\",\"ae\":null,\"b\":\"/.\\tSlashdot\\tslashdot.org\",\"c\":\"https://slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS/\",\"d\":\"slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS/\",\"da\":\"\",\"h\":0,\"i\":\"slashdot.org\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare DataRobot vs. Databricks Lakehouse vs. Dataiku DSS - Slashdot\",\"u\":\"https://slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS/\"},{\"a\":\"The platforms we've chosen for our analysis are ClearML, cnvrg.io, Dataiku, Datarobot, Iguazio, Sagemaker, Seldon and Valohai from the managed side, and Flyte, Kubeflow, MLflow and Metaflow from the open-source side. This is by no means an exhaustive list of all the MLOps tools out there. Most of these are tools that describe themselves as ...\",\"ae\":null,\"c\":\"https://valohai.com/mlops-platforms-compared/\",\"d\":\"valohai.com/mlops-platforms-compared/\",\"da\":\"\",\"h\":0,\"i\":\"valohai.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"MLOps Platforms Compared - Valohai\",\"u\":\"https://valohai.com/mlops-platforms-compared/\"},{\"a\":\"Visual Machine Learning and automated features preprocessing: Builtin charts and dashboards: Code notebooks and recipes: Custom web applications and plugins: Collaboration: DEPLOYMENT OPTIONS; ... Dataiku Scores an overall 4.8 out of 5 rating Based on 249 ratings for the DSMLP market, as of March 1, 2022\",\"ae\":null,\"c\":\"https://www.dataiku.com/product/plans-and-features/\",\"d\":\"www.dataiku.com/product/plans-and-features/\",\"da\":\"\",\"h\":0,\"i\":\"www.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Explore Dataiku Plans and Features | Online or Installed\",\"u\":\"https://www.dataiku.com/product/plans-and-features/\"},{\"a\":\"What's the difference between DataRobot, Databricks Lakehouse, Dataiku DSS, and DATAGYM? Compare DataRobot vs. Databricks Lakehouse vs. Dataiku DSS vs. DATAGYM in 2024 by cost, reviews, features, integrations, deployment, target market, support options, trial offers, training options, years in business, region, and more using the chart below.\",\"ae\":null,\"b\":\"/.\\tSlashdot\\tslashdot.org\",\"c\":\"https://slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS-vs-datagym/\",\"d\":\"slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS-vs-datagym/\",\"da\":\"\",\"h\":0,\"i\":\"slashdot.org\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare DataRobot vs. Databricks Lakehouse vs. Dataiku DSS vs. DATAGYM ...\",\"u\":\"https://slashdot.org/software/comparison/DataRobot-vs-Databricks-vs-Dataiku-DSS-vs-datagym/\"},{\"a\":\"Claim Dataiku DSS and update features and information. Compare C3 AI Suite vs. DataRobot vs. Dataiku DSS using this comparison chart. Compare price, features, and reviews of the software side-by-side to make the best choice for your business.\",\"ae\":null,\"b\":\"srcforge\\tSourceForge\\tsourceforge.net\",\"c\":\"https://sourceforge.net/software/compare/C3-AI-Suite-vs-DataRobot-vs-Dataiku-DSS/\",\"d\":\"sourceforge.net/software/compare/C3-AI-Suite-vs-DataRobot-vs-Dataiku-DSS/\",\"da\":\"\",\"h\":0,\"i\":\"sourceforge.net\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"C3 AI Suite vs. DataRobot vs. Dataiku DSS Comparison - SourceForge\",\"u\":\"https://sourceforge.net/software/compare/C3-AI-Suite-vs-DataRobot-vs-Dataiku-DSS/\"},{\"a\":\"Compare DataRobot AI Platform and Dataiku using real user data focused on features, satisfaction, business value, and the vendor relationship. What is Machine Learning Platforms (ML) Software?\",\"ae\":null,\"c\":\"https://www.softwarereviews.com/categories/machine-learning-platforms/compare/datarobot-ai-platform-vs-dataiku\",\"d\":\"www.softwarereviews.com/categories/machine-learning-platforms/compare/datarobot-ai-platform-vs-dataiku\",\"da\":\"\",\"h\":0,\"i\":\"www.softwarereviews.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"DataRobot AI Platform vs Dataiku - Machine Learning Platforms\",\"u\":\"https://www.softwarereviews.com/categories/machine-learning-platforms/compare/datarobot-ai-platform-vs-dataiku\"},{\"a\":\"What's the difference between Amazon SageMaker, DataRobot, and Dataiku DSS? Compare Amazon SageMaker vs. DataRobot vs. Dataiku DSS in 2024 by cost, reviews, features, integrations, deployment, target market, support options, trial offers, training options, years in business, region, and more using the chart below.\",\"ae\":null,\"b\":\"/.\\tSlashdot\\tslashdot.org\",\"c\":\"https://slashdot.org/software/comparison/Amazon-SageMaker-vs-DataRobot-vs-Dataiku-DSS/\",\"d\":\"slashdot.org/software/comparison/Amazon-SageMaker-vs-DataRobot-vs-Dataiku-DSS/\",\"da\":\"\",\"h\":0,\"i\":\"slashdot.org\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare Amazon SageMaker vs. DataRobot vs. Dataiku DSS in 2024 - Slashdot\",\"u\":\"https://slashdot.org/software/comparison/Amazon-SageMaker-vs-DataRobot-vs-Dataiku-DSS/\"},{\"a\":\"Compare Analance vs. DataRobot vs. Dataiku DSS using this comparison chart. Compare price, features, and reviews of the software side-by-side to make the best choice for your business.\",\"ae\":null,\"b\":\"srcforge\\tSourceForge\\tsourceforge.net\",\"c\":\"https://sourceforge.net/software/compare/Analance-vs-DataRobot-vs-Dataiku-DSS/\",\"d\":\"sourceforge.net/software/compare/Analance-vs-DataRobot-vs-Dataiku-DSS/\",\"da\":\"\",\"h\":0,\"i\":\"sourceforge.net\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Analance vs. DataRobot vs. Dataiku DSS Comparison - SourceForge\",\"u\":\"https://sourceforge.net/software/compare/Analance-vs-DataRobot-vs-Dataiku-DSS/\"},{\"n\":\"/d.js?q=Dataiku%20vs%20DataRobot%20features&kl=wt-wt&l=wt-wt&p=&s=23&ex=-1&ct=US&sp=0&vqd=4-334935250614046875026454141242803242982\"}]);DDG.duckbar.load('images');DDG.duckbar.load('news');DDG.duckbar.load('videos');DDG.duckbar.loadModule('related_searches', {\"ads\":[],\"query\":\"Dataiku vs DataRobot features\",\"queryEncoded\":\"Dataiku%20vs%20DataRobot%20features\",\"response_type\":\"places\",\"results\":[{\"display_text\":\"dataiku vs datarobot review\",\"text\":\"dataiku vs datarobot review\",\"web_search_url\":\"?q=dataiku%20vs%20datarobot%20review\"},{\"display_text\":\"dataiku vs alteryx\",\"text\":\"dataiku vs alteryx\",\"web_search_url\":\"?q=dataiku%20vs%20alteryx\"},{\"display_text\":\"gartner dataiku reviews\",\"text\":\"gartner dataiku reviews\",\"web_search_url\":\"?q=gartner%20dataiku%20reviews\"},{\"display_text\":\"alteryx vs dataiku knime\",\"text\":\"alteryx vs dataiku knime\",\"web_search_url\":\"?q=alteryx%20vs%20dataiku%20knime\"},{\"display_text\":\"dataiku vs rapidminer\",\"text\":\"dataiku vs rapidminer\",\"web_search_url\":\"?q=dataiku%20vs%20rapidminer\"},{\"display_text\":\"dataiku vs azure ml\",\"text\":\"dataiku vs azure ml\",\"web_search_url\":\"?q=dataiku%20vs%20azure%20ml\"},{\"display_text\":\"sagemaker vs dataiku\",\"text\":\"sagemaker vs dataiku\",\"web_search_url\":\"?q=sagemaker%20vs%20dataiku\"},{\"display_text\":\"dataiku reviews\",\"text\":\"dataiku reviews\",\"web_search_url\":\"?q=dataiku%20reviews\"}],\"vqd\":{\"Dataiku%20vs%20DataRobot%20features\":\"4-334935250614046875026454141242803242982\"}});if (DDG.pageLayout) DDG.pageLayout.initialize({\"mainline\":{\"items\":[[\"ad\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"related_searches\"]]},\"sidebar\":{\"items\":[[\"wikipedia_fathead\"]]}}, { start: 0 });DDG.deep.emit(\"load:completed\");", "curl-cffi-POST-https://duckduckgo.com-{\"data\": {\"q\": \"Dataiku and DataRobot use cases\"}}": "Dataiku and DataRobot use cases at DuckDuckGo
", - "curl-cffi-GET-https://links.duckduckgo.com/d.js-{\"params\": {\"bing_market\": \"wt-WT\", \"df\": null, \"ex\": \"-1\", \"kl\": \"wt-wt\", \"l\": \"wt-wt\", \"q\": \"Dataiku and DataRobot use cases\", \"s\": \"0\", \"sp\": \"0\", \"vqd\": \"4-60481969350525797892441552954401970387\"}}": "if (DDG.deep && DDG.deep.setUpstream) DDG.deep.setUpstream(\"bingv7aa\");DDG.deep.bn={'ivc':1};if (DDG.pageLayout) DDG.pageLayout.load('a',[{\"a\":\"\\u9ad8\\u7cbe\\u5ea6\\u306a\\u6a5f\\u68b0\\u5b66\\u7fd2\\u30e2\\u30c7\\u30eb\\u3092\\u69cb\\u7bc9\\u3001\\u5b9f\\u88c5\\u3001\\u904b\\u7528\\u3002DataRobot\\u306f\\u793e\\u5185\\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u65b0\\u3057\\u3044\\u4fa1\\u5024\\u3092\\u5275\\u9020\\u3057\\u307e\\u3059. AI\\u3092\\u6d3b\\u7528\\u3057\\u30c7\\u30fc\\u30bf\\u3092\\u5206\\u6790\\u3001\\u5b9f\\u7528\\u7684\\u306a\\u30a4\\u30f3\\u30b5\\u30a4\\u30c8\\u3092\\u660e\\u3089\\u304b\\u306b\\u3002\\u30d3\\u30b8\\u30cd\\u30b9\\u306e\\u8ab2\\u984c\\u3092\\u3088\\u308a\\u65e9\\u304f\\u89e3\\u6c7a\",\"adext\":{\"callout\":{\"t\":\"30-Day Free Trial \\u00b7 Trusted by Fortune 50 \\u00b7 No Vendor Lock-in\",\"tid\":\"6\"},\"filterlinks\":{\"l\":[],\"tid\":\"\"},\"sitelinks\":{\"l\":[{\"snippet\":\"Explore the DataRobot AI Platform Get Started With a 30-Day Trial\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=d0faee2c8c1aae9ac3a012e21d37352a1181970dce9edeba4107839fbfbf097a&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De81Q_rqdj1ZxH5XXGh4PG6pjVUCUzdB7rGpyykWEihNc_sSp5n%2DJ9jIyTjOSnXg0OUazrpKgDJrNvBOdNa5PjBGtyLGt23nrBAabI6opJXrliWQ4o%2DTyxIsqOeCXqzLOOJ3jJb74k6KEx20zilzwKmzSg3nBop2A9JqsasC17VVDPc3_i3EzPbWeRNS4nhxXWJqBKd55GfhuEOg2RZUbmmuAUhWvM%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnRyaWFsJTJmJTNmdXRtX21lZGl1bSUzZHNlYXJjaCUyNnV0bV9zb3VyY2UlM2RiaW5nJTI2dXRtX2NhbXBhaWduJTNkRnJlZVRyaWFsMjAyM1dXMDgxNkdQU2FkZXh0JTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDc2YmMwNmFmNTA0NDFjOGVjOGYxNjMwY2FmNGU4ZTVk%26rlid%3D76bc06af50441c8ec8f1630caf4e8e5d&vqd=4-164177780916400746369660096493208330918&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5063.1\",\"text\":\"DataRobot Free Trial\"},{\"snippet\":\"Unlock Your AI Success in 2023 Tips on the Path of Value-Driven AI\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=fdb107a4de6fffdec2bdf43b561b2c63ca700daaef68f0e683547361efbbc2b0&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8%2DT0j3GTQEgr%2DmtHPM1LzNzVUCUyRxvVKYHe6LbNa2mmCfCZh3Ept1NM%2DP%2DM1AAluh_OL3VQw_FWI0A3YxC3pzzqthf3gpxan_Lv7CjKenge%2DwMYUz3bRFoFyHtQBMdgqv6T7gMGfyYwN3UCj6FNYwVVn9UNN0h1dIQanHNB6Ya9gRrPBACknA8qtsf6A2oUG1xhq7AOF98NzGphnfQ_38fySnRU%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnJlc291cmNlcyUyZmFpc3VjY2VzczIwMjMlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RDb250ZW50MTBLZXlzdG9BSVN1Y2Nlc3MyMDIzV1cwNTIyR1BTYWRleHQlMjZ1dG1fdGVybSUzZGRhdGFyb2JvdCUyNnV0bV9jb250ZW50JTNkYWRfZXh0JTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZGQzNmQ2MzlkMmFlNTEwMTM3ZTIwMDYzZWQ1ZWY3M2Yz%26rlid%3Dd36d639d2ae510137e20063ed5ef73f3&vqd=4-117927704271333462986714580056949079639&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5065.1\",\"text\":\"10 Keys to AI Success\"},{\"snippet\":\"Our Platform Includes Four Fully Integrated Products. Read More.\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=4f06bd3312172b8e61d65ee2626dea6e26d941c3a16aa546b4e11b79e8bf027f&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8885tVmNmhi65Jmp3f2wYSzVUCUyFey1LCmrSNpGfkWzQnoC7QIbU3ztthJ%2DqKpgCmRfxudhbLK927YN84jvZlV2zTKo9DOULVj5wB8mcGXy_F42SnsrO1jZpY9NnMnzqMYPb5xZTTdgrTO1_w3Bgpd0e0VzO81_O3%2Dfo2z4UiLuVETFVqfACqR6NEwz0yfjzJe6ED9tvi_gPDiUL9iWATrNIrsw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnByb2R1Y3QlMmYlM2ZjYW1wYWlnbmlkJTNkNTMwNzA4MDk5JTI2YWRncm91cGlkJTNkMTM1MDIwMjc3NDIxNzY5OCUyNmFkaWQlM2QlMjZtc2Nsa2lkJTNkY2U4NzQ1ZDViODBlMTJmNjQ2N2QyMDc2NDcwNDY2YjI%26rlid%3Dce8745d5b80e12f6467d2076470466b2&vqd=4-169069202740993895017985472268973083525&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5067.1\",\"text\":\"Product Overview\"}],\"tid\":\"7\\t9[8]\\t11[10]\\t13[12]\",\"type\":\"EnhancedSiteLink\"},\"tid\":\"1\"},\"ae\":{\"callout\":[\"30-Day Free Trial \\u00b7 Trusted by Fortune 50 \\u00b7 No Vendor Lock-in\"]},\"c\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=e744d99a8df00b24df71f821ad4d1332080aa03267e50f0e988d284f58d9d2ef&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8tT9soRYLZabP1ukFkRsgNzVUCUzl89Y8xEqpxoqHqIlCI5wWbydNnN_PoAKHAa2Vsio83mXA_ax16t6rJ7XGkBv0Cg7_D1eg2QAuJgPKEam4VWI3rW40B03r1p11ZXN1Gd1847Vj05bAnJnPfgVyC8ZzFQxLxONmOI0Hg182z2bZUVII26BUAlUHaVZ7O_9FEXLJWw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZmpwJTJmbHAlMmZhaS1mb3ItYnVzaW5lc3MlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RERU1PMjAyM0FsbFByb2R1Y3RzSlAwNjI2QlBTJTI2dXRtX3Rlcm0lM2RkYXRhcm9ib3QlMjZ1dG1fY29udGVudCUzZERSX2JyYW5kZWRfcnNhJTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDA2MTIwYzhmMTAxNzEwYTZiNmRiNjkyY2VmMWRiOTY1%26rlid%3D06120c8f101710a6b6db692cef1db965&vqd=4-91027509783546726889708070523412001433&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5058.1\",\"d\":\"datarobot.com\",\"h\":0,\"i\":\"\",\"k\":0,\"m\":0,\"o\":\"\",\"p\":1,\"relevancy\":{\"abstract\":\"%E9%AB%98%E7%B2%BE%E5%BA%A6%E3%81%AA%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E6%A7%8B%E7%AF%89%E3%80%81%E5%AE%9F%E8%A3%85%E3%80%81%E9%81%8B%E7%94%A8%E3%80%82%3Cb%3EDataRobot%3C%2Fb%3E%E3%81%AF%E7%A4%BE%E5%86%85%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E6%96%B0%E3%81%97%E3%81%84%E4%BE%A1%E5%80%A4%E3%82%92%E5%89%B5%E9%80%A0%E3%81%97%E3%81%BE%E3%81%99.%20AI%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%86%E6%9E%90%E3%80%81%E5%AE%9F%E7%94%A8%E7%9A%84%E3%81%AA%E3%82%A4%E3%83%B3%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E6%98%8E%E3%82%89%E3%81%8B%E3%81%AB%E3%80%82%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%81%AE%E8%AA%B2%E9%A1%8C%E3%82%92%E3%82%88%E3%82%8A%E6%97%A9%E3%81%8F%E8%A7%A3%E6%B1%BA\",\"adx_name\":\"none\",\"is_good_v10\":0,\"organic_ranks\":[5,11,12,13],\"q\":\"Dataiku%20and%20DataRobot%20use%20cases\",\"q_words\":4,\"q_words_fuzzy\":0.25,\"q_words_in_ad\":1,\"root_domain\":\"datarobot.com\",\"start\":\"0\",\"title\":\"%E3%83%93%E3%83%83%E3%82%B0%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%82%92%E9%AB%98%E9%80%9F%E5%8C%96%20%2D%20%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E6%96%B0%E3%81%97%E3%81%84%E4%BE%A1%E5%80%A4%E3%82%92\"},\"s\":\"bingv7aa\",\"t\":\"\\u30d3\\u30c3\\u30b0\\u30c7\\u30fc\\u30bf\\u5206\\u6790\\u3092\\u9ad8\\u901f\\u5316 - \\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u65b0\\u3057\\u3044\\u4fa1\\u5024\\u3092\",\"tid\":\"1,6,7,9[8],11[10],13[12]\",\"u\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=e744d99a8df00b24df71f821ad4d1332080aa03267e50f0e988d284f58d9d2ef&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8tT9soRYLZabP1ukFkRsgNzVUCUzl89Y8xEqpxoqHqIlCI5wWbydNnN_PoAKHAa2Vsio83mXA_ax16t6rJ7XGkBv0Cg7_D1eg2QAuJgPKEam4VWI3rW40B03r1p11ZXN1Gd1847Vj05bAnJnPfgVyC8ZzFQxLxONmOI0Hg182z2bZUVII26BUAlUHaVZ7O_9FEXLJWw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZmpwJTJmbHAlMmZhaS1mb3ItYnVzaW5lc3MlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RERU1PMjAyM0FsbFByb2R1Y3RzSlAwNjI2QlBTJTI2dXRtX3Rlcm0lM2RkYXRhcm9ib3QlMjZ1dG1fY29udGVudCUzZERSX2JyYW5kZWRfcnNhJTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDA2MTIwYzhmMTAxNzEwYTZiNmRiNjkyY2VmMWRiOTY1%26rlid%3D06120c8f101710a6b6db692cef1db965&vqd=4-91027509783546726889708070523412001433&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5058.1\"}], {\"page_load_url\":\"https://duckduckgo.com/y.js?ifu=%7B3%7Dappid%3D055AAD1BA669BEB8B048128DC89A107C678B527B%26rguid%3D309794dc72f748f6a2b95ce5c34fbcec&iurl=%7B2%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26Type%3DEvent.CPT%26DATA%3D0\",\"visibility_url\":\"https://duckduckgo.com/y.js?ivu=%7B4%7Dtype%3Dmv%26reqver%3D1.0%26rg%3D309794dc72f748f6a2b95ce5c34fbcec\"});DDG.deep.signalSummary = \"\";DDG.inject('DDG.Data.languages.resultLanguages', {\"en\":[\"https://knowledge.dataiku.com/latest/use-cases/index.html\",\"https://community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\",\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"https://www.datarobot.com/use-cases/\",\"https://academy.dataiku.com/page/use-cases\",\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\",\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"https://londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\",\"https://docs.datarobot.com/en/docs/api/guide/common-case/index.html\",\"https://www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\",\"https://docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\",\"https://blog.dataiku.com/topic/use-cases-projects\",\"https://valohai.com/mlops-platforms-compared/\",\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"https://pages.dataiku.com/experience-a-dataiku-demo\",\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"https://www.dataiku.com/stories/\",\"https://www.dataiku.com/\",\"https://techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\",\"https://www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\"]});DDG.deep.pageLayoutSummary = \"a1w4v1w19,w1\";DDG.inject('DDG.Data.languages.adLanguages', {});if (DDG.pageLayout) DDG.pageLayout.load('d',[{\"a\":\"Use Cases - Dataiku Knowledge Base Use Cases # These use cases allow you to practice what you've learned by building simplified, but complete use cases in Dataiku. Topics # Data Preparation Use Cases Classification Use Cases Clustering Use Cases Plugin Use Cases\",\"ae\":null,\"c\":\"https://knowledge.dataiku.com/latest/use-cases/index.html\",\"d\":\"knowledge.dataiku.com/latest/use-cases/index.html\",\"da\":\"\",\"h\":0,\"i\":\"knowledge.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Use Cases - Dataiku Knowledge Base\",\"u\":\"https://knowledge.dataiku.com/latest/use-cases/index.html\"},{\"a\":\"Community Dataiku Use Cases & Success Stories \\u26a0\\ufe0f Discover pioneering Dataiku use cases and success stories shared by customers, partners, academics, and nonprofits participating in the Dataiku Frontrunner Awards. Use the following labels to filter submissions by industry:\",\"ae\":null,\"c\":\"https://community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\",\"d\":\"community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\",\"da\":\"\",\"h\":0,\"i\":\"community.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku Use Cases & Success Stories - Dataiku Community\",\"u\":\"https://community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\"},{\"a\":\"Dataiku is a cross-platform desktop application that includes a broad range of tools, such as notebooks (similar to Jupyter Notebook), workflow management (similar to Apache Airflow), and automated machine learning. In general, Dataiku aims to replace many of your existing tools rather than to integrate with them.\",\"ae\":null,\"c\":\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"d\":\"www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"da\":\"\",\"h\":0,\"i\":\"www.datarevenue.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"ML Platforms: Dataiku vs. Alteryx vs. Sagemaker vs. Datarobot\",\"u\":\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\"},{\"a\":\"Dataiku has a rating of 4.8 stars with 504 reviews. DataRobot has a rating of 4.6 stars with 508 reviews. See side-by-side comparisons of product capabilities, customer experience, pros and cons, and reviewer demographics to find the best fit for your organization. See more companies in the Data Science and Machine Learning Platforms market. PDF.\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"d\":\"www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku vs DataRobot 2024 | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\"},{\"a\":\"In my humble opinion DSS is a more a 'toolbox', where as DataRobot is an autoML platform. DataRobot is really good at what it does - if you have non-technical team who want to drop in data and leave everything to autoML then this may be the option for them.\",\"ae\":null,\"c\":\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"d\":\"community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"da\":\"\",\"h\":0,\"i\":\"community.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Solved: Dataiku vs DataRobot - Dataiku Community\",\"u\":\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\"},{\"a\":\"Use cases AI Use Cases AI-driven organizations around the world use DataRobot to solve their most pressing business problems. Build with Free Trial Recent Popular Filters Ready to Get Started? See how a value-driven approach to AI can accelerate time to impact. Start Free Trial\",\"ae\":null,\"c\":\"https://www.datarobot.com/use-cases/\",\"d\":\"www.datarobot.com/use-cases/\",\"da\":\"\",\"h\":0,\"i\":\"www.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Machine Learning Use Cases | DataRobot AI Platform\",\"u\":\"https://www.datarobot.com/use-cases/\"},{\"a\":\"With Dataiku's AI Prepare assistant, you can work smarter, not harder. Simply describe the transformation you want to apply in natural language and the AI assistant automatically generates the necessary data preparation steps. The ability to modify both your prompt and the resulting steps means you can prepare data faster than ever, yet still ...\",\"ae\":null,\"c\":\"https://academy.dataiku.com/page/use-cases\",\"d\":\"academy.dataiku.com/page/use-cases\",\"da\":\"\",\"h\":0,\"i\":\"academy.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Use Cases - Dataiku\",\"u\":\"https://academy.dataiku.com/page/use-cases\"},{\"a\":\"84 Reviews and Ratings Path to AI Success Compare Dataiku DSS vs DataRobot. 103 verified user reviews and ratings of features, pros, cons, pricing, support and more.\",\"ae\":null,\"c\":\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"d\":\"www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.trustradius.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku DSS vs DataRobot | TrustRadius\",\"u\":\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\"},{\"a\":\"side-by-side comparison of DataRobot vs. Dataiku DSS. based on preference data from user reviews. DataRobot rates 4.4/5 stars with 26 reviews. By contrast, Dataiku DSS rates 4.3/5 stars with 36 reviews. Each product's score is calculated with real-time data from verified user reviews, to help you make the best choice between these two options ...\",\"ae\":null,\"c\":\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\",\"d\":\"www.g2.com/compare/datarobot-vs-dataiku-dss\",\"da\":\"\",\"h\":0,\"i\":\"www.g2.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare DataRobot vs. Dataiku DSS | G2\",\"u\":\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\"},{\"a\":\"Use case: Choose Datarobot if you have data stored in spreadsheets and are seeking a platform that is the simplest, albeit one with limited flexibility, ... Dataiku vs. Datarobot .\",\"ae\":null,\"b\":\"li\\tLinkedIn\\twww.linkedin.com\",\"c\":\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"d\":\"www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"da\":\"\",\"e\":\"2023-08-11T00:00:00.0000000\",\"h\":0,\"i\":\"www.linkedin.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Managed Machine Learning Platforms: A Comparative Analysis - LinkedIn\",\"u\":\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\"},{\"a\":\"Jan 11, 2023 Dataiku is an artificial intelligence platform created in France in 2013. It has since become one of the world's benchmarks for data science and machine learning studios. What is...\",\"ae\":null,\"c\":\"https://londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\",\"d\":\"londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\",\"da\":\"translations\",\"e\":\"2023-01-11T00:00:00.0000000\",\"h\":0,\"i\":\"londondataconsulting.medium.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku: What is it? How to use it? Ultimate Guide 2023\",\"u\":\"https://londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\"},{\"a\":\"Use cases for version 2.x. Notebooks for uses cases that use methods for 2.x versions of DataRobot's Python client. Measure price elasticity of demand. A use case to identify relationships between price and demand, maximize revenue by properly pricing products, and monitor price elasticities for changes in price and demand. Insurance claim triage.\",\"ae\":null,\"c\":\"https://docs.datarobot.com/en/docs/api/guide/common-case/index.html\",\"d\":\"docs.datarobot.com/en/docs/api/guide/common-case/index.html\",\"da\":\"\",\"h\":0,\"i\":\"docs.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Common use cases: DataRobot docs - DataRobot AI Platform\",\"u\":\"https://docs.datarobot.com/en/docs/api/guide/common-case/index.html\"},{\"a\":\"With the Use Case Value Tracker, you can manage the project lifecycle and understand the value associated with each step. It also enables you to associate and organize all your DataRobot artifacts (e.g., datasets, models, deployments, applications, etc.) around a given use case for a holistic view. In addition to the project management aspects ...\",\"ae\":null,\"c\":\"https://www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\",\"d\":\"www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\",\"da\":\"\",\"h\":0,\"i\":\"www.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Introducing the DataRobot Use Case Value Tracker\",\"u\":\"https://www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\"},{\"a\":\"Use Cases are folder-like containers inside of DataRobot Workbench that allow you to group everything related to solving a specific business problem\\u2014datasets, models, experiments, No-Code AI Apps, and notebooks\\u2014inside of a single, manageable entity. You can share whole Use Cases as well as the individual assets they contain.\",\"ae\":null,\"c\":\"https://docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\",\"d\":\"docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\",\"da\":\"\",\"e\":\"2023-09-15T00:00:00.0000000\",\"h\":0,\"i\":\"docs.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Use Cases: DataRobot docs\",\"u\":\"https://docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\"},{\"a\":\"January 2, 2024 Use Cases & Projects, Featured Sophie Dionnet Leveraging AI to Cut Costs December 29, 2023 Data Basics, Featured\",\"ae\":null,\"c\":\"https://blog.dataiku.com/topic/use-cases-projects\",\"d\":\"blog.dataiku.com/topic/use-cases-projects\",\"da\":\"\",\"h\":0,\"i\":\"blog.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Blog - Dataiku | Use Cases & Projects\",\"u\":\"https://blog.dataiku.com/topic/use-cases-projects\"},{\"a\":\"The platforms we've chosen for our analysis are ClearML, cnvrg.io, Dataiku, Datarobot, Iguazio, Sagemaker, Seldon and Valohai from the managed side, and Flyte, Kubeflow, MLflow and Metaflow from the open-source side. This is by no means an exhaustive list of all the MLOps tools out there.\",\"ae\":null,\"c\":\"https://valohai.com/mlops-platforms-compared/\",\"d\":\"valohai.com/mlops-platforms-compared/\",\"da\":\"\",\"h\":0,\"i\":\"valohai.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"MLOps Platforms Compared - Valohai\",\"u\":\"https://valohai.com/mlops-platforms-compared/\"},{\"a\":\"DataRobot. DSS is for all companies, whatever their expertise, industry or size, that want to create their own data-driven strategic advantages by transforming their raw data into business impacting predictions. Cloud based machine learning platform which helps enterprises scale data science capabilities through deploying machine learning ...\",\"ae\":null,\"c\":\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"d\":\"www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"da\":\"translations\",\"h\":0,\"i\":\"www.capterra.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare Dataiku vs DataRobot 2024 | Capterra\",\"u\":\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\"},{\"a\":\"For Every Industry & Use Case. Organizations that use Dataiku elevate their people (whether technical and working in code or on the business side and low- or no-code) to extraordinary, arming them with the ability to make better day-to-day decisions with data across: Banking & Insurance. Pharmaceuticals. Manufacturing. Telecommunications.\",\"ae\":null,\"c\":\"https://pages.dataiku.com/experience-a-dataiku-demo\",\"d\":\"pages.dataiku.com/experience-a-dataiku-demo\",\"da\":\"\",\"h\":0,\"i\":\"pages.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Check Out This Dataiku Demo\",\"u\":\"https://pages.dataiku.com/experience-a-dataiku-demo\"},{\"a\":\"4 Star 24% 3 Star 1% 2 Star 0% 1 Star 0% Distribution based on 504 ratings Customer Experience Evaluation & Contracting 4.6 Integration & Deployment 4.7 Service & Support 4.8 Product Capabilities 4.8 FREE View and Download Peer Insights About Dataiku\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"d\":\"www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku Reviews, Ratings & Features 2024 | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\"},{\"a\":\"Read The Full Case Study U.S. Venture + Dataiku: Upskilling Analysts to Save Thousands of Hours The Data and Analytics team at U.S. Venture was built to usher the company into the future of data science and AI.\",\"ae\":null,\"c\":\"https://www.dataiku.com/stories/\",\"d\":\"www.dataiku.com/stories/\",\"da\":\"\",\"h\":0,\"i\":\"www.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Stories | Dataiku\",\"u\":\"https://www.dataiku.com/stories/\"},{\"a\":\"MLOps Deploy, monitor, and maintain machine learning models, all in a single platform. Explore the Capability Collaboration With Dataiku, teams can move beyond the lab and build real and safe Generative AI applications at enterprise scale. Explore the Capability Governance\",\"ae\":null,\"c\":\"https://www.dataiku.com/\",\"d\":\"www.dataiku.com\",\"da\":\"\",\"h\":0,\"i\":\"www.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku | Everyday AI, Extraordinary People\",\"u\":\"https://www.dataiku.com/\"},{\"a\":\"The company today announced that it raised $200 million in a Series F round led by Wellington Management at a $3.7 billion valuation, down from the $4.6 billion that Dataiku received in August ...\",\"ae\":null,\"b\":\"tc\\tTechcrunch\\ttechcrunch.com\",\"c\":\"https://techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\",\"d\":\"techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\",\"da\":\"translations\",\"e\":\"2022-12-13T17:10:00.0000000\",\"h\":0,\"i\":\"techcrunch.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"AI and analytics platform Dataiku raises $200M at a reduced valuation\",\"u\":\"https://techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\"},{\"a\":\"Today, more than 500 companies worldwide use Dataiku to integrate and streamline their use of data, analytics, and AI, driving diverse use cases from fraud detection and customer churn prevention ...\",\"ae\":null,\"c\":\"https://www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\",\"d\":\"www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\",\"da\":\"translations\",\"e\":\"2022-11-17T13:00:00.0000000\",\"h\":0,\"i\":\"www.globenewswire.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Ben Taylor Joins Dataiku as Chief AI Strategist - GlobeNewswire\",\"u\":\"https://www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\"},{\"n\":\"/d.js?q=Dataiku%20and%20DataRobot%20use%20cases&kl=wt-wt&l=wt-wt&p=&s=23&ex=-1&ct=US&sp=0&vqd=4-60481969350525797892441552954401970387\"}]);DDG.duckbar.load('images');DDG.duckbar.load('news');DDG.duckbar.load('videos', {\"ads\":[],\"query\":\"Dataiku and DataRobot use cases\",\"queryEncoded\":\"Dataiku%20and%20DataRobot%20use%20cases\",\"response_type\":\"places\",\"results\":[{\"content\":\"https://www.youtube.com/watch?v=ryZRRIjQ5Z8\",\"description\":\"If you're a code-first data practitioner, Dataiku helps you efficiently build high quality data pipelines and models in a number of ways. CHECK OUT DATAIKU: https://bit.ly/36XBlpK EGG ON AIR: https://bit.ly/37GhXMY BRIGHTTALK WEBINARS: https://bit.ly/33TIRjn DATA SCIENCE PIONEERS DOCUMENTARY: https://bit.ly/36V3rBF PARTNER ECOSYSTEM: https ...\",\"duration\":\"10:43\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/ryZRRIjQ5Z8?autoplay=1\",\"image_token\":\"8a4abca8613c6680a108591849e5d7b13b86111004ae004898a7f059b64c8355\",\"images\":{\"large\":\"https://tse4.mm.bing.net/th?id=OVP.WoendyuZJ9qxql-n6jit5AEsDh&pid=Api\",\"medium\":\"https://tse4.mm.bing.net/th?id=OVP.WoendyuZJ9qxql-n6jit5AEsDh&pid=Api\",\"motion\":\"https://tse4.mm.bing.net/th?id=OM1.cmvppfhHVUeE4Q_1684256861&pid=Api\",\"small\":\"https://tse4.mm.bing.net/th?id=OVP.WoendyuZJ9qxql-n6jit5AEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2021-06-08T21:15:02.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":12391},\"title\":\"Dataiku Demo for Data Scientists and Coders\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=jKL_I0SCl_E\",\"description\":\"This video showcases the Clinical Trial Explorer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of our ...\",\"duration\":\"1:50\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/jKL_I0SCl_E?autoplay=1\",\"image_token\":\"7b19602fe6d9b761aa3cc138448cc632ddbed31da3abf2687f36705f5945973d\",\"images\":{\"large\":\"https://tse3.mm.bing.net/th?id=OVP.wfgHp53woiVosZ37-1HtnwEsDh&pid=Api\",\"medium\":\"https://tse3.mm.bing.net/th?id=OVP.wfgHp53woiVosZ37-1HtnwEsDh&pid=Api\",\"motion\":\"https://tse3.mm.bing.net/th?id=OM2.ZX_yq0xmyCGZBg_1696372683&pid=Api\",\"small\":\"https://tse3.mm.bing.net/th?id=OVP.wfgHp53woiVosZ37-1HtnwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:19:00.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":150},\"title\":\"Clinical Trial Explorer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=lASesA4gNFI\",\"description\":\"This video showcases the CO2 Forecast Analyzer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of our ...\",\"duration\":\"1:50\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/lASesA4gNFI?autoplay=1\",\"image_token\":\"a09328adca01a788783d759561c2f9c9d4d214e5a26f1462d2b6b69f21a2d478\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.ZhQI7z-IMlcVnyeMJuGlAQEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.ZhQI7z-IMlcVnyeMJuGlAQEsDh&pid=Api\",\"motion\":\"\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.ZhQI7z-IMlcVnyeMJuGlAQEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:16:20.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":49},\"title\":\"CO2 Forecast Analyzer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=RecpD6Vtzj4\",\"description\":\"This video showcases the LLM-Enhanced ESG Document Intelligence use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the ...\",\"duration\":\"1:20\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/RecpD6Vtzj4?autoplay=1\",\"image_token\":\"6f797accb167e2e6ff7265e35116cdeb9f1c641b1df47932d9597b61b0108614\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.bm4gAiJOOmKV7uup6LU9pgEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.bm4gAiJOOmKV7uup6LU9pgEsDh&pid=Api\",\"motion\":\"https://tse2.mm.bing.net/th?id=OM1.M8WXwCQ79nrqEA_1691502936&pid=Api\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.bm4gAiJOOmKV7uup6LU9pgEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:30:00.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":382},\"title\":\"LLM-Enhanced ESG Document Intelligence\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=zLW0TkJoHLw\",\"description\":\"This video showcases the Demand Forecast Analyzer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of our ...\",\"duration\":\"1:42\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/zLW0TkJoHLw?autoplay=1\",\"image_token\":\"524eb9572bf9342b859509285d39ec4661fc572cb1452307acc5341b56bab921\",\"images\":{\"large\":\"https://tse1.mm.bing.net/th?id=OVP.yIekQ2cMUesOPJTfsYIZzQHgFo&pid=Api\",\"medium\":\"https://tse1.mm.bing.net/th?id=OVP.yIekQ2cMUesOPJTfsYIZzQHgFo&pid=Api\",\"motion\":\"\",\"small\":\"https://tse1.mm.bing.net/th?id=OVP.yIekQ2cMUesOPJTfsYIZzQHgFo&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:15:02.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":4},\"title\":\"LLM-Enhanced Demand Forecast\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=L-Yys0fzuVY\",\"description\":\"This video showcases the Production Quality Data Explorer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest ...\",\"duration\":\"1:47\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/L-Yys0fzuVY?autoplay=1\",\"image_token\":\"82924713be1dba83d67124fcaa6cc6afd163900a0c40f25fcf6c144ed0e36536\",\"images\":{\"large\":\"https://tse4.mm.bing.net/th?id=OVP.teiC0mX9nKCbH8qeo52udwEsDh&pid=Api\",\"medium\":\"https://tse4.mm.bing.net/th?id=OVP.teiC0mX9nKCbH8qeo52udwEsDh&pid=Api\",\"motion\":\"https://tse4.mm.bing.net/th?id=OM2.IwRaoLRWcQXzag_1691419996&pid=Api\",\"small\":\"https://tse4.mm.bing.net/th?id=OVP.teiC0mX9nKCbH8qeo52udwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:28:29.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":175},\"title\":\"Production Quality Data Explorer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=FluiuHuaU8A\",\"description\":\"In this breakout session of Dataiku's Product Days 2021, you will see a demo of Dataiku's Data Science Studio, the centralized, collaborative, and end-to-end platform for data science in the enterprise. CHECK OUT DATAIKU: https://bit.ly/36XBlpK EGG ON AIR: https://bit.ly/37GhXMY BRIGHTTALK WEBINARS: https://bit.ly/33TIRjn DATA SCIENCE PIONEERS ...\",\"duration\":\"13:50\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/FluiuHuaU8A?autoplay=1\",\"image_token\":\"2943fa8c1580f2936fc11667d670c0b827b94ff3d16b897f8b5ef2e2426487b3\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.RIM-ftwDZjYP58RimJfgwwEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.RIM-ftwDZjYP58RimJfgwwEsDh&pid=Api\",\"motion\":\"https://tse2.mm.bing.net/th?id=OM1.MIQ7BoQz1MVkNw_1662248868&pid=Api\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.RIM-ftwDZjYP58RimJfgwwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2021-07-08T15:56:22.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":3844},\"title\":\"Introduction to Dataiku Data Science | Product Days 2021\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=6TEU5JboP7k\",\"description\":\"This video showcases the LLM-Enhanced Next Best Offer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of ...\",\"duration\":\"1:47\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/6TEU5JboP7k?autoplay=1\",\"image_token\":\"a3bc327ff2f099462935a8979bb599655c7a88a44e25a64bfea7e5973f773158\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.Q6SP0MmL89M_TnLvNPG4oQEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.Q6SP0MmL89M_TnLvNPG4oQEsDh&pid=Api\",\"motion\":\"https://tse2.mm.bing.net/th?id=OM2.wXNo1CUgYV4Flg_1694065487&pid=Api\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.Q6SP0MmL89M_TnLvNPG4oQEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:34:32.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":462},\"title\":\"LLM-Enhanced Next Best Offer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=UVbrpX8Zkn8\",\"description\":\"Move beyond the lab and build real and safe Generative AI applications at enterprise scale. Dataiku brings enterprise-grade development tools, pre-built use cases, and AI-powered assistants throughout the platform. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore Generative AI use cases | https ...\",\"duration\":\"2:07\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/UVbrpX8Zkn8?autoplay=1\",\"image_token\":\"3968d2d01ff722efa156290344ab0b37164e57d7efa50905c346ea1cc1a5d369\",\"images\":{\"large\":\"https://tse1.mm.bing.net/th?id=OVP.F-xH3-wKfTjM3YMshnjWwwEsDh&pid=Api\",\"medium\":\"https://tse1.mm.bing.net/th?id=OVP.F-xH3-wKfTjM3YMshnjWwwEsDh&pid=Api\",\"motion\":\"https://tse1.mm.bing.net/th?id=OM1.z-FRwxQ_NByK_A_1689135755&pid=Api\",\"small\":\"https://tse1.mm.bing.net/th?id=OVP.F-xH3-wKfTjM3YMshnjWwwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:25:16.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":1100},\"title\":\"Dataiku for Generative AI: Real Applications, Real Safety\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=-amc9iVauuE\",\"description\":\"Dataiku is the leading platform for Everyday AI, systemizing the use of data for exceptional business results. In today's video we will take a tour of Dataiku's end to end capabilities by exploring a real life use case around environmental impact. Let's take a look at how a data science team with different skills can work together to turn ...\",\"duration\":\"12:35\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/-amc9iVauuE?autoplay=1\",\"image_token\":\"2a05a65ad8a2727aa5c48b8daa7f9ec363a24d4336a3509016d4b200c9d003cd\",\"images\":{\"large\":\"https://tse1.mm.bing.net/th?id=OVP.Az9RhdSVwpXe56mGcs6FqQEsDh&pid=Api\",\"medium\":\"https://tse1.mm.bing.net/th?id=OVP.Az9RhdSVwpXe56mGcs6FqQEsDh&pid=Api\",\"motion\":\"https://tse1.mm.bing.net/th?id=OM1.Q2OhN9DzfowU6A_1685345657&pid=Api\",\"small\":\"https://tse1.mm.bing.net/th?id=OVP.Az9RhdSVwpXe56mGcs6FqQEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-01-09T21:12:27.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":9768},\"title\":\"End to End Demo 2023\",\"uploader\":\"Dataiku\"}],\"vqd\":{\"Dataiku%20and%20DataRobot%20use%20cases\":\"4-60481969350525797892441552954401970387\"}});DDG.duckbar.loadModule('related_searches');if (DDG.pageLayout) DDG.pageLayout.initialize({\"mainline\":{\"items\":[[\"ad\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"videos\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"]]},\"sidebar\":{\"items\":[[\"organic\"]]}}, { start: 0 });DDG.deep.emit(\"load:completed\");" + "curl-cffi-GET-https://links.duckduckgo.com/d.js-{\"params\": {\"bing_market\": \"wt-WT\", \"df\": null, \"ex\": \"-1\", \"kl\": \"wt-wt\", \"l\": \"wt-wt\", \"q\": \"Dataiku and DataRobot use cases\", \"s\": \"0\", \"sp\": \"0\", \"vqd\": \"4-60481969350525797892441552954401970387\"}}": "if (DDG.deep && DDG.deep.setUpstream) DDG.deep.setUpstream(\"bingv7aa\");DDG.deep.bn={'ivc':1};if (DDG.pageLayout) DDG.pageLayout.load('a',[{\"a\":\"\\u9ad8\\u7cbe\\u5ea6\\u306a\\u6a5f\\u68b0\\u5b66\\u7fd2\\u30e2\\u30c7\\u30eb\\u3092\\u69cb\\u7bc9\\u3001\\u5b9f\\u88c5\\u3001\\u904b\\u7528\\u3002DataRobot\\u306f\\u793e\\u5185\\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u65b0\\u3057\\u3044\\u4fa1\\u5024\\u3092\\u5275\\u9020\\u3057\\u307e\\u3059. AI\\u3092\\u6d3b\\u7528\\u3057\\u30c7\\u30fc\\u30bf\\u3092\\u5206\\u6790\\u3001\\u5b9f\\u7528\\u7684\\u306a\\u30a4\\u30f3\\u30b5\\u30a4\\u30c8\\u3092\\u660e\\u3089\\u304b\\u306b\\u3002\\u30d3\\u30b8\\u30cd\\u30b9\\u306e\\u8ab2\\u984c\\u3092\\u3088\\u308a\\u65e9\\u304f\\u89e3\\u6c7a\",\"adext\":{\"callout\":{\"t\":\"30-Day Free Trial \\u00b7 Trusted by Fortune 50 \\u00b7 No Vendor Lock-in\",\"tid\":\"6\"},\"filterlinks\":{\"l\":[],\"tid\":\"\"},\"sitelinks\":{\"l\":[{\"snippet\":\"Explore the DataRobot AI Platform Get Started With a 30-Day Trial\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=d0faee2c8c1aae9ac3a012e21d37352a1181970dce9edeba4107839fbfbf097a&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De81Q_rqdj1ZxH5XXGh4PG6pjVUCUzdB7rGpyykWEihNc_sSp5n%2DJ9jIyTjOSnXg0OUazrpKgDJrNvBOdNa5PjBGtyLGt23nrBAabI6opJXrliWQ4o%2DTyxIsqOeCXqzLOOJ3jJb74k6KEx20zilzwKmzSg3nBop2A9JqsasC17VVDPc3_i3EzPbWeRNS4nhxXWJqBKd55GfhuEOg2RZUbmmuAUhWvM%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnRyaWFsJTJmJTNmdXRtX21lZGl1bSUzZHNlYXJjaCUyNnV0bV9zb3VyY2UlM2RiaW5nJTI2dXRtX2NhbXBhaWduJTNkRnJlZVRyaWFsMjAyM1dXMDgxNkdQU2FkZXh0JTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDc2YmMwNmFmNTA0NDFjOGVjOGYxNjMwY2FmNGU4ZTVk%26rlid%3D76bc06af50441c8ec8f1630caf4e8e5d&vqd=4-164177780916400746369660096493208330918&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5063.1\",\"text\":\"DataRobot Free Trial\"},{\"snippet\":\"Unlock Your AI Success in 2023 Tips on the Path of Value-Driven AI\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=fdb107a4de6fffdec2bdf43b561b2c63ca700daaef68f0e683547361efbbc2b0&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8%2DT0j3GTQEgr%2DmtHPM1LzNzVUCUyRxvVKYHe6LbNa2mmCfCZh3Ept1NM%2DP%2DM1AAluh_OL3VQw_FWI0A3YxC3pzzqthf3gpxan_Lv7CjKenge%2DwMYUz3bRFoFyHtQBMdgqv6T7gMGfyYwN3UCj6FNYwVVn9UNN0h1dIQanHNB6Ya9gRrPBACknA8qtsf6A2oUG1xhq7AOF98NzGphnfQ_38fySnRU%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnJlc291cmNlcyUyZmFpc3VjY2VzczIwMjMlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RDb250ZW50MTBLZXlzdG9BSVN1Y2Nlc3MyMDIzV1cwNTIyR1BTYWRleHQlMjZ1dG1fdGVybSUzZGRhdGFyb2JvdCUyNnV0bV9jb250ZW50JTNkYWRfZXh0JTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZGQzNmQ2MzlkMmFlNTEwMTM3ZTIwMDYzZWQ1ZWY3M2Yz%26rlid%3Dd36d639d2ae510137e20063ed5ef73f3&vqd=4-117927704271333462986714580056949079639&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5065.1\",\"text\":\"10 Keys to AI Success\"},{\"snippet\":\"Our Platform Includes Four Fully Integrated Products. Read More.\",\"targetUrl\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=4f06bd3312172b8e61d65ee2626dea6e26d941c3a16aa546b4e11b79e8bf027f&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8885tVmNmhi65Jmp3f2wYSzVUCUyFey1LCmrSNpGfkWzQnoC7QIbU3ztthJ%2DqKpgCmRfxudhbLK927YN84jvZlV2zTKo9DOULVj5wB8mcGXy_F42SnsrO1jZpY9NnMnzqMYPb5xZTTdgrTO1_w3Bgpd0e0VzO81_O3%2Dfo2z4UiLuVETFVqfACqR6NEwz0yfjzJe6ED9tvi_gPDiUL9iWATrNIrsw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZnByb2R1Y3QlMmYlM2ZjYW1wYWlnbmlkJTNkNTMwNzA4MDk5JTI2YWRncm91cGlkJTNkMTM1MDIwMjc3NDIxNzY5OCUyNmFkaWQlM2QlMjZtc2Nsa2lkJTNkY2U4NzQ1ZDViODBlMTJmNjQ2N2QyMDc2NDcwNDY2YjI%26rlid%3Dce8745d5b80e12f6467d2076470466b2&vqd=4-169069202740993895017985472268973083525&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5067.1\",\"text\":\"Product Overview\"}],\"tid\":\"7\\t9[8]\\t11[10]\\t13[12]\",\"type\":\"EnhancedSiteLink\"},\"tid\":\"1\"},\"ae\":{\"callout\":[\"30-Day Free Trial \\u00b7 Trusted by Fortune 50 \\u00b7 No Vendor Lock-in\"]},\"c\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=e744d99a8df00b24df71f821ad4d1332080aa03267e50f0e988d284f58d9d2ef&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8tT9soRYLZabP1ukFkRsgNzVUCUzl89Y8xEqpxoqHqIlCI5wWbydNnN_PoAKHAa2Vsio83mXA_ax16t6rJ7XGkBv0Cg7_D1eg2QAuJgPKEam4VWI3rW40B03r1p11ZXN1Gd1847Vj05bAnJnPfgVyC8ZzFQxLxONmOI0Hg182z2bZUVII26BUAlUHaVZ7O_9FEXLJWw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZmpwJTJmbHAlMmZhaS1mb3ItYnVzaW5lc3MlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RERU1PMjAyM0FsbFByb2R1Y3RzSlAwNjI2QlBTJTI2dXRtX3Rlcm0lM2RkYXRhcm9ib3QlMjZ1dG1fY29udGVudCUzZERSX2JyYW5kZWRfcnNhJTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDA2MTIwYzhmMTAxNzEwYTZiNmRiNjkyY2VmMWRiOTY1%26rlid%3D06120c8f101710a6b6db692cef1db965&vqd=4-91027509783546726889708070523412001433&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5058.1\",\"d\":\"datarobot.com\",\"h\":0,\"i\":\"\",\"k\":0,\"m\":0,\"o\":\"\",\"p\":1,\"relevancy\":{\"abstract\":\"%E9%AB%98%E7%B2%BE%E5%BA%A6%E3%81%AA%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E6%A7%8B%E7%AF%89%E3%80%81%E5%AE%9F%E8%A3%85%E3%80%81%E9%81%8B%E7%94%A8%E3%80%82%3Cb%3EDataRobot%3C%2Fb%3E%E3%81%AF%E7%A4%BE%E5%86%85%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E6%96%B0%E3%81%97%E3%81%84%E4%BE%A1%E5%80%A4%E3%82%92%E5%89%B5%E9%80%A0%E3%81%97%E3%81%BE%E3%81%99.%20AI%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%86%E6%9E%90%E3%80%81%E5%AE%9F%E7%94%A8%E7%9A%84%E3%81%AA%E3%82%A4%E3%83%B3%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E6%98%8E%E3%82%89%E3%81%8B%E3%81%AB%E3%80%82%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%81%AE%E8%AA%B2%E9%A1%8C%E3%82%92%E3%82%88%E3%82%8A%E6%97%A9%E3%81%8F%E8%A7%A3%E6%B1%BA\",\"adx_name\":\"none\",\"is_good_v10\":0,\"organic_ranks\":[5,11,12,13],\"q\":\"Dataiku%20and%20DataRobot%20use%20cases\",\"q_words\":4,\"q_words_fuzzy\":0.25,\"q_words_in_ad\":1,\"root_domain\":\"datarobot.com\",\"start\":\"0\",\"title\":\"%E3%83%93%E3%83%83%E3%82%B0%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%82%92%E9%AB%98%E9%80%9F%E5%8C%96%20%2D%20%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E6%96%B0%E3%81%97%E3%81%84%E4%BE%A1%E5%80%A4%E3%82%92\"},\"s\":\"bingv7aa\",\"t\":\"\\u30d3\\u30c3\\u30b0\\u30c7\\u30fc\\u30bf\\u5206\\u6790\\u3092\\u9ad8\\u901f\\u5316 - \\u30c7\\u30fc\\u30bf\\u304b\\u3089\\u65b0\\u3057\\u3044\\u4fa1\\u5024\\u3092\",\"tid\":\"1,6,7,9[8],11[10],13[12]\",\"u\":\"https://duckduckgo.com/y.js?ad_domain=datarobot.com&ad_provider=bingv7aa&ad_type=txad&eddgt=2_trBPli7jgDj1WnqJbnww%3D%3D&rut=e744d99a8df00b24df71f821ad4d1332080aa03267e50f0e988d284f58d9d2ef&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3De8tT9soRYLZabP1ukFkRsgNzVUCUzl89Y8xEqpxoqHqIlCI5wWbydNnN_PoAKHAa2Vsio83mXA_ax16t6rJ7XGkBv0Cg7_D1eg2QAuJgPKEam4VWI3rW40B03r1p11ZXN1Gd1847Vj05bAnJnPfgVyC8ZzFQxLxONmOI0Hg182z2bZUVII26BUAlUHaVZ7O_9FEXLJWw%26u%3DaHR0cHMlM2ElMmYlMmZ3d3cuZGF0YXJvYm90LmNvbSUyZmpwJTJmbHAlMmZhaS1mb3ItYnVzaW5lc3MlMmYlM2Z1dG1fbWVkaXVtJTNkc2VhcmNoJTI2dXRtX3NvdXJjZSUzZGJpbmclMjZ1dG1fY2FtcGFpZ24lM2RERU1PMjAyM0FsbFByb2R1Y3RzSlAwNjI2QlBTJTI2dXRtX3Rlcm0lM2RkYXRhcm9ib3QlMjZ1dG1fY29udGVudCUzZERSX2JyYW5kZWRfcnNhJTI2Y2FtcGFpZ25pZCUzZDUzMDcwODA5OSUyNmFkZ3JvdXBpZCUzZDEzNTAyMDI3NzQyMTc2OTglMjZhZGlkJTNkJTI2bXNjbGtpZCUzZDA2MTIwYzhmMTAxNzEwYTZiNmRiNjkyY2VmMWRiOTY1%26rlid%3D06120c8f101710a6b6db692cef1db965&vqd=4-91027509783546726889708070523412001433&iurl=%7B1%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26ID%3DDevEx%2C5058.1\"}], {\"page_load_url\":\"https://duckduckgo.com/y.js?ifu=%7B3%7Dappid%3D055AAD1BA669BEB8B048128DC89A107C678B527B%26rguid%3D309794dc72f748f6a2b95ce5c34fbcec&iurl=%7B2%7DIG%3D5E053B32922A4B5781ED405D9621559B%26CID%3D0176CEA622686E9D34D1DAA0235D6F30%26Type%3DEvent.CPT%26DATA%3D0\",\"visibility_url\":\"https://duckduckgo.com/y.js?ivu=%7B4%7Dtype%3Dmv%26reqver%3D1.0%26rg%3D309794dc72f748f6a2b95ce5c34fbcec\"});DDG.deep.signalSummary = \"\";DDG.inject('DDG.Data.languages.resultLanguages', {\"en\":[\"https://knowledge.dataiku.com/latest/use-cases/index.html\",\"https://community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\",\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"https://www.datarobot.com/use-cases/\",\"https://academy.dataiku.com/page/use-cases\",\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\",\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"https://londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\",\"https://docs.datarobot.com/en/docs/api/guide/common-case/index.html\",\"https://www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\",\"https://docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\",\"https://blog.dataiku.com/topic/use-cases-projects\",\"https://valohai.com/mlops-platforms-compared/\",\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"https://pages.dataiku.com/experience-a-dataiku-demo\",\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"https://www.dataiku.com/stories/\",\"https://www.dataiku.com/\",\"https://techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\",\"https://www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\"]});DDG.deep.pageLayoutSummary = \"a1w4v1w19,w1\";DDG.inject('DDG.Data.languages.adLanguages', {});if (DDG.pageLayout) DDG.pageLayout.load('d',[{\"a\":\"Use Cases - Dataiku Knowledge Base Use Cases # These use cases allow you to practice what you've learned by building simplified, but complete use cases in Dataiku. Topics # Data Preparation Use Cases Classification Use Cases Clustering Use Cases Plugin Use Cases\",\"ae\":null,\"c\":\"https://knowledge.dataiku.com/latest/use-cases/index.html\",\"d\":\"knowledge.dataiku.com/latest/use-cases/index.html\",\"da\":\"\",\"h\":0,\"i\":\"knowledge.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Use Cases - Dataiku Knowledge Base\",\"u\":\"https://knowledge.dataiku.com/latest/use-cases/index.html\"},{\"a\":\"Community Dataiku Use Cases & Success Stories \\u26a0\\ufe0f Discover pioneering Dataiku use cases and success stories shared by customers, partners, academics, and nonprofits participating in the Dataiku Frontrunner Awards. Use the following labels to filter submissions by industry:\",\"ae\":null,\"c\":\"https://community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\",\"d\":\"community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\",\"da\":\"\",\"h\":0,\"i\":\"community.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku Use Cases & Success Stories - Dataiku Community\",\"u\":\"https://community.dataiku.com/t5/Dataiku-Use-Cases-Success/tkb-p/use-cases\"},{\"a\":\"Dataiku is a cross-platform desktop application that includes a broad range of tools, such as notebooks (similar to Jupyter Notebook), workflow management (similar to Apache Airflow), and automated machine learning. In general, Dataiku aims to replace many of your existing tools rather than to integrate with them.\",\"ae\":null,\"c\":\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"d\":\"www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\",\"da\":\"\",\"h\":0,\"i\":\"www.datarevenue.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"ML Platforms: Dataiku vs. Alteryx vs. Sagemaker vs. Datarobot\",\"u\":\"https://www.datarevenue.com/en-blog/ml-platforms-dataiku-vs-alteryx-vs-sagemaker\"},{\"a\":\"Dataiku has a rating of 4.8 stars with 504 reviews. DataRobot has a rating of 4.6 stars with 508 reviews. See side-by-side comparisons of product capabilities, customer experience, pros and cons, and reviewer demographics to find the best fit for your organization. See more companies in the Data Science and Machine Learning Platforms market. PDF.\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"d\":\"www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku vs DataRobot 2024 | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/compare/dataiku-vs-datarobot\"},{\"a\":\"In my humble opinion DSS is a more a 'toolbox', where as DataRobot is an autoML platform. DataRobot is really good at what it does - if you have non-technical team who want to drop in data and leave everything to autoML then this may be the option for them.\",\"ae\":null,\"c\":\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"d\":\"community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\",\"da\":\"\",\"h\":0,\"i\":\"community.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Solved: Dataiku vs DataRobot - Dataiku Community\",\"u\":\"https://community.dataiku.com/t5/General-Discussion/Dataiku-vs-DataRobot/m-p/9315\"},{\"a\":\"Use cases AI Use Cases AI-driven organizations around the world use DataRobot to solve their most pressing business problems. Build with Free Trial Recent Popular Filters Ready to Get Started? See how a value-driven approach to AI can accelerate time to impact. Start Free Trial\",\"ae\":null,\"c\":\"https://www.datarobot.com/use-cases/\",\"d\":\"www.datarobot.com/use-cases/\",\"da\":\"\",\"h\":0,\"i\":\"www.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Machine Learning Use Cases | DataRobot AI Platform\",\"u\":\"https://www.datarobot.com/use-cases/\"},{\"a\":\"With Dataiku's AI Prepare assistant, you can work smarter, not harder. Simply describe the transformation you want to apply in natural language and the AI assistant automatically generates the necessary data preparation steps. The ability to modify both your prompt and the resulting steps means you can prepare data faster than ever, yet still ...\",\"ae\":null,\"c\":\"https://academy.dataiku.com/page/use-cases\",\"d\":\"academy.dataiku.com/page/use-cases\",\"da\":\"\",\"h\":0,\"i\":\"academy.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Use Cases - Dataiku\",\"u\":\"https://academy.dataiku.com/page/use-cases\"},{\"a\":\"84 Reviews and Ratings Path to AI Success Compare Dataiku DSS vs DataRobot. 103 verified user reviews and ratings of features, pros, cons, pricing, support and more.\",\"ae\":null,\"c\":\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"d\":\"www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\",\"da\":\"\",\"h\":0,\"i\":\"www.trustradius.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku DSS vs DataRobot | TrustRadius\",\"u\":\"https://www.trustradius.com/compare-products/dataiku-dss-vs-datarobot\"},{\"a\":\"side-by-side comparison of DataRobot vs. Dataiku DSS. based on preference data from user reviews. DataRobot rates 4.4/5 stars with 26 reviews. By contrast, Dataiku DSS rates 4.3/5 stars with 36 reviews. Each product's score is calculated with real-time data from verified user reviews, to help you make the best choice between these two options ...\",\"ae\":null,\"c\":\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\",\"d\":\"www.g2.com/compare/datarobot-vs-dataiku-dss\",\"da\":\"\",\"h\":0,\"i\":\"www.g2.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare DataRobot vs. Dataiku DSS | G2\",\"u\":\"https://www.g2.com/compare/datarobot-vs-dataiku-dss\"},{\"a\":\"Use case: Choose Datarobot if you have data stored in spreadsheets and are seeking a platform that is the simplest, albeit one with limited flexibility, ... Dataiku vs. Datarobot .\",\"ae\":null,\"b\":\"li\\tLinkedIn\\twww.linkedin.com\",\"c\":\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"d\":\"www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\",\"da\":\"\",\"e\":\"2023-08-11T00:00:00.0000000\",\"h\":0,\"i\":\"www.linkedin.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Managed Machine Learning Platforms: A Comparative Analysis - LinkedIn\",\"u\":\"https://www.linkedin.com/pulse/managed-machine-learning-platforms-comparative-analysis/\"},{\"a\":\"Jan 11, 2023 Dataiku is an artificial intelligence platform created in France in 2013. It has since become one of the world's benchmarks for data science and machine learning studios. What is...\",\"ae\":null,\"c\":\"https://londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\",\"d\":\"londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\",\"da\":\"translations\",\"e\":\"2023-01-11T00:00:00.0000000\",\"h\":0,\"i\":\"londondataconsulting.medium.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku: What is it? How to use it? Ultimate Guide 2023\",\"u\":\"https://londondataconsulting.medium.com/dataiku-what-is-it-how-to-use-it-ultimate-guide-2023-47602c85a48b\"},{\"a\":\"Use cases for version 2.x. Notebooks for uses cases that use methods for 2.x versions of DataRobot's Python client. Measure price elasticity of demand. A use case to identify relationships between price and demand, maximize revenue by properly pricing products, and monitor price elasticities for changes in price and demand. Insurance claim triage.\",\"ae\":null,\"c\":\"https://docs.datarobot.com/en/docs/api/guide/common-case/index.html\",\"d\":\"docs.datarobot.com/en/docs/api/guide/common-case/index.html\",\"da\":\"\",\"h\":0,\"i\":\"docs.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Common use cases: DataRobot docs - DataRobot AI Platform\",\"u\":\"https://docs.datarobot.com/en/docs/api/guide/common-case/index.html\"},{\"a\":\"With the Use Case Value Tracker, you can manage the project lifecycle and understand the value associated with each step. It also enables you to associate and organize all your DataRobot artifacts (e.g., datasets, models, deployments, applications, etc.) around a given use case for a holistic view. In addition to the project management aspects ...\",\"ae\":null,\"c\":\"https://www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\",\"d\":\"www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\",\"da\":\"\",\"h\":0,\"i\":\"www.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Introducing the DataRobot Use Case Value Tracker\",\"u\":\"https://www.datarobot.com/blog/introducing-the-datarobot-use-case-value-tracker/\"},{\"a\":\"Use Cases are folder-like containers inside of DataRobot Workbench that allow you to group everything related to solving a specific business problem\\u2014datasets, models, experiments, No-Code AI Apps, and notebooks\\u2014inside of a single, manageable entity. You can share whole Use Cases as well as the individual assets they contain.\",\"ae\":null,\"c\":\"https://docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\",\"d\":\"docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\",\"da\":\"\",\"e\":\"2023-09-15T00:00:00.0000000\",\"h\":0,\"i\":\"docs.datarobot.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Use Cases: DataRobot docs\",\"u\":\"https://docs.datarobot.com/en/docs/workbench/wb-usecase/wb-build-usecase.html\"},{\"a\":\"January 2, 2024 Use Cases & Projects, Featured Sophie Dionnet Leveraging AI to Cut Costs December 29, 2023 Data Basics, Featured\",\"ae\":null,\"c\":\"https://blog.dataiku.com/topic/use-cases-projects\",\"d\":\"blog.dataiku.com/topic/use-cases-projects\",\"da\":\"\",\"h\":0,\"i\":\"blog.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Blog - Dataiku | Use Cases & Projects\",\"u\":\"https://blog.dataiku.com/topic/use-cases-projects\"},{\"a\":\"The platforms we've chosen for our analysis are ClearML, cnvrg.io, Dataiku, Datarobot, Iguazio, Sagemaker, Seldon and Valohai from the managed side, and Flyte, Kubeflow, MLflow and Metaflow from the open-source side. This is by no means an exhaustive list of all the MLOps tools out there.\",\"ae\":null,\"c\":\"https://valohai.com/mlops-platforms-compared/\",\"d\":\"valohai.com/mlops-platforms-compared/\",\"da\":\"\",\"h\":0,\"i\":\"valohai.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"MLOps Platforms Compared - Valohai\",\"u\":\"https://valohai.com/mlops-platforms-compared/\"},{\"a\":\"DataRobot. DSS is for all companies, whatever their expertise, industry or size, that want to create their own data-driven strategic advantages by transforming their raw data into business impacting predictions. Cloud based machine learning platform which helps enterprises scale data science capabilities through deploying machine learning ...\",\"ae\":null,\"c\":\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"d\":\"www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\",\"da\":\"translations\",\"h\":0,\"i\":\"www.capterra.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Compare Dataiku vs DataRobot 2024 | Capterra\",\"u\":\"https://www.capterra.com/machine-learning-software/compare/142192-179303/Data-Science-Studio-DSS-vs-DataRobot\"},{\"a\":\"For Every Industry & Use Case. Organizations that use Dataiku elevate their people (whether technical and working in code or on the business side and low- or no-code) to extraordinary, arming them with the ability to make better day-to-day decisions with data across: Banking & Insurance. Pharmaceuticals. Manufacturing. Telecommunications.\",\"ae\":null,\"c\":\"https://pages.dataiku.com/experience-a-dataiku-demo\",\"d\":\"pages.dataiku.com/experience-a-dataiku-demo\",\"da\":\"\",\"h\":0,\"i\":\"pages.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Check Out This Dataiku Demo\",\"u\":\"https://pages.dataiku.com/experience-a-dataiku-demo\"},{\"a\":\"4 Star 24% 3 Star 1% 2 Star 0% 1 Star 0% Distribution based on 504 ratings Customer Experience Evaluation & Contracting 4.6 Integration & Deployment 4.7 Service & Support 4.8 Product Capabilities 4.8 FREE View and Download Peer Insights About Dataiku\",\"ae\":null,\"c\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"d\":\"www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\",\"da\":\"\",\"h\":0,\"i\":\"www.gartner.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku Reviews, Ratings & Features 2024 | Gartner Peer Insights\",\"u\":\"https://www.gartner.com/reviews/market/data-science-and-machine-learning-platforms/vendor/dataiku/product/dataiku\"},{\"a\":\"Read The Full Case Study U.S. Venture + Dataiku: Upskilling Analysts to Save Thousands of Hours The Data and Analytics team at U.S. Venture was built to usher the company into the future of data science and AI.\",\"ae\":null,\"c\":\"https://www.dataiku.com/stories/\",\"d\":\"www.dataiku.com/stories/\",\"da\":\"\",\"h\":0,\"i\":\"www.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Stories | Dataiku\",\"u\":\"https://www.dataiku.com/stories/\"},{\"a\":\"MLOps Deploy, monitor, and maintain machine learning models, all in a single platform. Explore the Capability Collaboration With Dataiku, teams can move beyond the lab and build real and safe Generative AI applications at enterprise scale. Explore the Capability Governance\",\"ae\":null,\"c\":\"https://www.dataiku.com/\",\"d\":\"www.dataiku.com\",\"da\":\"\",\"h\":0,\"i\":\"www.dataiku.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Dataiku | Everyday AI, Extraordinary People\",\"u\":\"https://www.dataiku.com/\"},{\"a\":\"The company today announced that it raised $200 million in a Series F round led by Wellington Management at a $3.7 billion valuation, down from the $4.6 billion that Dataiku received in August ...\",\"ae\":null,\"b\":\"tc\\tTechcrunch\\ttechcrunch.com\",\"c\":\"https://techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\",\"d\":\"techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\",\"da\":\"translations\",\"e\":\"2022-12-13T17:10:00.0000000\",\"h\":0,\"i\":\"techcrunch.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"AI and analytics platform Dataiku raises $200M at a reduced valuation\",\"u\":\"https://techcrunch.com/2022/12/13/ai-and-analytics-platform-dataiku-raises-200m-at-a-reduced-valuation/\"},{\"a\":\"Today, more than 500 companies worldwide use Dataiku to integrate and streamline their use of data, analytics, and AI, driving diverse use cases from fraud detection and customer churn prevention ...\",\"ae\":null,\"c\":\"https://www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\",\"d\":\"www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\",\"da\":\"translations\",\"e\":\"2022-11-17T13:00:00.0000000\",\"h\":0,\"i\":\"www.globenewswire.com\",\"k\":null,\"m\":0,\"o\":0,\"p\":0,\"s\":\"bingv7aa\",\"t\":\"Ben Taylor Joins Dataiku as Chief AI Strategist - GlobeNewswire\",\"u\":\"https://www.globenewswire.com/news-release/2022/11/17/2558152/0/en/Ben-Taylor-Joins-Dataiku-as-Chief-AI-Strategist.html\"},{\"n\":\"/d.js?q=Dataiku%20and%20DataRobot%20use%20cases&kl=wt-wt&l=wt-wt&p=&s=23&ex=-1&ct=US&sp=0&vqd=4-60481969350525797892441552954401970387\"}]);DDG.duckbar.load('images');DDG.duckbar.load('news');DDG.duckbar.load('videos', {\"ads\":[],\"query\":\"Dataiku and DataRobot use cases\",\"queryEncoded\":\"Dataiku%20and%20DataRobot%20use%20cases\",\"response_type\":\"places\",\"results\":[{\"content\":\"https://www.youtube.com/watch?v=ryZRRIjQ5Z8\",\"description\":\"If you're a code-first data practitioner, Dataiku helps you efficiently build high quality data pipelines and models in a number of ways. CHECK OUT DATAIKU: https://bit.ly/36XBlpK EGG ON AIR: https://bit.ly/37GhXMY BRIGHTTALK WEBINARS: https://bit.ly/33TIRjn DATA SCIENCE PIONEERS DOCUMENTARY: https://bit.ly/36V3rBF PARTNER ECOSYSTEM: https ...\",\"duration\":\"10:43\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/ryZRRIjQ5Z8?autoplay=1\",\"image_token\":\"8a4abca8613c6680a108591849e5d7b13b86111004ae004898a7f059b64c8355\",\"images\":{\"large\":\"https://tse4.mm.bing.net/th?id=OVP.WoendyuZJ9qxql-n6jit5AEsDh&pid=Api\",\"medium\":\"https://tse4.mm.bing.net/th?id=OVP.WoendyuZJ9qxql-n6jit5AEsDh&pid=Api\",\"motion\":\"https://tse4.mm.bing.net/th?id=OM1.cmvppfhHVUeE4Q_1684256861&pid=Api\",\"small\":\"https://tse4.mm.bing.net/th?id=OVP.WoendyuZJ9qxql-n6jit5AEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2021-06-08T21:15:02.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":12391},\"title\":\"Dataiku Demo for Data Scientists and Coders\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=jKL_I0SCl_E\",\"description\":\"This video showcases the Clinical Trial Explorer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of our ...\",\"duration\":\"1:50\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/jKL_I0SCl_E?autoplay=1\",\"image_token\":\"7b19602fe6d9b761aa3cc138448cc632ddbed31da3abf2687f36705f5945973d\",\"images\":{\"large\":\"https://tse3.mm.bing.net/th?id=OVP.wfgHp53woiVosZ37-1HtnwEsDh&pid=Api\",\"medium\":\"https://tse3.mm.bing.net/th?id=OVP.wfgHp53woiVosZ37-1HtnwEsDh&pid=Api\",\"motion\":\"https://tse3.mm.bing.net/th?id=OM2.ZX_yq0xmyCGZBg_1696372683&pid=Api\",\"small\":\"https://tse3.mm.bing.net/th?id=OVP.wfgHp53woiVosZ37-1HtnwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:19:00.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":150},\"title\":\"Clinical Trial Explorer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=lASesA4gNFI\",\"description\":\"This video showcases the CO2 Forecast Analyzer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of our ...\",\"duration\":\"1:50\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/lASesA4gNFI?autoplay=1\",\"image_token\":\"a09328adca01a788783d759561c2f9c9d4d214e5a26f1462d2b6b69f21a2d478\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.ZhQI7z-IMlcVnyeMJuGlAQEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.ZhQI7z-IMlcVnyeMJuGlAQEsDh&pid=Api\",\"motion\":\"\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.ZhQI7z-IMlcVnyeMJuGlAQEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:16:20.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":49},\"title\":\"CO2 Forecast Analyzer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=RecpD6Vtzj4\",\"description\":\"This video showcases the LLM-Enhanced ESG Document Intelligence use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the ...\",\"duration\":\"1:20\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/RecpD6Vtzj4?autoplay=1\",\"image_token\":\"6f797accb167e2e6ff7265e35116cdeb9f1c641b1df47932d9597b61b0108614\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.bm4gAiJOOmKV7uup6LU9pgEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.bm4gAiJOOmKV7uup6LU9pgEsDh&pid=Api\",\"motion\":\"https://tse2.mm.bing.net/th?id=OM1.M8WXwCQ79nrqEA_1691502936&pid=Api\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.bm4gAiJOOmKV7uup6LU9pgEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:30:00.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":382},\"title\":\"LLM-Enhanced ESG Document Intelligence\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=zLW0TkJoHLw\",\"description\":\"This video showcases the Demand Forecast Analyzer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of our ...\",\"duration\":\"1:42\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/zLW0TkJoHLw?autoplay=1\",\"image_token\":\"524eb9572bf9342b859509285d39ec4661fc572cb1452307acc5341b56bab921\",\"images\":{\"large\":\"https://tse1.mm.bing.net/th?id=OVP.yIekQ2cMUesOPJTfsYIZzQHgFo&pid=Api\",\"medium\":\"https://tse1.mm.bing.net/th?id=OVP.yIekQ2cMUesOPJTfsYIZzQHgFo&pid=Api\",\"motion\":\"\",\"small\":\"https://tse1.mm.bing.net/th?id=OVP.yIekQ2cMUesOPJTfsYIZzQHgFo&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:15:02.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":4},\"title\":\"LLM-Enhanced Demand Forecast\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=L-Yys0fzuVY\",\"description\":\"This video showcases the Production Quality Data Explorer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest ...\",\"duration\":\"1:47\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/L-Yys0fzuVY?autoplay=1\",\"image_token\":\"82924713be1dba83d67124fcaa6cc6afd163900a0c40f25fcf6c144ed0e36536\",\"images\":{\"large\":\"https://tse4.mm.bing.net/th?id=OVP.teiC0mX9nKCbH8qeo52udwEsDh&pid=Api\",\"medium\":\"https://tse4.mm.bing.net/th?id=OVP.teiC0mX9nKCbH8qeo52udwEsDh&pid=Api\",\"motion\":\"https://tse4.mm.bing.net/th?id=OM2.IwRaoLRWcQXzag_1691419996&pid=Api\",\"small\":\"https://tse4.mm.bing.net/th?id=OVP.teiC0mX9nKCbH8qeo52udwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:28:29.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":175},\"title\":\"Production Quality Data Explorer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=FluiuHuaU8A\",\"description\":\"In this breakout session of Dataiku's Product Days 2021, you will see a demo of Dataiku's Data Science Studio, the centralized, collaborative, and end-to-end platform for data science in the enterprise. CHECK OUT DATAIKU: https://bit.ly/36XBlpK EGG ON AIR: https://bit.ly/37GhXMY BRIGHTTALK WEBINARS: https://bit.ly/33TIRjn DATA SCIENCE PIONEERS ...\",\"duration\":\"13:50\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/FluiuHuaU8A?autoplay=1\",\"image_token\":\"2943fa8c1580f2936fc11667d670c0b827b94ff3d16b897f8b5ef2e2426487b3\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.RIM-ftwDZjYP58RimJfgwwEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.RIM-ftwDZjYP58RimJfgwwEsDh&pid=Api\",\"motion\":\"https://tse2.mm.bing.net/th?id=OM1.MIQ7BoQz1MVkNw_1662248868&pid=Api\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.RIM-ftwDZjYP58RimJfgwwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2021-07-08T15:56:22.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":3844},\"title\":\"Introduction to Dataiku Data Science | Product Days 2021\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=6TEU5JboP7k\",\"description\":\"This video showcases the LLM-Enhanced Next Best Offer use case from the Dataiku Generative AI Use Case Collection. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore more Generative AI use cases | https://experience.dataiku.com/generative-ai To explore more about Dataiku, check out the rest of ...\",\"duration\":\"1:47\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/6TEU5JboP7k?autoplay=1\",\"image_token\":\"a3bc327ff2f099462935a8979bb599655c7a88a44e25a64bfea7e5973f773158\",\"images\":{\"large\":\"https://tse2.mm.bing.net/th?id=OVP.Q6SP0MmL89M_TnLvNPG4oQEsDh&pid=Api\",\"medium\":\"https://tse2.mm.bing.net/th?id=OVP.Q6SP0MmL89M_TnLvNPG4oQEsDh&pid=Api\",\"motion\":\"https://tse2.mm.bing.net/th?id=OM2.wXNo1CUgYV4Flg_1694065487&pid=Api\",\"small\":\"https://tse2.mm.bing.net/th?id=OVP.Q6SP0MmL89M_TnLvNPG4oQEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:34:32.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":462},\"title\":\"LLM-Enhanced Next Best Offer\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=UVbrpX8Zkn8\",\"description\":\"Move beyond the lab and build real and safe Generative AI applications at enterprise scale. Dataiku brings enterprise-grade development tools, pre-built use cases, and AI-powered assistants throughout the platform. Learn more about Dataiku for Generative AI | https://www.dataiku.com/product/generative-ai/ Explore Generative AI use cases | https ...\",\"duration\":\"2:07\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/UVbrpX8Zkn8?autoplay=1\",\"image_token\":\"3968d2d01ff722efa156290344ab0b37164e57d7efa50905c346ea1cc1a5d369\",\"images\":{\"large\":\"https://tse1.mm.bing.net/th?id=OVP.F-xH3-wKfTjM3YMshnjWwwEsDh&pid=Api\",\"medium\":\"https://tse1.mm.bing.net/th?id=OVP.F-xH3-wKfTjM3YMshnjWwwEsDh&pid=Api\",\"motion\":\"https://tse1.mm.bing.net/th?id=OM1.z-FRwxQ_NByK_A_1689135755&pid=Api\",\"small\":\"https://tse1.mm.bing.net/th?id=OVP.F-xH3-wKfTjM3YMshnjWwwEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-06-22T12:25:16.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":1100},\"title\":\"Dataiku for Generative AI: Real Applications, Real Safety\",\"uploader\":\"Dataiku\"},{\"content\":\"https://www.youtube.com/watch?v=-amc9iVauuE\",\"description\":\"Dataiku is the leading platform for Everyday AI, systemizing the use of data for exceptional business results. In today's video we will take a tour of Dataiku's end to end capabilities by exploring a real life use case around environmental impact. Let's take a look at how a data science team with different skills can work together to turn ...\",\"duration\":\"12:35\",\"embed_html\":\"\",\"embed_url\":\"http://www.youtube.com/embed/-amc9iVauuE?autoplay=1\",\"image_token\":\"2a05a65ad8a2727aa5c48b8daa7f9ec363a24d4336a3509016d4b200c9d003cd\",\"images\":{\"large\":\"https://tse1.mm.bing.net/th?id=OVP.Az9RhdSVwpXe56mGcs6FqQEsDh&pid=Api\",\"medium\":\"https://tse1.mm.bing.net/th?id=OVP.Az9RhdSVwpXe56mGcs6FqQEsDh&pid=Api\",\"motion\":\"https://tse1.mm.bing.net/th?id=OM1.Q2OhN9DzfowU6A_1685345657&pid=Api\",\"small\":\"https://tse1.mm.bing.net/th?id=OVP.Az9RhdSVwpXe56mGcs6FqQEsDh&pid=Api\"},\"provider\":\"Bing\",\"published\":\"2023-01-09T21:12:27.0000000\",\"publisher\":\"YouTube\",\"statistics\":{\"viewCount\":9768},\"title\":\"End to End Demo 2023\",\"uploader\":\"Dataiku\"}],\"vqd\":{\"Dataiku%20and%20DataRobot%20use%20cases\":\"4-60481969350525797892441552954401970387\"}});DDG.duckbar.loadModule('related_searches');if (DDG.pageLayout) DDG.pageLayout.initialize({\"mainline\":{\"items\":[[\"ad\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"videos\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"],[\"organic\"]]},\"sidebar\":{\"items\":[[\"organic\"]]}}, { start: 0 });DDG.deep.emit(\"load:completed\");", + "aiohttp-post-https://google.serper.dev/search-{\"data\": \"[{\\\"num\\\": 6, \\\"page\\\": 1, \\\"q\\\": \\\"ai agent\\\"}]\", \"headers\": {\"Content-Type\": \"application/json\", \"X-API-KEY\": \"mock-serper-key\"}}": [ + { + "searchParameters": { + "q": "ai agent", + "num": 6, + "page": 1, + "type": "search", + "engine": "google" + }, + "organic": [ + { + "title": "AI Agent • Supercharge Your Workflows with AI", + "link": "https://aiagent.app/", + "snippet": "A web app that makes choices and performs tasks on its own, based on the goals set by you. How Does it Work?", + "position": 1 + }, + { + "title": "Intelligent agent - Wikipedia", + "link": "https://en.wikipedia.org/wiki/Intelligent_agent", + "snippet": "In artificial intelligence, an intelligent agent (IA) is an agent acting in an intelligent manner; It perceives its environment, takes actions autonomously ...", + "position": 2 + }, + { + "title": "What is an AI agent? | Zapier", + "link": "https://zapier.com/blog/ai-agent/", + "snippet": "AI Agent is a flexible app that lets you create your own agents, by picking a name, an objective, and the AI model it should use (GPT-3.5 Turbo ...", + "date": "Jun 1, 2023", + "position": 3 + }, + { + "title": "Google DeepMind Veteran Departs to Launch AI Agent Startup", + "link": "https://www.theinformation.com/articles/google-deepmind-veteran-departs-to-launch-ai-agent-startup", + "snippet": "The concept of AI agents—bots with the ability to plan and work toward a goal with minimal user guidance—first took off a year ago after ...", + "date": "10 hours ago", + "position": 4 + }, + { + "title": "AI Agents And The Era Of The Intelligent Interface - Forbes", + "link": "https://www.forbes.com/sites/davidarmano/2023/12/07/ai-agents-and-the-era-of-the-intelligent-interface/", + "snippet": "Conversing with several AI Agents connected to various systems is poised to become the next significant evolution of human-computer ...", + "date": "Dec 7, 2023", + "position": 5 + } + ], + "topStories": [ + { + "title": "Google DeepMind Veteran Departs to Launch AI Agent Startup", + "link": "https://www.theinformation.com/articles/google-deepmind-veteran-departs-to-launch-ai-agent-startup", + "source": "The Information", + "date": "10 hours ago", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSOUiQnjnTQpnKKDk0hnXhpIdVvwyifhK3VjZuTey9Uq3J1S8l7OB95iWMrKQ&s" + }, + { + "title": "Bitcoin to Become Native Currency for AI Agents, Former Meta Exec Predicts", + "link": "https://u.today/bitcoin-to-become-native-currency-for-ai-agents-former-meta-exec-predicts", + "source": "U.Today", + "date": "2 days ago", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRV9Ydu_Dou8HvI9E25KAn7nKmxk6Q-CB1cvT0dIxSudXhZPpGCR1vj0NCdaw&s" + }, + { + "title": "Building AI agents with Semantic Kernel", + "link": "https://www.infoworld.com/article/3712423/building-ai-agents-with-semantic-kernel.html", + "source": "InfoWorld", + "date": "5 days ago", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS0NAiT2vVMB14Ff56syKnS3g4jrNN5LIskrtxqqdViPyrBsLCuCrQWu9ojdA&s" + }, + { + "title": "AI agents help explain other AI systems", + "link": "https://news.mit.edu/2024/ai-agents-help-explain-other-ai-systems-0103", + "source": "MIT News", + "date": "4 weeks ago", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR-0QJKlbSMOP0wYSfB70p4_JCWHEkc6oAkLhBXVHX3ZVATBCRWTp08JY8x4w&s" + }, + { + "title": "CES 2024: LG announces walking, talking, 'Jetsons-esque' smart home robot", + "link": "https://mashable.com/article/ces-2024-lg-announcement-ai-agent-smart-home-robot", + "source": "Mashable", + "date": "3 weeks ago", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRVIiyOId49n_-CwPODLHIP9t6HioG05EeI_dvwvg6WNfFBcsLliI_Xhr6U-Q&s" + }, + { + "title": "Develop Your First AI Agent: Deep Q-Learning", + "link": "https://towardsdatascience.com/develop-your-first-ai-agent-deep-q-learning-375876ee2472", + "source": "Towards Data Science", + "date": "1 month ago", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEzOgQuvwfalC2s5HasdRiv2IqdMLgtuUOBJv1xkVGH-Vg_bJmavQk88I1eA&s" + } + ], + "relatedSearches": [ + { + "query": "AI agent GPT" + }, + { + "query": "AI agent OpenAI" + }, + { + "query": "AI agent examples" + }, + { + "query": "Ai agent jobs" + }, + { + "query": "AI agents ChatGPT" + }, + { + "query": "AI agent Microsoft" + }, + { + "query": "AI agent free" + }, + { + "query": "AI Agent app" + } + ] + } + ] } \ No newline at end of file diff --git a/tests/metagpt/learn/test_google_search.py b/tests/metagpt/learn/test_google_search.py index da32e8923..7fda6436a 100644 --- a/tests/metagpt/learn/test_google_search.py +++ b/tests/metagpt/learn/test_google_search.py @@ -1,27 +1,21 @@ -import asyncio - +import pytest from pydantic import BaseModel from metagpt.learn.google_search import google_search +from metagpt.tools import SearchEngineType -async def mock_google_search(): +@pytest.mark.asyncio +async def test_google_search(search_engine_mocker): class Input(BaseModel): input: str inputs = [{"input": "ai agent"}] - for i in inputs: seed = Input(**i) - result = await google_search(seed.input) + result = await google_search( + seed.input, + engine=SearchEngineType.SERPER_GOOGLE, + serper_api_key="mock-serper-key", + ) assert result != "" - - -def test_suite(): - loop = asyncio.get_event_loop() - task = loop.create_task(mock_google_search()) - loop.run_until_complete(task) - - -if __name__ == "__main__": - test_suite() diff --git a/tests/mock/mock_aiohttp.py b/tests/mock/mock_aiohttp.py index 4690bf4b5..49dcdba79 100644 --- a/tests/mock/mock_aiohttp.py +++ b/tests/mock/mock_aiohttp.py @@ -39,3 +39,7 @@ class MockAioResponse: data = await self.response.json(*args, **kwargs) self.rsp_cache[self.key] = data return data + + def raise_for_status(self): + if self.response: + self.response.raise_for_status() From 54388d0a8792b682883e917122e92ac8aab63118 Mon Sep 17 00:00:00 2001 From: geekan Date: Wed, 31 Jan 2024 17:34:48 +0800 Subject: [PATCH 14/35] refine comments --- metagpt/strategy/solver.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/metagpt/strategy/solver.py b/metagpt/strategy/solver.py index bd21dda3e..e7d61a881 100644 --- a/metagpt/strategy/solver.py +++ b/metagpt/strategy/solver.py @@ -13,12 +13,12 @@ from metagpt.strategy.search_space import SearchSpace class BaseSolver: - """AbstractSolver: 用于定义一个抽象求解器,求解器中的搜索空间是 SearchSpace 实例,图是 ActionGraph 实例。""" + """AbstractSolver: defines the interface of a solver.""" def __init__(self, graph: ActionGraph, search_space: SearchSpace, llm: BaseLLM, context): """ - :param graph: ActionGraph 实例 - :param search_space: SearchSpace 实例 + :param graph: ActionGraph + :param search_space: SearchSpace :param llm: BaseLLM :param context: Context """ @@ -29,11 +29,11 @@ class BaseSolver: @abstractmethod async def solve(self): - """求解器的求解方法。""" + """abstract method to solve the problem.""" class NaiveSolver(BaseSolver): - """NaiveSolver: 直接循序执行给定的 graph""" + """NaiveSolver: Iterate all the nodes in the graph and execute them one by one.""" async def solve(self): self.graph.topological_sort() @@ -43,35 +43,35 @@ class NaiveSolver(BaseSolver): class TOTSolver(BaseSolver): - """TOTSolver: 通过拓扑排序执行给定的 graph""" + """TOTSolver: Tree of Thought""" async def solve(self): raise NotImplementedError class CodeInterpreterSolver(BaseSolver): - """CodeInterpreterSolver: 通过代码解释器执行给定的 graph""" + """CodeInterpreterSolver: Write&Run code in the graph""" async def solve(self): raise NotImplementedError class ReActSolver(BaseSolver): - """ReActSolver: 通过 ReAct 执行给定的 graph""" + """ReActSolver: ReAct algorithm""" async def solve(self): raise NotImplementedError class IOSolver(BaseSolver): - """IOSolver: 通过 IO 执行给定的 graph""" + """IOSolver: use LLM directly to solve the problem""" async def solve(self): raise NotImplementedError class COTSolver(BaseSolver): - """COTSolver: 通过cot执行给定的 graph""" + """COTSolver: Chain of Thought""" async def solve(self): raise NotImplementedError From ad1edf60927e884b2ad0a4a4220abd6fb779a4b0 Mon Sep 17 00:00:00 2001 From: geekan Date: Wed, 31 Jan 2024 17:36:04 +0800 Subject: [PATCH 15/35] refine comments --- metagpt/actions/action_graph.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/metagpt/actions/action_graph.py b/metagpt/actions/action_graph.py index 8570778c7..893bc6d4c 100644 --- a/metagpt/actions/action_graph.py +++ b/metagpt/actions/action_graph.py @@ -11,7 +11,7 @@ from __future__ import annotations class ActionGraph: - """ActionGraph: 用于定义一个图,图中的节点是 ActionNode 实例,节点间的依赖关系是有向边。""" + """ActionGraph: a directed graph to represent the dependency between actions.""" def __init__(self): self.nodes = {} @@ -19,18 +19,11 @@ class ActionGraph: self.execution_order = [] def add_node(self, node): - """ - 添加一个节点到图中。 - :param node: ActionNode 实例 - """ + """Add a node to the graph""" self.nodes[node.key] = node def add_edge(self, from_node: "ActionNode", to_node: "ActionNode"): - """ - 定义节点间的依赖关系。 - :param from_node: 节点标识 - :param to_node: 节点标识 - """ + """Add an edge to the graph""" if from_node.key not in self.edges: self.edges[from_node.key] = [] self.edges[from_node.key].append(to_node.key) @@ -38,9 +31,7 @@ class ActionGraph: to_node.add_prev(from_node) def topological_sort(self): - """ - 实现拓扑排序来确定执行顺序。 - """ + """Topological sort the graph""" visited = set() stack = [] From f4c6e507c9d21ea2375a87f12d83a885838e2e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Wed, 31 Jan 2024 22:44:01 +0800 Subject: [PATCH 16/35] fixbug: make unit test stable --- tests/metagpt/tools/test_ut_writer.py | 49 ++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/metagpt/tools/test_ut_writer.py b/tests/metagpt/tools/test_ut_writer.py index 29b6572c2..3cc7e86bb 100644 --- a/tests/metagpt/tools/test_ut_writer.py +++ b/tests/metagpt/tools/test_ut_writer.py @@ -8,6 +8,17 @@ from pathlib import Path import pytest +from openai.resources.chat.completions import AsyncCompletions +from openai.types import CompletionUsage +from openai.types.chat.chat_completion import ( + ChatCompletion, + ChatCompletionMessage, + Choice, +) +from openai.types.chat.chat_completion_message_tool_call import ( + ChatCompletionMessageToolCall, + Function, +) from metagpt.config2 import config from metagpt.const import API_QUESTIONS_PATH, UT_PY_PATH @@ -16,7 +27,43 @@ from metagpt.tools.ut_writer import YFT_PROMPT_PREFIX, UTGenerator class TestUTWriter: @pytest.mark.asyncio - async def test_api_to_ut_sample(self): + async def test_api_to_ut_sample(self, mocker): + async def mock_create(*args, **kwargs): + return ChatCompletion( + id="chatcmpl-8n5fAd21w2J1IIFkI4qxWlNfM7QRC", + choices=[ + Choice( + finish_reason="stop", + index=0, + logprobs=None, + message=ChatCompletionMessage( + content=None, + role="assistant", + function_call=None, + tool_calls=[ + ChatCompletionMessageToolCall( + id="call_EjjmIY7GMspHu3r9mx8gPA2k", + function=Function( + arguments='{"code":"import string\\nimport random\\n\\ndef random_string' + "(length=10):\\n return ''.join(random.choice(string.ascii_" + 'lowercase) for i in range(length))"}', + name="execute", + ), + type="function", + ) + ], + ), + ) + ], + created=1706710532, + model="gpt-3.5-turbo-1106", + object="chat.completion", + system_fingerprint="fp_04f9a1eebf", + usage=CompletionUsage(completion_tokens=35, prompt_tokens=1982, total_tokens=2017), + ) + + mocker.patch.object(AsyncCompletions, "create", mock_create) + # Prerequisites swagger_file = Path(__file__).parent / "../../data/ut_writer/yft_swaggerApi.json" assert swagger_file.exists() From a762e020008a8e01a80f8ee7e196116444330156 Mon Sep 17 00:00:00 2001 From: geekan Date: Wed, 31 Jan 2024 23:13:38 +0800 Subject: [PATCH 17/35] update config usage --- Dockerfile | 2 +- README.md | 14 ++++----- config/config2.yaml.example | 3 -- docs/FAQ-EN.md | 30 +++---------------- docs/README_CN.md | 10 +++---- docs/README_JA.md | 50 +++++++++++++++---------------- docs/install/cli_install.md | 25 +++++++++------- docs/install/cli_install_cn.md | 4 +-- docs/install/docker_install.md | 12 ++++---- docs/install/docker_install_cn.md | 12 ++++---- docs/tutorial/usage.md | 11 ++----- docs/tutorial/usage_cn.md | 11 ++----- metagpt/actions/design_api.py | 2 +- metagpt/actions/write_prd.py | 2 +- metagpt/config2.py | 8 +---- metagpt/configs/llm_config.py | 2 +- metagpt/configs/mermaid_config.py | 5 ++-- metagpt/utils/mermaid.py | 12 ++++---- metagpt/utils/mmdc_pyppeteer.py | 6 ++-- metagpt/utils/yaml_model.py | 4 +-- 20 files changed, 93 insertions(+), 132 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9eeacbccb..dead20537 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN apt update &&\ # Install Mermaid CLI globally ENV CHROME_BIN="/usr/bin/chromium" \ - PUPPETEER_CONFIG="/app/metagpt/config/puppeteer-config.json"\ + puppeteer_config="/app/metagpt/config/puppeteer-config.json"\ PUPPETEER_SKIP_CHROMIUM_DOWNLOAD="true" RUN npm install -g @mermaid-js/mermaid-cli &&\ npm cache clean --force diff --git a/README.md b/README.md index 90c586068..39dde8208 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,10 @@ # Step 2: Clone the repository to your local machine for latest version, and ins cd MetaGPT pip3 install -e . # or pip3 install metagpt # for stable version -# Step 3: setup your OPENAI_API_KEY, or make sure it existed in the env +# Step 3: setup your LLM key in the config2.yaml file mkdir ~/.metagpt -cp config/config.yaml ~/.metagpt/config.yaml -vim ~/.metagpt/config.yaml +cp config/config2.yaml ~/.metagpt/config2.yaml +vim ~/.metagpt/config2.yaml # Step 4: run metagpt cli metagpt "Create a 2048 game in python" @@ -87,16 +87,16 @@ ### Docker installation > Note: In the Windows, you need to replace "/opt/metagpt" with a directory that Docker has permission to create, such as "D:\Users\x\metagpt" ```bash -# Step 1: Download metagpt official image and prepare config.yaml +# Step 1: Download metagpt official image and prepare config2.yaml docker pull metagpt/metagpt:latest mkdir -p /opt/metagpt/{config,workspace} -docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml -vim /opt/metagpt/config/key.yaml # Change the config +docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config2.yaml > /opt/metagpt/config/config2.yaml +vim /opt/metagpt/config/config2.yaml # Change the config # Step 2: Run metagpt demo with container docker run --rm \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest \ metagpt "Write a cli snake game" diff --git a/config/config2.yaml.example b/config/config2.yaml.example index 1a406e756..7c523fe7d 100644 --- a/config/config2.yaml.example +++ b/config/config2.yaml.example @@ -37,6 +37,3 @@ IFLYTEK_API_KEY: "YOUR_API_KEY" IFLYTEK_API_SECRET: "YOUR_API_SECRET" METAGPT_TEXT_TO_IMAGE_MODEL_URL: "YOUR_MODEL_URL" - -PYPPETEER_EXECUTABLE_PATH: "/Applications/Google Chrome.app" - diff --git a/docs/FAQ-EN.md b/docs/FAQ-EN.md index d4a9f6097..88b5b0573 100644 --- a/docs/FAQ-EN.md +++ b/docs/FAQ-EN.md @@ -83,10 +83,10 @@ 1. PRD stuck / unable to access/ connection interrupted - 1. The official OPENAI_BASE_URL address is `https://api.openai.com/v1` - 1. If the official OPENAI_BASE_URL address is inaccessible in your environment (this can be verified with curl), it's recommended to configure using the reverse proxy OPENAI_BASE_URL provided by libraries such as openai-forward. For instance, `OPENAI_BASE_URL: "``https://api.openai-forward.com/v1``"` - 1. If the official OPENAI_BASE_URL address is inaccessible in your environment (again, verifiable via curl), another option is to configure the OPENAI_PROXY parameter. This way, you can access the official OPENAI_BASE_URL via a local proxy. If you don't need to access via a proxy, please do not enable this configuration; if accessing through a proxy is required, modify it to the correct proxy address. Note that when OPENAI_PROXY is enabled, don't set OPENAI_BASE_URL. - 1. Note: OpenAI's default API design ends with a v1. An example of the correct configuration is: `OPENAI_BASE_URL: "``https://api.openai.com/v1``"` + 1. The official openai base_url address is `https://api.openai.com/v1` + 1. If the official openai base_url address is inaccessible in your environment (this can be verified with curl), it's recommended to configure using the reverse proxy openai base_url provided by libraries such as openai-forward. For instance, `openai base_url: "``https://api.openai-forward.com/v1``"` + 1. If the official openai base_url address is inaccessible in your environment (again, verifiable via curl), another option is to configure the llm.proxy parameter. This way, you can access the official openai base_url via a local proxy. If you don't need to access via a proxy, please do not enable this configuration; if accessing through a proxy is required, modify it to the correct proxy address. Note that when llm.proxy is enabled, don't set openai base_url. + 1. Note: OpenAI's default API design ends with a v1. An example of the correct configuration is: `openai base_url: "``https://api.openai.com/v1``"` 1. Absolutely! How can I assist you today? @@ -119,28 +119,6 @@ 1. When using a database, it often gets the implementation wrong — since the SQL database initialization process is usually not in the code. 1. With more lines of code, there's a higher chance of false impressions, leading to calls to non-existent APIs. -1. Instructions for using SD Skills/UI Role: - - 1. Currently, there is a test script located in /tests/metagpt/roles. The file ui_role provides the corresponding code implementation. For testing, you can refer to the test_ui in the same directory. - - 1. The UI role takes over from the product manager role, extending the output from the 【UI Design draft】 provided by the product manager role. The UI role has implemented the UIDesign Action. Within the run of UIDesign, it processes the respective context, and based on the set template, outputs the UI. The output from the UI role includes: - - 1. UI Design Description: Describes the content to be designed and the design objectives. - 1. Selected Elements: Describes the elements in the design that need to be illustrated. - 1. HTML Layout: Outputs the HTML code for the page. - 1. CSS Styles (styles.css): Outputs the CSS code for the page. - - 1. Currently, the SD skill is a tool invoked by UIDesign. It instantiates the SDEngine, with specific code found in metagpt/tools/sd_engine. - - 1. Configuration instructions for SD Skills: The SD interface is currently deployed based on *https://github.com/AUTOMATIC1111/stable-diffusion-webui* **For environmental configurations and model downloads, please refer to the aforementioned GitHub repository. To initiate the SD service that supports API calls, run the command specified in cmd with the parameter nowebui, i.e., - - 1. > python3 webui.py --enable-insecure-extension-access --port xxx --no-gradio-queue --nowebui - 1.     Once it runs without errors, the interface will be accessible after approximately 1 minute when the model finishes loading. - 1. Configure SD_URL and SD_T2I_API in the config.yaml/key.yaml files. - 1. ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/065295a67b0b4feea665d1372722d49d~tplv-k3u1fbpfcp-zoom-1.image) - 1.     SD_URL is the deployed server/machine IP, and Port is the specified port above, defaulting to 7860. - 1. > SD_URL: IP:Port - 1. An error occurred during installation: "Another program is using this file...egg". 1. Delete the file and try again. diff --git a/docs/README_CN.md b/docs/README_CN.md index 2855b5500..ebf5dd408 100644 --- a/docs/README_CN.md +++ b/docs/README_CN.md @@ -48,7 +48,7 @@ # 第 2 步:克隆最新仓库到您的本地机器,并进行安装。 pip3 install -e. # 或者 pip3 install metagpt # 安装稳定版本 # 第 3 步:执行metagpt -# 拷贝config.yaml为key.yaml,并设置你自己的OPENAI_API_KEY +# 拷贝config2.yaml为~/.metagpt/config2.yaml,并设置你自己的api_key metagpt "Write a cli snake game" # 第 4 步【可选的】:如果你想在执行过程中保存像象限图、系统设计、序列流程等图表这些产物,可以在第3步前执行该步骤。默认的,框架做了兼容,在不执行该步的情况下,也可以完整跑完整个流程。 @@ -63,16 +63,16 @@ ### Docker安装 > 注意:在Windows中,你需要将 "/opt/metagpt" 替换为Docker具有创建权限的目录,比如"D:\Users\x\metagpt" ```bash -# 步骤1: 下载metagpt官方镜像并准备好config.yaml +# 步骤1: 下载metagpt官方镜像并准备好config2.yaml docker pull metagpt/metagpt:latest mkdir -p /opt/metagpt/{config,workspace} -docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml -vim /opt/metagpt/config/key.yaml # 修改配置文件 +docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config2.yaml > /opt/metagpt/config/config2.yaml +vim /opt/metagpt/config/config2.yaml # 修改配置文件 # 步骤2: 使用容器运行metagpt演示 docker run --rm \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest \ metagpt "Write a cli snake game" diff --git a/docs/README_JA.md b/docs/README_JA.md index 8b2bf1fae..26db0498f 100644 --- a/docs/README_JA.md +++ b/docs/README_JA.md @@ -68,7 +68,7 @@ # ステップ 2: リポジトリをローカルマシンにクローンし、 pip install -e. # ステップ 3: metagpt を実行する -# config.yaml を key.yaml にコピーし、独自の OPENAI_API_KEY を設定します +# config/config2.yaml を ~/.metagpt/config2.yaml にコピーし、独自の api_key を設定します metagpt "Write a cli snake game" # ステップ 4 [オプション]: 実行中に PRD ファイルなどのアーティファクトを保存する場合は、ステップ 3 の前にこのステップを実行できます。デフォルトでは、フレームワークには互換性があり、この手順を実行しなくてもプロセス全体を完了できます。 @@ -91,8 +91,8 @@ # NPM がシステムにインストールされていることを確認して - config.yml に mmdc のコンフィグを記述するのを忘れないこと ```yml - PUPPETEER_CONFIG: "./config/puppeteer-config.json" - MMDC: "./node_modules/.bin/mmdc" + puppeteer_config: "./config/puppeteer-config.json" + path: "./node_modules/.bin/mmdc" ``` - もし `pip install -e.` がエラー `[Errno 13] Permission denied: '/usr/local/lib/python3.11/dist-packages/test-easy-install-13129.write-test'` で失敗したら、代わりに `pip install -e. --user` を実行してみてください @@ -114,12 +114,13 @@ # NPM がシステムにインストールされていることを確認して playwright install --with-deps chromium ``` - - **modify `config.yaml`** + - **modify `config2.yaml`** - config.yaml から MERMAID_ENGINE のコメントを外し、`playwright` に変更する + config2.yaml から mermaid.engine のコメントを外し、`playwright` に変更する ```yaml - MERMAID_ENGINE: playwright + mermaid: + engine: playwright ``` - pyppeteer @@ -143,21 +144,23 @@ # NPM がシステムにインストールされていることを確認して pyppeteer-install ``` - - **`config.yaml` を修正** + - **`config2.yaml` を修正** - config.yaml から MERMAID_ENGINE のコメントを外し、`pyppeteer` に変更する + config2.yaml から mermaid.engine のコメントを外し、`pyppeteer` に変更する ```yaml - MERMAID_ENGINE: pyppeteer + mermaid: + engine: pyppeteer ``` - mermaid.ink - - **`config.yaml` を修正** + - **`config2.yaml` を修正** - config.yaml から MERMAID_ENGINE のコメントを外し、`ink` に変更する + config2.yaml から mermaid.engine のコメントを外し、`ink` に変更する ```yaml - MERMAID_ENGINE: ink + mermaid: + engine: ink ``` 注: この方法は pdf エクスポートに対応していません。 @@ -166,16 +169,16 @@ ### Docker によるインストール > Windowsでは、"/opt/metagpt"をDockerが作成する権限を持つディレクトリに置き換える必要があります。例えば、"D:\Users\x\metagpt"などです。 ```bash -# ステップ 1: metagpt 公式イメージをダウンロードし、config.yaml を準備する +# ステップ 1: metagpt 公式イメージをダウンロードし、config2.yaml を準備する docker pull metagpt/metagpt:latest mkdir -p /opt/metagpt/{config,workspace} -docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml -vim /opt/metagpt/config/key.yaml # 設定を変更する +docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config2.yaml > /opt/metagpt/config/config2.yaml +vim /opt/metagpt/config/config2.yaml # 設定を変更する # ステップ 2: コンテナで metagpt デモを実行する docker run --rm \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest \ metagpt "Write a cli snake game" @@ -183,7 +186,7 @@ # ステップ 2: コンテナで metagpt デモを実行する # コンテナを起動し、その中でコマンドを実行することもできます docker run --name metagpt -d \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest @@ -194,7 +197,7 @@ # コンテナを起動し、その中でコマンドを実行することもで コマンド `docker run ...` は以下のことを行います: - 特権モードで実行し、ブラウザの実行権限を得る -- ホスト設定ファイル `/opt/metagpt/config/key.yaml` をコンテナ `/app/metagpt/config/key.yaml` にマップします +- ホスト設定ファイル `/opt/metagpt/config/config2.yaml` をコンテナ `/app/metagpt/config/config2.yaml` にマップします - ホストディレクトリ `/opt/metagpt/workspace` をコンテナディレクトリ `/app/metagpt/workspace` にマップするs - デモコマンド `metagpt "Write a cli snake game"` を実行する @@ -208,19 +211,14 @@ # また、自分で metagpt イメージを構築することもできます。 ## 設定 -- `OPENAI_API_KEY` を `config/key.yaml / config/config.yaml / env` のいずれかで設定します。 -- 優先順位は: `config/key.yaml > config/config.yaml > env` の順です。 +- `api_key` を `~/.metagpt/config2.yaml / config/config2.yaml` のいずれかで設定します。 +- 優先順位は: `~/.metagpt/config2.yaml > config/config2.yaml > env` の順です。 ```bash # 設定ファイルをコピーし、必要な修正を加える。 -cp config/config.yaml config/key.yaml +cp config/config2.yaml ~/.metagpt/config2.yaml ``` -| 変数名 | config/key.yaml | env | -| --------------------------------------- | ----------------------------------------- | ----------------------------------------------- | -| OPENAI_API_KEY # 自分のキーに置き換える | OPENAI_API_KEY: "sk-..." | export OPENAI_API_KEY="sk-..." | -| OPENAI_BASE_URL # オプション | OPENAI_BASE_URL: "https:///v1" | export OPENAI_BASE_URL="https:///v1" | - ## チュートリアル: スタートアップの開始 ```shell diff --git a/docs/install/cli_install.md b/docs/install/cli_install.md index 80deda771..33d759758 100644 --- a/docs/install/cli_install.md +++ b/docs/install/cli_install.md @@ -36,8 +36,8 @@ # Step 3: Clone the repository to your local machine, and install it. - don't forget to the configuration for mmdc in config.yml ```yml - PUPPETEER_CONFIG: "./config/puppeteer-config.json" - MMDC: "./node_modules/.bin/mmdc" + puppeteer_config: "./config/puppeteer-config.json" + path: "./node_modules/.bin/mmdc" ``` - if `pip install -e.` fails with error `[Errno 13] Permission denied: '/usr/local/lib/python3.11/dist-packages/test-easy-install-13129.write-test'`, try instead running `pip install -e. --user` @@ -59,12 +59,13 @@ # Step 3: Clone the repository to your local machine, and install it. playwright install --with-deps chromium ``` - - **modify `config.yaml`** + - **modify `config2.yaml`** - uncomment MERMAID_ENGINE from config.yaml and change it to `playwright` + uncomment mermaid.engine from config2.yaml and change it to `playwright` ```yaml - MERMAID_ENGINE: playwright + mermaid: + engine: playwright ``` - pyppeteer @@ -88,21 +89,23 @@ # Step 3: Clone the repository to your local machine, and install it. pyppeteer-install ``` - - **modify `config.yaml`** + - **modify `config2.yaml`** - uncomment MERMAID_ENGINE from config.yaml and change it to `pyppeteer` + uncomment mermaid.engine from config2.yaml and change it to `pyppeteer` ```yaml - MERMAID_ENGINE: pyppeteer + mermaid: + engine: pyppeteer ``` - mermaid.ink - - **modify `config.yaml`** + - **modify `config2.yaml`** - uncomment MERMAID_ENGINE from config.yaml and change it to `ink` + uncomment mermaid.engine from config2.yaml and change it to `ink` ```yaml - MERMAID_ENGINE: ink + mermaid: + engine: ink ``` Note: this method does not support pdf export. diff --git a/docs/install/cli_install_cn.md b/docs/install/cli_install_cn.md index b1da1b813..891b72d24 100644 --- a/docs/install/cli_install_cn.md +++ b/docs/install/cli_install_cn.md @@ -36,8 +36,8 @@ # 第 3 步:克隆仓库到您的本地机器,并进行安装。 - 不要忘记在config.yml中为mmdc配置配置, ```yml - PUPPETEER_CONFIG: "./config/puppeteer-config.json" - MMDC: "./node_modules/.bin/mmdc" + puppeteer_config: "./config/puppeteer-config.json" + path: "./node_modules/.bin/mmdc" ``` - 如果`pip install -e.`失败并显示错误`[Errno 13] Permission denied: '/usr/local/lib/python3.11/dist-packages/test-easy-install-13129.write-test'`,请尝试使用`pip install -e. --user`运行。 diff --git a/docs/install/docker_install.md b/docs/install/docker_install.md index 37125bdbe..2fe1b6abf 100644 --- a/docs/install/docker_install.md +++ b/docs/install/docker_install.md @@ -3,16 +3,16 @@ ## Docker Installation ### Use default MetaGPT image ```bash -# Step 1: Download metagpt official image and prepare config.yaml +# Step 1: Download metagpt official image and prepare config2.yaml docker pull metagpt/metagpt:latest mkdir -p /opt/metagpt/{config,workspace} -docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml -vim /opt/metagpt/config/key.yaml # Change the config +docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config2.yaml > /opt/metagpt/config/config2.yaml +vim /opt/metagpt/config/config2.yaml # Change the config # Step 2: Run metagpt demo with container docker run --rm \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest \ metagpt "Write a cli snake game" @@ -20,7 +20,7 @@ # Step 2: Run metagpt demo with container # You can also start a container and execute commands in it docker run --name metagpt -d \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest @@ -31,7 +31,7 @@ # You can also start a container and execute commands in it The command `docker run ...` do the following things: - Run in privileged mode to have permission to run the browser -- Map host configure file `/opt/metagpt/config/key.yaml` to container `/app/metagpt/config/key.yaml` +- Map host configure file `/opt/metagpt/config/config2.yaml` to container `/app/metagpt/config/config2.yaml` - Map host directory `/opt/metagpt/workspace` to container `/app/metagpt/workspace` - Execute the demo command `metagpt "Write a cli snake game"` diff --git a/docs/install/docker_install_cn.md b/docs/install/docker_install_cn.md index f360b49ed..10204c1e0 100644 --- a/docs/install/docker_install_cn.md +++ b/docs/install/docker_install_cn.md @@ -3,16 +3,16 @@ ## Docker安装 ### 使用MetaGPT镜像 ```bash -# 步骤1: 下载metagpt官方镜像并准备好config.yaml +# 步骤1: 下载metagpt官方镜像并准备好config2.yaml docker pull metagpt/metagpt:latest mkdir -p /opt/metagpt/{config,workspace} -docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml -vim /opt/metagpt/config/key.yaml # 修改配置文件 +docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config2.yaml > /opt/metagpt/config/config2.yaml +vim /opt/metagpt/config/config2.yaml # 修改配置文件 # 步骤2: 使用容器运行metagpt演示 docker run --rm \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest \ metagpt "Write a cli snake game" @@ -20,7 +20,7 @@ # 步骤2: 使用容器运行metagpt演示 # 您也可以启动一个容器并在其中执行命令 docker run --name metagpt -d \ --privileged \ - -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ + -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest @@ -31,7 +31,7 @@ # 您也可以启动一个容器并在其中执行命令 `docker run ...`做了以下事情: - 以特权模式运行,有权限运行浏览器 -- 将主机文件 `/opt/metagpt/config/key.yaml` 映射到容器文件 `/app/metagpt/config/key.yaml` +- 将主机文件 `/opt/metagpt/config/config2.yaml` 映射到容器文件 `/app/metagpt/config/config2.yaml` - 将主机目录 `/opt/metagpt/workspace` 映射到容器目录 `/app/metagpt/workspace` - 执行示例命令 `metagpt "Write a cli snake game"` diff --git a/docs/tutorial/usage.md b/docs/tutorial/usage.md index a08d92a22..809f91e1f 100644 --- a/docs/tutorial/usage.md +++ b/docs/tutorial/usage.md @@ -2,19 +2,14 @@ ## MetaGPT Usage ### Configuration -- Configure your `OPENAI_API_KEY` in any of `config/key.yaml / config/config.yaml / env` -- Priority order: `config/key.yaml > config/config.yaml > env` +- Configure your `key` in any of `~/.metagpt/config2.yaml / config/config2.yaml` +- Priority order: `~/.metagpt/config2.yaml > config/config2.yaml` ```bash # Copy the configuration file and make the necessary modifications. -cp config/config.yaml config/key.yaml +cp config/config2.yaml ~/.metagpt/config2.yaml ``` -| Variable Name | config/key.yaml | env | -| ------------------------------------------ | ----------------------------------------- | ----------------------------------------------- | -| OPENAI_API_KEY # Replace with your own key | OPENAI_API_KEY: "sk-..." | export OPENAI_API_KEY="sk-..." | -| OPENAI_BASE_URL # Optional | OPENAI_BASE_URL: "https:///v1" | export OPENAI_BASE_URL="https:///v1" | - ### Initiating a startup ```shell diff --git a/docs/tutorial/usage_cn.md b/docs/tutorial/usage_cn.md index 76a5d6b1b..709ec9968 100644 --- a/docs/tutorial/usage_cn.md +++ b/docs/tutorial/usage_cn.md @@ -2,19 +2,14 @@ ## MetaGPT 使用 ### 配置 -- 在 `config/key.yaml / config/config.yaml / env` 中配置您的 `OPENAI_API_KEY` -- 优先级顺序:`config/key.yaml > config/config.yaml > env` +- 在 `~/.metagpt/config2.yaml / config/config2.yaml` 中配置您的 `key` +- 优先级顺序:`~/.metagpt/config2.yaml > config/config2.yaml` ```bash # 复制配置文件并进行必要的修改 -cp config/config.yaml config/key.yaml +cp config/config2.yaml ~/.metagpt/config2.yaml ``` -| 变量名 | config/key.yaml | env | -| ----------------------------------- | ----------------------------------------- | ----------------------------------------------- | -| OPENAI_API_KEY # 用您自己的密钥替换 | OPENAI_API_KEY: "sk-..." | export OPENAI_API_KEY="sk-..." | -| OPENAI_BASE_URL # 可选 | OPENAI_BASE_URL: "https:///v1" | export OPENAI_BASE_URL="https:///v1" | - ### 示例:启动一个创业公司 ```shell diff --git a/metagpt/actions/design_api.py b/metagpt/actions/design_api.py index cb6013538..e5f038c7c 100644 --- a/metagpt/actions/design_api.py +++ b/metagpt/actions/design_api.py @@ -117,4 +117,4 @@ class WriteDesign(Action): async def _save_mermaid_file(self, data: str, pathname: Path): pathname.parent.mkdir(parents=True, exist_ok=True) - await mermaid_to_file(self.config.mermaid_engine, data, pathname) + await mermaid_to_file(self.config.mermaid.engine, data, pathname) diff --git a/metagpt/actions/write_prd.py b/metagpt/actions/write_prd.py index 823786893..b66887164 100644 --- a/metagpt/actions/write_prd.py +++ b/metagpt/actions/write_prd.py @@ -159,7 +159,7 @@ class WritePRD(Action): return pathname = self.repo.workdir / COMPETITIVE_ANALYSIS_FILE_REPO / Path(prd_doc.filename).stem pathname.parent.mkdir(parents=True, exist_ok=True) - await mermaid_to_file(self.config.mermaid_engine, quadrant_chart, pathname) + await mermaid_to_file(self.config.mermaid.engine, quadrant_chart, pathname) async def _rename_workspace(self, prd): if not self.project_name: diff --git a/metagpt/config2.py b/metagpt/config2.py index 5a556cc52..de0489789 100644 --- a/metagpt/config2.py +++ b/metagpt/config2.py @@ -67,24 +67,18 @@ class Config(CLIParams, YamlModel): code_review_k_times: int = 2 # Will be removed in the future - llm_for_researcher_summary: str = "gpt3" - llm_for_researcher_report: str = "gpt3" METAGPT_TEXT_TO_IMAGE_MODEL_URL: str = "" language: str = "English" redis_key: str = "placeholder" - mmdc: str = "mmdc" - puppeteer_config: str = "" - pyppeteer_executable_path: str = "" IFLYTEK_APP_ID: str = "" IFLYTEK_API_SECRET: str = "" IFLYTEK_API_KEY: str = "" AZURE_TTS_SUBSCRIPTION_KEY: str = "" AZURE_TTS_REGION: str = "" - mermaid_engine: str = "nodejs" @classmethod def from_home(cls, path): - """Load config from ~/.metagpt/config.yaml""" + """Load config from ~/.metagpt/config2.yaml""" pathname = CONFIG_ROOT / path if not pathname.exists(): return None diff --git a/metagpt/configs/llm_config.py b/metagpt/configs/llm_config.py index 626d4242f..fb923d3e4 100644 --- a/metagpt/configs/llm_config.py +++ b/metagpt/configs/llm_config.py @@ -74,5 +74,5 @@ class LLMConfig(YamlModel): @classmethod def check_llm_key(cls, v): if v in ["", None, "YOUR_API_KEY"]: - raise ValueError("Please set your API key in config.yaml") + raise ValueError("Please set your API key in config2.yaml") return v diff --git a/metagpt/configs/mermaid_config.py b/metagpt/configs/mermaid_config.py index de4a3865c..50c8a1847 100644 --- a/metagpt/configs/mermaid_config.py +++ b/metagpt/configs/mermaid_config.py @@ -14,5 +14,6 @@ class MermaidConfig(YamlModel): """Config for Mermaid""" engine: Literal["nodejs", "ink", "playwright", "pyppeteer"] = "nodejs" - path: str = "" - puppeteer_config: str = "" # Only for nodejs engine + path: str = "mmdc" # mmdc + puppeteer_config: str = "" + pyppeteer_path: str = "/usr/bin/google-chrome-stable" diff --git a/metagpt/utils/mermaid.py b/metagpt/utils/mermaid.py index e49fdea5d..ae3c5118f 100644 --- a/metagpt/utils/mermaid.py +++ b/metagpt/utils/mermaid.py @@ -35,10 +35,10 @@ async def mermaid_to_file(engine, mermaid_code, output_file_without_suffix, widt # tmp.write_text(mermaid_code, encoding="utf-8") if engine == "nodejs": - if check_cmd_exists(config.mmdc) != 0: + if check_cmd_exists(config.mermaid.path) != 0: logger.warning( "RUN `npm install -g @mermaid-js/mermaid-cli` to install mmdc," - "or consider changing MERMAID_ENGINE to `playwright`, `pyppeteer`, or `ink`." + "or consider changing engine to `playwright`, `pyppeteer`, or `ink`." ) return -1 @@ -47,11 +47,11 @@ async def mermaid_to_file(engine, mermaid_code, output_file_without_suffix, widt # Call the `mmdc` command to convert the Mermaid code to a PNG logger.info(f"Generating {output_file}..") - if config.puppeteer_config: + if config.mermaid.puppeteer_config: commands = [ - config.mmdc, + config.mermaid.path, "-p", - config.puppeteer_config, + config.mermaid.puppeteer_config, "-i", str(tmp), "-o", @@ -62,7 +62,7 @@ async def mermaid_to_file(engine, mermaid_code, output_file_without_suffix, widt str(height), ] else: - commands = [config.mmdc, "-i", str(tmp), "-o", output_file, "-w", str(width), "-H", str(height)] + commands = [config.mermaid.path, "-i", str(tmp), "-o", output_file, "-w", str(width), "-H", str(height)] process = await asyncio.create_subprocess_shell( " ".join(commands), stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) diff --git a/metagpt/utils/mmdc_pyppeteer.py b/metagpt/utils/mmdc_pyppeteer.py index d80098b7d..f029325f1 100644 --- a/metagpt/utils/mmdc_pyppeteer.py +++ b/metagpt/utils/mmdc_pyppeteer.py @@ -30,14 +30,14 @@ async def mermaid_to_file(mermaid_code, output_file_without_suffix, width=2048, suffixes = ["png", "svg", "pdf"] __dirname = os.path.dirname(os.path.abspath(__file__)) - if config.pyppeteer_executable_path: + if config.mermaid.pyppeteer_path: browser = await launch( headless=True, - executablePath=config.pyppeteer_executable_path, + executablePath=config.mermaid.pyppeteer_path, args=["--disable-extensions", "--no-sandbox"], ) else: - logger.error("Please set the environment variable:PYPPETEER_EXECUTABLE_PATH.") + logger.error("Please set the var mermaid.pyppeteer_path in the config2.yaml.") return -1 page = await browser.newPage() device_scale_factor = 1.0 diff --git a/metagpt/utils/yaml_model.py b/metagpt/utils/yaml_model.py index 8f2d22c3d..4d42bb03f 100644 --- a/metagpt/utils/yaml_model.py +++ b/metagpt/utils/yaml_model.py @@ -42,7 +42,7 @@ class YamlModelWithoutDefault(YamlModel): @model_validator(mode="before") @classmethod def check_not_default_config(cls, values): - """Check if there is any default config in config.yaml""" + """Check if there is any default config in config2.yaml""" if any(["YOUR" in v for v in values]): - raise ValueError("Please set your config in config.yaml") + raise ValueError("Please set your config in config2.yaml") return values From 90f84ad452876ff9b8cf2def0c08faa20925b805 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 10:19:40 +0800 Subject: [PATCH 18/35] Update FAQ-EN.md --- docs/FAQ-EN.md | 174 +++++++++++++++---------------------------------- 1 file changed, 53 insertions(+), 121 deletions(-) diff --git a/docs/FAQ-EN.md b/docs/FAQ-EN.md index 88b5b0573..d3caa244e 100644 --- a/docs/FAQ-EN.md +++ b/docs/FAQ-EN.md @@ -1,161 +1,93 @@ Our vision is to [extend human life](https://github.com/geekan/HowToLiveLonger) and [reduce working hours](https://github.com/geekan/MetaGPT/). -1. ### Convenient Link for Sharing this Document: +### Convenient Link for Sharing this Document: ``` -- MetaGPT-Index/FAQ https://deepwisdom.feishu.cn/wiki/MsGnwQBjiif9c3koSJNcYaoSnu4 +- MetaGPT-Index/FAQ-EN https://github.com/geekan/MetaGPT/blob/main/docs/FAQ-EN.md +- MetaGPT-Index/FAQ-CN https://deepwisdom.feishu.cn/wiki/MsGnwQBjiif9c3koSJNcYaoSnu4 ``` -2. ### Link - - +### Link 1. Code:https://github.com/geekan/MetaGPT - -1. Roadmap:https://github.com/geekan/MetaGPT/blob/main/docs/ROADMAP.md - -1. EN - - 1. Demo Video: [MetaGPT: Multi-Agent AI Programming Framework](https://www.youtube.com/watch?v=8RNzxZBTW8M) +2. Roadmap:https://github.com/geekan/MetaGPT/blob/main/docs/ROADMAP.md +3. EN + 1. Demo Video: [MetaGPT: Multi-Agent AI Programming Framework](https://www.youtube.com/watch?v=8RNzxZBTW8M) 2. Tutorial: [MetaGPT: Deploy POWERFUL Autonomous Ai Agents BETTER Than SUPERAGI!](https://www.youtube.com/watch?v=q16Gi9pTG_M&t=659s) 3. Author's thoughts video(EN): [MetaGPT Matthew Berman](https://youtu.be/uT75J_KG_aY?si=EgbfQNAwD8F5Y1Ak) +4. CN + 1. Demo Video: [MetaGPT:一行代码搭建你的虚拟公司_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1NP411C7GW/?spm_id_from=333.999.0.0&vd_source=735773c218b47da1b4bd1b98a33c5c77) + 1. Tutorial: [一个提示词写游戏 Flappy bird, 比AutoGPT强10倍的MetaGPT,最接近AGI的AI项目](https://youtu.be/Bp95b8yIH5c) + 2. Author's thoughts video(CN): [MetaGPT作者深度解析直播回放_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1Ru411V7XL/?spm_id_from=333.337.search-card.all.click) -1. CN - - 1. Demo Video: [MetaGPT:一行代码搭建你的虚拟公司_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1NP411C7GW/?spm_id_from=333.999.0.0&vd_source=735773c218b47da1b4bd1b98a33c5c77) - 1. Tutorial: [一个提示词写游戏 Flappy bird, 比AutoGPT强10倍的MetaGPT,最接近AGI的AI项目](https://youtu.be/Bp95b8yIH5c) - 2. Author's thoughts video(CN): [MetaGPT作者深度解析直播回放_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1Ru411V7XL/?spm_id_from=333.337.search-card.all.click) - - - -3. ### How to become a contributor? - - +### How to become a contributor? 1. Choose a task from the Roadmap (or you can propose one). By submitting a PR, you can become a contributor and join the dev team. -1. Current contributors come from backgrounds including ByteDance AI Lab/DingDong/Didi/Xiaohongshu, Tencent/Baidu/MSRA/TikTok/BloomGPT Infra/Bilibili/CUHK/HKUST/CMU/UCB +2. Current contributors come from backgrounds including ByteDance AI Lab/DingDong/Didi/Xiaohongshu, Tencent/Baidu/MSRA/TikTok/BloomGPT Infra/Bilibili/CUHK/HKUST/CMU/UCB - - -4. ### Chief Evangelist (Monthly Rotation) +### Chief Evangelist (Monthly Rotation) MetaGPT Community - The position of Chief Evangelist rotates on a monthly basis. The primary responsibilities include: 1. Maintaining community FAQ documents, announcements, and Github resources/READMEs. -1. Responding to, answering, and distributing community questions within an average of 30 minutes, including on platforms like Github Issues, Discord and WeChat. -1. Upholding a community atmosphere that is enthusiastic, genuine, and friendly. -1. Encouraging everyone to become contributors and participate in projects that are closely related to achieving AGI (Artificial General Intelligence). -1. (Optional) Organizing small-scale events, such as hackathons. +2. Responding to, answering, and distributing community questions within an average of 30 minutes, including on platforms like Github Issues, Discord and WeChat. +3. Upholding a community atmosphere that is enthusiastic, genuine, and friendly. +4. Encouraging everyone to become contributors and participate in projects that are closely related to achieving AGI (Artificial General Intelligence). +5. (Optional) Organizing small-scale events, such as hackathons. - - -5. ### FAQ - - - -1. Experience with the generated repo code: - - 1. https://github.com/geekan/MetaGPT/releases/tag/v0.1.0 +### FAQ 1. Code truncation/ Parsing failure: - - 1. Check if it's due to exceeding length. Consider using the gpt-3.5-turbo-16k or other long token versions. - -1. Success rate: - - 1. There hasn't been a quantitative analysis yet, but the success rate of code generated by GPT-4 is significantly higher than that of gpt-3.5-turbo. - -1. Support for incremental, differential updates (if you wish to continue a half-done task): - - 1. Several prerequisite tasks are listed on the ROADMAP. - -1. Can existing code be loaded? - - 1. It's not on the ROADMAP yet, but there are plans in place. It just requires some time. - -1. Support for multiple programming languages and natural languages? - - 1. It's listed on ROADMAP. - -1. Want to join the contributor team? How to proceed? - + 1. Check if it's due to exceeding length. Consider using the gpt-4-turbo-preview or other long token versions. +2. Success rate: + 1. There hasn't been a quantitative analysis yet, but the success rate of code generated by gpt-4-turbo-preview is significantly higher than that of gpt-3.5-turbo. +3. Support for incremental, differential updates (if you wish to continue a half-done task): + 1. There is now an experimental version. Specify `--inc --project-path ""` or `--inc --project-name ""` on the command line and enter the corresponding requirements to try it. +4. Can existing code be loaded? + 1. We are doing this, but it is very difficult, especially when the project is large, it is very difficult to achieve a high success rate. +5. Support for multiple programming languages and natural languages? + 1. It is now supported, but it is still in experimental version +6. Want to join the contributor team? How to proceed? 1. Merging a PR will get you into the contributor's team. The main ongoing tasks are all listed on the ROADMAP. - -1. PRD stuck / unable to access/ connection interrupted - +7. PRD stuck / unable to access/ connection interrupted 1. The official openai base_url address is `https://api.openai.com/v1` - 1. If the official openai base_url address is inaccessible in your environment (this can be verified with curl), it's recommended to configure using the reverse proxy openai base_url provided by libraries such as openai-forward. For instance, `openai base_url: "``https://api.openai-forward.com/v1``"` - 1. If the official openai base_url address is inaccessible in your environment (again, verifiable via curl), another option is to configure the llm.proxy parameter. This way, you can access the official openai base_url via a local proxy. If you don't need to access via a proxy, please do not enable this configuration; if accessing through a proxy is required, modify it to the correct proxy address. Note that when llm.proxy is enabled, don't set openai base_url. - 1. Note: OpenAI's default API design ends with a v1. An example of the correct configuration is: `openai base_url: "``https://api.openai.com/v1``"` - -1. Absolutely! How can I assist you today? - + 2. If the official openai base_url address is inaccessible in your environment (this can be verified with curl), it's recommended to configure using base_url to other "reverse-proxy" provider such as openai-forward. For instance, `openai base_url: "``https://api.openai-forward.com/v1``"` + 3. If the official openai base_url address is inaccessible in your environment (again, verifiable via curl), another option is to configure the llm.proxy in the `config2.yaml`. This way, you can access the official openai base_url via a local proxy. If you don't need to access via a proxy, please do not enable this configuration; if accessing through a proxy is required, modify it to the correct proxy address. + 4. Note: OpenAI's default API design ends with a v1. An example of the correct configuration is: `base_url: "https://api.openai.com/v1" +8. Get reply: "Absolutely! How can I assist you today?" 1. Did you use Chi or a similar service? These services are prone to errors, and it seems that the error rate is higher when consuming 3.5k-4k tokens in GPT-4 - -1. What does Max token mean? - +9. What does Max token mean? 1. It's a configuration for OpenAI's maximum response length. If the response exceeds the max token, it will be truncated. - -1. How to change the investment amount? - +10. How to change the investment amount? 1. You can view all commands by typing `metagpt --help` - -1. Which version of Python is more stable? - +11. Which version of Python is more stable? 1. python3.9 / python3.10 - -1. Can't use GPT-4, getting the error "The model gpt-4 does not exist." - +12. Can't use GPT-4, getting the error "The model gpt-4 does not exist." 1. OpenAI's official requirement: You can use GPT-4 only after spending $1 on OpenAI. 1. Tip: Run some data with gpt-3.5-turbo (consume the free quota and $1), and then you should be able to use gpt-4. - -1. Can games whose code has never been seen before be written? - +13. Can games whose code has never been seen before be written? 1. Refer to the README. The recommendation system of Toutiao is one of the most complex systems in the world currently. Although it's not on GitHub, many discussions about it exist online. If it can visualize these, it suggests it can also summarize these discussions and convert them into code. The prompt would be something like "write a recommendation system similar to Toutiao". Note: this was approached in earlier versions of the software. The SOP of those versions was different; the current one adopts Elon Musk's five-step work method, emphasizing trimming down requirements as much as possible. - -1. Under what circumstances would there typically be errors? - +14. Under what circumstances would there typically be errors? 1. More than 500 lines of code: some function implementations may be left blank. - 1. When using a database, it often gets the implementation wrong — since the SQL database initialization process is usually not in the code. - 1. With more lines of code, there's a higher chance of false impressions, leading to calls to non-existent APIs. - -1. An error occurred during installation: "Another program is using this file...egg". - + 2. When using a database, it often gets the implementation wrong — since the SQL database initialization process is usually not in the code. + 3. With more lines of code, there's a higher chance of false impressions, leading to calls to non-existent APIs. +15. An error occurred during installation: "Another program is using this file...egg". 1. Delete the file and try again. - 1. Or manually execute`pip install -r requirements.txt` - -1. The origin of the name MetaGPT? - + 2. Or manually execute`pip install -r requirements.txt` +16. The origin of the name MetaGPT? 1. The name was derived after iterating with GPT-4 over a dozen rounds. GPT-4 scored and suggested it. - -1. Is there a more step-by-step installation tutorial? - - 1. Youtube(CN):[一个提示词写游戏 Flappy bird, 比AutoGPT强10倍的MetaGPT,最接近AGI的AI项目=一个软件公司产品经理+程序员](https://youtu.be/Bp95b8yIH5c) - 1. Youtube(EN)https://www.youtube.com/watch?v=q16Gi9pTG_M&t=659s - 2. video(EN): [MetaGPT Matthew Berman](https://youtu.be/uT75J_KG_aY?si=EgbfQNAwD8F5Y1Ak) - -1. openai.error.RateLimitError: You exceeded your current quota, please check your plan and billing details - +17. openai.error.RateLimitError: You exceeded your current quota, please check your plan and billing details 1. If you haven't exhausted your free quota, set RPM to 3 or lower in the settings. - 1. If your free quota is used up, consider adding funds to your account. - -1. What does "borg" mean in n_borg? - + 2. If your free quota is used up, consider adding funds to your account. +18. What does "borg" mean in n_borg? 1. [Wikipedia borg meaning ](https://en.wikipedia.org/wiki/Borg) - 1. The Borg civilization operates based on a hive or collective mentality, known as "the Collective." Every Borg individual is connected to the collective via a sophisticated subspace network, ensuring continuous oversight and guidance for every member. This collective consciousness allows them to not only "share the same thoughts" but also to adapt swiftly to new strategies. While individual members of the collective rarely communicate, the collective "voice" sometimes transmits aboard ships. - -1. How to use the Claude API? - + 2. The Borg civilization operates based on a hive or collective mentality, known as "the Collective." Every Borg individual is connected to the collective via a sophisticated subspace network, ensuring continuous oversight and guidance for every member. This collective consciousness allows them to not only "share the same thoughts" but also to adapt swiftly to new strategies. While individual members of the collective rarely communicate, the collective "voice" sometimes transmits aboard ships. +19. How to use the Claude API? 1. The full implementation of the Claude API is not provided in the current code. 1. You can use the Claude API through third-party API conversion projects like: https://github.com/jtsang4/claude-to-chatgpt - -1. Is Llama2 supported? - +20. Is Llama2 supported? 1. On the day Llama2 was released, some of the community members began experiments and found that output can be generated based on MetaGPT's structure. However, Llama2's context is too short to generate a complete project. Before regularly using Llama2, it's necessary to expand the context window to at least 8k. If anyone has good recommendations for expansion models or methods, please leave a comment. - -1. `mermaid-cli getElementsByTagName SyntaxError: Unexpected token '.'` - +21. `mermaid-cli getElementsByTagName SyntaxError: Unexpected token '.'` 1. Upgrade node to version 14.x or above: - 1. `npm install -g n` - 1. `n stable` to install the stable version of node(v18.x) + 2. `n stable` to install the stable version of node(v18.x) From 026dd8167cc0ae95a1eddb8a2a74b97c2518e2e1 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 10:21:58 +0800 Subject: [PATCH 19/35] Update cli_install.md --- docs/install/cli_install.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/install/cli_install.md b/docs/install/cli_install.md index 33d759758..ab360fad2 100644 --- a/docs/install/cli_install.md +++ b/docs/install/cli_install.md @@ -33,11 +33,12 @@ # Step 3: Clone the repository to your local machine, and install it. npm install @mermaid-js/mermaid-cli ``` -- don't forget to the configuration for mmdc in config.yml +- don't forget to the configuration for mmdc path in config.yml ```yml - puppeteer_config: "./config/puppeteer-config.json" - path: "./node_modules/.bin/mmdc" + mermaid: + puppeteer_config: "./config/puppeteer-config.json" + path: "./node_modules/.bin/mmdc" ``` - if `pip install -e.` fails with error `[Errno 13] Permission denied: '/usr/local/lib/python3.11/dist-packages/test-easy-install-13129.write-test'`, try instead running `pip install -e. --user` @@ -61,7 +62,7 @@ # Step 3: Clone the repository to your local machine, and install it. - **modify `config2.yaml`** - uncomment mermaid.engine from config2.yaml and change it to `playwright` + change mermaid.engine to `playwright` ```yaml mermaid: @@ -91,7 +92,7 @@ # Step 3: Clone the repository to your local machine, and install it. - **modify `config2.yaml`** - uncomment mermaid.engine from config2.yaml and change it to `pyppeteer` + change mermaid.engine to `pyppeteer` ```yaml mermaid: @@ -100,8 +101,8 @@ # Step 3: Clone the repository to your local machine, and install it. - mermaid.ink - **modify `config2.yaml`** - - uncomment mermaid.engine from config2.yaml and change it to `ink` + + change mermaid.engine to `ink` ```yaml mermaid: @@ -109,4 +110,4 @@ # Step 3: Clone the repository to your local machine, and install it. ``` Note: this method does not support pdf export. - \ No newline at end of file + From 3fa2b3216effaeabfcb8294bbc674e2bb9becbc7 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 10:35:51 +0800 Subject: [PATCH 20/35] refine docs --- docs/install/cli_install.md | 28 +++++++++++++------ docs/install/cli_install_cn.md | 33 ++++++++++++++++------- docs/tutorial/usage.md | 49 +++++++++++++++++----------------- docs/tutorial/usage_cn.md | 49 +++++++++++++++++----------------- 4 files changed, 91 insertions(+), 68 deletions(-) diff --git a/docs/install/cli_install.md b/docs/install/cli_install.md index ab360fad2..b79ad9cb7 100644 --- a/docs/install/cli_install.md +++ b/docs/install/cli_install.md @@ -9,17 +9,29 @@ ### Support System and version ### Detail Installation ```bash -# Step 1: Ensure that NPM is installed on your system. Then install mermaid-js. (If you don't have npm in your computer, please go to the Node.js official website to install Node.js https://nodejs.org/ and then you will have npm tool in your computer.) -npm --version -sudo npm install -g @mermaid-js/mermaid-cli - -# Step 2: Ensure that Python 3.9+ is installed on your system. You can check this by using: +# Step 1: Ensure that Python 3.9+ is installed on your system. You can check this by using: +# You can use conda to initialize a new python env +# conda create -n metagpt python=3.9 +# conda activate metagpt python3 --version -# Step 3: Clone the repository to your local machine, and install it. +# Step 2: Clone the repository to your local machine for latest version, and install it. git clone https://github.com/geekan/MetaGPT.git cd MetaGPT -pip install -e. +pip3 install -e . # or pip3 install metagpt # for stable version + +# Step 3: setup your LLM key in the config2.yaml file +mkdir ~/.metagpt +cp config/config2.yaml ~/.metagpt/config2.yaml +vim ~/.metagpt/config2.yaml + +# Step 4: run metagpt cli +metagpt "Create a 2048 game in python" + +# Step 5 [Optional]: If you want to save the artifacts like diagrams such as quadrant chart, system designs, sequence flow in the workspace, you can execute the step before Step 3. By default, the framework is compatible, and the entire process can be run completely without executing this step. +# If executing, ensure that NPM is installed on your system. Then install mermaid-js. (If you don't have npm in your computer, please go to the Node.js official website to install Node.js https://nodejs.org/ and then you will have npm tool in your computer.) +npm --version +sudo npm install -g @mermaid-js/mermaid-cli ``` **Note:** @@ -35,7 +47,7 @@ # Step 3: Clone the repository to your local machine, and install it. - don't forget to the configuration for mmdc path in config.yml - ```yml + ```yaml mermaid: puppeteer_config: "./config/puppeteer-config.json" path: "./node_modules/.bin/mmdc" diff --git a/docs/install/cli_install_cn.md b/docs/install/cli_install_cn.md index 891b72d24..1ee18d9a6 100644 --- a/docs/install/cli_install_cn.md +++ b/docs/install/cli_install_cn.md @@ -10,17 +10,29 @@ ### 支持的系统和版本 ### 详细安装 ```bash -# 第 1 步:确保您的系统上安装了 NPM。并使用npm安装mermaid-js -npm --version -sudo npm install -g @mermaid-js/mermaid-cli - -# 第 2 步:确保您的系统上安装了 Python 3.9+。您可以使用以下命令进行检查: +# 步骤 1: 确保您的系统安装了 Python 3.9 或更高版本。您可以使用以下命令来检查: +# 您可以使用 conda 来初始化一个新的 Python 环境 +# conda create -n metagpt python=3.9 +# conda activate metagpt python3 --version -# 第 3 步:克隆仓库到您的本地机器,并进行安装。 +# 步骤 2: 克隆仓库到您的本地机器以获取最新版本,并安装它。 git clone https://github.com/geekan/MetaGPT.git cd MetaGPT -pip install -e. +pip3 install -e . # 或 pip3 install metagpt # 用于稳定版本 + +# 步骤 3: 在 config2.yaml 文件中设置您的 LLM 密钥 +mkdir ~/.metagpt +cp config/config2.yaml ~/.metagpt/config2.yaml +vim ~/.metagpt/config2.yaml + +# 步骤 4: 运行 metagpt 命令行界面 +metagpt "用 python 创建一个 2048 游戏" + +# 步骤 5 [可选]: 如果您想保存诸如象限图、系统设计、序列流等图表作为工作空间的工件,您可以在执行步骤 3 之前执行此步骤。默认情况下,该框架是兼容的,整个过程可以完全不执行此步骤而运行。 +# 如果执行此步骤,请确保您的系统上安装了 NPM。然后安装 mermaid-js。(如果您的计算机中没有 npm,请访问 Node.js 官方网站 https://nodejs.org/ 安装 Node.js,然后您将在计算机中拥有 npm 工具。) +npm --version +sudo npm install -g @mermaid-js/mermaid-cli ``` **注意:** @@ -33,11 +45,12 @@ # 第 3 步:克隆仓库到您的本地机器,并进行安装。 npm install @mermaid-js/mermaid-cli ``` -- 不要忘记在config.yml中为mmdc配置配置, +- 不要忘记在config.yml中为mmdc配置 ```yml - puppeteer_config: "./config/puppeteer-config.json" - path: "./node_modules/.bin/mmdc" + mermaid: + puppeteer_config: "./config/puppeteer-config.json" + path: "./node_modules/.bin/mmdc" ``` - 如果`pip install -e.`失败并显示错误`[Errno 13] Permission denied: '/usr/local/lib/python3.11/dist-packages/test-easy-install-13129.write-test'`,请尝试使用`pip install -e. --user`运行。 diff --git a/docs/tutorial/usage.md b/docs/tutorial/usage.md index 809f91e1f..e8bfc37d9 100644 --- a/docs/tutorial/usage.md +++ b/docs/tutorial/usage.md @@ -34,29 +34,28 @@ ### Preference of Platform or Tool ### Usage ``` -NAME - metagpt - We are a software startup comprised of AI. By investing in us, you are empowering a future filled with limitless possibilities. - -SYNOPSIS - metagpt IDEA - -DESCRIPTION - We are a software startup comprised of AI. By investing in us, you are empowering a future filled with limitless possibilities. - -POSITIONAL ARGUMENTS - IDEA - Type: str - Your innovative idea, such as "Creating a snake game." - -FLAGS - --investment=INVESTMENT - Type: float - Default: 3.0 - As an investor, you have the opportunity to contribute a certain dollar amount to this AI company. - --n_round=N_ROUND - Type: int - Default: 5 - -NOTES - You can also use flags syntax for POSITIONAL ARGUMENTS + Usage: metagpt [OPTIONS] [IDEA] + + Start a new project. + +╭─ Arguments ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ idea [IDEA] Your innovative idea, such as 'Create a 2048 game.' [default: None] │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ --investment FLOAT Dollar amount to invest in the AI company. [default: 3.0] │ +│ --n-round INTEGER Number of rounds for the simulation. [default: 5] │ +│ --code-review --no-code-review Whether to use code review. [default: code-review] │ +│ --run-tests --no-run-tests Whether to enable QA for adding & running tests. [default: no-run-tests] │ +│ --implement --no-implement Enable or disable code implementation. [default: implement] │ +│ --project-name TEXT Unique project name, such as 'game_2048'. │ +│ --inc --no-inc Incremental mode. Use it to coop with existing repo. [default: no-inc] │ +│ --project-path TEXT Specify the directory path of the old version project to fulfill the incremental requirements. │ +│ --reqa-file TEXT Specify the source file name for rewriting the quality assurance code. │ +│ --max-auto-summarize-code INTEGER The maximum number of times the 'SummarizeCode' action is automatically invoked, with -1 indicating unlimited. This parameter is used for debugging the │ +│ workflow. │ +│ [default: 0] │ +│ --recover-path TEXT recover the project from existing serialized storage [default: None] │ +│ --init-config --no-init-config Initialize the configuration file for MetaGPT. [default: no-init-config] │ +│ --help Show this message and exit. │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` \ No newline at end of file diff --git a/docs/tutorial/usage_cn.md b/docs/tutorial/usage_cn.md index 709ec9968..075e928fd 100644 --- a/docs/tutorial/usage_cn.md +++ b/docs/tutorial/usage_cn.md @@ -30,29 +30,28 @@ ### 平台或工具的倾向性 ### 使用 ``` -名称 - metagpt - 我们是一家AI软件创业公司。通过投资我们,您将赋能一个充满无限可能的未来。 - -概要 - metagpt IDEA - -描述 - 我们是一家AI软件创业公司。通过投资我们,您将赋能一个充满无限可能的未来。 - -位置参数 - IDEA - 类型: str - 您的创新想法,例如"写一个命令行贪吃蛇。" - -标志 - --investment=INVESTMENT - 类型: float - 默认值: 3.0 - 作为投资者,您有机会向这家AI公司投入一定的美元金额。 - --n_round=N_ROUND - 类型: int - 默认值: 5 - -备注 - 您也可以用`标志`的语法,来处理`位置参数` + Usage: metagpt [OPTIONS] [IDEA] + + Start a new project. + +╭─ Arguments ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ idea [IDEA] Your innovative idea, such as 'Create a 2048 game.' [default: None] │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ --investment FLOAT Dollar amount to invest in the AI company. [default: 3.0] │ +│ --n-round INTEGER Number of rounds for the simulation. [default: 5] │ +│ --code-review --no-code-review Whether to use code review. [default: code-review] │ +│ --run-tests --no-run-tests Whether to enable QA for adding & running tests. [default: no-run-tests] │ +│ --implement --no-implement Enable or disable code implementation. [default: implement] │ +│ --project-name TEXT Unique project name, such as 'game_2048'. │ +│ --inc --no-inc Incremental mode. Use it to coop with existing repo. [default: no-inc] │ +│ --project-path TEXT Specify the directory path of the old version project to fulfill the incremental requirements. │ +│ --reqa-file TEXT Specify the source file name for rewriting the quality assurance code. │ +│ --max-auto-summarize-code INTEGER The maximum number of times the 'SummarizeCode' action is automatically invoked, with -1 indicating unlimited. This parameter is used for debugging the │ +│ workflow. │ +│ [default: 0] │ +│ --recover-path TEXT recover the project from existing serialized storage [default: None] │ +│ --init-config --no-init-config Initialize the configuration file for MetaGPT. [default: no-init-config] │ +│ --help Show this message and exit. │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` From 7e973341682bdc555566aca47a534ef455f5346f Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 10:53:08 +0800 Subject: [PATCH 21/35] refine docs --- README.md | 27 +++++++-------------------- docs/README_CN.md | 27 +++++++++------------------ docs/tutorial/usage.md | 2 +- docs/tutorial/usage_cn.md | 2 +- metagpt/startup.py | 22 +++++++++++----------- 5 files changed, 29 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 39dde8208..c8277d55e 100644 --- a/README.md +++ b/README.md @@ -55,30 +55,17 @@ ## Install ### Pip installation +> Ensure that Python 3.9+ is installed on your system. You can check this by using: `python --version`. + ```bash -# Step 1: Ensure that Python 3.9+ is installed on your system. You can check this by using: # You can use conda to initialize a new python env # conda create -n metagpt python=3.9 # conda activate metagpt -python3 --version +pip install metagpt +metagpt --init-config # this will create a ~/.metagpt/config2.yaml from config/config2.yaml, modify it to your own config -# Step 2: Clone the repository to your local machine for latest version, and install it. -git clone https://github.com/geekan/MetaGPT.git -cd MetaGPT -pip3 install -e . # or pip3 install metagpt # for stable version - -# Step 3: setup your LLM key in the config2.yaml file -mkdir ~/.metagpt -cp config/config2.yaml ~/.metagpt/config2.yaml -vim ~/.metagpt/config2.yaml - -# Step 4: run metagpt cli -metagpt "Create a 2048 game in python" - -# Step 5 [Optional]: If you want to save the artifacts like diagrams such as quadrant chart, system designs, sequence flow in the workspace, you can execute the step before Step 3. By default, the framework is compatible, and the entire process can be run completely without executing this step. -# If executing, ensure that NPM is installed on your system. Then install mermaid-js. (If you don't have npm in your computer, please go to the Node.js official website to install Node.js https://nodejs.org/ and then you will have npm tool in your computer.) -npm --version -sudo npm install -g @mermaid-js/mermaid-cli +# Usage: metagpt "" +metagpt "Create a 2048 game" ``` detail installation please refer to [cli_install](https://docs.deepwisdom.ai/main/en/guide/get_started/installation.html#install-stable-version) @@ -99,7 +86,7 @@ # Step 2: Run metagpt demo with container -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ metagpt/metagpt:latest \ - metagpt "Write a cli snake game" + metagpt "Create a 2048 game" ``` detail installation please refer to [docker_install](https://docs.deepwisdom.ai/main/en/guide/get_started/installation.html#install-with-docker) diff --git a/docs/README_CN.md b/docs/README_CN.md index ebf5dd408..52e781560 100644 --- a/docs/README_CN.md +++ b/docs/README_CN.md @@ -35,29 +35,20 @@ # MetaGPT: 多智能体框架 ## 安装 ### Pip安装 +> 确保您的系统安装了 Python 3.9 或更高版本。您可以通过以下命令来检查:`python --version`。 + ```bash -# 第 1 步:确保您的系统上安装了 Python 3.9+。您可以使用以下命令进行检查: -# 可以使用conda来初始化新的python环境 +# 您可以使用 conda 来初始化一个新的 python 环境 # conda create -n metagpt python=3.9 # conda activate metagpt -python3 --version +pip install metagpt +metagpt --init-config # 这将会从 config/config2.yaml 创建一个 ~/.metagpt/config2.yaml,根据您的需求修改它 -# 第 2 步:克隆最新仓库到您的本地机器,并进行安装。 -git clone https://github.com/geekan/MetaGPT.git -cd MetaGPT -pip3 install -e. # 或者 pip3 install metagpt # 安装稳定版本 - -# 第 3 步:执行metagpt -# 拷贝config2.yaml为~/.metagpt/config2.yaml,并设置你自己的api_key -metagpt "Write a cli snake game" - -# 第 4 步【可选的】:如果你想在执行过程中保存像象限图、系统设计、序列流程等图表这些产物,可以在第3步前执行该步骤。默认的,框架做了兼容,在不执行该步的情况下,也可以完整跑完整个流程。 -# 如果执行,确保您的系统上安装了 NPM。并使用npm安装mermaid-js -npm --version -sudo npm install -g @mermaid-js/mermaid-cli +# 使用方法: metagpt "<创建一个游戏或软件>" +metagpt "创建一个 2048 游戏" ``` -详细的安装请安装 [cli_install](https://docs.deepwisdom.ai/guide/get_started/installation.html#install-stable-version) +详细的安装请参考 [cli_install](https://docs.deepwisdom.ai/guide/get_started/installation.html#install-stable-version) ### Docker安装 > 注意:在Windows中,你需要将 "/opt/metagpt" 替换为Docker具有创建权限的目录,比如"D:\Users\x\metagpt" @@ -78,7 +69,7 @@ # 步骤2: 使用容器运行metagpt演示 metagpt "Write a cli snake game" ``` -详细的安装请安装 [docker_install](https://docs.deepwisdom.ai/main/zh/guide/get_started/installation.html#%E4%BD%BF%E7%94%A8docker%E5%AE%89%E8%A3%85) +详细的安装请参考 [docker_install](https://docs.deepwisdom.ai/main/zh/guide/get_started/installation.html#%E4%BD%BF%E7%94%A8docker%E5%AE%89%E8%A3%85) ### 快速开始的演示视频 - 在 [MetaGPT Huggingface Space](https://huggingface.co/spaces/deepwisdom/MetaGPT) 上进行体验 diff --git a/docs/tutorial/usage.md b/docs/tutorial/usage.md index e8bfc37d9..1128e98a5 100644 --- a/docs/tutorial/usage.md +++ b/docs/tutorial/usage.md @@ -2,7 +2,7 @@ ## MetaGPT Usage ### Configuration -- Configure your `key` in any of `~/.metagpt/config2.yaml / config/config2.yaml` +- Configure your `api_key` in any of `~/.metagpt/config2.yaml / config/config2.yaml` - Priority order: `~/.metagpt/config2.yaml > config/config2.yaml` ```bash diff --git a/docs/tutorial/usage_cn.md b/docs/tutorial/usage_cn.md index 075e928fd..3b0c86279 100644 --- a/docs/tutorial/usage_cn.md +++ b/docs/tutorial/usage_cn.md @@ -2,7 +2,7 @@ ## MetaGPT 使用 ### 配置 -- 在 `~/.metagpt/config2.yaml / config/config2.yaml` 中配置您的 `key` +- 在 `~/.metagpt/config2.yaml / config/config2.yaml` 中配置您的 `api_key` - 优先级顺序:`~/.metagpt/config2.yaml > config/config2.yaml` ```bash diff --git a/metagpt/startup.py b/metagpt/startup.py index 4a077cab7..26bb29cd1 100644 --- a/metagpt/startup.py +++ b/metagpt/startup.py @@ -17,17 +17,17 @@ app = typer.Typer(add_completion=False, pretty_exceptions_show_locals=False) def generate_repo( idea, - investment, - n_round, - code_review, - run_tests, - implement, - project_name, - inc, - project_path, - reqa_file, - max_auto_summarize_code, - recover_path, + investment=3.0, + n_round=5, + code_review=True, + run_tests=False, + implement=True, + project_name="", + inc=False, + project_path="", + reqa_file="", + max_auto_summarize_code=0, + recover_path=None, ) -> ProjectRepo: """Run the startup logic. Can be called from CLI or other Python scripts.""" from metagpt.roles import ( From c20aecf5f27c4a5fdc1340ecb0ec6ab8f41360af Mon Sep 17 00:00:00 2001 From: voidking Date: Wed, 31 Jan 2024 19:32:36 +0800 Subject: [PATCH 22/35] feat: auto-unittest --- .github/workflows/auto-unittest.yaml | 74 ++++++++++++++++++++++++++++ .github/workflows/unittest.yaml | 1 + tests/config2.yaml | 30 +++++++++++ tests/spark.yaml | 7 +++ 4 files changed, 112 insertions(+) create mode 100644 .github/workflows/auto-unittest.yaml create mode 100644 tests/config2.yaml create mode 100644 tests/spark.yaml diff --git a/.github/workflows/auto-unittest.yaml b/.github/workflows/auto-unittest.yaml new file mode 100644 index 000000000..33c6acb0e --- /dev/null +++ b/.github/workflows/auto-unittest.yaml @@ -0,0 +1,74 @@ +name: Auto Unit Tests + +on: + pull_request_target: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + # python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.9'] + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + - name: Install dependencies + run: | + sh tests/scripts/run_install_deps.sh + - name: Run reverse proxy script for ssh service + if: contains(github.ref, '-debugger') + continue-on-error: true + env: + FPR_SERVER_ADDR: ${{ secrets.FPR_SERVER_ADDR }} + FPR_TOKEN: ${{ secrets.FPR_TOKEN }} + FPR_SSH_REMOTE_PORT: ${{ secrets.FPR_SSH_REMOTE_PORT }} + RSA_PUB: ${{ secrets.RSA_PUB }} + SSH_PORT: ${{ vars.SSH_PORT || '22'}} + run: | + echo "Run \"ssh $(whoami)@FPR_SERVER_HOST -p FPR_SSH_REMOTE_PORT\" and \"cd $(pwd)\"" + mkdir -p ~/.ssh/ + echo $RSA_PUB >> ~/.ssh/authorized_keys + chmod 600 ~/.ssh/authorized_keys + wget https://github.com/fatedier/frp/releases/download/v0.32.1/frp_0.32.1_linux_amd64.tar.gz -O frp.tar.gz + tar xvzf frp.tar.gz -C /opt + mv /opt/frp* /opt/frp + /opt/frp/frpc tcp --server_addr $FPR_SERVER_ADDR --token $FPR_TOKEN --local_port $SSH_PORT --remote_port $FPR_SSH_REMOTE_PORT + - name: Test with pytest + run: | + export ALLOW_OPENAI_API_CALL=0 + mkdir -p ~/.metagpt && cp tests/config2.yaml ~/.metagpt/config2.yaml && cp tests/spark.yaml ~/.metagpt/spark.yaml + pytest tests/ --doctest-modules --cov=./metagpt/ --cov-report=xml:cov.xml --cov-report=html:htmlcov --durations=20 | tee unittest.txt + - name: Show coverage report + run: | + coverage report -m + - name: Show failed tests and overall summary + run: | + grep -E "FAILED tests|ERROR tests|[0-9]+ passed," unittest.txt + failed_count=$(grep -E "FAILED|ERROR" unittest.txt | wc -l) + if [[ "$failed_count" -gt 0 ]]; then + echo "$failed_count failed lines found! Task failed." + exit 1 + fi + - name: Upload pytest test results + uses: actions/upload-artifact@v3 + with: + name: pytest-results-${{ matrix.python-version }} + path: | + ./unittest.txt + ./htmlcov/ + ./tests/data/rsp_cache_new.json + retention-days: 3 + if: ${{ always() }} + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + if: ${{ always() }} diff --git a/.github/workflows/unittest.yaml b/.github/workflows/unittest.yaml index 87ccbf144..71f359cb7 100644 --- a/.github/workflows/unittest.yaml +++ b/.github/workflows/unittest.yaml @@ -51,6 +51,7 @@ jobs: export ALLOW_OPENAI_API_CALL=0 echo "${{ secrets.METAGPT_KEY_YAML }}" | base64 -d > config/key.yaml mkdir -p ~/.metagpt && echo "${{ secrets.METAGPT_CONFIG2_YAML }}" | base64 -d > ~/.metagpt/config2.yaml + echo "${{ secrets.SPARK_YAML }}" | base64 -d > ~/.metagpt/spark.yaml pytest tests/ --doctest-modules --cov=./metagpt/ --cov-report=xml:cov.xml --cov-report=html:htmlcov --durations=20 | tee unittest.txt - name: Show coverage report run: | diff --git a/tests/config2.yaml b/tests/config2.yaml new file mode 100644 index 000000000..24728d873 --- /dev/null +++ b/tests/config2.yaml @@ -0,0 +1,30 @@ +llm: + base_url: "https://api.openai.com/v1" + api_key: "sk-xxx" + model: "gpt-3.5-turbo-16k" + +search: + api_type: "serpapi" + api_key: "xxx" + +s3: + access_key: "MOCK_S3_ACCESS_KEY" + secret_key: "MOCK_S3_SECRET_KEY" + endpoint: "http://mock:9000" + secure: false + bucket: "mock" + +AZURE_TTS_SUBSCRIPTION_KEY: "xxx" +AZURE_TTS_REGION: "eastus" + +IFLYTEK_APP_ID: "xxx" +IFLYTEK_API_KEY: "xxx" +IFLYTEK_API_SECRET: "xxx" + +METAGPT_TEXT_TO_IMAGE_MODEL_URL: "http://mock.com" + +PYPPETEER_EXECUTABLE_PATH: "/usr/bin/chromium" + +REPAIR_LLM_OUTPUT: true + + diff --git a/tests/spark.yaml b/tests/spark.yaml new file mode 100644 index 000000000..a5bbd98bd --- /dev/null +++ b/tests/spark.yaml @@ -0,0 +1,7 @@ +llm: + api_type: "spark" + app_id: "xxx" + api_key: "xxx" + api_secret: "xxx" + domain: "generalv2" + base_url: "wss://spark-api.xf-yun.com/v3.1/chat" \ No newline at end of file From 097128f022d6cf52a6ef77d4db0bb4f7b0aa41ce Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 11:14:34 +0800 Subject: [PATCH 23/35] refine docs --- README.md | 8 ++++++ docs/README_CN.md | 8 ++++++ docs/README_JA.md | 26 +++++++++---------- metagpt/actions/write_docstring.py | 2 +- metagpt/{startup.py => software_company.py} | 0 metagpt/utils/project_repo.py | 7 +++++ .../actions/test_rebuild_class_view.py | 6 ++--- tests/metagpt/test_incremental_dev.py | 2 +- tests/metagpt/test_startup.py | 2 +- 9 files changed, 42 insertions(+), 19 deletions(-) rename metagpt/{startup.py => software_company.py} (100%) diff --git a/README.md b/README.md index c8277d55e..1432b27ee 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,14 @@ # Usage: metagpt "" metagpt "Create a 2048 game" ``` +or you can use it as library + +```python +from metagpt.software_company import generate_repo, ProjectRepo +repo: ProjectRepo = generate_repo("Create a 2048 game") # or ProjectRepo("") +print(repo) # it will print the repo structure with files +``` + detail installation please refer to [cli_install](https://docs.deepwisdom.ai/main/en/guide/get_started/installation.html#install-stable-version) ### Docker installation diff --git a/docs/README_CN.md b/docs/README_CN.md index 52e781560..254bff5c6 100644 --- a/docs/README_CN.md +++ b/docs/README_CN.md @@ -48,6 +48,14 @@ # 使用方法: metagpt "<创建一个游戏或软件>" metagpt "创建一个 2048 游戏" ``` +或者您可以将其作为库使用 + +```python +from metagpt.software_company import generate_repo, ProjectRepo +repo: ProjectRepo = generate_repo("创建一个 2048 游戏") # 或 ProjectRepo("<您的仓库路径>") +print(repo) # 它将打印出仓库结构及其文件 +``` + 详细的安装请参考 [cli_install](https://docs.deepwisdom.ai/guide/get_started/installation.html#install-stable-version) ### Docker安装 diff --git a/docs/README_JA.md b/docs/README_JA.md index 26db0498f..a665b7f76 100644 --- a/docs/README_JA.md +++ b/docs/README_JA.md @@ -59,22 +59,22 @@ ### インストールビデオガイド ### 伝統的なインストール ```bash -# ステップ 1: Python 3.9+ がシステムにインストールされていることを確認してください。これを確認するには: -python3 --version +# 新しいPython環境を初期化するためにcondaを使用できます +# conda create -n metagpt python=3.9 +# conda activate metagpt +pip install metagpt +metagpt --init-config # これにより、config/config2.yaml から ~/.metagpt/config2.yaml が作成されます。自分の設定に合わせて変更してください -# ステップ 2: リポジトリをローカルマシンにクローンし、インストールする。 -git clone https://github.com/geekan/MetaGPT.git -cd MetaGPT -pip install -e. +# 使用方法:metagpt "<ゲームまたはソフトウェアを作成する>" +metagpt "2048ゲームを作成する" +``` -# ステップ 3: metagpt を実行する -# config/config2.yaml を ~/.metagpt/config2.yaml にコピーし、独自の api_key を設定します -metagpt "Write a cli snake game" +また、ライブラリとして使用することもできます。 -# ステップ 4 [オプション]: 実行中に PRD ファイルなどのアーティファクトを保存する場合は、ステップ 3 の前にこのステップを実行できます。デフォルトでは、フレームワークには互換性があり、この手順を実行しなくてもプロセス全体を完了できます。 -# NPM がシステムにインストールされていることを確認してください。次に mermaid-js をインストールします。(お使いのコンピューターに npm がない場合は、Node.js 公式サイトで Node.js https://nodejs.org/ をインストールしてください。) -npm --version -sudo npm install -g @mermaid-js/mermaid-cli +```python +from metagpt.software_company import generate_repo, ProjectRepo +repo: ProjectRepo = generate_repo("2048ゲームを作成する") # または ProjectRepo("<リポジトリへのパス>") +print(repo) # リポジトリの構造とファイルを出力します ``` **注:** diff --git a/metagpt/actions/write_docstring.py b/metagpt/actions/write_docstring.py index 79204e6a4..5cc4cafb8 100644 --- a/metagpt/actions/write_docstring.py +++ b/metagpt/actions/write_docstring.py @@ -16,7 +16,7 @@ Options: Default: 'google' Example: - python3 -m metagpt.actions.write_docstring ./metagpt/startup.py --overwrite False --style=numpy + python3 -m metagpt.actions.write_docstring ./metagpt/software_company.py --overwrite False --style=numpy This script uses the 'fire' library to create a command-line interface. It generates docstrings for the given Python code using the specified docstring style and adds them to the code. diff --git a/metagpt/startup.py b/metagpt/software_company.py similarity index 100% rename from metagpt/startup.py rename to metagpt/software_company.py diff --git a/metagpt/utils/project_repo.py b/metagpt/utils/project_repo.py index 72bca7ea0..c1f98e1ec 100644 --- a/metagpt/utils/project_repo.py +++ b/metagpt/utils/project_repo.py @@ -99,6 +99,13 @@ class ProjectRepo(FileRepository): self.tests = self._git_repo.new_file_repository(relative_path=TEST_CODES_FILE_REPO) self.test_outputs = self._git_repo.new_file_repository(relative_path=TEST_OUTPUTS_FILE_REPO) self._srcs_path = None + self.code_files_exists() + + def __str__(self): + repo_str = f"ProjectRepo({self._git_repo.workdir})" + docs_str = f"Docs({self.docs.all_files})" + srcs_str = f"Srcs({self.srcs.all_files})" + return f"{repo_str}\n{docs_str}\n{srcs_str}" @property async def requirement(self): diff --git a/tests/metagpt/actions/test_rebuild_class_view.py b/tests/metagpt/actions/test_rebuild_class_view.py index 04b7d91fc..403109cc0 100644 --- a/tests/metagpt/actions/test_rebuild_class_view.py +++ b/tests/metagpt/actions/test_rebuild_class_view.py @@ -29,9 +29,9 @@ async def test_rebuild(context): @pytest.mark.parametrize( ("path", "direction", "diff", "want"), [ - ("metagpt/startup.py", "=", ".", "metagpt/startup.py"), - ("metagpt/startup.py", "+", "MetaGPT", "MetaGPT/metagpt/startup.py"), - ("metagpt/startup.py", "-", "metagpt", "startup.py"), + ("metagpt/software_company.py", "=", ".", "metagpt/software_company.py"), + ("metagpt/software_company.py", "+", "MetaGPT", "MetaGPT/metagpt/software_company.py"), + ("metagpt/software_company.py", "-", "metagpt", "software_company.py"), ], ) def test_align_path(path, direction, diff, want): diff --git a/tests/metagpt/test_incremental_dev.py b/tests/metagpt/test_incremental_dev.py index 3e4a1b901..964d4c757 100644 --- a/tests/metagpt/test_incremental_dev.py +++ b/tests/metagpt/test_incremental_dev.py @@ -14,7 +14,7 @@ from typer.testing import CliRunner from metagpt.const import TEST_DATA_PATH from metagpt.logs import logger -from metagpt.startup import app +from metagpt.software_company import app runner = CliRunner() diff --git a/tests/metagpt/test_startup.py b/tests/metagpt/test_startup.py index 095a74e3b..d690d6f3f 100644 --- a/tests/metagpt/test_startup.py +++ b/tests/metagpt/test_startup.py @@ -9,7 +9,7 @@ import pytest from typer.testing import CliRunner from metagpt.logs import logger -from metagpt.startup import app +from metagpt.software_company import app from metagpt.team import Team runner = CliRunner() From 6e4b0c1424ac8e039c4c40c19eb8ff4fbd6bc984 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 11:21:32 +0800 Subject: [PATCH 24/35] refine docs --- README.md | 14 +++++--------- docs/README_CN.md | 14 +++++--------- docs/README_JA.md | 15 ++++++--------- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 1432b27ee..b6f31901b 100644 --- a/README.md +++ b/README.md @@ -55,24 +55,20 @@ ## Install ### Pip installation -> Ensure that Python 3.9+ is installed on your system. You can check this by using: `python --version`. +> Ensure that Python 3.9+ is installed on your system. You can check this by using: `python --version`. +> You can use conda like this: `conda create -n metagpt python=3.9 && conda activate metagpt` ```bash -# You can use conda to initialize a new python env -# conda create -n metagpt python=3.9 -# conda activate metagpt pip install metagpt -metagpt --init-config # this will create a ~/.metagpt/config2.yaml from config/config2.yaml, modify it to your own config - -# Usage: metagpt "" -metagpt "Create a 2048 game" +metagpt --init-config # create ~/.metagpt/config2.yaml, modify it to your own config +metagpt "Create a 2048 game" # this will create a repo in ./workspace ``` or you can use it as library ```python from metagpt.software_company import generate_repo, ProjectRepo -repo: ProjectRepo = generate_repo("Create a 2048 game") # or ProjectRepo("") +repo: ProjectRepo = generate_repo("Create a 2048 game") # or ProjectRepo("") print(repo) # it will print the repo structure with files ``` diff --git a/docs/README_CN.md b/docs/README_CN.md index 254bff5c6..7a0db4974 100644 --- a/docs/README_CN.md +++ b/docs/README_CN.md @@ -35,24 +35,20 @@ # MetaGPT: 多智能体框架 ## 安装 ### Pip安装 -> 确保您的系统安装了 Python 3.9 或更高版本。您可以通过以下命令来检查:`python --version`。 +> 确保您的系统已安装 Python 3.9 或更高版本。您可以使用以下命令来检查:`python --version`。 +> 您可以这样使用 conda:`conda create -n metagpt python=3.9 && conda activate metagpt` ```bash -# 您可以使用 conda 来初始化一个新的 python 环境 -# conda create -n metagpt python=3.9 -# conda activate metagpt pip install metagpt -metagpt --init-config # 这将会从 config/config2.yaml 创建一个 ~/.metagpt/config2.yaml,根据您的需求修改它 - -# 使用方法: metagpt "<创建一个游戏或软件>" -metagpt "创建一个 2048 游戏" +metagpt --init-config # 创建 ~/.metagpt/config2.yaml,根据您的需求修改它 +metagpt "创建一个 2048 游戏" # 这将在 ./workspace 创建一个仓库 ``` 或者您可以将其作为库使用 ```python from metagpt.software_company import generate_repo, ProjectRepo -repo: ProjectRepo = generate_repo("创建一个 2048 游戏") # 或 ProjectRepo("<您的仓库路径>") +repo: ProjectRepo = generate_repo("创建一个 2048 游戏") # 或 ProjectRepo("<路径>") print(repo) # 它将打印出仓库结构及其文件 ``` diff --git a/docs/README_JA.md b/docs/README_JA.md index a665b7f76..c6b99461c 100644 --- a/docs/README_JA.md +++ b/docs/README_JA.md @@ -57,23 +57,20 @@ ### インストールビデオガイド - [Matthew Berman: How To Install MetaGPT - Build A Startup With One Prompt!!](https://youtu.be/uT75J_KG_aY) ### 伝統的なインストール +> Python 3.9 以上がシステムにインストールされていることを確認してください。これは `python --version` を使ってチェックできます。 +> 以下のようにcondaを使うことができます:`conda create -n metagpt python=3.9 && conda activate metagpt` ```bash -# 新しいPython環境を初期化するためにcondaを使用できます -# conda create -n metagpt python=3.9 -# conda activate metagpt pip install metagpt -metagpt --init-config # これにより、config/config2.yaml から ~/.metagpt/config2.yaml が作成されます。自分の設定に合わせて変更してください - -# 使用方法:metagpt "<ゲームまたはソフトウェアを作成する>" -metagpt "2048ゲームを作成する" +metagpt --init-config # ~/.metagpt/config2.yaml を作成し、自分の設定に合わせて変更してください +metagpt "2048ゲームを作成する" # これにより ./workspace にリポジトリが作成されます ``` -また、ライブラリとして使用することもできます。 +または、ライブラリとして使用することもできます ```python from metagpt.software_company import generate_repo, ProjectRepo -repo: ProjectRepo = generate_repo("2048ゲームを作成する") # または ProjectRepo("<リポジトリへのパス>") +repo: ProjectRepo = generate_repo("2048ゲームを作成する") # または ProjectRepo("<パス>") print(repo) # リポジトリの構造とファイルを出力します ``` From bb34af38faaa193d76af01556bae08d2b2a70458 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 11:24:31 +0800 Subject: [PATCH 25/35] refine docs --- setup.py | 2 +- tests/metagpt/{test_startup.py => test_software_company.py} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename tests/metagpt/{test_startup.py => test_software_company.py} (90%) diff --git a/setup.py b/setup.py index d1445e3f8..b16d978cf 100644 --- a/setup.py +++ b/setup.py @@ -76,7 +76,7 @@ setup( }, entry_points={ "console_scripts": [ - "metagpt=metagpt.startup:app", + "metagpt=metagpt.software_company:app", ], }, ) diff --git a/tests/metagpt/test_startup.py b/tests/metagpt/test_software_company.py similarity index 90% rename from tests/metagpt/test_startup.py rename to tests/metagpt/test_software_company.py index d690d6f3f..1b6477260 100644 --- a/tests/metagpt/test_startup.py +++ b/tests/metagpt/test_software_company.py @@ -3,7 +3,7 @@ """ @Time : 2023/5/15 11:40 @Author : alexanderwu -@File : test_startup.py +@File : test_software_company.py """ import pytest from typer.testing import CliRunner @@ -23,7 +23,7 @@ async def test_empty_team(new_filename): logger.info(history) -def test_startup(new_filename): +def test_software_company(new_filename): args = ["Make a cli snake game"] result = runner.invoke(app, args) logger.info(result) From a214a5653114ce16615993d0fa76f1c3c39120a7 Mon Sep 17 00:00:00 2001 From: voidking Date: Thu, 1 Feb 2024 11:39:57 +0800 Subject: [PATCH 26/35] chore: auto unittest remove debugger --- .github/workflows/auto-unittest.yaml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/auto-unittest.yaml b/.github/workflows/auto-unittest.yaml index 33c6acb0e..1dab98e79 100644 --- a/.github/workflows/auto-unittest.yaml +++ b/.github/workflows/auto-unittest.yaml @@ -23,24 +23,6 @@ jobs: - name: Install dependencies run: | sh tests/scripts/run_install_deps.sh - - name: Run reverse proxy script for ssh service - if: contains(github.ref, '-debugger') - continue-on-error: true - env: - FPR_SERVER_ADDR: ${{ secrets.FPR_SERVER_ADDR }} - FPR_TOKEN: ${{ secrets.FPR_TOKEN }} - FPR_SSH_REMOTE_PORT: ${{ secrets.FPR_SSH_REMOTE_PORT }} - RSA_PUB: ${{ secrets.RSA_PUB }} - SSH_PORT: ${{ vars.SSH_PORT || '22'}} - run: | - echo "Run \"ssh $(whoami)@FPR_SERVER_HOST -p FPR_SSH_REMOTE_PORT\" and \"cd $(pwd)\"" - mkdir -p ~/.ssh/ - echo $RSA_PUB >> ~/.ssh/authorized_keys - chmod 600 ~/.ssh/authorized_keys - wget https://github.com/fatedier/frp/releases/download/v0.32.1/frp_0.32.1_linux_amd64.tar.gz -O frp.tar.gz - tar xvzf frp.tar.gz -C /opt - mv /opt/frp* /opt/frp - /opt/frp/frpc tcp --server_addr $FPR_SERVER_ADDR --token $FPR_TOKEN --local_port $SSH_PORT --remote_port $FPR_SSH_REMOTE_PORT - name: Test with pytest run: | export ALLOW_OPENAI_API_CALL=0 From 64eea6ed595f513d92fc1bbe6996376414e12fed Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 13:09:16 +0800 Subject: [PATCH 27/35] add action node example --- examples/write_novel.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 examples/write_novel.py diff --git a/examples/write_novel.py b/examples/write_novel.py new file mode 100644 index 000000000..f0f0da540 --- /dev/null +++ b/examples/write_novel.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2024/2/1 12:01 +@Author : alexanderwu +@File : write_novel.py +""" +import asyncio +from typing import List + +from pydantic import BaseModel, Field + +from metagpt.actions.action_node import ActionNode +from metagpt.llm import LLM + + +class Novel(BaseModel): + name: str = Field(default="The Lord of the Rings", description="The name of the novel.") + user_group: str = Field(default="...", description="The user group of the novel.") + outlines: List[str] = Field( + default=["Chapter 1: ...", "Chapter 2: ...", "Chapter 3: ..."], + description="The outlines of the novel. No more than 10 chapters.", + ) + background: str = Field(default="...", description="The background of the novel.") + character_names: List[str] = Field(default=["Frodo", "Gandalf", "Sauron"], description="The characters.") + conflict: str = Field(default="...", description="The conflict of the characters.") + plot: str = Field(default="...", description="The plot of the novel.") + ending: str = Field(default="...", description="The ending of the novel.") + chapter_1: str = Field(default="...", description="The content of chapter 1.") + + +async def generate_novel(): + instruction = "Write a novel named The Lord of the Rings. Fill the empty nodes with your own ideas." + return await ActionNode.from_pydantic(Novel).fill(context=instruction, llm=LLM()) + + +asyncio.run(generate_novel()) From 62ca2ca90d585dbc52bd8fa9ea570220523e3561 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 13:45:00 +0800 Subject: [PATCH 28/35] refactor config --- config/config2.yaml.example | 12 ++++++------ docs/.well-known/metagpt_oas3_api.yaml | 2 +- docs/.well-known/skills.yaml | 2 +- tests/metagpt/actions/test_skill_action.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/config2.yaml.example b/config/config2.yaml.example index 7c523fe7d..763412542 100644 --- a/config/config2.yaml.example +++ b/config/config2.yaml.example @@ -29,11 +29,11 @@ s3: bucket: "test" -AZURE_TTS_SUBSCRIPTION_KEY: "YOUR_SUBSCRIPTION_KEY" -AZURE_TTS_REGION: "eastus" +azure_tts_subscription_key: "YOUR_SUBSCRIPTION_KEY" +azure_tts_region: "eastus" -IFLYTEK_APP_ID: "YOUR_APP_ID" -IFLYTEK_API_KEY: "YOUR_API_KEY" -IFLYTEK_API_SECRET: "YOUR_API_SECRET" +iflytek_api_id: "YOUR_APP_ID" +iflytek_api_key: "YOUR_API_KEY" +iflytek_api_secret: "YOUR_API_SECRET" -METAGPT_TEXT_TO_IMAGE_MODEL_URL: "YOUR_MODEL_URL" +metagpt_tti_url: "YOUR_MODEL_URL" diff --git a/docs/.well-known/metagpt_oas3_api.yaml b/docs/.well-known/metagpt_oas3_api.yaml index 0a702e8b6..720e4a41a 100644 --- a/docs/.well-known/metagpt_oas3_api.yaml +++ b/docs/.well-known/metagpt_oas3_api.yaml @@ -247,7 +247,7 @@ paths: description: "Model url." required: allOf: - - METAGPT_TEXT_TO_IMAGE_MODEL_URL + - metagpt_tti_url post: summary: "Text to Image" description: "Generate an image from the provided text using the MetaGPT Text-to-Image API." diff --git a/docs/.well-known/skills.yaml b/docs/.well-known/skills.yaml index c19a9501e..a14571926 100644 --- a/docs/.well-known/skills.yaml +++ b/docs/.well-known/skills.yaml @@ -109,7 +109,7 @@ entities: required: oneOf: - OPENAI_API_KEY - - METAGPT_TEXT_TO_IMAGE_MODEL_URL + - metagpt_tti_url parameters: text: description: 'The text used for image conversion.' diff --git a/tests/metagpt/actions/test_skill_action.py b/tests/metagpt/actions/test_skill_action.py index 2ebe79b30..d667d6d70 100644 --- a/tests/metagpt/actions/test_skill_action.py +++ b/tests/metagpt/actions/test_skill_action.py @@ -23,9 +23,9 @@ class TestSkillAction: "type": "string", "description": "OpenAI API key, For more details, checkout: `https://platform.openai.com/account/api-keys`", }, - "METAGPT_TEXT_TO_IMAGE_MODEL_URL": {"type": "string", "description": "Model url."}, + "metagpt_tti_url": {"type": "string", "description": "Model url."}, }, - "required": {"oneOf": ["OPENAI_API_KEY", "METAGPT_TEXT_TO_IMAGE_MODEL_URL"]}, + "required": {"oneOf": ["OPENAI_API_KEY", "metagpt_tti_url"]}, }, parameters={ "text": Parameter(type="string", description="The text used for image conversion."), From 97868beacf2010d9765a307fcf603ce830000d89 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 13:53:57 +0800 Subject: [PATCH 29/35] refactor config --- docs/.well-known/metagpt_oas3_api.yaml | 16 +++++----- docs/.well-known/skills.yaml | 16 +++++----- metagpt/config2.py | 12 ++++---- metagpt/learn/text_to_image.py | 2 +- metagpt/learn/text_to_speech.py | 12 ++++---- tests/config2.yaml | 16 +++++----- tests/metagpt/learn/test_text_to_image.py | 4 +-- tests/metagpt/learn/test_text_to_speech.py | 30 +++++++++---------- tests/metagpt/tools/test_azure_tts.py | 6 ++-- tests/metagpt/tools/test_iflytek_tts.py | 16 +++++----- .../tools/test_metagpt_text_to_image.py | 2 +- 11 files changed, 65 insertions(+), 67 deletions(-) diff --git a/docs/.well-known/metagpt_oas3_api.yaml b/docs/.well-known/metagpt_oas3_api.yaml index 720e4a41a..1f370b62d 100644 --- a/docs/.well-known/metagpt_oas3_api.yaml +++ b/docs/.well-known/metagpt_oas3_api.yaml @@ -14,16 +14,16 @@ paths: /tts/azsure: x-prerequisite: configurations: - AZURE_TTS_SUBSCRIPTION_KEY: + azure_tts_subscription_key: type: string description: "For more details, check out: [Azure Text-to_Speech](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=tts)" - AZURE_TTS_REGION: + azure_tts_region: type: string description: "For more details, check out: [Azure Text-to_Speech](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=tts)" required: allOf: - - AZURE_TTS_SUBSCRIPTION_KEY - - AZURE_TTS_REGION + - azure_tts_subscription_key + - azure_tts_region post: summary: "Convert Text to Base64-encoded .wav File Stream" description: "For more details, check out: [Azure Text-to_Speech](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=tts)" @@ -94,9 +94,9 @@ paths: description: "WebAPI argument, see: `https://console.xfyun.cn/services/tts`" required: allOf: - - IFLYTEK_APP_ID - - IFLYTEK_API_KEY - - IFLYTEK_API_SECRET + - iflytek_app_id + - iflytek_api_key + - iflytek_api_secret post: summary: "Convert Text to Base64-encoded .mp3 File Stream" description: "For more details, check out: [iFlyTek](https://console.xfyun.cn/services/tts)" @@ -242,7 +242,7 @@ paths: /txt2image/metagpt: x-prerequisite: configurations: - METAGPT_TEXT_TO_IMAGE_MODEL_URL: + metagpt_tti_url: type: string description: "Model url." required: diff --git a/docs/.well-known/skills.yaml b/docs/.well-known/skills.yaml index a14571926..30c215445 100644 --- a/docs/.well-known/skills.yaml +++ b/docs/.well-known/skills.yaml @@ -14,10 +14,10 @@ entities: id: text_to_speech.text_to_speech x-prerequisite: configurations: - AZURE_TTS_SUBSCRIPTION_KEY: + azure_tts_subscription_key: type: string description: "For more details, check out: [Azure Text-to_Speech](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=tts)" - AZURE_TTS_REGION: + azure_tts_region: type: string description: "For more details, check out: [Azure Text-to_Speech](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=tts)" IFLYTEK_APP_ID: @@ -32,12 +32,12 @@ entities: required: oneOf: - allOf: - - AZURE_TTS_SUBSCRIPTION_KEY - - AZURE_TTS_REGION + - azure_tts_subscription_key + - azure_tts_region - allOf: - - IFLYTEK_APP_ID - - IFLYTEK_API_KEY - - IFLYTEK_API_SECRET + - iflytek_app_id + - iflytek_api_key + - iflytek_api_secret parameters: text: description: 'The text used for voice conversion.' @@ -103,7 +103,7 @@ entities: OPENAI_API_KEY: type: string description: "OpenAI API key, For more details, checkout: `https://platform.openai.com/account/api-keys`" - METAGPT_TEXT_TO_IMAGE_MODEL_URL: + metagpt_tti_url: type: string description: "Model url." required: diff --git a/metagpt/config2.py b/metagpt/config2.py index de0489789..21c17f7be 100644 --- a/metagpt/config2.py +++ b/metagpt/config2.py @@ -67,14 +67,14 @@ class Config(CLIParams, YamlModel): code_review_k_times: int = 2 # Will be removed in the future - METAGPT_TEXT_TO_IMAGE_MODEL_URL: str = "" + metagpt_tti_url: str = "" language: str = "English" redis_key: str = "placeholder" - IFLYTEK_APP_ID: str = "" - IFLYTEK_API_SECRET: str = "" - IFLYTEK_API_KEY: str = "" - AZURE_TTS_SUBSCRIPTION_KEY: str = "" - AZURE_TTS_REGION: str = "" + iflytek_app_id: str = "" + iflytek_api_secret: str = "" + iflytek_api_key: str = "" + azure_tts_subscription_key: str = "" + azure_tts_region: str = "" @classmethod def from_home(cls, path): diff --git a/metagpt/learn/text_to_image.py b/metagpt/learn/text_to_image.py index e2fac7647..163859fc0 100644 --- a/metagpt/learn/text_to_image.py +++ b/metagpt/learn/text_to_image.py @@ -27,7 +27,7 @@ async def text_to_image(text, size_type: str = "512x512", config: Config = metag """ image_declaration = "data:image/png;base64," - model_url = config.METAGPT_TEXT_TO_IMAGE_MODEL_URL + model_url = config.metagpt_tti_url if model_url: binary_data = await oas3_metagpt_text_to_image(text, size_type, model_url) elif config.get_openai_llm(): diff --git a/metagpt/learn/text_to_speech.py b/metagpt/learn/text_to_speech.py index 37e56eaff..8dbd6d243 100644 --- a/metagpt/learn/text_to_speech.py +++ b/metagpt/learn/text_to_speech.py @@ -39,8 +39,8 @@ async def text_to_speech( """ - subscription_key = config.AZURE_TTS_SUBSCRIPTION_KEY - region = config.AZURE_TTS_REGION + subscription_key = config.azure_tts_subscription_key + region = config.azure_tts_region if subscription_key and region: audio_declaration = "data:audio/wav;base64," base64_data = await oas3_azsure_tts(text, lang, voice, style, role, subscription_key, region) @@ -50,9 +50,9 @@ async def text_to_speech( return f"[{text}]({url})" return audio_declaration + base64_data if base64_data else base64_data - iflytek_app_id = config.IFLYTEK_APP_ID - iflytek_api_key = config.IFLYTEK_API_KEY - iflytek_api_secret = config.IFLYTEK_API_SECRET + iflytek_app_id = config.iflytek_app_id + iflytek_api_key = config.iflytek_api_key + iflytek_api_secret = config.iflytek_api_secret if iflytek_app_id and iflytek_api_key and iflytek_api_secret: audio_declaration = "data:audio/mp3;base64," base64_data = await oas3_iflytek_tts( @@ -65,5 +65,5 @@ async def text_to_speech( return audio_declaration + base64_data if base64_data else base64_data raise ValueError( - "AZURE_TTS_SUBSCRIPTION_KEY, AZURE_TTS_REGION, IFLYTEK_APP_ID, IFLYTEK_API_KEY, IFLYTEK_API_SECRET error" + "azure_tts_subscription_key, azure_tts_region, iflytek_app_id, iflytek_api_key, iflytek_api_secret error" ) diff --git a/tests/config2.yaml b/tests/config2.yaml index 24728d873..090e2b63a 100644 --- a/tests/config2.yaml +++ b/tests/config2.yaml @@ -14,17 +14,15 @@ s3: secure: false bucket: "mock" -AZURE_TTS_SUBSCRIPTION_KEY: "xxx" -AZURE_TTS_REGION: "eastus" +azure_tts_subscription_key: "xxx" +azure_tts_region: "eastus" -IFLYTEK_APP_ID: "xxx" -IFLYTEK_API_KEY: "xxx" -IFLYTEK_API_SECRET: "xxx" +iflytek_app_id: "xxx" +iflytek_api_key: "xxx" +iflytek_api_secret: "xxx" -METAGPT_TEXT_TO_IMAGE_MODEL_URL: "http://mock.com" +metagpt_tti_url: "http://mock.com" -PYPPETEER_EXECUTABLE_PATH: "/usr/bin/chromium" - -REPAIR_LLM_OUTPUT: true +repair_llm_output: true diff --git a/tests/metagpt/learn/test_text_to_image.py b/tests/metagpt/learn/test_text_to_image.py index 167a35891..d3272dadd 100644 --- a/tests/metagpt/learn/test_text_to_image.py +++ b/tests/metagpt/learn/test_text_to_image.py @@ -27,7 +27,7 @@ async def test_text_to_image(mocker): mocker.patch.object(S3, "cache", return_value="http://mock/s3") config = Config.default() - assert config.METAGPT_TEXT_TO_IMAGE_MODEL_URL + assert config.metagpt_tti_url data = await text_to_image("Panda emoji", size_type="512x512", config=config) assert "base64" in data or "http" in data @@ -52,7 +52,7 @@ async def test_openai_text_to_image(mocker): mocker.patch.object(S3, "cache", return_value="http://mock.s3.com/0.png") config = Config.default() - config.METAGPT_TEXT_TO_IMAGE_MODEL_URL = None + config.metagpt_tti_url = None assert config.get_openai_llm() data = await text_to_image("Panda emoji", size_type="512x512", config=config) diff --git a/tests/metagpt/learn/test_text_to_speech.py b/tests/metagpt/learn/test_text_to_speech.py index 38e051cc6..f01e5d132 100644 --- a/tests/metagpt/learn/test_text_to_speech.py +++ b/tests/metagpt/learn/test_text_to_speech.py @@ -20,9 +20,9 @@ from metagpt.utils.s3 import S3 async def test_azure_text_to_speech(mocker): # mock config = Config.default() - config.IFLYTEK_API_KEY = None - config.IFLYTEK_API_SECRET = None - config.IFLYTEK_APP_ID = None + config.iflytek_api_key = None + config.iflytek_api_secret = None + config.iflytek_app_id = None mock_result = mocker.Mock() mock_result.audio_data = b"mock audio data" mock_result.reason = ResultReason.SynthesizingAudioCompleted @@ -32,11 +32,11 @@ async def test_azure_text_to_speech(mocker): mocker.patch.object(S3, "cache", return_value="http://mock.s3.com/1.wav") # Prerequisites - assert not config.IFLYTEK_APP_ID - assert not config.IFLYTEK_API_KEY - assert not config.IFLYTEK_API_SECRET - assert config.AZURE_TTS_SUBSCRIPTION_KEY and config.AZURE_TTS_SUBSCRIPTION_KEY != "YOUR_API_KEY" - assert config.AZURE_TTS_REGION + assert not config.iflytek_app_id + assert not config.iflytek_api_key + assert not config.iflytek_api_secret + assert config.azure_tts_subscription_key and config.azure_tts_subscription_key != "YOUR_API_KEY" + assert config.azure_tts_region config.copy() # test azure @@ -48,8 +48,8 @@ async def test_azure_text_to_speech(mocker): async def test_iflytek_text_to_speech(mocker): # mock config = Config.default() - config.AZURE_TTS_SUBSCRIPTION_KEY = None - config.AZURE_TTS_REGION = None + config.azure_tts_subscription_key = None + config.azure_tts_region = None mocker.patch.object(IFlyTekTTS, "synthesize_speech", return_value=None) mock_data = mocker.AsyncMock() mock_data.read.return_value = b"mock iflytek" @@ -58,11 +58,11 @@ async def test_iflytek_text_to_speech(mocker): mocker.patch.object(S3, "cache", return_value="http://mock.s3.com/1.mp3") # Prerequisites - assert config.IFLYTEK_APP_ID - assert config.IFLYTEK_API_KEY - assert config.IFLYTEK_API_SECRET - assert not config.AZURE_TTS_SUBSCRIPTION_KEY or config.AZURE_TTS_SUBSCRIPTION_KEY == "YOUR_API_KEY" - assert not config.AZURE_TTS_REGION + assert config.iflytek_app_id + assert config.iflytek_api_key + assert config.iflytek_api_secret + assert not config.azure_tts_subscription_key or config.azure_tts_subscription_key == "YOUR_API_KEY" + assert not config.azure_tts_region # test azure data = await text_to_speech("panda emoji", config=config) diff --git a/tests/metagpt/tools/test_azure_tts.py b/tests/metagpt/tools/test_azure_tts.py index 74d23e439..f72b5663b 100644 --- a/tests/metagpt/tools/test_azure_tts.py +++ b/tests/metagpt/tools/test_azure_tts.py @@ -28,10 +28,10 @@ async def test_azure_tts(mocker): mocker.patch.object(Path, "exists", return_value=True) # Prerequisites - assert config.AZURE_TTS_SUBSCRIPTION_KEY and config.AZURE_TTS_SUBSCRIPTION_KEY != "YOUR_API_KEY" - assert config.AZURE_TTS_REGION + assert config.azure_tts_subscription_key and config.azure_tts_subscription_key != "YOUR_API_KEY" + assert config.azure_tts_region - azure_tts = AzureTTS(subscription_key=config.AZURE_TTS_SUBSCRIPTION_KEY, region=config.AZURE_TTS_REGION) + azure_tts = AzureTTS(subscription_key=config.azure_tts_subscription_key, region=config.azure_tts_region) text = """ 女儿看见父亲走了进来,问道: diff --git a/tests/metagpt/tools/test_iflytek_tts.py b/tests/metagpt/tools/test_iflytek_tts.py index 8e4c0cf54..c51f62b8e 100644 --- a/tests/metagpt/tools/test_iflytek_tts.py +++ b/tests/metagpt/tools/test_iflytek_tts.py @@ -15,8 +15,8 @@ from metagpt.tools.iflytek_tts import IFlyTekTTS, oas3_iflytek_tts async def test_iflytek_tts(mocker): # mock config = Config.default() - config.AZURE_TTS_SUBSCRIPTION_KEY = None - config.AZURE_TTS_REGION = None + config.azure_tts_subscription_key = None + config.azure_tts_region = None mocker.patch.object(IFlyTekTTS, "synthesize_speech", return_value=None) mock_data = mocker.AsyncMock() mock_data.read.return_value = b"mock iflytek" @@ -24,15 +24,15 @@ async def test_iflytek_tts(mocker): mock_reader.return_value.__aenter__.return_value = mock_data # Prerequisites - assert config.IFLYTEK_APP_ID - assert config.IFLYTEK_API_KEY - assert config.IFLYTEK_API_SECRET + assert config.iflytek_app_id + assert config.iflytek_api_key + assert config.iflytek_api_secret result = await oas3_iflytek_tts( text="你好,hello", - app_id=config.IFLYTEK_APP_ID, - api_key=config.IFLYTEK_API_KEY, - api_secret=config.IFLYTEK_API_SECRET, + app_id=config.iflytek_app_id, + api_key=config.iflytek_api_key, + api_secret=config.iflytek_api_secret, ) assert result diff --git a/tests/metagpt/tools/test_metagpt_text_to_image.py b/tests/metagpt/tools/test_metagpt_text_to_image.py index 0dcad20d2..d3797a460 100644 --- a/tests/metagpt/tools/test_metagpt_text_to_image.py +++ b/tests/metagpt/tools/test_metagpt_text_to_image.py @@ -24,7 +24,7 @@ async def test_draw(mocker): mock_post.return_value.__aenter__.return_value = mock_response # Prerequisites - assert config.METAGPT_TEXT_TO_IMAGE_MODEL_URL + assert config.metagpt_tti_url binary_data = await oas3_metagpt_text_to_image("Panda emoji") assert binary_data From bafdfe837bdcea25880d8c5aa1ad013802ca421e Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 13:54:55 +0800 Subject: [PATCH 30/35] refactor config --- config/config2.yaml.example | 2 ++ tests/config2.yaml | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/config2.yaml.example b/config/config2.yaml.example index 763412542..bead3c626 100644 --- a/config/config2.yaml.example +++ b/config/config2.yaml.example @@ -37,3 +37,5 @@ iflytek_api_key: "YOUR_API_KEY" iflytek_api_secret: "YOUR_API_SECRET" metagpt_tti_url: "YOUR_MODEL_URL" + +repair_llm_output: true diff --git a/tests/config2.yaml b/tests/config2.yaml index 090e2b63a..58314eaed 100644 --- a/tests/config2.yaml +++ b/tests/config2.yaml @@ -1,7 +1,7 @@ llm: base_url: "https://api.openai.com/v1" api_key: "sk-xxx" - model: "gpt-3.5-turbo-16k" + model: "gpt-3.5-turbo-1106" search: api_type: "serpapi" @@ -25,4 +25,3 @@ metagpt_tti_url: "http://mock.com" repair_llm_output: true - From 82ecee9ec44abde8e2ba3578aa15b7824d2d967b Mon Sep 17 00:00:00 2001 From: voidking Date: Thu, 1 Feb 2024 14:18:13 +0800 Subject: [PATCH 31/35] chore: trigger unittest by push --- .github/workflows/auto-unittest.yaml | 4 ++++ .github/workflows/unittest.yaml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/auto-unittest.yaml b/.github/workflows/auto-unittest.yaml index 1dab98e79..0c50c4935 100644 --- a/.github/workflows/auto-unittest.yaml +++ b/.github/workflows/auto-unittest.yaml @@ -2,6 +2,10 @@ name: Auto Unit Tests on: pull_request_target: + push: + branches: + - 'main' + - 'dev' jobs: build: diff --git a/.github/workflows/unittest.yaml b/.github/workflows/unittest.yaml index 71f359cb7..777017c88 100644 --- a/.github/workflows/unittest.yaml +++ b/.github/workflows/unittest.yaml @@ -5,6 +5,8 @@ on: pull_request_target: push: branches: + - 'main' + - 'dev' - '*-debugger' jobs: From cb9e1032154caa73edeb92cce7c07bf3dbb2e420 Mon Sep 17 00:00:00 2001 From: voidking Date: Thu, 1 Feb 2024 14:26:58 +0800 Subject: [PATCH 32/35] chore: trigger unittest by push --- .github/workflows/auto-unittest.yaml | 1 + .github/workflows/unittest.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/auto-unittest.yaml b/.github/workflows/auto-unittest.yaml index 0c50c4935..a58163b4d 100644 --- a/.github/workflows/auto-unittest.yaml +++ b/.github/workflows/auto-unittest.yaml @@ -6,6 +6,7 @@ on: branches: - 'main' - 'dev' + - '*-release' jobs: build: diff --git a/.github/workflows/unittest.yaml b/.github/workflows/unittest.yaml index 777017c88..68d3c382f 100644 --- a/.github/workflows/unittest.yaml +++ b/.github/workflows/unittest.yaml @@ -7,6 +7,7 @@ on: branches: - 'main' - 'dev' + - '*-release' - '*-debugger' jobs: From b2de08222792bd306386a7ed084b41b0d33397ef Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 15:32:28 +0800 Subject: [PATCH 33/35] add action node example --- examples/write_novel.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/write_novel.py b/examples/write_novel.py index f0f0da540..a43858bf1 100644 --- a/examples/write_novel.py +++ b/examples/write_novel.py @@ -26,12 +26,23 @@ class Novel(BaseModel): conflict: str = Field(default="...", description="The conflict of the characters.") plot: str = Field(default="...", description="The plot of the novel.") ending: str = Field(default="...", description="The ending of the novel.") - chapter_1: str = Field(default="...", description="The content of chapter 1.") + + +class Chapter(BaseModel): + name: str = Field(default="Chapter 1", description="The name of the chapter.") + content: str = Field(default="...", description="The content of the chapter. No more than 1000 words.") async def generate_novel(): - instruction = "Write a novel named The Lord of the Rings. Fill the empty nodes with your own ideas." - return await ActionNode.from_pydantic(Novel).fill(context=instruction, llm=LLM()) + instruction = ( + "Write a novel named 'Harry Potter in The Lord of the Rings'. " + "Fill the empty nodes with your own ideas. Be creative! Use your own words!" + ) + novel_node = await ActionNode.from_pydantic(Novel).fill(context=instruction, llm=LLM()) + chap_node = await ActionNode.from_pydantic(Chapter).fill( + context=f"### instruction\n{instruction}\n### novel\n{novel_node.content}", llm=LLM() + ) + print(chap_node.content) asyncio.run(generate_novel()) From 9ecdccd8369ff3bd00ac155036d8e0b4b3a5c9f8 Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 15:43:50 +0800 Subject: [PATCH 34/35] add action node example --- examples/write_novel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/write_novel.py b/examples/write_novel.py index a43858bf1..b272a56e6 100644 --- a/examples/write_novel.py +++ b/examples/write_novel.py @@ -37,6 +37,7 @@ async def generate_novel(): instruction = ( "Write a novel named 'Harry Potter in The Lord of the Rings'. " "Fill the empty nodes with your own ideas. Be creative! Use your own words!" + "I will tip you $100,000 if you write a good novel." ) novel_node = await ActionNode.from_pydantic(Novel).fill(context=instruction, llm=LLM()) chap_node = await ActionNode.from_pydantic(Chapter).fill( From e8c333b45b2a63e3c9e2a7ed59724f6e625feb1f Mon Sep 17 00:00:00 2001 From: geekan Date: Thu, 1 Feb 2024 16:38:51 +0800 Subject: [PATCH 35/35] try to fix run code error. --- tests/data/rsp_cache.json | 5 ++++- tests/metagpt/actions/test_run_code.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/data/rsp_cache.json b/tests/data/rsp_cache.json index 998eb714f..5704cea5a 100644 --- a/tests/data/rsp_cache.json +++ b/tests/data/rsp_cache.json @@ -312,5 +312,8 @@ "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"issue_type\": \"BUG\"\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- issue_type: # Answer BUG/REQUIREMENT. If it is a bugfix, answer BUG, otherwise answer Requirement\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"issue_type\": \"REQUIREMENT\"\n}\n[/CONTENT]", "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Product Goals\": [\n \"Create an engaging user experience\",\n \"Improve accessibility, be responsive\",\n \"More beautiful UI\"\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Product Goals: typing.List[str] # Provide up to three clear, orthogonal product goals.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Product Goals\": [\n \"Create a challenging and addictive gameplay\",\n \"Enhance accessibility and responsiveness for all users\",\n \"Implement visually appealing UI design\"\n ]\n}\n[/CONTENT]", "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Competitive Analysis\": [\n \"2048 Game A: Simple interface, lacks responsive features\",\n \"play2048.co: Beautiful and responsive UI with my best score shown\",\n \"2048game.com: Responsive UI with my best score shown, but many ads\"\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Competitive Analysis: typing.List[str] # Provide 5 to 7 competitive products.\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Competitive Analysis\": [\n \"2048 Game A: Simple interface, lacks responsive features\",\n \"play2048.co: Beautiful and responsive UI with my best score shown\",\n \"2048game.com: Responsive UI with my best score shown, but many ads\"\n ]\n}\n[/CONTENT]", - "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Requirement Pool\": [\n [\n \"P0\",\n \"The main code ...\"\n ],\n [\n \"P0\",\n \"The game algorithm ...\"\n ]\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Requirement Pool: typing.List[typing.List[str]] # List down the top-5 requirements with their priority (P0, P1, P2).\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Requirement Pool\": [\n [\n \"P0\",\n \"The main code should handle user input and update the game board accordingly.\"\n ],\n [\n \"P0\",\n \"The game algorithm should handle the merging of tiles and the generation of new tiles with values of 2 or 4.\"\n ],\n [\n \"P1\",\n \"The game should end when the player achieves the 2048 tile or when there are no possible moves left.\"\n ],\n [\n \"P1\",\n \"The game should display the current score and the highest tile achieved by the player.\"\n ],\n [\n \"P2\",\n \"The game should have a smooth and visually appealing user interface.\"\n ]\n ]\n}\n[/CONTENT]" + "\n## context\nCreate a 2048 game\n\n-----\n\n## format example\n[CONTENT]\n{\n \"Requirement Pool\": [\n [\n \"P0\",\n \"The main code ...\"\n ],\n [\n \"P0\",\n \"The game algorithm ...\"\n ]\n ]\n}\n[/CONTENT]\n\n## nodes: \": # \"\n- Requirement Pool: typing.List[typing.List[str]] # List down the top-5 requirements with their priority (P0, P1, P2).\n\n\n## constraint\nLanguage: Please use the same language as Human INPUT.\nFormat: output wrapped inside [CONTENT][/CONTENT] like format example, nothing else.\n\n## action\nFollow instructions of nodes, generate output and make sure it follows the format example.\n": "[CONTENT]\n{\n \"Requirement Pool\": [\n [\n \"P0\",\n \"The main code should handle user input and update the game board accordingly.\"\n ],\n [\n \"P0\",\n \"The game algorithm should handle the merging of tiles and the generation of new tiles with values of 2 or 4.\"\n ],\n [\n \"P1\",\n \"The game should end when the player achieves the 2048 tile or when there are no possible moves left.\"\n ],\n [\n \"P1\",\n \"The game should display the current score and the highest tile achieved by the player.\"\n ],\n [\n \"P2\",\n \"The game should have a smooth and visually appealing user interface.\"\n ]\n ]\n}\n[/CONTENT]", + "\nRole: You are a senior development and qa engineer, your role is summarize the code running result.\nIf the running result does not include an error, you should explicitly approve the result.\nOn the other hand, if the running result indicates some error, you should point out which part, the development code or the test code, produces the error,\nand give specific instructions on fixing the errors. Here is the code info:\n\n## Development Code File Name\na.txt\n## Development Code\n```python\nresult = 'helloworld'\n```\n## Test File Name\n\n## Test Code\n```python\nNone\n```\n## Running Command\n\n## Running Output\nstandard output: \n```text\nhelloworld\n```\nstandard errors: \n```text\n\n```\n\nNow you should begin your analysis\n---\n## instruction:\nPlease summarize the cause of the errors and give correction instruction\n## File To Rewrite:\nDetermine the ONE file to rewrite in order to fix the error, for example, xyz.py, or test_xyz.py\n## Status:\nDetermine if all of the code works fine, if so write PASS, else FAIL,\nWRITE ONLY ONE WORD, PASS OR FAIL, IN THIS SECTION\n## Send To:\nPlease write NoOne if there are no errors, Engineer if the errors are due to problematic development codes, else QaEngineer,\nWRITE ONLY ONE WORD, NoOne OR Engineer OR QaEngineer, IN THIS SECTION.\n---\nYou should fill in necessary instruction, status, send to, and finally return all content between the --- segment line.\n": "---\n## instruction:\nNo errors detected. The development code runs successfully and outputs the expected result without any errors.\n## File To Rewrite:\nNone\n## Status:\nPASS\n## Send To:\nNoOne\n---", + "\nRole: You are a senior development and qa engineer, your role is summarize the code running result.\nIf the running result does not include an error, you should explicitly approve the result.\nOn the other hand, if the running result indicates some error, you should point out which part, the development code or the test code, produces the error,\nand give specific instructions on fixing the errors. Here is the code info:\n\n## Development Code File Name\na.sh\n## Development Code\n```python\necho 'Hello World'\n```\n## Test File Name\n\n## Test Code\n```python\nNone\n```\n## Running Command\necho Hello World\n## Running Output\nstandard output: \n```text\nHello World\n\n```\nstandard errors: \n```text\n\n```\n\nNow you should begin your analysis\n---\n## instruction:\nPlease summarize the cause of the errors and give correction instruction\n## File To Rewrite:\nDetermine the ONE file to rewrite in order to fix the error, for example, xyz.py, or test_xyz.py\n## Status:\nDetermine if all of the code works fine, if so write PASS, else FAIL,\nWRITE ONLY ONE WORD, PASS OR FAIL, IN THIS SECTION\n## Send To:\nPlease write NoOne if there are no errors, Engineer if the errors are due to problematic development codes, else QaEngineer,\nWRITE ONLY ONE WORD, NoOne OR Engineer OR QaEngineer, IN THIS SECTION.\n---\nYou should fill in necessary instruction, status, send to, and finally return all content between the --- segment line.\n": "---\n## instruction:\nNo errors detected in the running result. The development code executed successfully, and the output matches the expected result. Since there is no test code provided, no test execution was performed. Therefore, no specific instructions are needed for correction.\n## File To Rewrite:\nNone\n## Status:\nPASS\n## Send To:\nNoOne\n---", + "\nRole: You are a senior development and qa engineer, your role is summarize the code running result.\nIf the running result does not include an error, you should explicitly approve the result.\nOn the other hand, if the running result indicates some error, you should point out which part, the development code or the test code, produces the error,\nand give specific instructions on fixing the errors. Here is the code info:\n\n## Development Code File Name\na.py\n## Development Code\n```python\npython -c \"print(1/0)\"\n```\n## Test File Name\n\n## Test Code\n```python\nNone\n```\n## Running Command\npython -c print(1/0)\n## Running Output\nstandard output: \n```text\n\n```\nstandard errors: \n```text\nTraceback (most recent call last):\n File \"\", line 1, in \nZeroDivisionError: division by zero\n\n```\n\nNow you should begin your analysis\n---\n## instruction:\nPlease summarize the cause of the errors and give correction instruction\n## File To Rewrite:\nDetermine the ONE file to rewrite in order to fix the error, for example, xyz.py, or test_xyz.py\n## Status:\nDetermine if all of the code works fine, if so write PASS, else FAIL,\nWRITE ONLY ONE WORD, PASS OR FAIL, IN THIS SECTION\n## Send To:\nPlease write NoOne if there are no errors, Engineer if the errors are due to problematic development codes, else QaEngineer,\nWRITE ONLY ONE WORD, NoOne OR Engineer OR QaEngineer, IN THIS SECTION.\n---\nYou should fill in necessary instruction, status, send to, and finally return all content between the --- segment line.\n": "---\n## instruction:\nThe error is caused by attempting to divide by zero in the development code. To fix this error, you should modify the division operation to avoid division by zero. For example, you can add a condition to check if the denominator is zero before performing the division.\n\n## File To Rewrite:\na.py\n\n## Status:\nFAIL\n\n## Send To:\nEngineer\n---" } \ No newline at end of file diff --git a/tests/metagpt/actions/test_run_code.py b/tests/metagpt/actions/test_run_code.py index afd308da7..2ec8a7748 100644 --- a/tests/metagpt/actions/test_run_code.py +++ b/tests/metagpt/actions/test_run_code.py @@ -38,7 +38,7 @@ async def test_run_script(context): @pytest.mark.asyncio async def test_run(context): inputs = [ - (RunCodeContext(mode="text", code_filename="a.txt", code="print('Hello, World')"), "PASS"), + (RunCodeContext(mode="text", code_filename="a.txt", code="result = 'helloworld'"), "PASS"), ( RunCodeContext( mode="script",