Installation and Getting Started with Fabric – The Prompt Optimizer

A vibrant, abstract digital artwork featuring a futuristic command-line interface surrounded by flowing text, code snippets, and creative patterns, symbolizing the process of optimizing AI model prompts with Fabric. The image combines modern, dynamic elements with a mix of bright and subdued colors

Introduction to Fabric

The qual­i­ty of results when using Large Lan­guage Mod­els (LLMs) like Olla­ma or Chat­G­PT heav­i­ly depends on the qual­i­ty of the prompts used. This under­stand­ing has led to the emer­gence of spe­cial­ized pro­fes­sions like Prompt Engi­neers, whose task is to con­fig­ure LLMs opti­mal­ly to achieve the best pos­si­ble results for spe­cif­ic require­ments or con­texts. In addi­tion, hun­dreds of arti­cles have been pub­lished with promis­ing titles like “The 100 Best Prompts for Gen­er­at­ing a Job Appli­ca­tion for a Top-Man­ag­er Posi­tion.”

Fab­ric, the tool intro­duced here, aims to sim­pli­fy and opti­mize the prompt cre­ation process to obtain the best results from a LLM. This arti­cle explains the instal­la­tion and basic usage.

What is Fabric?

The Fab­ric project by Daniel Miessler was devel­oped to enable LLM users to refo­cus on con­tent instead of get­ting lost in count­less prompt exper­i­ments. Fab­ric offers a library of over 140 so-called pat­terns tai­lored to spe­cif­ic tasks and prob­lems. Exam­ples include “extract_wisdom,” which extracts insights and key points from a text or YouTube video, and “create_coding_project,” which helps cre­ate the frame­work for a devel­op­ment project. The pat­terns describe in great detail which steps are per­formed with the input, the role the LLM should play, what it should pay spe­cial atten­tion to, and how the out­put should be struc­tured.

Fab­ric com­bines the input, whether it’s a text or a task con­text, with the cho­sen pat­tern and pass­es it to an LLM. This can either be done local­ly, as with LLMs pro­vid­ed by Olla­ma, or through cloud ser­vices like Ope­nAI, Claude, or Google.

As of late August 2024, Fab­ric is only a com­mand-line tool. The pre­vi­ous Python ver­sion had a GUI and serv­er inter­face, but these are not cur­rent­ly avail­able.

Installation of Fabric

The instal­la­tion is done through the pro­jec­t’s GitHub repos­i­to­ry. Fab­ric is writ­ten in Go, and some addi­tion­al tools are need­ed to run the exam­ples. There­fore, some prepa­ra­tions are nec­es­sary before instal­la­tion. Since the instal­la­tion and lat­er usage hap­pen in the Ter­mi­nal pro­gram, some expe­ri­ence with the com­mand line is rec­om­mend­ed. Feel free to ask any open ques­tions in the com­ments; I will try to answer them as quick­ly as pos­si­ble.

Preparation for Installation

First, go, git, and ffmpeg may need to be installed. I use the pack­age man­ag­er Home­brew for this pur­pose. If Home­brew is installed on the Mac, the nec­es­sary tools can be quick­ly installed in the Ter­mi­nal with the fol­low­ing com­mand:

brew install git go ffmpeg

If the pro­grams were already installed, no rein­stal­la­tion will occur.

After installing GO on my Mac, the search paths were not added to the .zshrc file. For a go installed with brew, a slight­ly dif­fer­ent path for GOROOT is need­ed than described in the instruc­tions on GitHub. To add these search paths, open the ~/.zshrc file in an edi­tor:

# I use nano as an editor
nano ~/.zsh

Then scroll to the end of the file and enter the fol­low­ing:

# Set Go Path
export GOROOT="$(brew --prefix golang)/libexec"
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$GOROOT/bin:$HOME/.local/bin:$PATH:

If Go was not installed with Home­brew, the GOROOT might look dif­fer­ent. How­ev­er, I can­not val­i­date this:

export GOROOT=/usr/local/go

With ⌃x⌃y the edi­tor is closed and the file is saved. Now, with the com­mand

source ~/.zshrc

the changes are made known to the sys­tem.

Steps to Install Fabric

First, the lat­est ver­sion of Fab­ric is installed from the GitHub repos­i­to­ry using the go com­mand:

go install github.com/danielmiessler/fabric@latest

Then, the set­up is start­ed with the fol­low­ing com­mand:

fabric --setup

If an error occurs when run­ning fabric --setup, indi­cat­ing that Fab­ric was not found, it may be due to incor­rect entries in the ~/.zshrc file, or the source com­mand was not exe­cut­ed. Alter­na­tive­ly, you can close the Ter­mi­nal win­dow and try run­ning the set­up again in a new win­dow.

