使用这个工具,基于代码仓库直接生成教程文档,感觉比我自己写的还好

360影视 欧美动漫 2025-04-24 08:52 1

摘要:我比较喜欢写教程,但是纯手写的话,一方面太麻烦了,另一方面就是觉得自己写的不太好,很多时候都喜欢直接贴代码算了。但直接贴代码对有编程基础的人而言可能很有帮助,但是对想入门的小白而言,一上来就是一大堆代码就很容易劝退。

前言

我比较喜欢写教程,但是纯手写的话,一方面太麻烦了,另一方面就是觉得自己写的不太好,很多时候都喜欢直接贴代码算了。但直接贴代码对有编程基础的人而言可能很有帮助,但是对想入门的小白而言,一上来就是一大堆代码就很容易劝退。

怎么把教程写好,是我一直都在探索的事情。

昨天在GitHub上偶然刷到了一个项目,说是基于代码仓库直接就能生成教程文档,我抱着试一试的心态去尝试了一下,结果确实被惊艳到了,今天就来分享给大家,我也会带大家实践一下。

这个项目叫Tutorial-Codebase-Knowledge。

GitHub地址:https://github.com/The-Pocket/Tutorial-Codebase-Knowledge

image-20250423163151094Tutorial-Codebase-Knowledge介绍

这是一个 Pocket Flow 的教程项目,一个仅100行代码的LLM框架。它爬取 GitHub 仓库,并从代码中构建知识库。它分析整个代码库以识别核心抽象及其交互方式,并将复杂的代码转化为带有清晰可视化内容的初学者友好教程。

实践

创建一个python虚拟环境,安装包:

pip install -r requirements.txt

需要修改一下call_llm.py:

使用谷歌的模型可以这样写:

def call_llm(prompt, use_cache: bool = True):
client = genai.Client(
api_key=os.getenv("GEMINI_API_KEY""你的api key"),
)
model = os.getenv("GEMINI_MODEL""gemini-2.5-pro-exp-03-25")
response = client.models.generate_content(
model=model,
contents=[prompt]
)
response_text = response.text
return response_text

使用兼容OpenAI格式的模型可以这样写:

# Use OpenAI o1
def call_llm(prompt, use_cache: bool = True):
from openai import OpenAI
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY""你的api key"),
base_url="https://api.siliconflow.cn/v1")
r = client.chat.completions.create(
model="Qwen/QwQ-32B"
messages=[{"role":"user""content": prompt}],
response_format={
"type":"text"
},
reasoning_effort="medium"
store=False
)
return r.choices[0].message.content

使用这个命令用于测试:

python utils/call_llm.py

参考README的使用方法:

# Analyze a GitHub repository
python main.py --repo https://github.com/username/repo --include"*.py""*.js"--exclude"tests/*"--max-size50000

# Or, analyze a local directory
python main.py --dir /path/to/your/codebase --include"*.py"--exclude"*test*"

# Or, generate a tutorial in Chinese
python main.py --repo https://github.com/username/repo --language"Chinese"

--repo 或 --dir - 指定 GitHub 仓库 URL 或本地目录路径(必需,互斥)

-n, --name - 项目名称(可选,如果省略则从 URL/目录派生)

-t, --token - GitHub 令牌(或设置 GITHUB_TOKEN 环境变量)

-o, --output - 输出目录(默认:./output)

-i, --include - 要包含的文件(例如,".py" ".js")

-e, --exclude - 要排除的文件(例如,"tests/" "docs/")

-s, --max-size - 文件最大大小(以字节为单位,默认:100KB)

--language - 生成教程的语言(默认:"english")

正常运行如下图所示:

image-20250423164613454

会开始分析章节然后开始写章节的内容。

以自己的一个教程仓库为例,我使用了不同的模型创建教程,把生成的教程我上传到GitHub了。

地址:https://github.com/Ming-jiayou/Avalonia_With_Dependency_Injection_Example/tree/main/Tutorials

image-20250423164851899

在我使用的模型中,我觉得效果最好的是gemini-2.5-pro-exp-03-25。

感兴趣的朋友可以自己看看对比一下。

我现在把gemini-2.5-pro-exp-03-25生成的贴出来看看。

Tutorial: Avalonia_With_Dependency_Injection_Example

本项目 Avalonia_With_Dependency_Injection_Example是一个使用Avalonia UI依赖注入技术构建的示例应用。它展示了如何通过依赖注入管理应用的组件和服务,并通过导航服务实现不同视图之间的切换。通过视图模型与视图的分离设计,项目实现了模块化开发,提高了代码的复用性和可维护性。

Source Repository:https://github.com/Ming-jiayou/Avalonia_With_Dependency_Injection_Example

欢迎初学者!

