Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions artificial-intelligence/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Artificial Intelligence

## Security

- Filter sensitive information before sending data to an LLM or chatbot.
[Example](./how-to/filter_sensitive_information.md).
44 changes: 44 additions & 0 deletions artificial-intelligence/how-to/filter_sensitive_information.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the guideline, but I think the example is too specific as this guide is more general than just Ruby.

This API might change in the future. A link to the repo is enough, IMO.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Filter Sensitive Information

Before sending free text to an LLM or chatbot, filter all messages for
potentially sensitive information first.

```ruby
require "openai"
require "top_secret"

openai = OpenAI::Client.new(
api_key: Rails.application.credentials.openai.api_key!
)

original_messages = [
"Ralph lives in Boston.",
"You can reach them at [email protected] or 877-976-2687"
]

# Filter all messages
result = TopSecret::Text.filter_all(original_messages)
filtered_messages = result.items.map(&:output)

user_messages = filtered_messages.map { {role: "user", content: it} }

# Instruct LLM how to handle filtered messages
instructions = <<~TEXT
I'm going to send filtered information to you in the form of free text.
If you need to refer to the filtered information in a response, just reference it by the filter.
TEXT

messages = [
{role: "system", content: instructions},
*user_messages
]

chat_completion = openai.chat.completions.create(messages:, model: :"gpt-5")
response = chat_completion.choices.last.message.content

# Restore the response from the mapping
mapping = result.mapping
restored_response = TopSecret::FilteredText.restore(response, mapping:).output

puts(restored_response)
```