当前位置: 首页 > news >正文

gig-gitignore工具实战开发(四):使用ai辅助生成gitignore

文章目录

  • gig-gitignore工具实战开发(四):使用ai辅助生成gitignore
    • ai配置
    • 编写promot
    • 流失响应

gig-gitignore工具实战开发(四):使用ai辅助生成gitignore

前言: 在上一篇我们编写了gig add命令基础代码,下面详细介绍ai生成模板代码。

ai配置

由于ai模型众多,这里我们采用最简单的方案,兼容openai的api规范,提供base_url修改,这样无需和一个个模型提供商进行对接。

引导用户进行ai配置输入

func runInteractiveConfig() {fmt.Println("Entering interactive configuration mode...")// Prompt for API KeypromptAPIKey := promptui.Prompt{Label:   "OpenAI API Key",Default: viper.GetString("ai.api_key"),Mask:    '*',}apiKey, err := promptAPIKey.Run()if err != nil {fmt.Printf("Prompt failed %v\n", err)os.Exit(1)}viper.Set("ai.api_key", apiKey)// Prompt for AI URLpromptURL := promptui.Prompt{Label:   "AI Service URL",Default: viper.GetString("ai.url"),}apiURL, err := promptURL.Run()if err != nil {fmt.Printf("Prompt failed %v\n", err)os.Exit(1)}viper.Set("ai.url", apiURL)// Prompt for AI ModelpromptModel := promptui.Prompt{Label:   "AI Model",Default: viper.GetString("ai.model"),}model, err := promptModel.Run()if err != nil {fmt.Printf("Prompt failed %v\n", err)os.Exit(1)}viper.Set("ai.model", model)saveConfig()
}

存储

func saveConfig() {// Get the config file path from vipercfgFile := viper.ConfigFileUsed()if cfgFile == "" {// If no config file is used, create one in the default pathhome, err := os.UserHomeDir()if err != nil {fmt.Println("Error finding home directory:", err)os.Exit(1)}cfgFile = filepath.Join(home, ".ciclebyte", "gig", "config", "config.yaml")}if err := viper.WriteConfigAs(cfgFile); err != nil {fmt.Println("Error writing configuration file:", err)os.Exit(1)}fmt.Println("Configuration saved successfully to", cfgFile)
}

编写promot

