https://github.com/patrols/ruby_llm-text
ActiveSupport-style Ruby gem for LLM text operations: summarize, translate, extract, classify, fix grammar, sentiment analysis, and more with intuitive one-liner methods
https://github.com/patrols/ruby_llm-text
ai anthropic claude gem gemini llm nlp openai rails ruby text-processing
Last synced: 4 months ago
JSON representation
ActiveSupport-style Ruby gem for LLM text operations: summarize, translate, extract, classify, fix grammar, sentiment analysis, and more with intuitive one-liner methods
- Host: GitHub
- URL: https://github.com/patrols/ruby_llm-text
- Owner: patrols
- License: mit
- Created: 2026-02-16T01:31:04.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-17T13:45:41.000Z (4 months ago)
- Last Synced: 2026-02-18T13:58:40.525Z (4 months ago)
- Topics: ai, anthropic, claude, gem, gemini, llm, nlp, openai, rails, ruby, text-processing
- Language: Ruby
- Homepage:
- Size: 29.3 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# ruby_llm-text
ActiveSupport-style LLM utilities for Ruby that make AI operations feel like native Ruby.
[](https://badge.fury.io/rb/ruby_llm-text)
[](https://github.com/patrols/ruby_llm-text/actions)
## Overview
`ruby_llm-text` provides intuitive one-liner utility methods for common LLM tasks like summarizing text, translation, data extraction, and classification. It integrates seamlessly with the [ruby_llm](https://github.com/crmne/ruby_llm) ecosystem, providing a simple interface without requiring chat objects, message arrays, or configuration boilerplate.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'ruby_llm-text'
```
And then execute:
```bash
$ bundle install
```
Or install it yourself as:
```bash
$ gem install ruby_llm-text
```
## Quick Start
```ruby
require 'ruby_llm/text'
# Configure ruby_llm with your API key
RubyLLM.configure do |config|
config.openai_api_key = ENV["OPENAI_API_KEY"]
end
# Summarize text
long_article = "This is a very long article about..."
summary = RubyLLM::Text.summarize(long_article)
# Translate text
greeting = RubyLLM::Text.translate("Bonjour le monde", to: "en")
# Extract structured data
text = "My name is John and I am 30 years old."
data = RubyLLM::Text.extract(text, schema: { name: :string, age: :integer })
# Classify text
review = "This product is amazing!"
sentiment = RubyLLM::Text.classify(review, categories: ["positive", "negative", "neutral"])
```
## API Reference
### Summarize
Condense text into a shorter summary.
```ruby
RubyLLM::Text.summarize(text, length: :medium, max_words: nil, model: nil)
```
**Parameters:**
- `text` (String): The text to summarize
- `length` (Symbol|String): Predefined length (`:short`, `:medium`, `:detailed`) or custom description
- `max_words` (Integer, optional): Maximum word count for summary
- `model` (String, optional): Specific model to use
**Examples:**
```ruby
# Basic usage
RubyLLM::Text.summarize("Long article text...")
# With length option
RubyLLM::Text.summarize(text, length: :short)
# With word limit
RubyLLM::Text.summarize(text, length: :medium, max_words: 50)
# Custom length description
RubyLLM::Text.summarize(text, length: "bullet points")
```
### Translate
Translate text between languages.
```ruby
RubyLLM::Text.translate(text, to:, from: nil, model: nil)
```
**Parameters:**
- `text` (String): The text to translate
- `to` (String): Target language (e.g., "en", "spanish", "français")
- `from` (String, optional): Source language for better accuracy
- `model` (String, optional): Specific model to use
**Examples:**
```ruby
# Basic translation
RubyLLM::Text.translate("Bonjour", to: "en")
# With source language specified
RubyLLM::Text.translate("Hola mundo", to: "en", from: "es")
# Natural language specifications
RubyLLM::Text.translate("Hello", to: "french")
```
### Extract
Extract structured data from unstructured text.
```ruby
RubyLLM::Text.extract(text, schema:, model: nil)
```
**Parameters:**
- `text` (String): The text to extract data from
- `schema` (Hash): Data structure specification
- `model` (String, optional): Specific model to use
**Schema Types:**
- `:string` - Text fields
- `:integer`, `:number` - Numeric fields
- `:boolean` - True/false fields
- `:array` - List fields
**Examples:**
```ruby
# Extract person details
text = "John Smith is 30 years old and works as a software engineer in San Francisco."
schema = {
name: :string,
age: :integer,
profession: :string,
location: :string
}
data = RubyLLM::Text.extract(text, schema: schema)
# Extract product information
product_text = "iPhone 15 Pro costs $999 and has excellent reviews"
product_schema = {
name: :string,
price: :number,
currency: :string,
reviews: :array
}
product_data = RubyLLM::Text.extract(product_text, schema: product_schema)
```
### Classify
Classify text into predefined categories.
```ruby
RubyLLM::Text.classify(text, categories:, model: nil)
```
**Parameters:**
- `text` (String): The text to classify
- `categories` (Array): List of possible categories
- `model` (String, optional): Specific model to use
**Examples:**
```ruby
# Sentiment analysis
review = "This product exceeded my expectations!"
sentiment = RubyLLM::Text.classify(review,
categories: ["positive", "negative", "neutral"]
)
# Topic classification
article = "The stock market reached new highs today..."
topic = RubyLLM::Text.classify(article,
categories: ["technology", "finance", "sports", "politics"]
)
# Priority classification
email = "URGENT: Server is down and customers can't access the site"
priority = RubyLLM::Text.classify(email,
categories: ["low", "medium", "high", "critical"]
)
```
## Configuration
This gem uses `ruby_llm`'s configuration for API keys and default models:
```ruby
# Configure ruby_llm (API keys, default model, etc.)
RubyLLM.configure do |config|
config.openai_api_key = ENV["OPENAI_API_KEY"]
config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"]
config.default_model = "gpt-4.1-mini"
end
```
Optionally configure text-specific settings:
```ruby
RubyLLM::Text.configure do |config|
# Temperature for text operations (default: 0.3)
config.temperature = 0.3
# Method-specific model overrides (falls back to RubyLLM.config.default_model)
config.summarize_model = "gpt-4.1-mini"
config.translate_model = "claude-sonnet-4-5" # Use Claude for translation
config.extract_model = "gpt-4.1" # Use GPT-4 for extraction
config.classify_model = "gpt-4.1-mini"
end
```
**Per-call overrides:**
```ruby
# Override model for specific calls
RubyLLM::Text.summarize(text, model: "claude-sonnet-4-5")
# Pass additional options (passed through to ruby_llm)
RubyLLM::Text.translate(text, to: "es", temperature: 0.1)
```
## String Extensions (Optional)
For a more Rails-like experience, you can enable String monkey-patching:
```ruby
require 'ruby_llm/text/string_ext'
# Now you can call methods directly on strings
"Long article text...".summarize
"Bonjour".translate(to: "en")
"John is 30".extract(schema: { name: :string, age: :integer })
"Great product!".classify(categories: ["positive", "negative"])
```
## Integration with ruby_llm
This gem builds on top of [ruby_llm](https://github.com/crmne/ruby_llm) and inherits its configuration and model support:
- **Models**: Supports all ruby_llm models (OpenAI GPT, Anthropic Claude, etc.)
- **Configuration**: Uses ruby_llm's underlying configuration system
- **Error handling**: Inherits ruby_llm's robust error handling
## Error Handling
The gem provides clear error messages for common issues:
```ruby
# Missing required parameters
RubyLLM::Text.extract("text") # ArgumentError: schema is required
RubyLLM::Text.classify("text", categories: []) # ArgumentError: categories are required
# API errors are wrapped with context
RubyLLM::Text.summarize("text") # RubyLLM::Text::Error: LLM call failed: [original error]
```
## Development
After checking out the repo, run:
```bash
bin/setup # Install dependencies
rake test # Run tests
rake rubocop # Run linter
rake # Run tests and linter
```
## Testing
The test suite uses Mocha for mocking LLM API calls, ensuring reliable and fast tests without requiring API keys:
```bash
# Run all tests
bundle exec rake test
# Run tests with linting
bundle exec rake
# Run linting only
bundle exec rubocop
```
### Manual Testing
For manual testing with real API calls, use the provided test script:
```bash
# Set up your API key
export OPENAI_API_KEY="your-key"
# or
export ANTHROPIC_API_KEY="your-key"
# Run manual tests
bin/manual-test
```
This script tests all four methods with real LLM APIs and provides helpful output for verification.
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/patrols/ruby_llm-text.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).