# Git2Note **Repository Path**: lizhenping/git2note ## Basic Information - **Project Name**: Git2Note - **Description**: 将GIT 仓库中的代码自动注释并导入到个人笔记本中 - **Primary Language**: NodeJS - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-10-10 - **Last Updated**: 2024-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # github2notion #### 介绍 用于将 GitHub 中的代码下载到 Notion 中,并使用 Qwen AI 模型 API 对代码进行注释。 #### 软件架构 本项目采用模块化设计,主要包含以下模块: - **控制器 (controllers)**: 负责协调各个服务的调用,处理 Git 仓库与 Notion 之间的同步。 - **接口 (interfaces)**: 定义各个服务的接口,确保服务之间的解耦。 - **工具 (utils)**: 提供一些实用函数,用于处理和格式化 Notion 内容。 - **配置 (config)**: 负责加载和管理应用的配置。 - **服务 (services)**: 包含与 GitHub 和 Notion API 交互的具体实现。 - **笔记服务 (noteServices)**: 处理与 Notion API 的交互,提供页面的创建、更新和管理功能。 - **AI 模型服务 (aiModelServices)**: 负责与 Qwen AI 模型的交互,生成代码注释。 #### 安装教程 1. 克隆本仓库到本地: ```bash git clone https://github.com/yourusername/github2notion.git ``` 2. 进入项目目录: ```bash cd github2notion ``` 3. 安装依赖: ```bash cnpm install ``` #### 使用说明 1. 运行代码请使用 `node index.js` 或者 `npm start`。 2. 确保在 `.env` 文件中配置了必要的环境变量,例如 GitHub Token 和 Notion Token。 3. 根据需要修改配置文件以适应你的项目需求。 #### 参与贡献 1. lizhenping 2. claude,cursor,chatgpt-o1-mini,sider ## 待办事项 - [ ] 修复 Notion API 请求中的错误,目前错误是代码块不能超过 2000 字符,超过后会丢失高亮,经过查询这个是 Notion 代码快自身渲染问题,采用了分块处理,但是维持原有格式排版的形式,目前没有太好的解决方案,需要手动调整 - [ ] 撰写 Python 版本的代码 - [ ] 支持 Gitee - [ ] 支持 更多笔记本形式,譬如本地markdown文件,印象笔记,有道云笔记等 - [ ] 支持更多 AI 模型 - [ ] 在 AutoDL上发布 Docker #### 知识点 #### 单一模型文件策略的 Python 实现示例 为了模仿 Hugging Face 的 **单一模型文件策略**,我们将创建一个简单的 Python 示例。该示例展示了如何将每个模型的所有逻辑集中在单独的文件中,并通过工厂函数根据模型名称进行实例化。这种设计使用户能够通过模型名称轻松调用和使用不同的模型。 #### 背景故事 这个方法是我在 Google 实习时,褚泽伟老师教我的。那时候我对其中的 `model_factory` 部分感到非常困惑,甚至有些抵触,能把代码没 BUG 的跑通就很困难了。然而在再次工作时,我发现许多当时的情景恰好与我现在经历的相似。在接受教育的时候,我并未意识到哪些是必须做的,哪些是不该做的。有趣的是,在工作中我发现以前我被教育所有要做的是事情全都没做,所有应避免的事情却无一例外地做了。这让我想起了过去自己的经历,也正是这段宝贵的经历让我瞬间理解了很多。 褚老师他们提出 prmopt 的时候,我真的感觉没有任何意义。当时交流的原话是,很多事情的真正意义往往是在五年、十年后才能显现出来。剑来:“你不入十四境见我如井中蛙观天上月,等你哪天侥幸跻身十四境了,见我就如一粒蜉蝣见青天。” 教育这个事情确实需要经历才看得懂,有时候父母花太多钱在教育上太功利,太着急可能未必有用,就像树木成长,我确实是从北京到大凉山,到MIT GOOGLE 走了一整圈才懂一些什么。我在 UCL 当时组里有个说诺奖提名人,他说的一句话是写的论文一定是让别人看的。而不是自己看的。过去学到的知识可能都需要我重新实现一遍,以便于在新的理解层面上重新掌握它们的价值。 ### 目录 1. [项目结构](#项目结构) 2. [模型实现](#模型实现) - [BaseModel](#basemodel) - [ModelA](#modela) - [ModelB](#modelb) 3. [模型工厂](#模型工厂) 4. [示例用法](#示例用法) 5. [完整代码](#完整代码) 6. [结论](#结论) --- ### 项目结构 ``` single_model_policy_example/ │ ├── models/ │ ├── __init__.py │ ├── base_model.py │ ├── model_a.py │ └── model_b.py │ ├── model_factory.py └── main.py ``` ### 模型实现 每个模型都位于 `models` 目录下的单独文件中,并继承自 `BaseModel`。这种结构遵循了单一模型文件策略,将每个模型的所有逻辑集中在一个文件中。 #### `base_model.py` 首先,我们定义一个基础模型类,所有具体模型将继承自该类: ```python # models/base_model.py class BaseModel: def __init__(self, params): self.params = params def forward(self, input): raise NotImplementedError("Forward method must be implemented by the subclass.") def predict(self, input): raise NotImplementedError("Predict method must be implemented by the subclass.") ``` #### `model_a.py` ```python # models/model_a.py from .base_model import BaseModel class ModelA(BaseModel): def __init__(self, params): super().__init__(params) # 初始化 ModelA 的特定参数 self.weight = self.params.get('weight', 1) def forward(self, input): # ModelA 的前向传播逻辑 return input * self.weight # Copied from ModelB.predict def predict(self, input): return 'Positive' if self.forward(input) > 0.5 else 'Negative' ``` #### `model_b.py` ```python # models/model_b.py from .base_model import BaseModel class ModelB(BaseModel): def __init__(self, params): super().__init__(params) # 初始化 ModelB 的特定参数 self.bias = self.params.get('bias', 0) def forward(self, input): # ModelB 的前向传播逻辑 return input + self.bias # Copied from ModelA.predict def predict(self, input): return 'Yes' if self.forward(input) > 0 else 'No' ``` ### 模型工厂 `model_factory.py` 文件包含一个工厂函数,用于根据模型名称实例化相应的模型。这类似于 Hugging Face 的 `AutoModel` 机制。 ```python # model_factory.py from models.model_a import ModelA from models.model_b import ModelB def get_model(model_name, params): models = { 'model_a': ModelA, 'model_b': ModelB } model_class = models.get(model_name.lower()) if not model_class: raise ValueError(f"Model '{model_name}' is not supported.") return model_class(params) ``` ### 示例用法 `main.py` 展示了如何使用工厂函数根据模型名称加载模型,并调用其方法。 ```python # main.py from model_factory import get_model def main(): # 定义模型参数 params_a = {'weight': 2} params_b = {'bias': -1} # 加载模型 model_a = get_model('model_a', params_a) model_b = get_model('model_b', params_b) # 使用模型 input_value = 0.3 output_a = model_a.forward(input_value) prediction_a = model_a.predict(input_value) input_value_b = 1 output_b = model_b.forward(input_value_b) prediction_b = model_b.predict(input_value_b) print(f"ModelA forward({input_value}) = {output_a}") print(f"ModelA predict({input_value}) = {prediction_a}") print(f"ModelB forward({input_value_b}) = {output_b}") print(f"ModelB predict({input_value_b}) = {prediction_b}") if __name__ == "__main__": main() ``` ### 完整代码 为了方便理解,以下是所有相关文件的完整代码。 #### `models/__init__.py` ```python # models/__init__.py # 空文件,用于将 models 目录标识为一个包 ``` #### `models/base_model.py` ```python # models/base_model.py class BaseModel: def __init__(self, params): self.params = params def forward(self, input): raise NotImplementedError("Forward method must be implemented by the subclass.") def predict(self, input): raise NotImplementedError("Predict method must be implemented by the subclass.") ``` #### `models/model_a.py` ```python # models/model_a.py from .base_model import BaseModel class ModelA(BaseModel): def __init__(self, params): super().__init__(params) # 初始化 ModelA 的特定参数 self.weight = self.params.get('weight', 1) def forward(self, input): # ModelA 的前向传播逻辑 return input * self.weight # Copied from ModelB.predict def predict(self, input): return 'Positive' if self.forward(input) > 0.5 else 'Negative' ``` #### `models/model_b.py` ```python # models/model_b.py from .base_model import BaseModel class ModelB(BaseModel): def __init__(self, params): super().__init__(params) # 初始化 ModelB 的特定参数 self.bias = self.params.get('bias', 0) def forward(self, input): # ModelB 的前向传播逻辑 return input + self.bias # Copied from ModelA.predict def predict(self, input): return 'Yes' if self.forward(input) > 0 else 'No' ``` #### `model_factory.py` ```python # model_factory.py from models.model_a import ModelA from models.model_b import ModelB def get_model(model_name, params): models = { 'model_a': ModelA, 'model_b': ModelB } model_class = models.get(model_name.lower()) if not model_class: raise ValueError(f"Model '{model_name}' is not supported.") return model_class(params) ``` #### `main.py` ```python # main.py from model_factory import get_model def main(): # 定义模型参数 params_a = {'weight': 2} params_b = {'bias': -1} # 加载模型 model_a = get_model('model_a', params_a) model_b = get_model('model_b', params_b) # 使用模型 input_value = 0.3 output_a = model_a.forward(input_value) prediction_a = model_a.predict(input_value) input_value_b = 1 output_b = model_b.forward(input_value_b) prediction_b = model_b.predict(input_value_b) print(f"ModelA forward({input_value}) = {output_a}") print(f"ModelA predict({input_value}) = {prediction_a}") print(f"ModelB forward({input_value_b}) = {output_b}") print(f"ModelB predict({input_value_b}) = {prediction_b}") if __name__ == "__main__": main() ``` ### 运行示例 确保项目结构正确后,运行 `main.py` 将输出: ``` ModelA forward(0.3) = 0.6 ModelA predict(0.3) = Positive ModelB forward(1) = 0 ModelB predict(1) = No ``` ### 结论 通过上述示例,我们实现了一个简单的 **单一模型文件策略**,模仿了 Hugging Face 的设计思想。每个模型的所有逻辑都集中在单独的文件中,用户可以通过模型名称轻松实例化和使用不同的模型。这种设计提高了代码的可读性和可维护性,特别适用于需要快速迭代和扩展的项目。 在实际项目中,可以进一步扩展工厂函数以支持更多模型,或者引入自动注册机制,减少手动维护模型映射的工作量。此外,结合配置文件或命令行参数,可以实现更加灵活和动态的模型加载策略。