编写promot,让ai生成符合要求的gitignore文件

 You are an expert assistant specializing in generating high-quality .gitignore files.Your task is to create a .gitignore file for a project based on the provided languages and frameworks.<instructions>1.  **Content**: The file MUST only contain rules for the following languages/frameworks: %s.2.  **Structure**: Organize the rules into logical categories (e.g., "Dependencies", "Build output", "Logs", "IDE files").3.  **Headers**: Each category MUST start with a header formatted exactly as '# === Category Name ===', followed by a blank line.4.  **Comments**: Add concise comments (starting with '#') to explain the purpose of non-obvious rules or groups of rules.5.  **Exclusivity**: Do NOT include rules for any other languages, frameworks, or tools not specified.6.  **Output Format**: Your response MUST be ONLY the raw text content of the .gitignore file. Do NOT include any introductory text, explanations, or markdown code blocks like ` + "`" + ` ` + "`" + ` or ` + "`" + ` ` + "`" + `gitignore.</instructions>`

流失响应

根据配置的ai模型、promot返回生成的gitignore文件内容

// 通用流式AI请求,返回完整内容
func (AIUtil) StreamChat(promptType string, vars ...string) (string, error) {apiKey := viper.GetString("ai.api_key")if apiKey == "" {fmt.Println("AI API Key is not configured. Please run 'gig config' or设置 GIG_AI_API_KEY.")os.Exit(1)}apiURL := viper.GetString("ai.url")model := viper.GetString("ai.model")promptTpl := models.AppConfig.Prompts[promptType]anyVars := make([]any, len(vars))for i, v := range vars {anyVars[i] = v}prompt := fmt.Sprintf(promptTpl, anyVars...)reqBody, err := json.Marshal(models.OpenAIRequest{Model:    model,Messages: []models.Message{{Role: "user", Content: prompt}},Stream:   true,})if err != nil {return "", err}req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(reqBody))if err != nil {return "", err}req.Header.Set("Content-Type", "application/json")req.Header.Set("Authorization", "Bearer "+apiKey)client := &http.Client{}resp, err := client.Do(req)if err != nil {return "", err}defer resp.Body.Close()if resp.StatusCode != http.StatusOK {bodyBytes, _ := ioutil.ReadAll(resp.Body)return "", fmt.Errorf("AI service returned %d: %s", resp.StatusCode, string(bodyBytes))}var fullContent strings.Builderreader := bufio.NewReader(resp.Body)for {line, err := reader.ReadString('\n')if err != nil {if err == io.EOF {break}return "", err}if strings.HasPrefix(line, "data: ") {data := strings.TrimPrefix(line, "data: ")if strings.TrimSpace(data) == "[DONE]" {break}var streamResp models.OpenAIStreamResponseif err := json.Unmarshal([]byte(data), &streamResp); err == nil {if len(streamResp.Choices) > 0 {content := streamResp.Choices[0].Delta.Contentfmt.Print(content) // 实时输出fullContent.WriteString(content)}}}}return fullContent.String(), nil
}// 建议流式返回切片
func (AIUtil) StreamSuggestions(promptType string, vars ...string) ([]string, error) {content, err := AI.StreamChat(promptType, vars...)if err != nil {return nil, err}return strings.Split(strings.TrimSpace(content), "\n"), nil
}
http://www.lryc.cn/news/599278.html

相关文章:

  • 熵与交叉熵:从信息论到机器学习的「不确定性」密码
  • 有关于k8s中的CSI和CRI的有关知识
  • [硬件电路-85]:一款高集成度热电制冷器(TEC)控制器芯片ADN8835ACPZ
  • 【Docker项目实战】在Docker环境下部署go-file文件分享工具
  • SaaS型小程序自动化发布解决方案
  • 飞行控制领军者 | 边界智控携高安全级飞控系统亮相2025深圳eVTOL展
  • 大型微服务项目:听书——11 Redisson分布式布隆过滤器+Redisson分布式锁改造专辑详情接口
  • 巧用Proxy与异步编程:绕过浏览器安全限制实现文件选择器触发
  • 秋招Day19 - 分布式 - 分布式锁
  • 线性代数 下
  • 关于回归决策树CART生成算法中的最优化算法详解
  • 机器学习笔记(三)——决策树、随机森林
  • 水库大坝安全监测的主要内容
  • 在VSCode配置Java开发环境的保姆级教程(适配各类AI编程IDE)
  • 【内网穿透】使用FRP实现内网与公网Linux/Ubuntu服务器穿透项目部署多项目穿透方案
  • SSSD介绍
  • 【阅读整理】野火ADC_AD7192模块资料
  • “即时零售”风起,E3+企业中台如何赋能品牌企业破局增长?
  • CIU32L051 DMA+Lwrb环形队列实现串口无阻塞性数据的收发 + 数据百分百不丢失的实现
  • 百度蜘蛛池解析机制:原创
  • 通用CI/CD软件平台TeamCity v2025.3全新发布——主要界面交互体验升级
  • AWS CAF:企业云转型的战略指南
  • 佳能iR-ADV C5560复印机如何扫描文件到电脑
  • 零售收银系统开源代码全解析:连锁门店一体化解决方案(含POS+进销存+商城)
  • 深入解析Linux匿名管道机制与应用
  • 没有 Mac,如何上架 iOS App?多项目复用与流程标准化实战分享
  • AI浪潮涌,数据库“融合智能”奏响产业新乐章
  • 用 Docker 一键部署 Flask + Redis 微服务
  • 如何将 iPhone 备份到 Mac/MacBook
  • 从huggingface上下载模型