欢迎来到我们的第一个章节!在这个章节中,我们将学习如何配置和启动Avalonia应用程序。如果你是第一次接触Avalonia或者依赖注入(Dependency Injection, DI),请不要担心,我们将通过具体的例子来一步步引导你。

为什么要配置主应用程序?

在开发任何应用程序时,首先需要做的一件事情就是配置和启动它。在Avalonia中,主应用程序配置类似于一家公司的前台,负责接待访客并引导他们进入正确的房间。在这个例子中,我们的“前台”会做一些必要的初始化工作,比如设置主窗口和初始化依赖注入。这样的配置能确保应用程序能够顺利启动,用户可以使用所有的功能。

具体实现1. 创建应用程序类我们从创建应用程序类开始。在Avalonia中,应用程序类继承自Application,并重写一些方法来配置应用程序。我们来看一下App.aXaml.cs文件中的代码:using System.Linq;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using AvaloniaWithDependencyInjection.ViewModels;
using AvaloniaWithDependencyInjection.Views;
using Microsoft.Extensions.DependencyInjection;

namespaceAvaloniaWithDependencyInjection
{
publicpartialclassApp : Application
{
public override void Initialize
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
DisableAvaloniaDataAnnotationValidation;

var mainWindow = Program.ServiceProvider?.GetRequiredService;
var mainViewModel = Program.ServiceProvider?.GetRequiredService;

if (mainWindow != && mainViewModel != )
{
mainWindow.DataContext = mainViewModel;
desktop.MainWindow = mainWindow;
}
}

base.OnFrameworkInitializationCompleted;
}

private void DisableAvaloniaDataAnnotationValidation
{
var dataValidationPluginsToRemove =
BindingPlugins.DataValidators.OfType.ToArray;

foreach (var plugin in dataValidationPluginsToRemove)
{
BindingPlugins.DataValidators.Remove(plugin);
}
}
}
}
代码解释

Initialize 方法:

AvaloniaXamlLoader.Load(this);:加载XAML资源,初始化用户界面。

OnFrameworkInitializationCompleted 方法:

ApplicationLifetime:检查应用程序是否在传统的桌面环境中运行。

DisableAvaloniaDataAnnotationValidation

:禁用Avalonia的数据注释验证,避免与CommunityToolkit重复验证。

Program.ServiceProvider.GetRequiredService

Program.ServiceProvider.GetRequiredService

:从依赖注入服务中获取主窗口和主窗口视图模型。

mainWindow.DataContext = mainViewModel;

:将主窗口的 DataContext 设置为主窗口视图模型。

desktop.MainWindow = mainWindow;:设置应用程序的主窗口。

DisableAvaloniaDataAnnotationValidation 方法:

从数据验证插件中移除Avalonia的数据注释验证插件,避免重复验证。

2. 配置依赖注入接下来,我们来看看如何配置依赖注入。在Program.cs文件中,我们会创建一个服务集合,并注册所需的依赖项:using System;
using Avalonia;
using Microsoft.Extensions.DependencyInjection;

namespaceAvaloniaWithDependencyInjection
{
internalsealedclassProgram
{
publicstatic IServiceProvider? ServiceProvider { get; privateset; }

[STAThread]
public static void Main(string args)
{
var services = new ServiceCollection;

services.AddViews
.AddViewModels
.AddServices;

ServiceProvider = services.BuildServiceProvider;

BuildAvaloniaApp.StartWithClassicDesktopLifetime(args);
}

public static AppBuilder BuildAvaloniaApp
=> AppBuilder.Configure
.UsePlatformDetect
.WithInterFont
.LogToTrace;
}
}
代码解释

Main 方法:

var services = new ServiceCollection;

:创建一个服务集合。

services.AddViews.AddViewModels.AddServices;

:注册视图、视图模型和其他服务。

ServiceProvider = services.BuildServiceProvider;

:构建服务提供者。

BuildAvaloniaApp.StartWithClassicDesktopLifetime(args);

:配置并启动Avalonia应用程序。

BuildAvaloniaApp 方法:

AppBuilder.Configure:配置应用程序。

UsePlatformDetect:自动检测平台。

WithInterFont:使用Inter字体。

LogToTrace:将日志记录到跟踪。

内部实现步骤详解

创建应用程序类:

配置依赖注入:

image-20250423171117560结论

通过本章,我们学习了如何配置和启动Avalonia应用程序。我们介绍了应用程序类的创建和依赖注入的配置。希望你现在已经能够理解这些基本概念,并能够自己动手配置一个简单Avalonia应用程序。

接下来,我们将深入学习依赖注入的更多内容。请继续阅读:依赖注入。

从上一章过渡

在上一章 主应用程序配置 中,我们学习了如何配置和启动一个Avalonia应用程序。我们介绍了应用程序类的创建和依赖注入的基本概念。在这一章中,我们将深入探讨依赖注入(Dependency Injection, 简称DI)这一重要的设计模式。通过理解依赖注入,你将能够更灵活地管理和使用应用程序中的各个组件。

