by danduran on Development , AI Technology 9 min read, Comments: 0 (Add Your Comment!)

I Built an AI Blog/Article TL;DR Summarizer. Here's How I Did It.

TL;DR:

This is a guide for setting up a Python script for automatic web page summarization using the Ollama models. It covers environment setup, a two-pass approach to bullet-free summaries, specifying models and character limits, advanced usage tips, common pitfalls, and troubleshooting technical issues.

I Built an AI Blog/Article TL;DR Summarizer. Here's How I Did It.

Introduction

Welcome to the Two-Pass TL;DR Summarizer tutorial. This script condenses the content of a single webpage into a single-paragraph summary—stripping out bullet points, disclaimers, and enumerations. It harnesses the power of Ollama to run various local models (e.g., LLaMA, Qwen, Whiterabbit) and uses a two-pass approach to ensure the final output is as clean and bullet-free as possible.

Why Two-Pass Summarization?

  1. Pass One – We ask the chosen model to produce a concise summary, with instructions to avoid bullet points, enumerations, or disclaimers.
  2. Pass Two – If the model still sneaks them in, we feed that result back to the model and say, “Rewrite this. Remove any bullets or enumerations,” effectively giving it a second chance to comply.

This solves a common problem with large language models: sometimes they ignore or only partially follow instructions. The second pass drastically reduces the risk of bullet points and disclaimers creeping in.


1. Prerequisites

1.1 Python 3.7+

  • You need at least Python 3.7 on your system.
  • Check with:
python3 --version
  • If you have multiple Python versions, ensure you’re using the correct one (e.g., python3 vs. python).

1.2 Ollama

  • Ollama is a system for running large language models (like LLaMA, Qwen, etc.) locally on your machine.
  • Follow their installation instructions:
    Ollama GitHub
  • After installing, you should be able to run:
ollama list

to view all the models you have downloaded or built.
- If you need help installing Ollama or a specific model, watch:
YouTube Tutorial

1.3 Python Libraries

  • requests: For making HTTP requests to fetch the webpage HTML.
  • beautifulsoup4: For parsing the HTML content into raw text.

You’ll install these in a moment when we discuss setting up your environment.


2. Environment Setup

2.1 Cloning/Downloading the Script

  1. Navigate to the repo:
    https://github.com/Dan-Duran/tldr
  2. Clone it via command line:
git clone https://github.com/Dan-Duran/tldr.git
cd tldr

or simply download the ZIP file and unzip it into your chosen directory.

2.2 Virtual Environment (Required)

  1. Create a venv:
python3 -m venv venv
  1. Activate it:
  2. On Linux/macOS:
source venv/bin/activate
  • On Windows:
.\venv\Scripts\activate

Why required?
A dedicated virtual environment keeps your system-level Python packages separate and ensures you have a clean workspace for installing dependencies. This prevents version conflicts and environment pollution.

2.3 Installing Dependencies

Inside the activated virtual environment, run:

pip install requests beautifulsoup4

This ensures the script can fetch webpages and parse HTML. If the installation succeeds, you’re ready to run the summarizer.


3. Script Overview

The script (named tldr.py) is designed to:

  1. Parse Command-Line Arguments:
  2. -u/--url: Which webpage to summarize.
  3. -c/--characters: How many characters to limit the summary to.
  4. -m/--model: Which Ollama model to use.
  5. Fetch Article: Uses requests to get the HTML for the URL you provide.
  6. Extract Text: Strips out scripts/styles with BeautifulSoup, then extracts the main text.
  7. Run Pass One:
  8. Calls Ollama with a “Don’t use bullet points, disclaimers” prompt.
  9. Receives the first attempt at a summary.
  10. Check for Bullet Points/Disclaimers:
  11. If found, it runs Pass Two, instructing the model to rewrite the text without bullets, disclaimers, or enumerations.
  12. If not found, it proceeds to final post-processing.
  13. Post-Processing:
  14. A regex checks each line for bullet-like patterns, disclaimers, etc., removing or merging lines as needed.
  15. Ensures the final output doesn’t exceed the -c/--characters limit (default 500).
  16. Print the Summaries:
  17. Displays the final result in your terminal with a neat header:
--- SUMMARY ---
[Summary here]
---------------

Key Components to Note

  • Regex Patterns: The script uses compiled regex to detect bullet points like *, -, 1., 1), etc. It also checks for disclaimers or references to “the article.” If you see that the script misses certain bullet styles, you can tweak these patterns.
  • Character Limit Enforcement: If the model’s summary is too long, the script truncates it and appends a period, making sure the final text is neat.
  • Model Name: By default, it might use something like llama3.2-vision:11b, but you can switch to any model recognized by your local Ollama setup.

4. Running the Summarizer

With your virtual environment active and tldr.py in the same directory, you have a few usage scenarios:

4.1 Default Run

python tldr.py
  • Uses the default URL stored in the script (usually EXAMPLE_URL).
  • Uses the default model (e.g., llama3.2-vision:11b) and default character limit (e.g., 500).
  • Not ideal in real usage, but a quick test to confirm everything is working.

4.2 Summarize a Custom URL

python tldr.py --url https://example.com/interesting-article
  • Fetches https://example.com/interesting-article
  • Outputs a bullet-free summary with the default character limit.

4.3 Specify a Character Limit

python tldr.py --url https://example.com/interesting-article --characters 300
  • Ensures the final summary does not exceed 300 characters.
  • Be aware that a very tight limit can cause abrupt or incomplete-sounding sentences, but the script tries to end with a period to smooth things out.

