├── .gitignore ├── requirements.txt ├── .env.example ├── README.md └── app.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .env 3 | .conda 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | autogen 2 | openai 3 | colorama 4 | python-dotenv 5 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | YI_API_KEY=your_api_key_here 2 | YI_BASE_URL=https://api.lingyiwanwu.com/v1 3 | YI_MODEL=yi-large -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Academic Agents V2 (学术写作智能助手) 2 | 3 | Academic Agents V2 是一个基于微软autogen框架开发的学术论文写作辅助工具。它通过多个专业化的智能代理(Agents)来协助用户完成从选题到大纲的论文写作过程。 4 | 5 | ## 功能特点 6 | 7 | - 🎯 **研究领域确定**:根据用户的专业背景和学术兴趣,推荐合适的研究领域 8 | - 🔍 **研究对象分析**:提供3-5个具体的研究对象建议 9 | - 💡 **本质问题提炼**:帮助分析现象问题,揭示深层本质问题 10 | - 📝 **研究论题形成**:协助构建理论框架,形成完整研究论题 11 | - 📑 **论文框架生成**:自动生成论文题目和详细的三级目录结构 12 | 13 | ## 安装要求 14 | 15 | - Python 3.8+ 16 | - 依赖包: 17 | 18 | ```bash 19 | pip install -r requirements.txt 20 | ``` 21 | 22 | ## 配置说明 23 | 24 | 本项目支持两种配置方式: 25 | 26 | 1. 环境变量配置 27 | 2. .env 文件配置 28 | 29 | ### 配置项(只需要配置大模型参数,默认为零一万物,可使用兼容openai格式的任何大模型) 30 | 31 | ```bash 32 | YI_API_KEY=your_api_key_here 33 | YI_BASE_URL= 34 | YI_MODEL=yi-large 35 | ``` 36 | 37 | 请复制 `.env.example` 文件为 `.env` 并填入你的配置信息。 38 | 39 | ## 使用截图 40 | 41 | ![使用截图](https://s2.loli.net/2024/10/30/QnNz7erCK1Ed4LG.png) 42 | 43 | ## 使用方法 44 | 45 | 1. 克隆项目: 46 | 47 | ```bash 48 | git clone https://github.com/anarchysaiko/academicagentsV2.git 49 | ``` 50 | 51 | 2. 安装依赖: 52 | 53 | ```bash 54 | pip install -r requirements.txt 55 | ``` 56 | 57 | 3. 配置环境变量或 .env 文件 58 | 59 | 4. 运行程序: 60 | 61 | ```bash 62 | python app.py 63 | ``` 64 | 65 | 5. 按照提示输入你的专业领域和学术兴趣 66 | 67 | ## 输出说明 68 | 69 | 程序会生成一个 Markdown 格式的输出文件,包含: 70 | 71 | - 论文题目 72 | - 详细的三级目录结构 73 | - 完整的研究过程记录 74 | 75 | 输出文件命名格式:`research_process_YYYYMMDD_HHMMSS.md` 76 | 77 | ## 代理(Agents)说明 78 | 79 | 本项目包含以下专业化代理: 80 | 81 | - **ResearchField**: 研究领域专家 82 | - **ResearchObject**: 研究对象定义专家 83 | - **EssentialProblem**: 研究问题分析专家 84 | - **ResearchThesis**: 研究论题专家 85 | - **PaperTitleAndOutline**: 论文题目和大纲专家 86 | 87 | ## 鸣谢 88 | 89 | 特别感谢 [autogen](https://github.com/microsoft/autogen) 项目为本工具的开发提供了支持和灵感。 90 | 91 | ## 贡献指南 92 | 93 | 欢迎提交 Issue 和 Pull Request 来帮助改进项目。 94 | 95 | ## 许可证 96 | 97 | 本项目采用 [Apache License 2.0](LICENSE) 许可证。 98 | 99 | ## 联系方式 100 | 101 | 如有问题或建议,请通过 GitHub Issues 与我们联系。 102 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | import autogen 4 | from openai import AuthenticationError as openai_AuthenticationError 5 | from colorama import Fore, Back, Style, init 6 | import datetime 7 | 8 | # 初始化 colorama 9 | init(autoreset=True) 10 | 11 | # 加载 .env 文件 12 | load_dotenv() 13 | 14 | 15 | def get_config(): 16 | """获取API配置,优先使用环境变量,其次使用.env文件""" 17 | # 尝试从环境变量获取配置 18 | api_key = os.getenv("YI_API_KEY") 19 | base_url = os.getenv("YI_BASE_URL") 20 | model = os.getenv("YI_MODEL", "yi-large") # 设置默认值为 yi-large 21 | 22 | if not api_key or not base_url: 23 | print( 24 | Fore.RED 25 | + "警告: 未找到API配置。请确保设置了环境变量或.env文件。" 26 | + Style.RESET_ALL 27 | ) 28 | print("需要设置以下环境变量:") 29 | print("- YI_API_KEY: API密钥") 30 | print("- YI_BASE_URL: API基础URL") 31 | print("- YI_MODEL: 模型名称(可选,默认为yi-large)") 32 | exit(1) 33 | 34 | return [ 35 | { 36 | "model": model, 37 | "api_key": api_key, 38 | "base_url": base_url, 39 | } 40 | ] 41 | 42 | 43 | # 替换原有的 config_list 44 | config_list = get_config() 45 | 46 | 47 | def get_human_input(): 48 | user_input = input( 49 | Fore.YELLOW + "您的回复 (输入 'exit' 切换到下一个 agent): " + Style.RESET_ALL 50 | ) 51 | return user_input if user_input.lower() != "exit" else None 52 | 53 | 54 | def run_conversation(agent, user_proxy, initial_message, context=""): 55 | print(Fore.CYAN + f"\n--- 开始与 {agent.name} 的对话 ---" + Style.RESET_ALL) 56 | print(Fore.MAGENTA + "上下文:" + Style.RESET_ALL) 57 | print(context) 58 | print(Fore.MAGENTA + "初始消息:" + Style.RESET_ALL) 59 | print(initial_message) 60 | 61 | messages = [ 62 | {"role": "system", "content": context}, 63 | {"role": "user", "content": initial_message}, 64 | ] 65 | response = agent.generate_reply(sender=user_proxy, messages=messages) 66 | print(Fore.GREEN + f"{agent.name}: {response}" + Style.RESET_ALL) 67 | 68 | full_conversation = f"{context}\n\n{agent.name}: {response}" 69 | 70 | while True: 71 | user_input = get_human_input() 72 | if user_input is None: 73 | break 74 | messages.append({"role": "user", "content": user_input}) 75 | response = agent.generate_reply(sender=user_proxy, messages=messages) 76 | print(Fore.GREEN + f"{agent.name}: {response}" + Style.RESET_ALL) 77 | full_conversation += f"\n\nHuman: {user_input}\n\n{agent.name}: {response}" 78 | 79 | print(Fore.CYAN + f"--- 结束与 {agent.name} 的对话 ---\n" + Style.RESET_ALL) 80 | return full_conversation 81 | 82 | 83 | # 创建agents 84 | user_proxy = autogen.UserProxyAgent( 85 | name="Human", 86 | system_message="""你是一个人文社会科学研究者,需要协助完成论文选题和写作。在这个过程中,请遵循以下原则: 87 | 88 | 1. 坚持专业方向: 89 | - 确保论文选题聚焦于你的专业领域(例如,公共管理学科领域) 90 | 91 | 2. 理论联系实际: 92 | - 选题应该既有理论基础,又能解决实际问题 93 | 94 | 3. 聚焦实践问题: 95 | - 选题要密切结合研究领域的理论实践问题 96 | - 关注当前热点和实际需求 97 | 98 | 4. 明确研究对象: 99 | - 选题要落实到研究领域的具体领域和具体问题 100 | - 避免过于宽泛或模糊的主题 101 | 102 | 5. 创新性: 103 | - 选题要有新观点、新见解 104 | - 确保选题具有理论和应用价值 105 | 106 | 6. 可行性: 107 | - 考虑研究的可行性,包括时间、资源等因素 108 | - 评估资料获取的难易程度 109 | 110 | 你的任务是在整个论文选题和写作过程中,根据这些原则提供指导和反馈。请确保每个步骤都符合这些原则,并在必要时提出修改建议。""", 111 | human_input_mode="NEVER", 112 | code_execution_config={"use_docker": False}, 113 | ) 114 | 115 | research_field = autogen.ConversableAgent( 116 | name="ResearchField", 117 | system_message="""你是一个专业的研究领域专家。你的任务是根据用户的专业背景和学术兴趣,确定一个具体且有价值的研究领域。请遵循以下步骤: 118 | 119 | 1. 分析用户的专业背景(大前提条件): 120 | - 确保研究领域与用户的专业背景紧密相关 121 | - 例如,公共管理专业的用户应围绕公共管理领域,如行政管理、现代城市社会治理等 122 | 123 | 2. 考虑用户的学术兴趣(小前提条件): 124 | - 将用户的兴趣与其专业背景结合 125 | - 例如,对生成式人工智能感兴趣的公共管理专业用户,可以研究生成式人工智能在公共管理领域的应用和影响 126 | 127 | 3. 提出创新视角: 128 | - 尝试新的角度解释传统问题 129 | - 或探索专业领域中新兴的研究方向 130 | 131 | 4. 考虑当前的学术热点和发展趋势 132 | 133 | 5. 提出2-3个可能的研究领域选项,并解释每个选项的以下方面: 134 | - 与用户专业背景的相关性 135 | - 如何结合用户的学术兴趣 136 | - 研究的创新性 137 | - 潜在的学术价值和实际应用价值 138 | 139 | 请确保你的建议既符合用户的专业背景,又能满足其学术兴趣,同时具有学术价值和创新性。""", 140 | llm_config={"config_list": config_list}, 141 | ) 142 | 143 | research_object = autogen.ConversableAgent( 144 | name="ResearchObject", 145 | system_message="""你是一个研究对象定义专家。基于已确定的研究领域,你的任务是提出3-5个具体的研究对象。在确定研究对象时,请遵循以下原则: 146 | 147 | 1. 具体明确: 148 | - 研究对象应该比研领域更加具体和明确 149 | - 例如,如果研究领域是"民营养老",那么研究对象可以是"民营养老机构的定价机制" 150 | 151 | 2. 问题导向: 152 | - 研究对象应该包含可以解释的问题或社会热点问题 153 | - 确保选择的研究对象能够引发有意义的学术讨论或解决实际问题 154 | 155 | 3. 可行性: 156 | - 研究对象应该具有研究的可行性 157 | - 可以进行实证调研或获得相关统计数据 158 | - 考虑数据可获得性和研究方法的适用性 159 | 160 | 对于每个提出的研究对象,请提供以下信息: 161 | 1. 研究对象的具体描述 162 | 2. 与该研究对象相关的潜在问题或社会热点 163 | 3. 研究该对象的可行性分析(如可能的数据来源、研究方法等) 164 | 4. 该研究对象的理论意义和实际应用价值 165 | 166 | 请确保你提出的研究对象既符合上述原则,又与之前确定的研究领域紧密相关。""", 167 | llm_config={"config_list": config_list}, 168 | ) 169 | 170 | essential_problem = autogen.ConversableAgent( 171 | name="EssentialProblem", 172 | system_message="""你是一个研究问题分析专家。你的任务是深入分析研究对象,揭示其中的本质问题。请遵循以下步骤: 173 | 174 | 1. 识别现象问题:描述具体的、多变的社会矛盾现象或难以解释的社会现象。 175 | 176 | 2. 分析深层原因:通过"果索因"的方法,探究导致现象问题的根本原因。考虑社会经济因素、制度因素、文化因素等多个方面。 177 | 178 | 3. 提炼本质问题: 179 | - 找出决定现象问题背后的内在矛盾 180 | - 确保本质问题是看不见的、不变的,且能解释多个现象问题 181 | - 使用简洁、明确的名词性结构表述 182 | - 避免"假问题",确保提出的是"真问题" 183 | 184 | 4. 展示推理过程:清晰地说明从现象问题到本质问题的推理过程。 185 | 186 | 5. 最终输出: 187 | - 现象问题:[简要描述] 188 | - 推理过程:[详细说明] 189 | - 本质问题:[使用名词性结构,不超过10个字] 190 | 191 | 请确保你的分析逻辑清晰,论证有力,并能揭示问题的本质。""", 192 | llm_config={"config_list": config_list}, 193 | ) 194 | 195 | research_thesis = autogen.ConversableAgent( 196 | name="ResearchThesis", 197 | system_message="""你是一个研究论题专家。你的任务是基于之前的讨论,形成一个完整的研究论题。研究论题是对解决本质问题的基本判断,也可以说是基本理论假设。在形成研究论题时,请遵循以下步骤: 198 | 199 | 1. 理论假设的提出: 200 | - 根据研究问题的性质,选择合适的理论作为研究的基础 201 | - 确保选择的理论与之前讨论的研究对象和本质问题相关 202 | 203 | 2. 构建理论框架: 204 | - 阐述所选理论的核心概念、主要观点、假设前提以及发展历程 205 | - 分析理论对于当前研究问题的适应性 206 | - 根据理论框架,进一步明确研究问题和研究目标 207 | 208 | 3. 形成完整的研究论题: 209 | - 对本质问题提出基本判断 210 | - 阐述初步的理论框架 211 | - 提出具体的研究问题 212 | - 明确研究目标 213 | 214 | 请确保你的研究论题: 215 | 1. 与之前讨论的研究对象和本问题紧密相关 216 | 2. 具有理论深度和现实意义 217 | 3. 能够在所选理论框架的指导下得到深入探讨 218 | 4. 清晰、具体,并能引导后续的研究过程 219 | 220 | 请提供一个结构化的研究论题,包括上述所有要素。""", 221 | llm_config={"config_list": config_list}, 222 | ) 223 | 224 | paper_title = autogen.ConversableAgent( 225 | name="PaperTitleAndOutline", 226 | system_message="""你是一个论文题目和大纲专家。你的任务是基于之前的所有讨论,创造一个引人注目且学术性强的论���题目,并生成详细的三级目录。请遵循以下步骤: 227 | 228 | 1. 凝练论文题目: 229 | a) 内容完整性:包含研究对象和研究问题 230 | b) 简洁明了:控制在20个字以内 231 | c) 学术性:使用恰当的学术用语 232 | d) 吸引力:突出研究的创新性或重要性 233 | 234 | 2. 生成三级目录: 235 | a) 严格遵循提供的目录结构框架 236 | b) 每一章的标题、每一节的标题、每一目的标题都使用名词性结构,不使用逗号分隔 237 | c) 确保章标题、节标题与目标题之间形成逻辑闭环 238 | d) 第3章到第7章的具体内容需要根据研究内容进行扩展 239 | 240 | 3. 目录结构说明: 241 | 第1章 绪论 242 | 1.1 研究缘起(强调论文写作背景和研究问题,结合研究内容高度凝练) 243 | 1.1.1 研究背景 244 | 1.1.2 研究问题 245 | 1.2 研究意义(解释解决研究问题的意义,结合研究内容) 246 | 1.2.1 理论意义 247 | 1.2.2 实践意义 248 | 1.3 国内外研究现状(文献综述,包括实践发展、不足、政策与实施状况) 249 | 1.3.1 国内研究现状 250 | 1.3.2 国外研究现状 251 | 1.4 研究方法(至少两个研究方法,说明方法是什么,为什么使用,如何使用) 252 | 1.4.1 研究方法1 253 | 1.4.2 研究方法2 254 | 1.5 研究思路(研究角度、展开方面、技术路线) 255 | 1.5.1 研究角度 256 | 1.5.2 研究框架结构 257 | 258 | 第2章 核心概念与理论基础 259 | 2.1 核心概念(不超过3个,阐释包括提出者、普遍观点、不同观点) 260 | 2.1.1 核心概念1 261 | 2.1.2 核心概念2 262 | 2.1.3 核心概念3 263 | 2.2 理论基础(不超过2个理论,说明选择原因、依据和应用方式) 264 | 2.2.1 理论1 265 | 2.2.2 理论2 266 | 267 | 第3章 理论假设(针对研究问题,结合第2章理论基础提出假设) 268 | 269 | 第4章 现实分析(通过实证调查方法揭示并分析问题) 270 | 271 | 第5章 实证论证(通过定量分析模型论证之前提出的理论假设) 272 | 273 | 第6章 实现路径(基于理论假设与论证结果,提出解决研究问题的实践路径) 274 | 275 | 第7章 对策建议(提出实现理论假设和实践方案的对策建议) 276 | 277 | 请提供: 278 | 1. 一个符合要求的论文题目 279 | 2. 一个完整的三级目录,确保严格符合上述结构要求 280 | 281 | 确保你的题目和目录既符合学术规范,又能准确反映研究内容,同时具有吸引读者的能力。对于第3章到第7章,请根据之前的讨论内容进行适当扩展,保持逻辑一致性。""", 282 | llm_config={"config_list": config_list}, 283 | ) 284 | 285 | # 主程序 286 | print(Fore.YELLOW + "请输入您的专业领域和学术兴趣:" + Style.RESET_ALL) 287 | user_input = input() 288 | initial_message = ( 289 | f"用户的专业领域和学术兴趣是: {user_input}。请基于这些信息确定合适的研究领域。" 290 | ) 291 | 292 | print(Fore.CYAN + "\n--- 开始论文写作过程 ---" + Style.RESET_ALL) 293 | 294 | all_conversations = [] 295 | 296 | print(Fore.BLUE + "\n确定研究领域:" + Style.RESET_ALL) 297 | field_context = run_conversation(research_field, user_proxy, initial_message) 298 | all_conversations.append(("确定研究领域", field_context)) 299 | 300 | print(Fore.BLUE + "\n确定研究对象:" + Style.RESET_ALL) 301 | object_context = run_conversation( 302 | research_object, user_proxy, "基于研究领域,请确定具体的研究对象。", field_context 303 | ) 304 | all_conversations.append(("确定研究对象", object_context)) 305 | 306 | print(Fore.BLUE + "\n揭示本质问题:" + Style.RESET_ALL) 307 | problem_context = run_conversation( 308 | essential_problem, 309 | user_proxy, 310 | "请基于之前的讨论,分析现象问题,找出本质问题。", 311 | object_context, 312 | ) 313 | all_conversations.append(("揭示本质问题", problem_context)) 314 | 315 | print(Fore.BLUE + "\n形成研究的论题:" + Style.RESET_ALL) 316 | thesis_context = run_conversation( 317 | research_thesis, 318 | user_proxy, 319 | "请基于之前的所有讨论,形成研究论题,并阐述理论框架。", 320 | problem_context, 321 | ) 322 | all_conversations.append(("形成研究的论题", thesis_context)) 323 | 324 | print(Fore.BLUE + "\n凝练论文题目:" + Style.RESET_ALL) 325 | title_context = run_conversation( 326 | paper_title, 327 | user_proxy, 328 | "请基于之前的所有讨论,凝练简洁明了的论文题目,并按照上述要求输出三级目录。", 329 | thesis_context, 330 | ) 331 | all_conversations.append(("凝练论文题目", title_context)) 332 | 333 | print(Fore.CYAN + "\n--- 论文写作过程结束 ---" + Style.RESET_ALL) 334 | 335 | # 将所有对话内容输出到 Markdown 文件 336 | timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") 337 | filename = f"research_process_{timestamp}.md" 338 | 339 | with open(filename, "w", encoding="utf-8") as f: 340 | f.write("# 研究过程记录\n\n") 341 | f.write(f"用户输入: {user_input}\n\n") 342 | 343 | # 只写入"凝练论文题目"的内容 344 | for title, content in all_conversations: 345 | if title == "凝练论文题目": 346 | f.write(f"## {title}\n\n") 347 | f.write(f"\n{content}\n\n") 348 | 349 | print(Fore.GREEN + f"\n所有对话内容已保存到 {filename}" + Style.RESET_ALL) 350 | --------------------------------------------------------------------------------