依赖注入的基本概念为什么使用依赖注入?

假设你正在开发一个应用程序,其中包含多个组件,例如视图(View)、视图模型(ViewModel)和服务(Service)。每个组件都可能需要依赖其他组件来完成特定的功能。例如,一个视图模型可能会依赖一个服务来获取数据。如果没有依赖注入,每个组件都需要自己创建或查找依赖,这样会导致代码耦合度高,难以测试和维护。

依赖注入通过将依赖关系从组件内部移到外部来解决这个问题。就像在一个团队中,领导分配任务,而不是每个成员自己找任务。这种方式使得组件更加独立和模块化,更容易测试和维护。

依赖注入的关键概念

依赖(Dependency)

一个组件需要使用的其他组件。例如,视图模型可能需要一个服务来获取数据。

注入(Injection)

通过构造函数、属性或方法将依赖传递给组件的过程。这种方式使得组件不需要自己创建或查找依赖。

依赖注入容器(Dependency Injection Container)

管理和提供依赖的工具。在Avalonia中,我们使用

Microsoft.Extensions.DependencyInjection

来创建和管理依赖注入容器。

如何使用依赖注入一个简单的例子假设我们有一个视图模型MainWindowViewModel,它需要使用一个服务DataService来获取数据。我们可以通过依赖注入来实现这一点。定义服务首先,我们定义一个服务namespace AvaloniaWithDependencyInjection.Services
{
publicinterfaceIDataService
{
string GetData;
}

publicclassDataService : IDataService
{
public string GetData
{
return"Hello, World!";
}
}
}
注册服务接下来,我们需要在依赖注入容器中注册这个服务。我们已经在Program.cspublic static AppBuilder BuildAvaloniaApp
=> AppBuilder.Configure
.UsePlatformDetect
.WithInterFont
.LogToTrace;

[STAThread]
public static void Main(string args)
{
var services = new ServiceCollection;

services.AddViews
.AddViewModels
.AddServices;

ServiceProvider = services.BuildServiceProvider;

BuildAvaloniaApp.StartWithClassicDesktopLifetime(args);
}
在文件中,我们注册了所有的视图、视图模型和服务:public staticclassServiceCollectionExtensions
{
public static IServiceCollection AddViews(this IServiceCollection services)
{
services.AddSingleton;
services.AddSingleton;
services.AddSingleton;

return services;
}

public static IServiceCollection AddViewModels(this IServiceCollection services)
{
services.AddSingleton;
services.AddSingleton;
services.AddSingleton;

return services;
}

public static IServiceCollection AddServices(this IServiceCollection services)
{
services.AddSingleton;

return services;
}
}
注入依赖现在,我们可以在中注入:namespace AvaloniaWithDependencyInjection.ViewModels
{
publicclassMainWindowViewModel
{
privatereadonly IDataService _dataService;

publicstring Data { get; privateset; }

public MainWindowViewModel(IDataService dataService)
{
_dataService = dataService;
Data = _dataService.GetData;
}
}
}
代码解释

定义服务

DataService实现了IDataService接口,并提供了GetData方法。

注册服务

ServiceCollectionExtensions中,我们通过AddServices方法注册了DataService。

注入依赖

MainWindowViewModel中,我们通过构造函数注入了IDataService,并在构造函数中调用了GetData方法。

当应用程序启动时,依赖注入容器会自动创建DataService实例,并将其传递给的构造函数。会调用GetData方法,并将返回的数据赋值给Data属性。最终,Data属性的值会显示在主窗口中。内部实现依赖注入容器的工作原理

创建服务集合

在 Program.cs中,我们创建了一个ServiceCollection实例。

注册依赖

通过 AddViews、AddViewModels和AddServices方法,我们注册了所有的视图、视图模型和服务。

构建服务提供者

使用 services.BuildServiceProvider方法,我们构建了一个IServiceProvider实例。

获取服务

在 App.axaml.cs文件中,我们通过

Program.ServiceProvider.GetRequiredService

Program.ServiceProvider.GetRequiredService

方法从服务提供者中获取主窗口和主窗口视图模型。

序列图image-20250423171232102结论

通过本章,我们深入探讨了依赖注入的基本概念和使用方法。我们学习了如何通过依赖注入来管理和使用应用程序中的各个组件,使得代码更加模块化和易于测试。希望你现在能够理解依赖注入的重要性和使用方法。

接下来,我们将学习 应用程序生命周期 的相关内容。请继续阅读,了解应用程序的各个生命周期阶段。

最后

多的就不放了,感兴趣的朋友可以去GitHub上看完整的,让我惊讶的地方是感觉gemini-2.5-pro-exp-03-25的图画的很不错,在教程中多放点这种图,会让读者更加清晰易懂。

image-20250423165834003

来源:opendotnet

相关推荐