Dur­ing the set­up process, you will first be prompt­ed to enter the API keys for ser­vices like Groq, Gem­i­ni, Anthrop­ic, Ope­nAI, and Azure. If you don’t plan to use any of these ser­vices, you must at least install Olla­ma and pro­vide the Olla­ma URL, which is typ­i­cal­ly http://localhost:11434. After enter­ing the infor­ma­tion for one or more of these ser­vices, a list of all avail­able LLMs will be gen­er­at­ed, from which you can select the default LLM. Fol­low­ing this, you will be asked to enter the YouTube API key. For the final prompts under the “Pat­terns Loader” sec­tion, I accept­ed the sug­gest­ed val­ues.

Once these inputs are com­plet­ed, the pat­terns are down­loaded and installed in $HOME/.config/fabric/patterns. Addi­tion­al­ly, a .env file is cre­at­ed in the $HOME/.config/fabric direc­to­ry, where the pro­vid­ed infor­ma­tion is stored. A file named unique_patterns.txt con­tains a list of all pat­terns. In the context fold­er, you can store text files that pro­vide addi­tion­al con­text when invok­ing Fab­ric. This allows you to define gen­er­al sup­ple­men­tary infor­ma­tion once and apply it across dif­fer­ent pat­terns as need­ed.

The pur­pose of the sessions fold­er, which is also cre­at­ed dur­ing set­up, is still unclear to me.

Basic Usage of Fabric

Fab­ric is a com­mand-line tool that adheres to the Unix phi­los­o­phy of flex­i­bly com­bin­ing small, spe­cial­ized pro­grams to cre­ate more com­plex work­flows. Pro­grams are con­nect­ed using the pipe sym­bol (|), where the out­put (std­out) of one pro­gram becomes the input (stdin) of the next. In a work­flow with Fab­ric, any com­mand-line tool that gen­er­ates out­put on std­out or con­sumes input via stdin can be uti­lized. For exam­ple, echo can be used for text input, or cat can be used to pass a text file. Addi­tion­al­ly, results can be writ­ten to a file using > or append­ed to a file with >>.

The fol­low­ing com­mand line demon­strates how to cre­ate a sim­ple work­flow with echo and Fab­ric that process­es a text and gen­er­ates a prompt sug­ges­tion for DALL‑E or Sta­ble Dif­fu­sion to cre­ate a logo:

echo "Two parrots on a skyscraper rooftop" | fabric --stream --pattern create_logo

In this exam­ple, the echo com­mand out­puts the text “Two par­rots on a sky­scraper rooftop,” which is then passed to the Fab­ric com­mand via the pipe sym­bol (|). Fab­ric process­es this text using the create_logo pat­tern, sends the result to the LLM, which in turn gen­er­ates a prompt sug­ges­tion that is dis­played in the com­mand line. The LLM, in this case, GPT-4o-mini, gen­er­at­ed the fol­low­ing prompt:

A simple, vector graphic logo featuring two stylized parrots perched on the edge of a minimalist skyscraper rooftop. The design should emphasize elegance and simplicity, using clean lines and a limited color palette to convey a modern urban feel

I man­u­al­ly sub­mit­ted the com­mand to Chat­G­PT and received the fol­low­ing image:

The image depicts a minimalist, stylized logo featuring two parrots perched on either side of a geometric structure that resembles a tall building with vertical lines. The design is enclosed within a rectangular frame, giving it a modern and symmetrical appearance. The parrots are facing each other, creating a balanced and cohesive look. The overall color scheme is monochromatic, likely in shades of black, gray, or white, which adds to the sleek and contemporary feel of the logo.

This approach allows for seam­less inte­gra­tion of dif­fer­ent com­mand-line tools into a cohe­sive work­flow with Fab­ric, pro­vid­ing flex­i­bil­i­ty and pow­er in han­dling var­i­ous text pro­cess­ing tasks.

The fol­low­ing exam­ple demon­strates how to cre­ate a sum­ma­ry of a web­page using Fab­ric (Note that wget and pandoc may need to be installed using Home­brew):

wget -qO - https://example.com/my-blog-article | pandoc -f html -t plain | fabric --stream --pattern summarize

In this exam­ple:

  1. wget down­loads the web­page con­tent.
  2. The HTML code is passed to pandoc, which con­verts it to plain text.
  3. The plain text is then piped to Fab­ric, which uses the summarize pat­tern to process the text with the LLM, and the sum­ma­ry is out­put.

