[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-crmne--ruby_llm":3,"tool-crmne--ruby_llm":64},[4,17,27,35,43,56],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":16},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,3,"2026-04-05T11:01:52",[13,14,15],"开发框架","图像","Agent","ready",{"id":18,"name":19,"github_repo":20,"description_zh":21,"stars":22,"difficulty_score":23,"last_commit_at":24,"category_tags":25,"status":16},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",138956,2,"2026-04-05T11:33:21",[13,15,26],"语言模型",{"id":28,"name":29,"github_repo":30,"description_zh":31,"stars":32,"difficulty_score":23,"last_commit_at":33,"category_tags":34,"status":16},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107662,"2026-04-03T11:11:01",[13,14,15],{"id":36,"name":37,"github_repo":38,"description_zh":39,"stars":40,"difficulty_score":23,"last_commit_at":41,"category_tags":42,"status":16},3704,"NextChat","ChatGPTNextWeb\u002FNextChat","NextChat 是一款轻量且极速的 AI 助手，旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性，以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发，NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。\n\n这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言，它也提供了便捷的自托管方案，支持一键部署到 Vercel 或 Zeabur 等平台。\n\nNextChat 的核心亮点在于其广泛的模型兼容性，原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型，让用户在一个界面即可自由切换不同 AI 能力。此外，它还率先支持 MCP（Model Context Protocol）协议，增强了上下文处理能力。针对企业用户，NextChat 提供专业版解决方案，具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能，满足公司对数据隐私和个性化管理的高标准要求。",87618,"2026-04-05T07:20:52",[13,26],{"id":44,"name":45,"github_repo":46,"description_zh":47,"stars":48,"difficulty_score":23,"last_commit_at":49,"category_tags":50,"status":16},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",84991,"2026-04-05T10:45:23",[14,51,52,53,15,54,26,13,55],"数据工具","视频","插件","其他","音频",{"id":57,"name":58,"github_repo":59,"description_zh":60,"stars":61,"difficulty_score":10,"last_commit_at":62,"category_tags":63,"status":16},3128,"ragflow","infiniflow\u002Fragflow","RAGFlow 是一款领先的开源检索增强生成（RAG）引擎，旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体（Agent）能力相结合，不仅支持从各类文档中高效提取知识，还能让模型基于这些知识进行逻辑推理和任务执行。\n\n在大模型应用中，幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构（如表格、图表及混合排版），显著提升了信息检索的准确度，从而有效减少模型“胡编乱造”的现象，确保回答既有据可依又具备时效性。其内置的智能体机制更进一步，使系统不仅能回答问题，还能自主规划步骤解决复杂问题。\n\n这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统，还是致力于探索大模型在垂直领域落地的创新者，都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口，既降低了非算法背景用户的上手门槛，也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目，它正成为连接通用大模型与行业专有知识之间的重要桥梁。",77062,"2026-04-04T04:44:48",[15,14,13,26,54],{"id":65,"github_repo":66,"name":67,"description_en":68,"description_zh":69,"ai_summary_zh":70,"readme_en":71,"readme_zh":72,"quickstart_zh":73,"use_case_zh":74,"hero_image_url":75,"owner_login":76,"owner_name":77,"owner_avatar_url":78,"owner_bio":79,"owner_company":80,"owner_location":81,"owner_email":82,"owner_twitter":83,"owner_website":84,"owner_url":85,"languages":86,"stars":95,"forks":96,"last_commit_at":97,"license":98,"difficulty_score":23,"env_os":99,"env_gpu":99,"env_ram":99,"env_deps":100,"category_tags":107,"github_topics":108,"view_count":23,"oss_zip_url":80,"oss_zip_packed_at":80,"status":16,"created_at":129,"updated_at":130,"faqs":131,"releases":162},4008,"crmne\u002Fruby_llm","ruby_llm","One beautiful Ruby API for OpenAI, Anthropic, Gemini, Bedrock, Azure, OpenRouter, DeepSeek, Ollama, VertexAI, Perplexity, Mistral, xAI, GPUStack & OpenAI compatible APIs. Agents, Chat, Vision, Audio, PDF, Images, Embeddings, Tools, Streaming & Rails integration.","ruby_llm 是一款专为 Ruby 开发者打造的统一 AI 接口库，旨在简化大语言模型的集成流程。面对市场上 OpenAI、Anthropic、Gemini、Ollama 等众多服务商各自为政、接口差异巨大的现状，ruby_llm 提供了一套优雅且一致的 API，让开发者无需反复适配不同文档，即可轻松切换或同时使用多种模型。\n\n无论是构建智能聊天机器人、开发具备自主能力的 AI Agent，还是实现文档分析、图像识别、音频转录及向量嵌入等功能，ruby_llm 都能通过简洁的代码高效完成。其独特亮点在于极致的轻量化设计，仅依赖三个基础库，却完整支持流式输出、多模态文件处理、自定义工具调用以及结构化数据输出等高级特性。此外，它还深度集成了 Ruby on Rails 框架，方便 Web 开发者快速落地 AI 应用。\n\n这款工具非常适合熟悉 Ruby 语言的软件工程师、初创团队技术负责人以及希望在不增加架构复杂度的前提下引入 AI 能力的开发者。通过 ruby_llm，你可以将原本繁琐的模型对接工作转化为直观的代码逻辑，专注于业务创新而非底层适配，真正体验“两分钟从零构建 AI 应用”","ruby_llm 是一款专为 Ruby 开发者打造的统一 AI 接口库，旨在简化大语言模型的集成流程。面对市场上 OpenAI、Anthropic、Gemini、Ollama 等众多服务商各自为政、接口差异巨大的现状，ruby_llm 提供了一套优雅且一致的 API，让开发者无需反复适配不同文档，即可轻松切换或同时使用多种模型。\n\n无论是构建智能聊天机器人、开发具备自主能力的 AI Agent，还是实现文档分析、图像识别、音频转录及向量嵌入等功能，ruby_llm 都能通过简洁的代码高效完成。其独特亮点在于极致的轻量化设计，仅依赖三个基础库，却完整支持流式输出、多模态文件处理、自定义工具调用以及结构化数据输出等高级特性。此外，它还深度集成了 Ruby on Rails 框架，方便 Web 开发者快速落地 AI 应用。\n\n这款工具非常适合熟悉 Ruby 语言的软件工程师、初创团队技术负责人以及希望在不增加架构复杂度的前提下引入 AI 能力的开发者。通过 ruby_llm，你可以将原本繁琐的模型对接工作转化为直观的代码逻辑，专注于业务创新而非底层适配，真正体验“两分钟从零构建 AI 应用”的高效开发乐趣。","\u003Cdiv align=\"center\">\n\n\u003Cpicture>\n  \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"\u002Fdocs\u002Fassets\u002Fimages\u002Flogotype_dark.svg\">\n  \u003Cimg src=\"\u002Fdocs\u002Fassets\u002Fimages\u002Flogotype.svg\" alt=\"RubyLLM\" height=\"120\" width=\"250\">\n\u003C\u002Fpicture>\n\n\u003Cstrong>One *beautiful* Ruby API for GPT, Claude, Gemini, and more.\u003C\u002Fstrong>\n\nBattle tested at [\u003Cpicture>\u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fchatwithwork.com\u002Flogotype-dark.svg\">\u003Cimg src=\"https:\u002F\u002Fchatwithwork.com\u002Flogotype.svg\" alt=\"Chat with Work\" height=\"30\" align=\"absmiddle\">\u003C\u002Fpicture>](https:\u002F\u002Fchatwithwork.com) — *Your AI coworker*\n\n[![Gem Version](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fruby_llm.svg)](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fruby_llm)\n[![Ruby Style Guide](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fcode_style-rubocop-brightgreen.svg)](https:\u002F\u002Fgithub.com\u002Frubocop\u002Frubocop)\n[![Gem Downloads](https:\u002F\u002Fimg.shields.io\u002Fgem\u002Fdt\u002Fruby_llm)](https:\u002F\u002Frubygems.org\u002Fgems\u002Fruby_llm)\n[![codecov](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fcrmne\u002Fruby_llm\u002Fbranch\u002Fmain\u002Fgraph\u002Fbadge.svg)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fcrmne\u002Fruby_llm)\n\n\u003Ca href=\"https:\u002F\u002Ftrendshift.io\u002Frepositories\u002F13640\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fcrmne_ruby_llm_readme_4a68feb902da.png\" alt=\"crmne%2Fruby_llm | Trendshift\" style=\"width: 250px; height: 55px;\" width=\"250\" height=\"55\"\u002F>\u003C\u002Fa>\n\u003C\u002Fdiv>\n\n> [!NOTE]\n> Using RubyLLM? [Share your story](https:\u002F\u002Ftally.so\u002Fr\u002F3Na02p)! Takes 5 minutes.\n\n---\n\nBuild chatbots, AI agents, RAG applications. Works with OpenAI, xAI, Anthropic, Google, AWS, local models, and any OpenAI-compatible API.\n\n## From zero to AI chat app in under two minutes\n\nhttps:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F65422091-9338-47da-a303-92b918bd1345\n\n## Why RubyLLM?\n\nEvery AI provider ships their own bloated client. Different APIs. Different response formats. Different conventions. It's exhausting.\n\nRubyLLM gives you one beautiful API for all of them. Same interface whether you're using GPT, Claude, or your local Ollama. Just three dependencies: Faraday, Zeitwerk, and Marcel. That's it.\n\n## Show me the code\n\n```ruby\n# Just ask questions\nchat = RubyLLM.chat\nchat.ask \"What's the best way to learn Ruby?\"\n```\n\n```ruby\n# Analyze any file type\nchat.ask \"What's in this image?\", with: \"ruby_conf.jpg\"\nchat.ask \"What's happening in this video?\", with: \"video.mp4\"\nchat.ask \"Describe this meeting\", with: \"meeting.wav\"\nchat.ask \"Summarize this document\", with: \"contract.pdf\"\nchat.ask \"Explain this code\", with: \"app.rb\"\n```\n\n```ruby\n# Multiple files at once\nchat.ask \"Analyze these files\", with: [\"diagram.png\", \"report.pdf\", \"notes.txt\"]\n```\n\n```ruby\n# Stream responses\nchat.ask \"Tell me a story about Ruby\" do |chunk|\n  print chunk.content\nend\n```\n\n```ruby\n# Generate images\nRubyLLM.paint \"a sunset over mountains in watercolor style\"\n```\n\n```ruby\n# Create embeddings\nRubyLLM.embed \"Ruby is elegant and expressive\"\n```\n\n```ruby\n# Transcribe audio to text\nRubyLLM.transcribe \"meeting.wav\"\n```\n\n```ruby\n# Moderate content for safety\nRubyLLM.moderate \"Check if this text is safe\"\n```\n\n```ruby\n# Let AI use your code\nclass Weather \u003C RubyLLM::Tool\n  description \"Get current weather\"\n  param :latitude\n  param :longitude\n\n  def execute(latitude:, longitude:)\n    url = \"https:\u002F\u002Fapi.open-meteo.com\u002Fv1\u002Fforecast?latitude=#{latitude}&longitude=#{longitude}&current=temperature_2m,wind_speed_10m\"\n    JSON.parse(Faraday.get(url).body)\n  end\nend\n\nchat.with_tool(Weather).ask \"What's the weather in Berlin?\"\n```\n\n```ruby\n# Define an agent with instructions + tools\nclass WeatherAssistant \u003C RubyLLM::Agent\n  model \"gpt-5-nano\"\n  instructions \"Be concise and always use tools for weather.\"\n  tools Weather\nend\n\nWeatherAssistant.new.ask \"What's the weather in Berlin?\"\n```\n\n```ruby\n# Get structured output\nclass ProductSchema \u003C RubyLLM::Schema\n  string :name\n  number :price\n  array :features do\n    string\n  end\nend\n\nresponse = chat.with_schema(ProductSchema).ask \"Analyze this product\", with: \"product.txt\"\n```\n\n## Features\n\n* **Chat:** Conversational AI with `RubyLLM.chat`\n* **Vision:** Analyze images and videos\n* **Audio:** Transcribe and understand speech with `RubyLLM.transcribe`\n* **Documents:** Extract from PDFs, CSVs, JSON, any file type\n* **Image generation:** Create images with `RubyLLM.paint`\n* **Embeddings:** Generate embeddings with `RubyLLM.embed`\n* **Moderation:** Content safety with `RubyLLM.moderate`\n* **Tools:** Let AI call your Ruby methods\n* **Agents:** Reusable assistants with `RubyLLM::Agent`\n* **Structured output:** JSON schemas that just work\n* **Streaming:** Real-time responses with blocks\n* **Rails:** ActiveRecord integration with `acts_as_chat`\n* **Async:** Fiber-based concurrency\n* **Model registry:** 800+ models with capability detection and pricing\n* **Extended thinking:** Control, view, and persist model deliberation\n* **Providers:** OpenAI, xAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, and any OpenAI-compatible API\n\n## Installation\n\nAdd to your Gemfile:\n```ruby\ngem 'ruby_llm'\n```\nThen `bundle install`.\n\nConfigure your API keys:\n```ruby\n# config\u002Finitializers\u002Fruby_llm.rb\nRubyLLM.configure do |config|\n  config.openai_api_key = ENV['OPENAI_API_KEY']\nend\n```\n\n## Rails\n\n```bash\n# Install Rails Integration\nbin\u002Frails generate ruby_llm:install\nbin\u002Frails db:migrate\nbin\u002Frails ruby_llm:load_models # v1.13+\n\n# Add Chat UI (optional)\nbin\u002Frails generate ruby_llm:chat_ui\n```\n\n```ruby\nclass Chat \u003C ApplicationRecord\n  acts_as_chat\nend\n\nchat = Chat.create! model: \"claude-sonnet-4\"\nchat.ask \"What's in this file?\", with: \"report.pdf\"\n```\n\nVisit `http:\u002F\u002Flocalhost:3000\u002Fchats` for a ready-to-use chat interface!\n\n## Documentation\n\n[rubyllm.com](https:\u002F\u002Frubyllm.com)\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nReleased under the MIT License.\n","\u003Cdiv align=\"center\">\n\n\u003Cpicture>\n  \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"\u002Fdocs\u002Fassets\u002Fimages\u002Flogotype_dark.svg\">\n  \u003Cimg src=\"\u002Fdocs\u002Fassets\u002Fimages\u002Flogotype.svg\" alt=\"RubyLLM\" height=\"120\" width=\"250\">\n\u003C\u002Fpicture>\n\n\u003Cstrong>一款*简洁美观*的 Ruby API，适用于 GPT、Claude、Gemini 等多种模型。\u003C\u002Fstrong>\n\n已在 [\u003Cpicture>\u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fchatwithwork.com\u002Flogotype-dark.svg\">\u003Cimg src=\"https:\u002F\u002Fchatwithwork.com\u002Flogotype.svg\" alt=\"Chat with Work\" height=\"30\" align=\"absmiddle\">\u003C\u002Fpicture>](https:\u002F\u002Fchatwithwork.com) 经过实战检验——*您的 AI 工作伙伴*\u003C\u002Fp>\n\n[![Gem 版本](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fruby_llm.svg)](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fruby_llm)\n[![Ruby 代码风格](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fcode_style-rubocop-brightgreen.svg)](https:\u002F\u002Fgithub.com\u002Frubocop\u002Frubocop)\n[![Gem 下载量](https:\u002F\u002Fimg.shields.io\u002Fgem\u002Fdt\u002Fruby_llm)](https:\u002F\u002Frubygems.org\u002Fgems\u002Fruby_llm)\n[![Codecov](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fcrmne\u002Fruby_llm\u002Fbranch\u002Fmain\u002Fgraph\u002Fbadge.svg)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fcrmne\u002Fruby_llm)\n\n\u003Ca href=\"https:\u002F\u002Ftrendshift.io\u002Frepositories\u002F13640\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fcrmne_ruby_llm_readme_4a68feb902da.png\" alt=\"crmne%2Fruby_llm | Trendshift\" style=\"width: 250px; height: 55px;\" width=\"250\" height=\"55\"\u002F>\u003C\u002Fa>\n\u003C\u002Fdiv>\n\n> [!NOTE]\n> 您在使用 RubyLLM 吗？[分享您的故事](https:\u002F\u002Ftally.so\u002Fr\u002F3Na02p)吧！只需 5 分钟。\n\n---\n\n构建聊天机器人、AI 助手和 RAG 应用程序。支持 OpenAI、xAI、Anthropic、Google、AWS、本地模型以及任何兼容 OpenAI 的 API。\n\n## 两分钟内从零打造一个 AI 聊天应用\n\nhttps:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F65422091-9338-47da-a303-92b918bd1345\n\n## 为什么选择 RubyLLM？\n\n每个 AI 提供商都提供各自臃肿的客户端，API 不同、响应格式不同、规范也各异，让人应接不暇。\n\n而 RubyLLM 则为您提供一套统一且简洁的 API，无论您使用的是 GPT、Claude 还是本地的 Ollama，接口都保持一致。仅需三个依赖：Faraday、Zeitwerk 和 Marcel，简单明了。\n\n## 让我们看看代码吧\n\n```ruby\n# 直接提问\nchat = RubyLLM.chat\nchat.ask \"学习 Ruby 的最佳方法是什么？\"\n```\n\n```ruby\n# 分析任意文件类型\nchat.ask \"这张图片里有什么？\", with: \"ruby_conf.jpg\"\nchat.ask \"这段视频讲了什么？\", with: \"video.mp4\"\nchat.ask \"请描述这次会议的内容。\", with: \"meeting.wav\"\nchat.ask \"请总结这份合同。\", with: \"contract.pdf\"\nchat.ask \"请解释这段代码。\", with: \"app.rb\"\n```\n\n```ruby\n# 同时处理多个文件\nchat.ask \"分析这些文件。\", with: [\"diagram.png\", \"report.pdf\", \"notes.txt\"]\n```\n\n```ruby\n# 流式响应\nchat.ask \"给我讲个关于 Ruby 的故事。\" do |chunk|\n  print chunk.content\nend\n```\n\n```ruby\n# 生成图片\nRubyLLM.paint \"一幅水彩风格的山间日落图\"\n```\n\n```ruby\n# 创建嵌入向量\nRubyLLM.embed \"Ruby 语言优雅而富有表现力。\"\n```\n\n```ruby\n# 将音频转录为文本\nRubyLLM.transcribe \"meeting.wav\"\n```\n\n```ruby\n# 内容安全审核\nRubyLLM.moderate \"请检查这段文字是否安全。\"\n```\n\n```ruby\n# 让 AI 使用您的代码\nclass Weather \u003C RubyLLM::Tool\n  description \"获取当前天气\"\n  param :latitude\n  param :longitude\n\n  def execute(latitude:, longitude:)\n    url = \"https:\u002F\u002Fapi.open-meteo.com\u002Fv1\u002Fforecast?latitude=#{latitude}&longitude=#{longitude}&current=temperature_2m,wind_speed_10m\"\n    JSON.parse(Faraday.get(url).body)\n  end\nend\n\nchat.with_tool(Weather).ask \"柏林现在的天气如何？\"\n```\n\n```ruby\n# 定义带有指令和工具的智能体\nclass WeatherAssistant \u003C RubyLLM::Agent\n  model \"gpt-5-nano\"\n  instructions \"言简意赅，始终使用工具查询天气。\"\n  tools Weather\nend\n\nWeatherAssistant.new.ask \"柏林的天气怎么样？\"\n```\n\n```ruby\n# 获取结构化输出\nclass ProductSchema \u003C RubyLLM::Schema\n  string :name\n  number :price\n  array :features do\n    string\n  end\nend\n\nresponse = chat.with_schema(ProductSchema).ask \"请分析这款产品。\", with: \"product.txt\"\n```\n\n## 核心功能\n\n* **对话:** 基于 `RubyLLM.chat` 的对话式 AI\n* **视觉:** 分析图像和视频\n* **音频:** 使用 `RubyLLM.transcribe` 转录并理解语音\n* **文档:** 从 PDF、CSV、JSON 等任意文件中提取信息\n* **图像生成:** 使用 `RubyLLM.paint` 创建图片\n* **嵌入:** 使用 `RubyLLM.embed` 生成嵌入向量\n* **内容审核:** 使用 `RubyLLM.moderate` 进行内容安全检测\n* **工具:** 让 AI 调用您的 Ruby 方法\n* **智能体:** 使用 `RubyLLM::Agent` 构建可复用的助手\n* **结构化输出:** 即开即用的 JSON 模式\n* **流式传输:** 支持块级实时响应\n* **Rails:** 通过 `acts_as_chat` 集成 ActiveRecord\n* **异步:** 基于 Fiber 的并发机制\n* **模型注册中心:** 汇集 800 多种模型，具备能力检测与定价功能\n* **扩展思考:** 控制、查看及持久化模型推理过程\n* **多提供商支持:** OpenAI、xAI、Anthropic、Gemini、VertexAI、Bedrock、DeepSeek、Mistral、Ollama、OpenRouter、Perplexity、GPUStack，以及任何兼容 OpenAI 的 API\n\n## 安装\n\n将以下内容添加到您的 Gemfile：\n```ruby\ngem 'ruby_llm'\n```\n然后运行 `bundle install`。\n\n配置您的 API 密钥：\n```ruby\n# config\u002Finitializers\u002Fruby_llm.rb\nRubyLLM.configure do |config|\n  config.openai_api_key = ENV['OPENAI_API_KEY']\nend\n```\n\n## Rails 集成\n\n```bash\n# 安装 Rails 集成\nbin\u002Frails generate ruby_llm:install\nbin\u002Frails db:migrate\nbin\u002Frails ruby_llm:load_models # v1.13+\n```\n\n```ruby\nclass Chat \u003C ApplicationRecord\n  acts_as_chat\nend\n\nchat = Chat.create!(model: \"claude-sonnet-4\")\nchat.ask \"这份报告里写了什么？\", with: \"report.pdf\"\n```\n\n访问 `http:\u002F\u002Flocalhost:3000\u002Fchats`，即可获得开箱即用的聊天界面！\n\n## 文档\n\n[rubyllm.com](https:\u002F\u002Frubyllm.com)\n\n## 贡献\n\n详情请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。\n\n## 许可证\n\n采用 MIT 许可协议发布。","# RubyLLM 快速上手指南\n\nRubyLLM 是一个优雅的 Ruby API，统一封装了 GPT、Claude、Gemini 等主流大模型。它让你无需关心不同厂商的 API 差异，仅需极少的依赖即可构建聊天机器人、AI 代理和 RAG 应用。\n\n## 环境准备\n\n*   **系统要求**: 支持 macOS、Linux 及 Windows (WSL)。\n*   **Ruby 版本**: 建议 Ruby 3.1 或更高版本。\n*   **前置依赖**: 无需额外安装系统级依赖，Gem 会自动处理核心依赖（Faraday, Zeitwerk, Marcel）。\n*   **API 密钥**: 需提前准备好对应模型服务商的 API Key（如 OpenAI, Anthropic, Google 等）。\n\n> **提示**：国内开发者若访问 RubyGems 源较慢，可临时切换至国内镜像源：\n> ```bash\n> gem sources --add https:\u002F\u002Fgems.ruby-china.com\u002F --remove https:\u002F\u002Frubygems.org\u002F\n> ```\n\n## 安装步骤\n\n### 1. 添加依赖\n在你的项目 `Gemfile` 中添加：\n\n```ruby\ngem 'ruby_llm'\n```\n\n### 2. 安装 Gem\n执行以下命令安装：\n\n```bash\nbundle install\n```\n\n### 3. 配置 API 密钥\n在初始化文件（如 `config\u002Finitializers\u002Fruby_llm.rb` 或项目入口文件）中配置密钥：\n\n```ruby\nRubyLLM.configure do |config|\n  config.openai_api_key = ENV['OPENAI_API_KEY']\n  # 如需使用其他模型，也可配置对应 key，例如：\n  # config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']\nend\n```\n\n## 基本使用\n\n### 最简单的对话示例\n只需三行代码即可发起对话：\n\n```ruby\nchat = RubyLLM.chat\nresponse = chat.ask \"What's the best way to learn Ruby?\"\nputs response.content\n```\n\n### 多模态能力（图片\u002F文件分析）\n直接传入文件路径即可让 AI 分析图片、视频、音频或文档：\n\n```ruby\nchat.ask \"What's in this image?\", with: \"ruby_conf.jpg\"\nchat.ask \"Summarize this document\", with: \"contract.pdf\"\n```\n\n### 流式输出\n通过代码块实时获取回复内容：\n\n```ruby\nchat.ask \"Tell me a story about Ruby\" do |chunk|\n  print chunk.content\nend\n```\n\n### 调用自定义工具 (Tools)\n让 AI 调用你的 Ruby 方法（例如查询天气）：\n\n```ruby\nclass Weather \u003C RubyLLM::Tool\n  description \"Get current weather\"\n  param :latitude\n  param :longitude\n\n  def execute(latitude:, longitude:)\n    url = \"https:\u002F\u002Fapi.open-meteo.com\u002Fv1\u002Fforecast?latitude=#{latitude}&longitude=#{longitude}&current=temperature_2m,wind_speed_10m\"\n    JSON.parse(Faraday.get(url).body)\n  end\nend\n\nchat.with_tool(Weather).ask \"What's the weather in Berlin?\"\n```\n\n### Rails 集成（可选）\n如果你使用的是 Rails 项目，可以使用生成器快速集成：\n\n```bash\nbin\u002Frails generate ruby_llm:install\nbin\u002Frails db:migrate\nbin\u002Frails generate ruby_llm:chat_ui\n```\n\n然后在 Model 中启用：\n\n```ruby\nclass Chat \u003C ApplicationRecord\n  acts_as_chat\nend\n\nchat = Chat.create! model: \"claude-sonnet-4\"\nchat.ask \"What's in this file?\", with: \"report.pdf\"\n```\n\n启动服务器后访问 `http:\u002F\u002Flocalhost:3000\u002Fchats` 即可使用内置的聊天界面。","一家电商初创公司的 Ruby 后端团队，正急需为客服系统构建一个能同时处理用户上传图片、订单 PDF 及实时天气查询的智能助手。\n\n### 没有 ruby_llm 时\n- **多厂商适配痛苦**：团队需分别引入 OpenAI、Anthropic 和 AWS Bedrock 的官方重型 SDK，代码中充斥着三种完全不同的 API 调用方式和响应解析逻辑。\n- **多模态开发繁琐**：想要让 AI“看懂”用户上传的商品瑕疵图或读取订单 PDF，需要手动编写复杂的文件编码、Base64 转换及特定格式构造代码。\n- **功能扩展困难**：实现“查询当地天气以解答物流延迟”这类工具调用（Tool Use）时，需深入阅读各厂商文档来定义函数结构，调试成本极高。\n- **维护负担重**：一旦某个模型供应商更新接口规范，整个项目的多处依赖代码都需要同步修改，极易引发线上故障。\n\n### 使用 ruby_llm 后\n- **统一优雅接口**：无论底层切换为 Claude、GPT 还是本地 Ollama 模型，团队只需使用 `RubyLLM.chat` 这一套简洁的 Ruby 风格 API，彻底抹平厂商差异。\n- **原生多模态支持**：直接传入图片文件或 PDF 路径（如 `chat.ask \"检查此图\", with: \"error.jpg\"`），ruby_llm 自动处理底层数据格式化，让 AI 瞬间具备视觉与文档理解力。\n- **极简工具定义**：通过继承 `RubyLLM::Tool` 类即可用纯 Ruby 代码定义天气查询工具，框架自动将其转换为模型可理解的格式，大幅降低 Agent 开发门槛。\n- **轻量灵活集成**：仅依赖 Faraday 等三个轻量库，无缝融入现有 Rails 项目，后续更换模型提供商只需修改配置行，无需重构业务逻辑。\n\nruby_llm 让 Ruby 开发者能用最地道的语言风格，在几分钟内构建出支持多模态、多模型且具备工具调用能力的生产级 AI 应用。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fcrmne_ruby_llm_5e2f8d3b.png","crmne","Carmine Paolino","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fcrmne_aebf1f58.png","Building Chat with Work, RubyLLM and more. Co-founded @freshflowai. Tech enthusiast, music producer, and photographer.",null,"Berlin, Germany","carmine@paolino.me","paolino","https:\u002F\u002Fpaolino.me","https:\u002F\u002Fgithub.com\u002Fcrmne",[87,91],{"name":88,"color":89,"percentage":90},"Ruby","#701516",100,{"name":92,"color":93,"percentage":94},"Shell","#89e051",0,3814,413,"2026-04-05T13:42:58","MIT","未说明",{"notes":101,"python":102,"dependencies":103},"这是一个 Ruby Gem 库，非 Python 工具。运行需要 Ruby 环境。支持连接本地模型（如 Ollama）或云端 API（OpenAI, Anthropic 等），自身不直接运行大型模型，因此无特定 GPU\u002F显存硬性要求，具体取决于所连接的后端服务。","不适用 (基于 Ruby)",[104,105,106],"faraday","zeitwerk","marcel",[13,14,15,26],[109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128],"llm","ruby","ai","anthropic","chatgpt","claude","embeddings","gemini","image-generation","openai","rails","deepseek","mistral","ollama","openrouter","perplexity","vertex-ai","gpustack","xai","agents","2026-03-27T02:49:30.150509","2026-04-06T07:11:18.979521",[132,137,142,147,152,157],{"id":133,"question_zh":134,"answer_zh":135,"source_url":136},18261,"如何启用结构化输出（Structured Output）支持？","RubyLLM 已原生支持结构化输出。你可以使用新的 `with_schema` 方法，该方法接受 `RubyLLM::Schema` 对象或纯 JSON Schema。\n\n主要特性包括：\n1. **自动 JSON 解析**：当激活 Schema 时，响应会自动解析。\n2. **提供商特定实现**：OpenAI 使用 `response_format.type: \"json_schema\"`，Gemini 使用 `responseSchema`。\n3. **强制模式**：如果模型不支持结构化输出，默认会抛出 `UnsupportedStructuredOutputError`，但可以使用 `force: true` 标志绕过检查。\n\n示例代码：\n```ruby\nclass PersonSchema \u003C RubyLLM::Schema\n  string :name\n  integer :age\n  string :email, required: false\nend\n\nchat = RubyLLM.chat\n# 使用定义的 Schema\nresponse = chat.with_schema(PersonSchema).ask(\"生成一个名为 John 的人\")\n# 或者强制模式\nresponse = chat.with_schema(PersonSchema, force: true).ask(\"...\")\n```","https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fissues\u002F11",{"id":138,"question_zh":139,"answer_zh":140,"source_url":141},18262,"是否支持 MCP (Model Context Protocol)？","RubyLLM 核心库暂无计划直接集成 MCP，因为 MCP 属于协议层，更适合独立的专注库。\n\n官方推荐使用社区维护的 **[ruby_llm-mcp](https:\u002F\u002Fgithub.com\u002Fpatvice\u002Fruby_llm-mcp)** gem，它可以与 RubyLLM 无缝组合使用。该方案允许你连接到 MCP 服务器并透明地使用其工具。\n\n使用示例：\n```ruby\nrequire 'ruby_llm\u002Fmcp'\n\n# 连接到 MCP 服务器\nclient = RubyLLM::MCP.client(\n  name: \"my-mcp-server\",\n  transport_type: \"sse\", \n  config: { url: \"http:\u002F\u002Flocalhost:9292\u002Fmcp\u002Fsse\" }\n)\n\n# 将 MCP 工具传递给聊天对象\nchat = RubyLLM.chat\nchat.with_tools(*client.tools)\n```\n这种架构保持了 RubyLLM 专注于 LLM 通信，同时通过组合实现了 MCP 功能。","https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fissues\u002F77",{"id":143,"question_zh":144,"answer_zh":145,"source_url":146},18263,"如何配置自定义 API 端点或使用未在列表中的模型（如本地代理或新模型）？","你可以通过以下方式配置自定义端点和未列出的模型：\n\n1. **配置自定义端点（用于代理）**：\n   在初始化配置中设置 `openai_api_base`（或其他提供商对应的 base）：\n   ```ruby\n   RubyLLM.configure do |config|\n     config.openai_api_key = ENV['OPENAI_API_KEY']\n     config.openai_api_base = \"https:\u002F\u002Fyour-proxy.example.com\"\n   end\n   ```\n\n2. **使用未注册的模型名称**：\n   如果模型不在 `models.json` 中（例如最新的预览版模型或自定义部署名），可以使用 `assume_model_exists: true` 参数跳过验证：\n   ```ruby\n   chat = RubyLLM.chat(\n     model: \"gpt-5-preview\",  # 或你的自定义部署名\n     provider: :openai,\n     assume_model_exists: true\n   )\n   ```\n   这既保证了默认行为的安全性，又为高级用户提供了灵活性。","https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fissues\u002F9",{"id":148,"question_zh":149,"answer_zh":150,"source_url":151},18264,"AWS Bedrock 支持哪些模型？为什么我使用非 Anthropic 模型时报错？","目前 RubyLLM 对 AWS Bedrock 的支持主要集中在 Anthropic 模型上。\n\n如果你尝试使用 Bedrock 上的其他模型（如 `gemma-3-12b` 或非 Anthropic 系列），可能会遇到 `RubyLLM::ModelNotFoundError` 错误。这是因为当前的实现可能尚未完全覆盖 Bedrock 提供的所有基础模型家族。\n\n建议：\n- 确认你使用的模型是否在官方支持的列表中。\n- 关注相关 PR（如 #377）以获取对其他 Bedrock 模型的支持进展。\n- 如果急需使用特定非 Anthropic 模型，可能需要等待后续更新或通过自定义端点方式尝试（如果该模型兼容 OpenAI 接口）。","https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fissues\u002F16",{"id":153,"question_zh":154,"answer_zh":155,"source_url":156},18265,"遇到“多个同时工具调用导致错误”或“text content blocks must be non-empty”报错怎么办？","这是一个已知问题，通常发生在 LLM 返回多个工具调用时，RubyLLM 在处理中间回调时可能出现异常。\n\n**临时解决方案**：\n在提示词（Prompt）中明确要求模型在每次工具调用后说明执行情况，这有助于稳定流程：\n> \"ALWAYS tell me what you did after each tool call.\"\n\n**注意事项**：\n- 该问题在某些环境（如 staging 服务器）或使用流式传输（streaming）配合特定模型（如 Claude 3.7 Sonnet）时更容易复现。\n- 如果问题持续，请确保升级到最新版本，因为维护者正在持续修复多工具调用的聚合逻辑（预期行为是聚合所有结果后再回调 LLM）。","https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fissues\u002F236",{"id":158,"question_zh":159,"answer_zh":160,"source_url":161},18266,"升级 gem 版本后出现 'Undefined local variable or method acts_as_model' 错误如何解决？","此错误通常发生在从旧版本（如 1.3.x）升级到新版本（如 1.7.0）时，数据库迁移生成的模型文件缺少必要的依赖或加载顺序问题。\n\n**解决步骤**：\n1. 确保已正确运行升级生成器：\n   ```bash\n   bundle update ruby_llm\n   rails generate ruby_llm:upgrade_to_v1_7\n   rails db:migrate\n   ```\n2. 检查生成的 `app\u002Fmodels\u002Fmodel.rb` 文件，确认包含 `acts_as_model`。\n3. 如果报错依旧，可能是由于 `models.json` 加载时机早于模型类定义，或者 gem 内部变更导致宏方法未注入。\n   - 尝试重启 Rails 服务器或控制台。\n   - 确认 `Gemfile` 中已锁定正确的版本。\n   - 如果是在迁移过程中报错，检查是否需要在 `config\u002Fapplication.rb` 或相关 initializer 中提前引入 RubyLLM 的 ActiveRecord 扩展。\n\n*注：这是一个破坏性更新带来的常见问题，建议仔细阅读版本的 CHANGELOG 以获取特定的迁移指南。*","https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fissues\u002F400",[163,168,173,178,183,188,193,198,203,208,213,218,223,228,233,238,243,248,253,258],{"id":164,"version":165,"summary_zh":166,"released_at":167},108795,"1.14.1","# RubyLLM 1.14.1：精简提供商代码 + ActiveStorage 修复 🔧🐛\n\n这是一个补丁版本，旨在精简提供商代码、修复 ActiveStorage Blob 的重新上传问题，并更新模型注册表。\n\n## 🏗️ 更精简的提供商模型回退逻辑\n\n提供商的 `Capabilities` 模块不再包含数百行硬编码的价格、上下文窗口和功能标志。这些值现在都来自模型注册表（`models.json`），而 Ruby 回退代码也已精简至仅保留提供商级别真正需要的字段（例如 `supports_tool_choice?`）。这使得 Anthropic、OpenAI、Gemini、DeepSeek 和 Perplexity 等提供商的代码量净减少了约 400 行，并确保注册表成为模型元数据的唯一可信来源。\n\n对您而言，这意味着今后的能力和定价将更加准确。\n\n## 🐛 修复：ActiveStorage::Blob 重新上传问题\n\n当通过 `with:` 参数将 `ActiveStorage::Blob` 传递给 `ask` 或 `create_user_message` 时，该 Blob 会被下载并作为新 Blob 重新上传。现在，系统会检测并直接复用现有 Blob，从而避免不必要的存储操作。修复了 #665 问题。\n\n## 📦 更新的模型注册表\n\n模型注册表已更新为所有提供商提供的最新可用模型。\n\n## 📝 文档\n\n修正了审核指南中的一个拼写错误（“Patters” → “Patterns”）。\n\n## 安装\n\n```ruby\ngem \"ruby_llm\", \"1.14.1\"\n```\n\n## 从 1.14.0 升级\n\n```bash\nbundle update ruby_llm\n```\n\n## 已合并的 PR\n* @bubiche 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F683 中修复了在 `with:` 参数中使用 `ActiveStorage::Blob` 时的重新上传问题。\n* @artinboghosian 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F703 中更新了 moderation.md 文件。\n\n## 新贡献者\n* @bubiche 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F683 中完成了首次贡献。\n* @artinboghosian 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F703 中完成了首次贡献。\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.14.0...1.14.1","2026-04-02T12:25:30",{"id":169,"version":170,"summary_zh":171,"released_at":172},108796,"1.14.0","# RubyLLM 1.14：Tailwind 聊天 UI + Rails AI 生成器 + 配置 DSL 🎨🤖🛠️\n\n本次发布彻底革新了 Rails 开发体验。\n\nRubyLLM `1.14` 带来了一个完整的、基于 Tailwind 的聊天 UI，全新的 Rails 生成器用于创建智能体、工具和模式定义，以及一个简化的配置 DSL——提供商可自行注册其配置选项；此外还修复了日志记录、智能体、关联关系和依赖约束等方面的一系列问题。\n\n## 🎨 Tailwind 聊天 UI\n\n![Tailwind Chat UI](https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F65422091-9338-47da-a303-92b918bd1345)\n\nRails 聊天 UI 生成器现在开箱即用地提供一个精美的 Tailwind 驱动界面。只需运行该生成器，即可获得一个可工作的聊天应用，支持消息流式传输、模型选择、工具调用展示以及合理的空状态提示——所有这些都由 Tailwind CSS 进行样式化。\n\n```bash\nbin\u002Frails generate ruby_llm:chat_ui\n```\n\n生成的视图使用基于角色的局部模板（`_user`、`_assistant`、`_system`、`_tool`、`_error`），以实现干净的消息渲染；利用 Turbo Stream 模板实现实时更新，并通过 `broadcasts_to` 简化广播逻辑。\n\n## 🏗️ Rails AI 生成器\n\n新增的生成器可通过一条命令快速搭建智能体、工具和模式定义：\n\n```bash\nbin\u002Frails generate ruby_llm:agent SupportAgent\nbin\u002Frails generate ruby_llm:tool WeatherTool\n```\n\n安装生成器现在会创建符合惯例的目录结构（`app\u002Fagents`、`app\u002Ftools`、`app\u002Fschemas`、`app\u002Fprompts`），并附带 `.gitkeep` 文件。工具部分采用了新的命名规范，用于特定于工具的渲染，同时生成器还会一并生成相应的测试用例。\n\n## ⚙️ 简化的配置 DSL\n\n各提供商的配置选项现可通过声明式的 `configuration_options` 方法自动注册，取代了之前在 `Configuration` 中采用的单一大列表式 `attr_accessor` 定义。当某个提供商被注册后，其配置选项将自动成为 `RubyLLM::Configuration` 上的 `attr_accessor` 属性。\n\n每个提供商均按照 `\u003Cprovider_slug>_\u003Coption>` 的命名规范声明自己的选项键：\n\n```ruby\n# 在提供商类中：\nclass DeepSeek \u003C RubyLLM::Provider\n  class \u003C\u003C self\n    def configuration_options\n      %i[deepseek_api_key deepseek_api_base]\n    end\n  end\nend\n\n# 这些选项随即在配置中可用：\nRubyLLM.configure do |config|\n  config.deepseek_api_key  = ENV[\"DEEPSEEK_API_KEY\"]\n  config.deepseek_api_base = ENV[\"DEEPSEEK_API_BASE\"]\nend\n```\n\n这意味着第三方提供商的 gem 可以自行注册其配置键，而无需对 `Configuration` 进行任何修改。\n\n## 🐛 修复内容\n\n### Faraday 日志记录导致的内存膨胀\n\n当日志级别高于 DEBUG 时，Faraday 不再序列化大型负载（例如 Base64 编码的 PDF 文件）。此举避免了每次请求时不必要的内存分配，解决了 #562 问题。\n\n### gemspec 中 Faraday 版本约束回归\n\n修复了 gemspec 中过于严格的 Faraday 版本约束问题，该问题曾导致部分用户的兼容性故障。解决了 #682 问题。\n\n### 智能体 `assume_model_exists` 配置的传播\n\n智能体类级别的 `assume_model_exists` 配置现已正确传播……","2026-03-16T21:10:24",{"id":174,"version":175,"summary_zh":176,"released_at":177},108797,"1.13.2","# RubyLLM 1.13.2：模式与流式传输的补丁修复 🐛🔧\n\n这是一个包含三项修复的小型补丁版本。\n\n## 🧩 修复：模式名称始终兼容 OpenAI\n\n现在，模式名称始终会生成适用于 OpenAI 的有效 `response_format.json_schema.name`：\n\n- 带命名空间的名称（如 `MyApp::Schema`）会被规范化处理；\n- 空名称则安全地回退为 `response`。\n\n修复了 #654。\n\n## 🌊 修复：流式传输会忽略非哈希格式的 SSE 负载\n\n流式传输处理器现在会在调用提供商的分块构建器之前，跳过非哈希格式的 JSON 负载（例如 `true`），从而避免 Anthropic 流式传输中的间歇性崩溃。\n\n修复了 #656。\n\n## 🗓️ 修复：models.dev 的 `created_at` 日期处理\n\n改进了在填充 `created_at` 元数据时，对缺失 `models.dev` 日期的处理。\n\n## 安装\n\n```ruby\ngem \"ruby_llm\", \"1.13.2\"\n```\n\n## 从 1.13.1 升级\n\n```bash\nbundle update ruby_llm\n```\n\n## 已合并的 PR\n* 由 @afurm 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F652 中提交的修复：为 `created_at` 元数据添加对缺失 models.dev 日期的处理。\n* [BUG] 由 @alexey-hunter-io 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F655 中提交的修复：修复模式名称的规范化处理，以确保与 OpenAI API 兼容。\n* 由 @crmne 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F657 中提交的修复：修复 Anthropic 流式传输在遇到非哈希格式 SSE 负载时的崩溃问题。\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.13.1...1.13.2","2026-03-05T10:26:10",{"id":179,"version":180,"summary_zh":181,"released_at":182},108798,"1.13.1","# RubyLLM 1.13.1：快速修复 🐛🔧\n\n这是一个包含三项修复的小型补丁版本。\n\n## 🧩 修复：Schema + 工具调用不再崩溃\n\n同时使用 `with_schema` 和 `with_tool` 时，会导致中间的工具调用响应被提前进行 JSON 解析，从而在下一次 API 调用时引发崩溃。RubyLLM 现在仅对最终的响应内容进行解析。修复了 #649。\n\n## 📊 Gemini：缓存 token 使用量\n\nGemini 的响应现在会为常规响应和流式响应都填充 `cached_tokens`。\n\n## 🪟 修复：Windows 上的二进制附件读取问题\n\n基于路径的附件现在使用 `File.binread` 而不是 `File.read`，以防止在 Windows 上以文本模式截断二进制文件。\n\n## 安装\n\n```ruby\ngem \"ruby_llm\", \"1.13.1\"\n```\n\n## 从 1.13.0 升级\n\n```bash\nbundle update ruby_llm\n```\n\n## 已合并的 PR\n* @trouni 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F650 中修复了中间工具调用响应的 Schema JSON 解析问题\n\n## 新贡献者\n* @trouni 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F650 中做出了首次贡献\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.13.0...1.13.1","2026-03-04T11:54:52",{"id":184,"version":185,"summary_zh":186,"released_at":187},108799,"1.13.0","# RubyLLM 1.13：大量修复 + 大量合并的 PR 🎉🤖🛠️\n\n这是一个重要的稳定性版本。\n\nRubyLLM `1.13.0` 带来了非常全面的可靠性修复和生产级优化，覆盖了工具调用、结构化输出、提供商配置、重试与错误分类、Rails 生成器以及代理生命周期行为等多个方面。\n\n此外，本轮发布还合并了许多来自社区的 PR。\n\n## 亮点\n\n## 🛠️ 工具调用：更精细的控制 + 更好的实际场景错误处理\n\nRubyLLM 现在支持内置的工具控制参数，并对边缘情况进行了更好的处理。\n\n通过两个选项来控制工具的行为：\n\n- `choice` 用于控制是否以及如何调用工具（`:auto`、`:none`、`:required`，或指定某个特定工具）\n- `calls` 用于控制模型在单次助手响应中可以返回一个还是多个工具调用（`:one` \u002F `:many`），即“并行”工具调用\n- 现在，无效的关键字参数以及幻觉或不可用的工具调用会被作为工具错误返回给模型，以便模型能够恢复并重试（而不是抛出应用异常）\n- 修复了流式工具调用中的空参数处理问题，以及助手工具调用消息内容为空的情况，从而确保工具调用记录在多轮对话中始终保持有效。\n\n```ruby\nchat = RubyLLM.chat(model: \"gpt-5-nano\")\n  .with_tools(WeatherTool, CalculatorTool, choice: :required, calls: :one)\n\nresponse = chat.ask(\"使用工具估算通勤时间和费用\")\nputs response.content\n```\n\n### 工具选择 (`choice`)\n\n使用 `choice` 来控制模型是否可以调用工具，以及可以调用哪些工具。\n\n```ruby\n# 模型自行决定是否调用工具\nchat.with_tools(WeatherTool, CalculatorTool, choice: :auto)\n\n# 模型必须调用提供的工具之一\nchat.with_tools(WeatherTool, CalculatorTool, choice: :required)\n\n# 禁用工具调用\nchat.with_tools(WeatherTool, CalculatorTool, choice: :none)\n\n# 强制调用某个特定工具\nchat.with_tools(WeatherTool, CalculatorTool, choice: :weather_tool)\n```\n\n有效值：\n- `:auto`\n- `:required`\n- `:none`\n- 工具名称符号\u002F字符串，或 `ToolClass`\n\n### “并行”工具调用控制 (`calls`)\n\n使用 `calls` 来控制模型在单次助手响应中可以返回多少个工具调用。\n\n提供商通常将这种行为称为“并行工具调用”。我们称之为 `calls`，是因为“并行”可能会产生误解：除非你的工具执行器本身是并行化的，否则工具并不会真正并行执行。而 `calls` 则直接描述了响应的行为。\n\n```ruby\n# 提供商\u002F模型的默认行为\nchat = RubyLLM.chat.with_tools(WeatherTool, CalendarTool)\n\n# 允许在一次助手响应中返回多个工具调用\nchat = RubyLLM.chat.with_tools(WeatherTool, CalendarTool, calls: :many)\n\n# 允许在一次助手响应中返回一个工具调用\nchat = RubyLLM.chat.with_tools(WeatherTool, CalendarTool, calls: :one)\n\n# 等价写法：\nchat = RubyLLM.chat.with_tools(WeatherTool, CalendarTool, calls: 1)\n```\n\n有效值：\n- `:many`\n- `:one`\n- `1`\n\n如果未提供 `calls`，RubyLLM 将使用","2026-03-03T14:18:51",{"id":189,"version":190,"summary_zh":191,"released_at":192},108800,"1.12.1","# RubyLLM 1.12.1：代理 API 委托 + Rails `add_message` 持久化 + 依赖兼容性 🎉🤖🛠️\n\n这是一次专注的补丁版本发布。\n\nRubyLLM `1.12.1` 进一步规范了 Agent 的行为，修复了 Rails 聊天会话中 `add_message` 的持久化问题，并放宽了依赖约束以提升兼容性。\n\n## 🤖 代理 API：通过 `Forwardable` 完全委托 `Chat` 接口\n\n现在，Agent 会利用 Ruby 的 `Forwardable` 模块，将 `RubyLLM::Chat` 实例的完整 API 委托给被包装的聊天对象。\n\n这一改进也修复了 PORO 中出现的 `undefined method 'delegate' for class RubyLLM::Agent` 错误。\n\n被委托的方法现在包括核心访问器以及流畅的配置方法，例如：\n\n- `model`、`messages`、`tools`、`params`、`headers`、`schema`\n- `ask`、`say`、`complete`、`add_message`、`reset_messages!`\n- `with_model`、`with_tools`、`with_params`、`with_headers`、`with_schema` 等。\n\n```ruby\nagent = WorkAssistant.new\nagent.with_model(\"gpt-5-nano\")\nagent.add_message(role: :user, content: \"请总结一下这个话题\")\nresponse = agent.complete\n```\n\n## Rails：`Chat#add_message` 现已正确持久化\n\n基于 Rails 的聊天会话现在在使用 `add_message` 方法时能够正确持久化消息（而不仅限于 `ask` 或旧有流程）。\n\n```ruby\nchat = Chat.find(params[:chat_id])\nchat.add_message(role: :user, content: params[:content]) # 现已持久化\n```\n\n此次修复还包括以下内容：\n\n- 新增消息的工具调用关联关系持久化\n- 附件与内容持久化的处理优化\n- `create_user_message` 仍作为兼容性封装（遗留且已废弃的路径）\n\n## 📎 Rails 多部分输入的附件健壮性\n\n`RubyLLM::Content` 现在会忽略 Rails 多部分数组中空白或空值的附件占位项，从而避免因附件包含空值而导致的冗余错误。\n\n## 📦 依赖兼容性更新\n\n为减少不必要的版本锁定带来的摩擦，更新了依赖约束：\n\n- `ruby_llm-schema`：`~> 0.2.1` → `~> 0`\n- `marcel`：`~> 1.0` → `~> 1`\n\n## 安装\n\n```ruby\ngem \"ruby_llm\", \"1.12.1\"\n```\n\n## 从 1.12.0 升级\n\n```bash\nbundle update ruby_llm\n```\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.12.0...1.12.1","2026-02-19T16:40:52",{"id":194,"version":195,"summary_zh":196,"released_at":197},108801,"1.12.0","# RubyLLM 1.12：智能体 + 全面云服务商支持 + 新指令语义与贡献者指南 🎉🤖☁️\n\n这是一次重大更新。\n\nRubyLLM 1.12 引入了全新的智能体接口，并实现了对各大云服务商的全面覆盖：\n\n* 通过 Vertex AI 实现 GCP 支持（已支持）\n* 新增：通过 Bedrock Converse API 实现完整的 AWS 支持\n* 新增：通过 Azure AI Foundry API 实现完整的 Azure 支持\n\n## 🤖 新智能体接口\n\n智能体现在成为定义可重用 AI 行为的一流方式，只需一次定义，即可在任何地方使用。\n\n```ruby\nclass WorkAssistant \u003C RubyLLM::Agent\n  chat_model Chat\n  model \"gpt-4.1-nano\"\n  instructions \"你是一位简洁的工作助手。\"\n  tools TodoTool, GoogleDriveSearchTool\nend\n```\n\n可以直接使用：\n\n```ruby\nresponse = WorkAssistant.new.ask(\"我今天应该做些什么？\")\n```\n\n或者结合 Rails 后端的聊天功能：\n\n```ruby\nchat = WorkAssistant.create!(user: current_user)\nWorkAssistant.find(chat.id).complete\n```\n\n内置了提示约定（`app\u002Fprompts\u002F\u003Cagent_name>\u002Finstructions.txt.erb`）。\n\n更多关于智能体的信息：https:\u002F\u002Frubyllm.com\u002Fagents\n\n## ☁️ Bedrock Converse API：全面覆盖 Bedrock\n\nRubyLLM 现在采用 Bedrock Converse API，这意味着所有 Bedrock 聊天模型都可以通过统一的接口进行调用。\n\n```ruby\nchat = RubyLLM.chat(\n  model: \"anthropic.claude-haiku-4-5-20251001-v1:0\",\n  provider: :bedrock\n)\n\nresponse = chat.ask(\"请给我三个降低 API 延迟的建议。\")\n```\n\n只要能在 Bedrock 上运行，RubyLLM 就能与其交互。\n\n## ☁️ 支持 Azure Foundry API\n\nRubyLLM 现在支持 Azure Foundry AI，让您能够以相同的 RubyLLM 接口，在 Azure 平台上广泛访问各类模型。\n\n```ruby\nRubyLLM.configure do |config|\n  config.azure_api_key = ENV[\"AZURE_API_KEY\"]\n  config.azure_api_base = ENV[\"AZURE_API_BASE\"]\nend\n\nchat = RubyLLM.chat(model: \"gpt-4.1\", provider: :azure)\nresponse = chat.ask(\"请用一段话概括这个架构。\")\n```\n\n同样的 API，覆盖 Azure 全域的模型资源。\n\n## 🧠 指令语义优化\n\n`with_instructions` 的行为现在更加清晰：\n\n* 默认调用会替换当前的系统指令\n* 追加行为明确无误\n* 指令始终在其他消息之前发送\n\n```ruby\nchat.with_instructions(\"你说话要简洁。\")\nchat.with_instructions(\"请使用项目符号列出要点。\", append: true)\n```\n\n## 🤝 扩展贡献者与服务商指导\n\n我们明确了贡献流程，以便评审更加快速、减少意外情况。\n\n目前的要求如下：\n\n* 在编写新功能之前，请先提交一个议题，并等待维护人员的反馈。\n* PR 应保持专注且规模适中。\n* 即使使用了 AI 工具，代码的所有权仍归您所有：在提交 PR 之前，请确保理解每一行代码。\n\n针对不同服务商的指导也更加清晰：\n\n* 核心服务商的接纳标准较高。\n* 对于规模较小或新兴的服务商，我们通常更倾向于由社区维护 gem，而非将其直接加入 RubyLLM 核心。\n\n最终效果是：评审过程中的反复减少，前期期望更加明确。\n\n## 📚 文档与开发体验优化\n\n一系列质量提升措施…","2026-02-14T12:04:38",{"id":199,"version":200,"summary_zh":201,"released_at":202},108802,"1.11.0","# RubyLLM 1.11：xAI 提供者与 Grok 模型 🚀🤖⚡\n\n本次发布正式将 xAI 纳入一流提供者行列，新增 Grok 模型至模型注册表，并对配置及思考相关文档进行了优化。只需填入您的 xAI API 密钥，即可在几秒钟内开始与 Grok 对话。\n\n## 🚀 xAI 提供者（你好，Grok！）\n\n通过专门的 xAI 提供者接口，您可以使用其兼容 OpenAI 的 API 直接开启对话：\n\n```ruby\nRubyLLM.configure do |config|\n  config.xai_api_key = ENV[\"XAI_API_KEY\"]\nend\n\nchat = RubyLLM.chat(model: \"grok-4-fast-non-reasoning\")\nresponse = chat.ask(\"在 Ruby 中解析 CSV 的最快方法是什么？\")\nresponse.content\n```\n\n- xAI 现已成为一流提供者（`:xai`），底层使用与 OpenAI 兼容的端点。\n- Grok 模型已加入注册表，您只需按名称选择即可，无需额外配置。\n- 流式响应、工具调用和结构化输出等功能的使用方式与现有 OpenAI 兼容提供者完全一致。\n\n流式响应的使用方式与以往相同：\n\n```ruby\nchat = RubyLLM.chat(model: \"grok-3-mini\")\n\nchat.ask(\"请用 3 条要点概括这个 PR\") do |chunk|\n  print chunk.content\nend\n```\n\n## 🧩 模型注册表更新\n\n模型元数据及公开模型列表已更新，新增了 Grok 模型及相关内容。\n\n## 📚 文档优化\n\n- 配置文档现包含 xAI 的设置示例。\n- 思考指南的逻辑更加清晰，示例也更为明确。\n\n## 🛠️ 提供者修复\n\n- 修复了因新 URI 接口引入而产生的 OpenAI、Bedrock 和 Anthropic 错误。\n\n## 安装\n\n```ruby\ngem \"ruby_llm\", \"1.11.0\"\n```\n\n## 从 1.10.x 升级\n\n```bash\nbundle update ruby_llm\n```\n\n## 已合并的 PR\n* @infinityrobot 和 @crmne 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F373 中添加了 xAI 提供者\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.10.0...1.11.0","2026-01-16T17:47:26",{"id":204,"version":205,"summary_zh":206,"released_at":207},108803,"1.10.0","# RubyLLM 1.10：扩展思考、持久化思考与流式处理修复 🧠✨🚆\n\n本次发布带来了跨提供商的一流扩展思考功能，全面支持 Gemini 3 Pro\u002FFlash 的思考签名（聊天 + 工具调用），提供了一个升级到 Rails 的路径以实现持久化存储，并优化了流式传输管道。此外，还正式支持 Ruby 4.0，增强了模型注册表刷新的安全性，修复了 Vertex AI 全球端点问题，并更新了文档。\n\n## 🧠 扩展思考无处不在\n\n通过 `with_thinking` 可以在不同提供商之间调整推理深度和预算，并在可用时获取思考输出：\n\n```ruby\nchat = RubyLLM.chat(model: \"claude-opus-4.5\")\n  .with_thinking(effort: :high, budget: 8000)\n\nresponse = chat.ask(\"用数字证明这一点。\")\nresponse.thinking&.text\nresponse.thinking&.signature\nresponse.thinking_tokens\n```\n\n- `response.thinking` 和 `chunk.thinking` 在普通请求和流式请求中都会暴露思考内容。\n- `response.thinking_tokens` 和 `response.tokens.thinking` 会在提供商报告时跟踪思考 token 的使用情况。\n- Gemini 3 Pro\u002FFlash 完全支持聊天和工具调用中的思考签名，因此多步会话将保持一致。\n- 扩展思考的差异现在已在各提供商之间标准化，因此只需调整一个 API 即可获得可预测的输出。\n\n并行流式输出思考内容和回答内容：\n\n```ruby\nchat = RubyLLM.chat(model: \"claude-opus-4.5\")\n  .with_thinking(effort: :medium)\n\nchat.ask(\"请逐步解答：127 乘以 43 等于多少？\") do |chunk|\n  print chunk.thinking&.text\n  print chunk.content\nend\n```\n\n- 流式传输保持向后兼容：现有应用可以继续打印 `chunk.content`，而更丰富的 UI 也可以同时渲染 `chunk.thinking`。\n\n## 🧰 Rails + ActiveRecord 持久化\n\n思考输出现在可以与消息一起存储（包括文本、签名和 token 使用情况），并为现有应用提供了升级生成器：\n\n```bash\nrails generate ruby_llm:upgrade_to_v1_10\nrails db:migrate\n```\n\n- 在消息表中新增了 `thinking_text`、`thinking_signature` 和 `thinking_tokens` 字段。\n- 为 Gemini 工具调用添加了 `thought_signature` 字段。\n- 修复了一个 Rails 流式传输问题，该问题会导致首个 token 被丢弃。\n\n## 📊 统一的 Token 追踪\n\n所有 token 计数现在都位于 `response.tokens` 和 `message.tokens` 中，包括输入、输出、缓存、缓存创建以及思考 token。\n\n## ✅ 正式支持 Ruby 4.0\n\nRuby 4.0 现已在 CI 和依赖项中得到官方支持。\n\n## 🧩 模型注册表更新\n\n- 刷新注册表时不再删除尚未配置的提供商中的模型。\n\n## 🌍 Vertex AI 全球端点修复\n\n当 `vertexai_location` 设置为 `global` 时，API 基础 URL 现已正确解析为：\n\n```\nhttps:\u002F\u002Faiplatform.googleapis.com\u002Fv1beta1\n```\n\n## 📚 文档更新\n\n- 新增扩展思考指南。\n- Token 使用文档现已包含思考 token。\n\n## 安装\n\n```ruby\ngem \"ruby_llm\", \"1.10.0\"\n```\n\n## 从 1.9.x 升级\n\n```bash\nbundle update ruby_llm\nrails generate ruby_llm:upgrade_to_v1_10\nrails db:migrate\n```\n\n## 已合并的 PR\n* 修复 Vertex AI 全球端点 URL 构建问题 by ","2026-01-13T19:03:45",{"id":209,"version":210,"summary_zh":211,"released_at":212},108804,"1.9.2","# RubyLLM 1.9.2：Models.dev 注册表、Imagen 4.0 和设置优化 🧭🖼️🧪\n\n这是一个小补丁，更换了模型注册表的后端，更新了 Imagen 的默认配置，并优化了迁移和本地设置流程——此外还对代码检查和测试做了一些调整。\n\n## 🧭 模型注册表迁移到 Models.dev\n\n这对 RubyLLM 来说是个重大改进。将注册表切换到 Models.dev 解决了我们之前在模型元数据方面遇到的所有问题：定价一致、功能描述一致，且所有信息都基于开放数据。非常感谢 Models.dev 团队的辛勤工作。\n\n并非针对 Parsera，只是他们目前事务繁忙。\n\n• 修复了 #545、#459、#559、#561、#560 等问题\n• 更新了指向 Models.dev 跟踪系统的链接，以保持一致性\n\n## 🖼️ Imagen 4.0 成为默认模型\n\n图像生成规范和模型列表现在默认使用 Imagen 4.0，因此新生成的图像将自动采用最新版本，无需手动指定。\n\n## 🧬 修复 1.7 版本迁移中的拼写错误\n\n修正了 1.7 版本迁移中一个类名拼写错误，确保旧版本升级过程更加可靠。\n\n• 修复了 #498\n\n## 安装\n\n  gem \"ruby_llm\", \"1.9.2\"\n\n### 从 1.9.1 升级\n\n  bundle update ruby_llm\n\n## 已合并的 PR\n* 由 @tpaulshippy 在 https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F554 中解决 Style\u002FModuleMemberExistenceCheck 问题\n\n\n**完整变更日志**：https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.9.1...1.9.2","2026-01-09T17:51:04",{"id":214,"version":215,"summary_zh":216,"released_at":217},108805,"1.9.1","# RubyLLM 1.9.1: Rails Namespaces, Vertex AI Auth & Anthropic Uploads 🛤️🔐\n\nA focused patch release that keeps ActiveRecord integrations humming in namespaced apps, restores Anthropic uploads, and hardens Vertex AI auth while smoothing out MySQL migrations and attachment handling.\n\n## 🧭 Namespaced ActiveRecord Chats Keep Their Foreign Keys\n`acts_as_*` helpers now accept explicit foreign key overrides, matching Rails’ association API, so namespaced chats and tool calls work even when their FK column doesn’t follow the default pattern.\n\n```ruby\nclass Support::Message \u003C ActiveRecord::Base\n  acts_as_message chat_class: \"Support::Conversation\",\n                  chat_foreign_key: \"conversation_id\",\n                  tool_call_class: \"Support::ToolCall\",\n                  tool_calls_foreign_key: \"support_tool_call_id\"\nend\n```\n\n- Fixes the regression introduced in 1.8.x for engines and modularized apps.\n- Generators include the right foreign keys out of the box when you opt into namespaces.\n\n## 🚆 Zeitwerk Eager Loading Behaves Outside Rails\nThe Railtie is now safely ignored during eager loading when `Rails::Railtie` isn’t defined, preventing `NameError` crashes in gems and background workers that depend on RubyLLM but don’t run inside Rails.\n\n## 📎 Attachments Understand Uploaded Files\n`RubyLLM::Attachment` detects `ActionDispatch::Http::UploadedFile`, `Pathname`, and Active Storage blobs automatically, preserving filenames and content types so file flows stay intact across providers.\n\n```ruby\nattachment = RubyLLM::Attachment.new(params[:file])\nattachment.filename # => original upload name\n```\n\n- Normalizes MIME detection and rewinds IO sources for consistent encoding.\n- Anthropic uploads once again serialize local PDFs\u002Fimages correctly after the 1.9.0 regression fix.\n\n## 🔐 Vertex AI Auth Uses googleauth the Right Way\nSwapped `fetch_access_token!` for `apply` when building Vertex AI headers, keeping compatibility with recent `googleauth` releases and avoiding token caching errors.\n\n## 🗄️ MySQL JSON Columns Skip Illegal Defaults\nRails generators detect MySQL adapters and omit default values for JSON columns, eliminating migration errors on Aurora\u002FMySQL deployments.\n\n## 🧪 Reliability Tweaks\nFresh specs cover `RubyLLM::Utils` coercion helpers so nested hashes and key transforms stay stable as we expand provider support.\n\n## Installation\n\n```ruby\ngem \"ruby_llm\", \"1.9.1\"\n```\n\n### Upgrading from 1.9.0\n\n```bash\nbundle update ruby_llm\n```\n\n## Merged PRs\n* fix(#403): Don't specify default values on mysql json by @UnderpantsGnome in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F491\n* Use apply instead of fetch_access_token for GAuth on vertex AI by @eddietokens in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F492\n* Refactor Attachment#initialize to extract source handling methods by @pekopekopekopayo in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F487\n* Fix Zeitwerk eager loading for railtie.rb by @trevorturk in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F486\n* Add specs for RubyLLM utils by @afurm in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F494\n* Fix namespaced models foreign key by @andreaslillebo in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F460\n\n## New Contributors\n* @UnderpantsGnome made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F491\n* @eddietokens made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F492\n* @pekopekopekopayo made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F487\n* @trevorturk made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F486\n* @afurm made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F494\n* @andreaslillebo made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F460\n\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.9.0...1.9.1\n","2025-11-05T09:36:59",{"id":219,"version":220,"summary_zh":221,"released_at":222},108806,"1.9.0","# RubyLLM 1.9.0: Tool Schemas, Prompt Caching & Transcriptions ✨🎙️\n\nMajor release that makes tool definitions feel like Ruby, lets you lean on Anthropic prompt caching everywhere, and turns audio transcription into a one-liner—plus better Gemini structured output and Nano Banana image responses.\n\n## 🧰 JSON Schema Tooling That Feels Native\nThe new `RubyLLM::Schema` `params` DSL supports full JSON Schema for tool parameter definitions, including nested objects, arrays, enums, and nullable fields.\n\n```ruby\nclass Scheduler \u003C RubyLLM::Tool\n  description \"Books a meeting\"\n\n  params do\n    object :window, description: \"Time window to reserve\" do\n      string :start, description: \"ISO8601 start\"\n      string :finish, description: \"ISO8601 finish\"\n    end\n\n    array :participants, of: :string, description: \"Email invitees\"\n\n    any_of :format, description: \"Optional meeting format\" do\n      string enum: %w[virtual in_person]\n      null\n    end\n  end\n\n  def execute(window:, participants:, format: nil)\n    Booking.reserve(window:, participants:, format:)\n  end\nend\n```\n\n- Powered by [`RubyLLM::Schema`](https:\u002F\u002Fgithub.com\u002Fdanielfriis\u002Fruby_llm-schema), the same awesome Ruby DSL we recommend to use for Structured Output's `chat.with_schema`.\n- Already handles Anthropic\u002FGemini quirks like nullable unions and enums - no more ad-hoc translation layers.\n- Prefer raw hashes? Pass `params schema: { ... }` to keep your existing JSON Schema verbatim.\n\n## 🧱 Raw Content Blocks & Anthropic Prompt Caching Everywhere\nWhen you need to handcraft message envelopes:\n\n```ruby\nchat = RubyLLM.chat(model: \"claude-sonnet-4-5\")\nraw_request = RubyLLM::Content::Raw.new([\n  { type: \"text\", text: File.read(\"prompt.md\"), cache_control: { type: \"ephemeral\" } },\n  { type: \"text\", text: \"Summarize today’s work.\" }\n])\n\nchat.ask(raw_request)\n```\n\nWe also provide an helper specifically for Anthropic Prompt Caching:\n\n```ruby\nsystem_block = RubyLLM::Providers::Anthropic::Content.new(\n  \"You are our release-notes assistant.\",\n  cache: true\n)\n\nchat.add_message(role: :system, content: system_block)\n```\n\n- `RubyLLM::Content::Raw` lets you ship provider-native payloads for content blocks.\n- Anthropic helpers keep `cache_control` hints readable while still producing the right JSON structure.\n- Every `RubyLLM::Message` now exposes `cached_tokens` and `cache_creation_tokens`, so you can see exactly what the provider pulled from cache versus what it had to recreate.\n\nPlease run `rails generate ruby_llm:upgrade_to_v1_9` in your Rails app if you come from 1.8.x.\n\n## ⚙️ Tool.with_params Plays Nice with Anthropic Caching\nSimilarly to Raw Content Blocks, `.with_params` lets you set arbitrary params in tool definitions. Perfect for Anthropic’s `cache_control` hints.\n\n```ruby\nclass ChangelogTool \u003C RubyLLM::Tool\n  description \"Formats commits into release notes\"\n\n  params do\n    array :commits, of: :string\n  end\n\n  with_params cache_control: { type: \"ephemeral\" }\n\n  def execute(commits:)\n    ReleaseNotes.format(commits)\n  end\nend\n```\n\n## 🎙️ RubyLLM.transcribe Turns Audio into Text (With Diarization)\nOne method call gives you transcripts, diarized segments, and consistent token tallies across providers.\n\n```ruby\ntranscription = RubyLLM.transcribe(\n  \"all-hands.m4a\",\n  model: \"gpt-4o-transcribe-diarize\",\n  language: \"en\",\n  prompt: \"Focus on action items.\"\n)\n\ntranscription.segments.each do |segment|\n  puts \"#{segment['speaker']}: #{segment['text']} (#{segment['start']}s – #{segment['end']}s)\"\nend\n```\n\n- Supports OpenAI (`whisper-1`, `gpt-4o-transcribe`, diarization variants), Gemini 2.5 Flash, and Vertex AI with the same API.\n- Optional speaker references map diarized voices to real names.\n\n## 🛠️ Gemini Structured Output Fixes & Nano Banana Inline Images\nWe went deep on Gemini’s edges so you don’t have to.\n\n- Nullables and `anyOf` now translate cleanly, and Gemini 2.5 finally respects `responseJsonSchema`, so complex structured output works out of the box.\n- Parallel tool calls return one single message with the right role. This should increase its accuracy in using and responding to tool calls.\n- Gemini 2.5 Flash Image (“Nano Banana”) surfaces inline images as actual attachments—pair it with your UI immediately.\n\n```ruby\nchat = RubyLLM.chat(model: \"gemini-2.5-flash-image\")\nreply = chat.ask(\"Sketch a Nano Banana wearing aviators.\")\nimage = reply.content.attachments.first\nFile.binwrite(\"nano-banana.png\", image.read)\n```\n\n(If you missed the backstory, my blog post [Nano Banana with RubyLLM](https:\u002F\u002Fpaolino.me\u002Fnano-banana-with-rubyllm\u002F) has the full walkthrough.)\n\n## 🗂️ Configurable Model Registry file path\nDeploying to read-only filesystems? Point RubyLLM at a writable JSON registry and keep refreshing models without hacks.\n\n```ruby\nRubyLLM.models.save_to_json(\"\u002Fvar\u002Fapp\u002Fmodels.json\")\n\nRubyLLM.configure do |config|\n  config.model_registry_file = \"\u002Fvar\u002Fapp\u002Fmodels.json\"\nend\n```\n\nJust remember that `RubyLLM.models.refresh!` only updates the in-memory registry. To persist changes to","2025-11-03T15:30:54",{"id":224,"version":225,"summary_zh":226,"released_at":227},108807,"1.8.2","# RubyLLM 1.8.2: Enhanced Tool Calling & Reliability 🔧✨\r\n\r\nMinor release improving tool calling visualization in Rails chat UIs, fixing namespaced model support, and enhancing stability.\r\n\r\n## 🔧 Tool Call Visualization\r\n\r\nEnhanced chat UI with basic visualization of tool\u002Ffunction calls:\r\n\r\n- **Tool call display**: Messages now show function calls with name and arguments in JSON format\r\n- **Improved readability**: Styled with monospace font and gray background for clear distinction\r\n- **Seamless integration**: Tool calls integrate naturally into the conversation flow\r\n\r\n## 🐛 Bug Fixes & Improvements\r\n\r\n### Chat UI Generator\r\n- **Namespaced model support**: Fixed chat UI generator to properly handle namespaced models (fixes #425)\r\n- **Cleaner output**: Refined model class injection for better code generation\r\n\r\n### Network Reliability\r\n- **Faraday adapter**: Explicitly set `net_http` adapter instead of relying on environment defaults (fixes #428)\r\n- **Improved stability**: Ensures consistent network behavior across different environments\r\n\r\n## 📚 Documentation & Testing\r\n\r\n- **CI optimization**: Test suite now runs more efficiently, with coverage reports from latest Ruby\u002FRails only\r\n- **Generator tests**: Optimized to run only on latest Ruby and Rails versions\r\n- **Coverage accuracy**: Excluded generator code from coverage metrics for more accurate reporting\r\n\r\n## Installation\r\n\r\n```ruby\r\ngem 'ruby_llm', '1.8.2'\r\n```\r\n\r\n### Upgrading from 1.8.1\r\n\r\n```bash\r\nbundle update ruby_llm\r\n```\r\n\r\nAll changes are backward compatible. To benefit from the tool call visualization, regenerate your chat UI with `rails generate ruby_llm:chat_ui`.\r\n\r\n## Merged PRs\r\n* Display tool calls in message template by @marckohlbrugge in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F416\r\n* Set adapter to be net_http instead of Faraday.default_adapter. by @jkogara in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F429\r\n\r\n## New Contributors\r\n* @marckohlbrugge made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F416\r\n* @jkogara made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F429\r\n\r\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.8.1...1.8.2\r\n","2025-09-24T15:34:09",{"id":229,"version":230,"summary_zh":231,"released_at":232},108808,"1.8.1","# RubyLLM 1.8.1: Efficient Chat Streaming 🚀💬\n\nSmall release bringing production-ready streaming for Rails chat UIs and minor fixes.\n\n## 💬 Production-Ready Chat Streaming\n\nImproved the chat UI generator with efficient chunk streaming that reduces bandwidth usage:\n\n- **Bandwidth optimized**: New `broadcast_append_chunk` method appends individual chunks without re-transmitting entire messages\n- **Single subscription**: Maintains one Turbo Stream subscription at chat level (not per message)\n- **Reduced overhead**: Jobs now append chunks instead of updating entire messages, reducing database writes\n\n## 🔧 Improvements & Fixes\n\n- **Cleaner injection**: Refined message model class injection for chat UI generator\n- **GPT-5 capabilities**: Fixed missing capability declarations for parsera compatibility\n- **Funding support**: Added funding URI to gemspec metadata\n- **Documentation updates**: Enhanced README and moderation guides\n- **Model registry**: Latest model updates across all providers\n- **Dependency updates**: Updated Appraisal gemfiles\n\n## Installation\n\n```ruby\ngem 'ruby_llm', '1.8.1'\n```\n\n### Upgrading from 1.8.0\n\n```bash\nbundle update ruby_llm\n```\n\nAll changes are backward compatible. To benefit from the streaming improvements, regenerate your chat UI with `rails generate ruby_llm:chat_ui`.\n\n## Merged PRs\n* Update gpt-5 capabilities by @mnort9 in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F345\n\n## New Contributors\n* @mnort9 made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F345\n\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.8.0...1.8.1\n","2025-09-21T15:07:04",{"id":234,"version":235,"summary_zh":236,"released_at":237},108809,"1.8.0","# RubyLLM 1.8.0: Video Support & Content Moderation 🎥🛡️\r\n\r\nMajor feature release bringing video file support for multimodal models and content moderation capabilities to ensure safer AI interactions.\r\n\r\n## 🎥 Video File Support\r\n\r\nFull video file support for models with video capabilities:\r\n\r\n```ruby\r\n# Local video files\r\nchat = RubyLLM.chat(model: \"gemini-2.5-flash\")\r\nresponse = chat.ask(\"What happens in this video?\", with: \"video.mp4\")\r\n\r\n# Remote video URLs (with or without extensions)\r\nresponse = chat.ask(\"Describe this video\", with: \"https:\u002F\u002Fexample.com\u002Fvideo\")\r\n\r\n# Multiple attachments including video\r\nresponse = chat.ask(\"Compare these\", with: [\"image.jpg\", \"video.mp4\"])\r\n```\r\n\r\nFeatures:\r\n- Automatic MIME type detection for video formats\r\n- Support for remote videos without file extensions\r\n- Seamless integration with existing attachment system\r\n- Full support for Gemini and VertexAI video-capable models \r\n\r\n## 🛡️ Content Moderation\r\n\r\nNew content moderation API to identify potentially harmful content before sending to LLMs:\r\n\r\n```ruby\r\n# Basic moderation\r\nresult = RubyLLM.moderate(\"User input text\")\r\nputs result.flagged?  # => true\u002Ffalse\r\nputs result.flagged_categories  # => [\"harassment\", \"hate\"]\r\n\r\n# Integration pattern - screen before chat\r\ndef safe_chat(user_input)\r\n  moderation = RubyLLM.moderate(user_input)\r\n  return \"Content not allowed\" if moderation.flagged?\r\n\r\n  RubyLLM.chat.ask(user_input)\r\nend\r\n\r\n# Check specific categories\r\nresult = RubyLLM.moderate(\"Some text\")\r\nputs result.category_scores[\"harassment\"]  # => 0.0234\r\nputs result.category_scores[\"violence\"]    # => 0.0012\r\n```\r\n\r\nFeatures:\r\n- Detects sexual, hate, harassment, violence, self-harm, and other harmful content\r\n- Convenience methods: `flagged?`, `flagged_categories`, `category_scores`\r\n- Currently supports OpenAI's moderation API\r\n- Extensible architecture for future providers\r\n- Configurable default model (defaults to `omni-moderation-latest`)\r\n\r\n## 🐛 Bug Fixes\r\n\r\n### Rails Inflection Issue\r\n- Fixed critical bug where Rails apps using `Llm` module\u002Fnamespace would break due to inflection conflicts\r\n- RubyLLM now properly isolates its inflections\r\n\r\n### Migration Foreign Key Errors\r\n- Fixed install generator creating migrations with foreign key references to non-existent tables\r\n- Migrations now create tables first, then add references in correct order\r\n- Prevents \"relation does not exist\" errors in PostgreSQL and other databases\r\n\r\n### Model Registry Improvements\r\n- Fixed `Models.resolve` instance method delegation\r\n- Fixed helper methods to return all models supporting specific modalities\r\n- `image_models`, `audio_models`, and `embedding_models` now correctly include all capable models\r\n\r\n## 📚 Documentation\r\n- Added comprehensive moderation guide with Rails integration examples\r\n- Updated video support documentation with examples\r\n- Clarified version requirements in documentation\r\n\r\n## Installation\r\n\r\n```ruby\r\ngem 'ruby_llm', '1.8.0'\r\n```\r\n\r\n### Upgrading from 1.7.x\r\n\r\n```bash\r\nbundle update ruby_llm\r\n```\r\n\r\nAll changes are backward compatible. New features are opt-in.\r\n\r\n## Merged PRs\r\n* Fix create_table migrations to prevent foreign key errors (#409) by @matiasmoya in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F411\r\n* Fix: Add resolve method delegation from Models instance to class by @kieranklaassen in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F407\r\n* Models helps should return all supporting modalities by @dacamp in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F408\r\n* Add Content Moderation Feature by @iraszl in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F383\r\n* Add video file support by @altxtech in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F405 and @arnodirlam in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F260\r\n\r\n## New Contributors\r\n* @matiasmoya made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F411\r\n* @dacamp made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F408\r\n* @iraszl made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F383\r\n* @altxtech made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F405\r\n* @arnodirlam made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F260\r\n\r\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.7.1...1.8.0\r\n","2025-09-14T11:47:21",{"id":239,"version":240,"summary_zh":241,"released_at":242},108810,"1.7.1","# RubyLLM 1.7.1: Generator Fixes & Enhanced Upgrades 🔧\r\n\r\nBug fixes and improvements for Rails generators, with special focus on namespaced models and automatic migration of existing apps.\r\n\r\n## 🐛 Critical Fixes\r\n\r\n### Namespaced Model Support\r\n\r\nThe generators now properly handle namespaced models throughout:\r\n\r\n```bash\r\n# Now works correctly with namespaced models\r\nrails g ruby_llm:install chat:LLM::Chat message:LLM::Message model:LLM::Model\r\nrails g ruby_llm:upgrade_to_v1_7 chat:Assistant::Chat message:Assistant::Message\r\n```\r\n\r\nFixed issues:\r\n- Invalid table names like `:assistant\u002Fchats` → `:assistant_chats` ✅\r\n- Model migration failures with namespaced models ✅\r\n- Foreign key migrations now handle custom table names correctly ✅\r\n- Namespace modules automatically created with `table_name_prefix` ✅\r\n\r\n## ✨ Automatic acts_as API Migration\r\n\r\nThe upgrade generator now **automatically converts** from the old acts_as API to the new one:\r\n\r\n```ruby\r\n# BEFORE running upgrade generator (OLD API)\r\nclass Conversation \u003C ApplicationRecord\r\n  acts_as_chat message_class: 'ChatMessage', tool_call_class: 'AIToolCall'\r\nend\r\n\r\nclass ChatMessage \u003C ApplicationRecord\r\n  acts_as_message chat_class: 'Conversation', chat_foreign_key: 'conversation_id'\r\nend\r\n\r\n# AFTER running upgrade generator (NEW API)\r\nclass Conversation \u003C ApplicationRecord\r\n  acts_as_chat messages: :chat_messages, message_class: 'ChatMessage', model: :model\r\nend\r\n\r\nclass ChatMessage \u003C ApplicationRecord\r\n  acts_as_message chat: :conversation, chat_class: 'Conversation', tool_calls: :ai_tool_calls, tool_call_class: 'AIToolCall', model: :model\r\nend\r\n```\r\n\r\nThe generator:\r\n- Converts from old `*_class` parameters to new association-based parameters\r\n- Adds the new `model` association to all models\r\n- Preserves custom class names and associations\r\n- Handles both simple and complex\u002Fnamespaced models\r\n\r\nNo manual changes needed - the generator handles the complete API migration automatically! 🎉\r\n\r\n## 🏗️ Generator Architecture Improvements\r\n\r\n### DRY Generator Code\r\n\r\nCreated a shared `GeneratorHelpers` module to eliminate duplication between generators:\r\n- Shared `acts_as_*` declaration logic\r\n- Common database detection methods\r\n- Unified namespace handling\r\n- Consistent table name generation\r\n\r\n### Better Rails Conventions\r\n\r\n- Generators reorganized into proper subdirectories\r\n- Private methods moved to conventional location\r\n- Follows Rails generator best practices\r\n- Cleaner, more maintainable code\r\n\r\n## 🚨 Troubleshooting Helper\r\n\r\nAdded clear troubleshooting for the most common upgrade issue:\r\n\r\n```ruby\r\n# If you see: \"undefined local variable or method 'acts_as_model'\"\r\n# Add this to config\u002Fapplication.rb BEFORE your Application class:\r\n\r\nRubyLLM.configure do |config|\r\n  config.use_new_acts_as = true\r\nend\r\n\r\nmodule YourApp\r\n  class Application \u003C Rails::Application\r\n    # ...\r\n  end\r\nend\r\n```\r\n\r\nThe upgrade generator now shows this warning proactively and documentation includes a dedicated troubleshooting section.\r\n\r\n## 🔄 Migration Improvements\r\n\r\n- Fixed instance variable usage in migration templates\r\n- Better handling of existing Model tables during upgrade\r\n- Initializer creation if missing during upgrade\r\n- Simplified upgrade instructions pointing to migration guide\r\n\r\n## Installation\r\n\r\n```ruby\r\ngem 'ruby_llm', '1.7.1'\r\n```\r\n\r\n### Upgrading from 1.7.0\r\n\r\nJust update your gem - all fixes are backward compatible:\r\n\r\n```bash\r\nbundle update ruby_llm\r\n```\r\n\r\n### Upgrading from 1.6.x\r\n\r\nUse the improved upgrade generator:\r\n\r\n```bash\r\nrails generate ruby_llm:upgrade_to_v1_7\r\nrails db:migrate\r\n```\r\n\r\nThe generator now handles everything automatically, including updating your model files!\r\n\r\n## Merged PRs\r\n* Fix namespaced model table names in upgrade generator by @willcosgrove in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F398\r\n* Fix namespaced models in Model migration and foreign key migrations by @willcosgrove in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F399\r\n\r\n## New Contributors\r\n* @willcosgrove made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F398\r\n\r\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.7.0...1.7.1\r\n","2025-09-11T13:43:44",{"id":244,"version":245,"summary_zh":246,"released_at":247},108811,"1.7.0","# RubyLLM 1.7: Rails Revolution & Vertex AI 🚀\r\n\r\nMajor Rails integration overhaul bringing database-backed models, UI generators, and a more intuitive acts_as API. Plus Google Cloud Vertex AI support, regional AWS Bedrock, and streamlined installation!\r\n\r\n## 🌟 Google Cloud Vertex AI Support\r\n\r\nFull Vertex AI provider integration with dynamic model discovery:\r\n\r\n```ruby\r\n# Add to your Gemfile:\r\ngem \"googleauth\"  # Required for Vertex AI authentication\r\n\r\n# Configure Vertex AI:\r\nRubyLLM.configure do |config|\r\n  config.vertexai_project_id = \"your-project\"\r\n  config.vertexai_location = \"us-central1\"\r\nend\r\n\r\n# Access Gemini and other Google models through Vertex AI\r\nchat = RubyLLM.chat(model: \"gemini-2.5-pro\", provider: :vertexai)\r\nresponse = chat.ask(\"What can you do?\")\r\n```\r\n\r\nFeatures:\r\n- Dynamic model fetching from Vertex AI API with pagination\r\n- Automatic discovery of Gemini foundation models\r\n- Metadata enrichment from Parsera API\r\n- Full chat and embeddings support\r\n- Seamless integration with existing Gemini provider\r\n- Uses Application Default Credentials (ADC) for authentication\r\n\r\n## 🎉 New Rails-Like acts_as API\r\n\r\nThe Rails integration gets a massive upgrade with a more intuitive, Rails-like API:\r\n\r\n```ruby\r\n# OLD way (still works, deprecated in v2.0)\r\nclass Chat \u003C ApplicationRecord\r\n  acts_as_chat message_class: 'Message', tool_call_class: 'ToolCall'\r\nend\r\n\r\n# NEW way - use association names as primary parameters!\r\nclass Chat \u003C ApplicationRecord\r\n  acts_as_chat messages: :messages, model: :model\r\nend\r\n\r\nclass Message \u003C ApplicationRecord\r\n  acts_as_message chat: :chat, tool_calls: :tool_calls, model: :model\r\nend\r\n```\r\n\r\n### Two-Command Upgrade\r\n\r\nExisting apps can upgrade seamlessly:\r\n\r\n```bash\r\n# Step 1: Run the upgrade generator\r\nrails generate ruby_llm:upgrade_to_v1_7\r\n\r\n# Step 2: Run migrations\r\nrails db:migrate\r\n```\r\n\r\nThat's it! The upgrade generator:\r\n- Creates the models table if needed\r\n- Automatically adds `config.use_new_acts_as = true` to your initializer\r\n- Migrates your existing data to use foreign keys\r\n- Preserves all your data (old string columns renamed to `model_id_string`)\r\n\r\n## 🖥️ Complete Chat UI Generator\r\n\r\nBuild a full chat interface with one command:\r\n\r\n```bash\r\n# Generate complete chat UI with Turbo streaming\r\nrails generate ruby_llm:chat_ui\r\n```\r\n\r\nThis creates:\r\n- **Controllers**: Chat and message controllers with Rails best practices\r\n- **Views**: Clean HTML views for chat list, creation, and messaging\r\n- **Models page**: Browse available AI models\r\n- **Turbo Streams**: Real-time message updates\r\n- **Background job**: Streaming AI responses\r\n- **Model selector**: Choose models in chat creation\r\n\r\nThe UI is intentionally simple and clean - perfect for customization!\r\n\r\n## 💾 Database-Backed Model Registry\r\n\r\nModels are now first-class ActiveRecord objects with rich metadata:\r\n\r\n```ruby\r\n# Chat.create! has the same interface as RubyLLM.chat (PORO)\r\nchat = Chat.create!  # Uses default model from config\r\nchat = Chat.create!(model: \"gpt-4o-mini\")  # Specify model\r\nchat = Chat.create!(model: \"claude-3-5-haiku\", provider: \"bedrock\")  # Cross-provider\r\nchat = Chat.create!(\r\n  model: \"experimental-llm-v2\",\r\n  provider: \"openrouter\",\r\n  assume_model_exists: true  # Creates Model record if not found\r\n)\r\n\r\n# Access rich model metadata through associations\r\nchat.model.context_window  # => 128000\r\nchat.model.capabilities    # => [\"streaming\", \"function_calling\", \"structured_output\"]\r\nchat.model.pricing[\"text_tokens\"][\"standard\"][\"input_per_million\"]  # => 2.5\r\n\r\n# Works with Model objects too\r\nmodel = Model.find_by(model_id: \"gpt-4o\")\r\nchat = Chat.create!(model: model)\r\n\r\n# Refresh models from provider APIs\r\nModel.refresh!  # Populates\u002Fupdates models table from all configured providers\r\n```\r\n\r\nThe install generator creates a Model model by default:\r\n\r\n```bash\r\n# Custom model names supported\r\nrails g ruby_llm:install chat:Discussion message:Comment model:LLModel\r\n```\r\n\r\n## 🌍 AWS Bedrock Regional Support\r\n\r\nCross-region inference now works correctly in all AWS regions:\r\n\r\n```ruby\r\n# EU regions now work!\r\nRubyLLM.configure do |config|\r\n  config.bedrock_region = \"eu-west-3\"\r\nend\r\n\r\n# Automatically uses correct region prefix:\r\n# - EU: eu.anthropic.claude-3-sonnet...\r\n# - US: us.anthropic.claude-3-sonnet...\r\n# - AP: ap.anthropic.claude-3-sonnet...\r\n# - CA: ca.anthropic.claude-3-sonnet...\r\n```\r\n\r\nThanks to @elthariel for the contribution! (#338)\r\n\r\n## 🎵 MP3 Audio Support Fixed\r\n\r\nOpenAI's Whisper API now correctly handles MP3 files:\r\n\r\n```ruby\r\n# Previously failed with MIME type errors\r\nchat.add_attachment(\"audio.mp3\")\r\nresponse = chat.ask(\"Transcribe this audio\")  # Now works!\r\n```\r\n\r\nThe fix properly converts `audio\u002Fmpeg` MIME type to the `mp3` format string OpenAI expects. (#390)\r\n\r\n## 🚀 Performance & Developer Experience\r\n\r\n### Simplified Installation\r\n\r\nThe post-install message is now concise and helpful, pointing to docs instead of overwhelming with text.\r\n\r\n### Better Generator Experi","2025-09-10T16:00:16",{"id":249,"version":250,"summary_zh":251,"released_at":252},108812,"1.6.4","# RubyLLM 1.6.4: Multimodal Tools & Better Schemas 🖼️\r\n\r\nMaintenance release bringing multimodal tool responses, improved rake tasks, and important fixes for Gemini schema conversion. Plus better documentation and developer experience!\r\n\r\n## 🖼️ Tools Can Now Return Files and Images\r\n\r\nTools can now return rich content with attachments, not just text! Perfect for screenshot tools, document generators, and visual analyzers:\r\n\r\n```ruby\r\nclass ScreenshotTool \u003C RubyLLM::Tool\r\n  description \"Takes a screenshot and returns it\"\r\n  param :url, desc: \"URL to screenshot\"\r\n  \r\n  def execute(url:)\r\n    screenshot_path = capture_screenshot(url)  # Your screenshot logic\r\n    \r\n    # Return a Content object with text and attachments\r\n    RubyLLM::Content.new(\r\n      \"Screenshot of #{url} captured successfully\",\r\n      [screenshot_path]  # Can be file path, StringIO, or ActiveStorage blob\r\n    )\r\n  end\r\nend\r\n\r\n# The LLM can now see and analyze the screenshot\r\nchat = RubyLLM.chat.with_tool(ScreenshotTool)\r\nresponse = chat.ask(\"Take a screenshot of ruby-lang.org and describe what you see\")\r\n```\r\n\r\nThis opens up powerful workflows:\r\n- **Visual debugging**: Screenshot tools that capture and analyze UI states\r\n- **Document generation**: Tools that create PDFs and return them for review\r\n- **Data visualization**: Generate charts and have the LLM interpret them\r\n- **Multi-step workflows**: Chain tools that produce and consume visual content\r\n\r\nWorks with all providers that support multimodal content.\r\n\r\n## 🔧 Fixed: Gemini Schema Conversion\r\n\r\nGemini's structured output was not preserving all the schema fields and integer schemas were converted to number. Now the conversion logic  correctly handles:\r\n\r\n```ruby\r\n# Preserve description\r\nschema = {\r\n  type: 'object',\r\n  description: 'An object',\r\n  properties: {\r\n    example: {\r\n      type: \"string\",\r\n      description: \"a brief description about the person's time at the conference\"\r\n    }\r\n  },\r\n  required: ['example']\r\n}\r\n\r\n# Define schema with both number and integer types\r\nschema = {\r\n  type: 'object',\r\n  properties: {\r\n    number1: {\r\n      type: 'number',\r\n    },\r\n    number2: {\r\n      type: 'integer',\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nAlso added tests to cover simple and complex schemas, nested objects and arrays, all constraint attributes, nullable fields, descriptions, property ordering for objects.\r\n\r\nFixes #354, closes #355.\r\n\r\nThanks to @BrianBorge for reporting and working on the initial PR.\r\n\r\n## 🛠️ Developer Experience: Improved Rake Tasks\r\n\r\n### Consolidated Model Management\r\n\r\nAll model-related tasks are now streamlined and better organized:\r\n\r\n```bash\r\n# Default task now runs overcommit hooks + model updates\r\nbundle exec rake\r\n\r\n# Update models, generate docs, and create aliases in one command\r\nbundle exec rake models\r\n\r\n# Individual tasks still available\r\nbundle exec rake models:update    # Fetch latest models from providers\r\nbundle exec rake models:docs      # Generate model documentation\r\nbundle exec rake models:aliases   # Generate model aliases\r\n```\r\n\r\nThe tasks have been refactored from 3 separate files into a single, well-organized `models.rake` file following Rails conventions.\r\n\r\n### Release Preparation\r\n\r\nNew comprehensive release preparation task:\r\n\r\n```bash\r\n# Prepare for release: refresh cassettes, run hooks, update models\r\nbundle exec rake release:prepare\r\n```\r\n\r\nThis task:\r\n- Automatically refreshes stale VCR cassettes (>1 day old)\r\n- Runs overcommit hooks for code quality\r\n- Updates models, docs, and aliases\r\n- Ensures everything is ready for a clean release\r\n\r\n### Cassette Management\r\n\r\n```bash\r\n# Verify cassettes are fresh\r\nbundle exec rake release:verify_cassettes\r\n\r\n# Refresh stale cassettes automatically\r\nbundle exec rake release:refresh_stale_cassettes\r\n```\r\n\r\n## 📚 Documentation Updates\r\n\r\n- **Redirect fix**: `\u002Finstallation` now properly redirects to `\u002Fgetting-started`\r\n- **Badge refresh**: README badges updated to bust GitHub's cache\r\n- **Async pattern fix**: Corrected supervisor pattern example in agentic workflows guide to avoid \"Cannot wait on own fiber!\" errors\r\n\r\n## 🧹 Additional Updates\r\n\r\n- **Appraisal gemfiles updated**: All Rails version test matrices refreshed\r\n- **Test coverage**: New specs for multimodal tool responses\r\n- **Provider compatibility**: Verified with latest API versions\r\n\r\n## Installation\r\n\r\n```ruby\r\ngem 'ruby_llm', '1.6.4'\r\n```\r\n\r\nFull backward compatibility maintained. The multimodal tool support is opt-in - existing tools continue working as before.\r\n\r\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.6.3...1.6.4\r\n","2025-08-20T20:09:12",{"id":254,"version":255,"summary_zh":256,"released_at":257},108813,"1.6.3","# RubyLLM 1.6.3: Smarter Defaults & Easier Contributing 🎯\n\nMaintenance release improving model temperature defaults and making it easier to contribute to the project.\n\n## 🌡️ Models Now Use Their Own Temperature Defaults\n\nWe were overriding model defaults with `temperature: 0.7` everywhere. But different models have different optimal defaults - why fight them?\n\n```ruby\n# Before 1.6.3: Always forced temperature to 0.7\nchat = RubyLLM.chat(model: 'claude-3-5-haiku')  # temperature: 0.7\n\n# Now: Models use their native defaults\nchat = RubyLLM.chat(model: 'claude-3-5-haiku')  # temperature: (model's default)\nchat = RubyLLM.chat(model: 'gpt-4.1-nano')      # temperature: (model's default)\n\n# You can still override when needed\nchat = RubyLLM.chat(model: 'claude-3-5-haiku', temperature: 0.9)\n```\n\nEach provider knows the best default for their models. OpenAI might default to 1.0, Anthropic to something else - we now respect those choices. Fixes #349.\n\n## 🤝 Easier Contributing: Overcommit Improvements\n\nThe RakeTarget pre-commit hook was making it difficult for contributors to submit PRs. As noted in discussion #335, the hook would run `models:update` which deleted models if you didn't have API keys for all providers!\n\n```yaml\n# Removed from .overcommit.yml:\nRakeTarget:\n  enabled: true\n  command: ['bundle', 'exec', 'rake']\n  targets: ['models:update', 'models:docs', 'aliases:generate']\n```\n\nNow contributors can:\n- Submit PRs without having all provider API keys\n- Make targeted changes without unintended side effects\n- Focus on their contributions without fighting the tooling\n\nThe model registry is now maintained centrally rather than requiring every contributor to have complete API access.\n\n## 🧹 Additional Updates\n\n- **Test cassettes refreshed**: All VCR cassettes updated for reliable testing\n- **Model registry updated**: Latest models from all providers\n\n## Installation\n\n```ruby\ngem 'ruby_llm', '1.6.3'\n```\n\nFull backward compatibility maintained. The temperature change means your models might behave slightly differently (using their native defaults), but you can always explicitly set temperature if you need the old behavior.\n\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.6.2...1.6.3","2025-08-19T11:11:24",{"id":259,"version":260,"summary_zh":261,"released_at":262},108814,"1.6.2","# RubyLLM 1.6.2: Thinking Tokens & Performance 🧠\n\nQuick maintenance release fixing Gemini's thinking token counting and bringing performance improvements. Plus we're removing capability gatekeeping - trust providers to know what they can do!\n\n## 🧮 Fixed: Gemini Thinking Token Counting\n\nGemini 2.5 with thinking mode wasn't counting tokens correctly, leading to incorrect billing calculations:\n\n```ruby\n# Before: Only counted candidatesTokenCount (109 tokens)\n# Actual API response had:\n#   candidatesTokenCount: 109\n#   thoughtsTokenCount: 443\n#   => Should be 552 total!\n\n# Now: Correctly sums both token types\nchat = RubyLLM.chat(model: 'gemini-2.5-flash')\nresponse = chat.ask('What is 2+2? Think step by step.')\nresponse.output_tokens  # => 552 (correctly summed)\n```\n\nThis aligns with how all providers bill thinking\u002Freasoning tokens - they're all output tokens. Fixes #346.\n\n## 🚫 Capability Gatekeeping Removed\n\nWe were pre-checking if models support certain features before attempting to use them. But sometimes pre-emptive checks were getting in the way:\n\n```ruby\n# Before 1.6.2: Pre-checked capabilities before attempting\nchat.with_tool(MyTool)  # => UnsupportedFunctionsError (without trying)\n\n# Now: Let the provider handle it\nchat.with_tool(MyTool)  # Works if supported, provider errors if not\n```\n\nWhy this approach is better:\n- **Direct feedback** - Get the actual provider error, not our pre-emptive block\n- **Immediate support** - New models and features work as soon as providers ship them\n- **Custom models** - Fine-tuned and custom models aren't artificially limited\n- **Simpler flow** - One less layer of validation between you and the provider\n\nThe provider knows what it can do. If it works, great! If not, you'll get a clear error from the source.\n\nSame philosophy applies to structured output (`with_schema`).\n\n## ⚡ Performance Improvements\n\nThanks to @tagliala for introducing RuboCop Performance (#316), bringing multiple optimizations:\n\n- More efficient string operations\n- Better collection handling\n- Optimized method calls\n- Reduced object allocations\n\nEvery little bit helps when you're streaming thousands of tokens!\n\n## 🐛 Additional Fixes\n\n- **Logging cleanup**: Removed unnecessary \"assuming model exists\" debug logging after capability gatekeeping removal\n- **Test improvements**: Real API tests for token counting verification\n\n## Installation\n\n```ruby\ngem 'ruby_llm', '1.6.2'\n```\n\nFull backward compatibility maintained. If you're using Gemini with thinking mode, this update is recommended for accurate token counting.\n\n## Merged PRs\n* Introduce RuboCop Performance by @tagliala in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F316\n\n## New Contributors\n* @tagliala made their first contribution in https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fpull\u002F316\n\n**Full Changelog**: https:\u002F\u002Fgithub.com\u002Fcrmne\u002Fruby_llm\u002Fcompare\u002F1.6.1...1.6.2\n","2025-08-14T09:49:38"]