4.4 Choose a Different Model

python tldr.py --url https://example.com/another-article --model "qwen2.5-coder:14b"
  • Tell Ollama to use the "qwen2.5-coder:14b" model.
  • You can do this for any model that appears in ollama list.

4.5 Combine All Options

python tldr.py \
  --url https://example.com/another-article \
  --characters 250 \
  --model "jimscard/whiterabbit-neo:latest"
  • Summarizes https://example.com/another-article
  • Caps the summary at 250 characters
  • Uses the "jimscard/whiterabbit-neo:latest" model

5. Detailed Workflow Explanation

Let’s dive deeper into each step so you fully understand what’s happening under the hood:

  1. Command-Line Parsing
    The script uses argparse to interpret your flags. If you omit -u, it uses the default URL. If you omit -m, it uses the default model name.

  2. Fetch Article

response = requests.get(url, timeout=10)
response.raise_for_status()
  • The script sets a 10-second timeout to avoid hanging indefinitely on a slow or unresponsive server.
  • If the request fails (e.g., 404 error, DNS error), it prints an error and exits.

  • Extract Main Text

soup = BeautifulSoup(html_content, "html.parser")
for tag in soup(["script", "style"]):
  tag.decompose()
text = soup.get_text(separator="\n").strip()
  • The script removes <script> and <style> tags, then extracts the raw text.
  • This is a basic approach—it won’t always perfectly isolate the main article body. For more advanced use cases, you might integrate a library like readability-lxml or a specialized parser.

  • First Pass Prompt

prompt_1 = f"Produce a concise, single-paragraph TLDR of the text below..."
...
first_pass_output = ollama_run(model_name, prompt_1)
  • This instructs the chosen Ollama model to not use bullet points, disclaimers, or enumerations.
  • The script receives the model’s output as a string.

  • Check & (Possibly) Rewrite

  • The script scans the first-pass output for bullet points or disclaimers. If it finds them, it constructs a second prompt (prompt_2) saying, “Rewrite the following text...”
  • The rewritten text is then re-checked and cleaned up with regex for any leftover bullet patterns.

  • Post-Processing

  • The script merges multiple lines into a single paragraph.
  • If certain disclaimers are found (like “the article,” “rewrite,” or “disclaimer”), they are removed.
  • Finally, if the summary is too long, it’s truncated to your chosen character limit.

  • Output

print("\n--- SUMMARY ---\n")
print(summary)
print("\n---------------")
  • A neat header around the final summary is displayed.
  • You can redirect this output to a file if desired, for example:
python tldr.py -u https://example.com/another-article > summary.txt

6. Security & Malicious Sites

Some users worry about potentially malicious pages. Here’s the truth:

  • The script only downloads raw HTML and extracts text.
  • It does not execute any JavaScript or server-side code from the page.
  • However, the mere act of connecting to a malicious site might reveal your IP or attempt to exploit vulnerabilities in the requests library. While requests is generally safe, you should always be cautious when fetching unknown URLs.
  • If you manually open the downloaded HTML in a web browser, that’s a different risk scenario. The script itself never opens a browser or runs the HTML in an engine—it just reads text.

Disclaimer: The maintainers aren’t responsible for misuse of this script or any harm that might come from summarizing malicious content.


7. Advanced Tips & Customizations

  1. Adjust the Regex:
    If you see bullet points or enumerations the script misses, open tldr.py and search for the lines that define the bullet patterns. You can add or refine them.

  2. Experiment with Model Parameters:
    Ollama often supports parameters like --temperature. You could modify ollama_run calls to pass these parameters if you want more creative or more deterministic summaries.

  3. Chunk Very Large Articles:
    If the page’s text is enormous (several thousand tokens), you might consider splitting it into multiple chunks (e.g., 3000 tokens each) and summarizing them individually before merging the final summary. That’s beyond this script’s default scope, but it’s a common technique for large LLM tasks.

  4. Local vs. System-Wide Installation:

  5. We strongly recommend using a virtual environment to avoid messing up your system packages.
  6. If you must install things system-wide, just remember that updates to system libraries might break your script’s dependencies in the future.

  7. Logging & Debugging:

  8. If you run into errors, you might add print(prompt) or print(first_pass_output) lines to see what the script is sending or receiving from Ollama.
  9. This can help you debug the prompts or see how the model is actually responding.

  10. Using nohup or tmux

  11. If you’re summarizing multiple URLs on a server, you might run the script in a tmux session or with nohup so it keeps running even if your SSH session closes.

8. Example Scenario

Let’s walk through a practical example:

  1. You want to summarize https://example.com/security-news in 300 characters, using the qwen2.5-coder:14b model.
  2. You run:
python tldr.py --url https://example.com/security-news \
--characters 300 \
--model "qwen2.5-coder:14b"
  1. First Pass:
    The model might respond with:
"Here's a quick summary:
- The article discusses recent security vulnerabilities in ..."

Notice the bullet point.
4. Second Pass:
The script sees the bullet - and triggers a rewrite:

"Rewritten final summary:
This article covers recent security vulnerabilities..."

Now it’s bullet-free.
5. Post-Processing:
The script merges lines, removes disclaimers, and truncates if over 300 characters.
6. Result:
A single paragraph, no bullet points, no disclaimers, under 300 characters.


With these steps, you’ll have a robust, bullet-free summarization workflow running locally via Ollama. If you have more questions or feature requests, visit the GitHub repository and open an issue or discussion.

Happy summarizing!

No comments yet. Be the first to comment!