To process a spe­cif­ic sec­tion of text from a doc­u­ment and direct­ly rein­sert the result back into the doc­u­ment, the pbpaste and pbcopy com­mands on macOS are par­tic­u­lar­ly use­ful. These com­mands allow you to pass the clip­board con­tent to Fab­ric, then copy the out­put back to the clip­board, which can sub­se­quent­ly be past­ed direct­ly into the doc­u­ment using ⌘-V.

Here’s how you can do it:

pbpaste | fabric -sp improve_writing | pbcopy

In this work­flow:

  1. pbpaste takes the cur­rent con­tent of the clip­board and pass­es it to Fab­ric.
  2. Fab­ric process­es the text using the improve_writing pat­tern.
  3. The processed text is then copied back to the clip­board using pbcopy.
  4. You can then paste the improved text back into your doc­u­ment by press­ing ⌘-V.

This method stream­lines the edit­ing process, mak­ing it easy to enhance spe­cif­ic sec­tions of your text and quick­ly rein­te­grate them into your doc­u­ments.

Advanced Features of Fabric

In the old Python ver­sion of Fab­ric, addi­tion­al tools like yt for tran­scrib­ing YouTube videos, ts for tran­scrib­ing audio files, and save for sav­ing the out­put to a defined fold­er were includ­ed. As of August 24, 2024, only the yt com­mand has been port­ed to the new ver­sion. It is cur­rent­ly uncer­tain whether the oth­er tools will be rein­tro­duced.

How­ev­er, the yt com­mand needs to be installed sep­a­rate­ly in this ver­sion:

go install github.com/danielmiessler/yt@latest

The yt tool extracts spo­ken text from a YouTube video, which can then be processed by Fab­ric.

Here’s how you can use it:

yt --transcript https://www.youtube.com/watch?v=UbDyjIIGaxQ | fabric --stream --output $HOME/Video_transcript.md --pattern extract_wisdom

In this exam­ple, the text from the video “You’ve Been Using AI Wrong” by Net­workChuck is extract­ed and ana­lyzed. The key insights, accord­ing to the defined rules of the extract_wisdom pat­tern, are saved in a Mark­down file named Video_transcript.md in the home direc­to­ry.

The video “You’ve Been Using AI Wrong” is what brought Fab­ric to my atten­tion. It’s worth watch­ing, though it dis­cuss­es the old, Python-based ver­sion of Fab­ric.

As a replace­ment for the save com­mand, which allowed sav­ing the out­put to a defined loca­tion, I use the fol­low­ing shell script. I save it under $HOME/Applications (which is includ­ed in my search path) with the name save, and make it exe­cutable with the fol­low­ing com­mand:

chmod +x $HOME/Applications/save 

Here is the script:

#!/bin/zsh

export PATH=$HOME/Applications/:$PATH:

# Define the directory where the file will be saved
TARGET_DIR="$HOME/Documents/fabric_files"

# Create the directory if it doesn't exist
mkdir -p "$TARGET_DIR"

# Set the current date as a prefix for the filename
DATE_PREFIX=$(date +"%Y-%m-%d")

# Set the base filename
BASENAME="note"
EXTENSION=".md"

# Generate the initial filename
FILENAME="${DATE_PREFIX}-${BASENAME}${EXTENSION}"

# Check if the file exists and find an incremental number
COUNTER=1
while [[ -e "${TARGET_DIR}/${FILENAME}" ]]; do
    FILENAME="${DATE_PREFIX}-${BASENAME}-${COUNTER}${EXTENSION}"
    COUNTER=$((COUNTER + 1))
done

# Read the text from the pipe and save it to the file
cat > "${TARGET_DIR}/${FILENAME}"

Now, the result of a Fab­ric com­mand can eas­i­ly be saved in the Documents/fabric_files fold­er under the name 2024–08-23-note.md using the fol­low­ing com­mand:

cat ~/Documents/Article_Draft.md | fabric -sp summarize | save

Useful Commands for Fabric

Before div­ing into the real mag­ic of Fab­ric, name­ly the pat­terns, here are some impor­tant com­mands:

fabric --listpatterns # This command lists all available patterns.
fabric --listmodels # This command lists all available LLM.
fabric --changeDefaultModel # This command allows you to change the default LLM.
fabric --model llama3.1:latest -sp summarize # This command temporarily changes the LLM to `llama3.1:latest` for this specific call.
fabric --output myFile.md -sp summarize # This command saves the output of the Fabric call to `myFile.md`.
fabric --context blogger-support -sp summarize

As pre­vi­ous­ly men­tioned, you can store files in the ~/.config/fabric/context direc­to­ry that pro­vide addi­tion­al infor­ma­tion for the Fab­ric com­mand. For exam­ple, in the blogger-support file, you could define addi­tion­al rules that are help­ful in the con­text of writ­ing a blog arti­cle. So these rules can be used not only with one pat­tern but also with the --context option in var­i­ous dif­fer­ent pat­tern calls.

cat ~/.config/fabric/.env #This command shows the current configuration stored in the `.env` file.

Additional Help

For more options and expla­na­tions, you can use the fol­low­ing com­mands:

fabric --help

or

yt --help

These com­mands pro­vide a detailed list of avail­able options and their expla­na­tions for both Fab­ric and the YT tool.

The Impor­tance of Pat­terns in Fab­ric

Pat­terns are the core of Fab­ric, as they effi­cient­ly pro­vide proven prompts that are mixed with your own con­tent and sent to an LLM for pro­cess­ing. These pat­terns can be eas­i­ly adapt­ed to your spe­cif­ic needs, or you can con­vert your own tried-and-true prompts into pat­terns direc­to­ry to use with Fab­ric.

Dur­ing instal­la­tion, around 140 pat­terns are installed (and the num­ber keeps grow­ing). These pat­terns are typ­i­cal­ly divid­ed into sec­tions. Most pat­terns begin with the “IDENTITY and PURPOSE” sec­tion, which describes the role the LLM should play and the tasks it has to per­form. This is fol­lowed by sec­tions with instruc­tions on how the LLM should approach the analy­sis of the input and what it should pay par­tic­u­lar atten­tion to. The “OUTPUT” sec­tion describes the for­mat of the out­put. The final sec­tion is the “INPUT,” which will lat­er be sup­ple­ment­ed with your input.

For exam­ple, the write_essay pat­tern includes the fol­low­ing instruc­tion in the “IDENTITY and PURPOSE” sec­tion:

# IDENTITY and PURPOSE You are an expert on writing concise, clear, and illuminating essays on the topic of the input provided.

How­ev­er, this alone is not suf­fi­cient, as the LLM also needs to under­stand what Paul Graham’s style looks like. There­fore, the pat­tern includes text exam­ples total­ing 9,025 words that define the typ­i­cal essay style of Paul Gra­ham. Fol­low­ing this, there are also some detailed out­put instruc­tions.

This is, of course, a pat­tern that begs to be cus­tomized. For instance, instead of Paul Gra­ham, you could use your own name, the text exam­ples could be tak­en from your own writ­ings, and the instruc­tions could be adjust­ed so that the out­put is an arti­cle for a mag­a­zine rather than an essay.

As a Ger­man native speak­er, you might find it espe­cial­ly use­ful to include an instruc­tion in the “OUTPUT INSTRUCTIONS” sec­tion that ensures the out­put is in Ger­man:

- Make the output in German.

When cus­tomiz­ing pat­terns, it’s advis­able to make changes in a copy of the pat­tern fold­er, which you can then rename to some­thing like my_summary. The devel­op­ers rec­om­mend sav­ing these cus­tomized fold­ers in a sep­a­rate direc­to­ry and only plac­ing a copy in the pat­terns fold­er. This pre­cau­tion is impor­tant because the orig­i­nal pat­terns, and poten­tial­ly your cus­tomized pat­terns stored in that fold­er, may be over­writ­ten dur­ing an updates

Using Context Files: Another way to adopt Patterns

As men­tioned above, using the –con­text option is anoth­er effec­tive method to tai­lor the out­put to your per­son­al needs. Let’s con­tin­ue with the exam­ple of ensur­ing the out­put is in Ger­man. To do this, cre­ate a file in the con­text direc­to­ry:

nano ~/.config/fabric/contexts/german

And include the fol­low­ing con­tent:

Make the output in German

Now, when­ev­er you call Fab­ric with the –context=german option along­side any pat­tern, the out­put will be in Ger­man.

For exam­ple:

echo "Why is the sky is blue" | fabric --context german --pattern create_academic_paper

In this case, Fab­ric will process the input and gen­er­ate the out­put in Ger­man, regard­less of the pat­tern used. This approach pro­vides a flex­i­ble and reusable way to ensure con­sis­tent out­put across var­i­ous tasks and pat­terns.

But using con­text files in Fab­ric offers far more pos­si­bil­i­ties than sim­ply set­ting a lan­guage pref­er­ence. The con­text fea­ture allows you to include a wide range of instruc­tions that can enhance or mod­i­fy the behav­ior of mul­ti­ple pat­terns, mak­ing it a pow­er­ful tool for cus­tomiz­ing how Fab­ric process­es your input.

For exam­ple, sup­pose you want to con­sis­tent­ly gen­er­ate aca­d­e­m­ic con­tent with a for­mal tone, (still) ensure that the out­put is in Ger­man, and include cita­tions in APA style. You can achieve this by cre­at­ing a con­text file that encap­su­lates all these require­ments:

nano ~/.config/fabric/contexts/academic_german

Then, include the fol­low­ing con­tent:

Make the output in German
Use a formal academic tone
Include citations in APA style
Ensure the content is well-structured with clear headings and subheadings

Now, when­ev­er you invoke Fab­ric with this con­text, it will apply these instruc­tions in addi­tion to the pattern’s default behav­ior:

echo "The effects of climate change on Arctic wildlife" | fabric --context academic_german --pattern create_academic_paper | pandoc -f latex -o output.pdf

This exam­ple cre­ates the paper in Ger­man and uses pandoc to con­vert fabric’s out­put direct­ly to a PDF.

Con­text files can be expand­ed to include any instruc­tions that are use­ful to you, such as:

  • Tar­get audi­ence con­sid­er­a­tions: Tai­lor­ing con­tent for spe­cif­ic read­ers, like indus­try pro­fes­sion­als or a gen­er­al audi­ence.
  • Spe­cif­ic writ­ing styles: Adopt­ing the style of a par­tic­u­lar author or pub­li­ca­tion.
  • For­mat­ting guide­lines: Ensur­ing con­sis­tent for­mat­ting, such as bul­let points, lists, or para­graph styles.

By lever­ag­ing the pow­er of con­text files, you can cre­ate ver­sa­tile, reusable con­fig­u­ra­tions that extend and enrich the func­tion­al­i­ty of Fab­ric pat­terns, mak­ing your work­flows more effi­cient and tai­lored to your exact needs.

Optimizing the Fabric Call

In the old ver­sion of Fab­ric, a file was includ­ed that cre­at­ed an alias def­i­n­i­tion for each Fab­ric pat­tern call and made these alias­es avail­able through the ini­tial­iza­tion of the .zshrc file. Since the new ver­sion no longer pro­vides this func­tion­al­i­ty, I have recre­at­ed it as a shell script. In this exam­ple, as a Ger­man speak­er, I added the con­text file from above to ensure that all out­put is in Ger­man.

#!/bin/bash
# Fixed path to the directory to be scanned
input_dir="$HOME/.config/fabric/patterns"

# Check if the path is a valid directory
if [ ! -d "$input_dir" ]; then
    echo "The directory $input_dir does not exist or is not a valid directory."
    exit 1
fi

# Filename for the .inc file
output_file="$HOME/.config/fabric/fabric-bootstrap.inc"

# Initialize the .inc file
echo "# Automatically generated aliases" > "$output_file"

# Loop through the subdirectories in the specified directory
for dir in "$input_dir"/*/; do
    # Check if it is indeed a directory
    if [ -d "$dir" ]; then
        # Remove the trailing slash and the path to get only the folder name
        folder_name=$(basename "$dir")
        # Create an alias in the form: alias foldername="fabric -sp foldername"
        echo "alias $folder_name=\"fabric -C=german -sp $folder_name\"" >> "$output_file"
    fi
done

echo "The file $output_file was successfully created."

Next, add the fol­low­ing entry at the end of your ~/.zshrc file:

# Created by `Fabric Installation` on 2024-08-06 12:45:30
if [ -f "/Users/leifjp/.config/fabric/fabric-bootstrap.inc" ]; 
    then . "/Users/leifjp/.config/fabric/fabric-bootstrap.inc"; 
fi

Acti­vate the new .zshrc with:

source ~/.zshrc

Now, a com­mand like:

wget -qO- https://example.com/my-blog-article | pandoc -f html -t plain | summarize

will out­put the sum­ma­ry in Ger­man instead of requir­ing:

wget -qO- https://example.com/my-blog-article | pandoc -f html -t plain | fabric -sp summarize

This approach works with any pat­tern with­out need­ing mod­i­fi­ca­tion. Of course, you can also add addi­tion­al gen­er­al instruc­tions to the con­text file.

Conclusion and Outlook

I hope this brief intro­duc­tion to Fab­ric makes get­ting start­ed a bit eas­i­er. In a future post, I will demon­strate how to fur­ther sim­pli­fy the use of Fab­ric and how it can be inte­grat­ed with Apple’s Short­cuts.

If you have any ques­tions, feed­back, or ideas regard­ing Fab­ric and its instal­la­tion, please feel free to use the com­ments sec­tion.

Leave a Reply

Your email address will not be published. Required fields are marked *