Use system instructions to steer the behavior of a model

This commit is contained in:
ajaysi
2024-08-18 17:13:00 +05:30
parent f35649f129
commit b97ad5eb2b
7 changed files with 90 additions and 61 deletions

View File

@@ -15,26 +15,9 @@ from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
def write_blog_google_serp(search_keyword, search_results): def write_blog_google_serp(search_keyword, search_results):
"""Combine the given online research and GPT blog content""" """Combine the given online research and GPT blog content"""
try:
config_path = Path(os.environ["ALWRITY_CONFIG"])
with open(config_path, 'r', encoding='utf-8') as file:
config = json.load(file)
except Exception as err:
logger.error(f"Error: Failed to read values from config: {err}")
exit(1)
blog_characteristics = config['Blog Content Characteristics']
prompt = f""" prompt = f"""
As expert Creative Content writer, As expert Creative Content writer,
I want you to write {blog_characteristics['Blog Type']} blog post, I want you to write blog post, that explores {search_keyword} and also include 5 FAQs.
that explores {search_keyword} and also include 5 FAQs.
Below are the guidelines to follow:
1). You must respond in {blog_characteristics['Blog Language']} language.
2). Tone and Brand Alignment: Adjust your tone, voice, personality for {blog_characteristics['Blog Tone']} audience.
3). Make sure your response content length is of {blog_characteristics['Blog Length']} words.
4). Include FAQs from 'People also Ask' section of provided context 'google search result'.
I want the post to offer unique insights, relatable examples, and a fresh perspective on the topic. I want the post to offer unique insights, relatable examples, and a fresh perspective on the topic.
Here are some Google search results to spark your creativity on {search_keyword}: Here are some Google search results to spark your creativity on {search_keyword}:
@@ -51,6 +34,7 @@ def write_blog_google_serp(search_keyword, search_results):
logger.error(f"Exit: Failed to get response from LLM: {err}") logger.error(f"Exit: Failed to get response from LLM: {err}")
exit(1) exit(1)
def improve_blog_intro(blog_content, blog_intro): def improve_blog_intro(blog_content, blog_intro):
"""Combine the given online research and gpt blog content""" """Combine the given online research and gpt blog content"""
prompt = f""" prompt = f"""

View File

@@ -13,59 +13,84 @@ def tweet_writer():
col1, col2 = st.columns([5, 5]) col1, col2 = st.columns([5, 5])
with col1: with col1:
hook = st.text_input( hook = st.text_input(
label="What's the tweet about:(Hook)", label="**What's the tweet about? (Hook)**",
placeholder="e.g., Discover the future of tech today!", placeholder="e.g., Discover the future of tech today!",
help="Provide a compelling opening statement or question to grab attention." help="Provide a compelling opening statement or question to grab attention."
) )
with col2: with col2:
# Collect user inputs with placeholders and help text
target_audience = st.text_input( target_audience = st.text_input(
label="Target Audience", label="**Target Audience**",
placeholder="e.g., technology enthusiasts, travel lovers", placeholder="e.g., technology enthusiasts, travel lovers",
help="Describe the audience you want to target with this tweet." help="Describe the audience you want to target with this tweet."
) )
col3, col4 = st.columns([5, 5])
with col3:
tweet_tone = st.selectbox(
label="**Tweet Tone**",
options=["Humorous", "Informative", "Inspirational", "Serious", "Casual"],
help="Choose the tone you'd like the tweet to have."
)
with col4:
cta = st.text_input(
label="**Call to Action (Optional)**",
placeholder="e.g., Retweet this if you agree! (Leave blank if not applicable)",
help="Provide a call to action if you'd like to include one."
)
col5, col6 = st.columns([5, 5])
with col5:
keywords_hashtags = st.text_input(
label="**Keywords/Hashtags**",
placeholder="e.g., #AI #Innovation",
help="Provide 2-3 relevant keywords or hashtags."
)
with col6:
tweet_length = st.selectbox(
"Tweet Length (Optional)",
options=["Short (under 100 characters)", "Medium (100-200 characters)", "Long (200+ characters)"],
help="Choose the desired tweet length.",
)
if st.button('**Write Tweets**'): if st.button('**Write Tweets**'):
if not target_audience or not hook: if not target_audience or not hook:
st.error("🚫 Please provide all required inputs.") st.error("🚫 Please provide all required inputs.")
else: else:
with st.status("Assigning AI professional to write your Google Ads copy..", expanded=True) as status: with st.status("Assigning AI professional to write your tweets...", expanded=True) as status:
response = tweet_generator(target_audience, hook) response = tweet_generator(target_audience, hook, tweet_tone, cta, keywords_hashtags, tweet_length)
if response: if response:
st.subheader(f'**🧕👩: Your Tweets!**') st.subheader(f'**🧕👩: Your Tweets!**')
st.markdown(response) st.markdown(response)
else: else:
st.error("💥**Failed to write Letter. Please try again!**") st.error("💥**Failed to generate tweets. Please try again!**")
def tweet_generator(target_audience, hook): def tweet_generator(target_audience, hook, tone_style, cta, keywords_hashtags, tweet_length):
""" Email project_update_writer """ """ Tweet Generator """
prompt = f""" prompt = f"""
You are a social media expert creating tweets for an audience interested in {target_audience}. You are a social media expert creating tweets for an audience interested in {target_audience}.
Write 5 engaging, concise, and visually appealing tweets that each: Write 5 engaging, concise, and visually appealing tweets that each:
1. Start with a compelling hook based on the following keywords: "{hook}" 1. Start with a compelling hook based on the following input: "{hook}"
2. Include a compelling call to action. 2. Include the following call to action: "{cta}"
3. Use 2-3 relevant hashtags. 3. Use 2-3 relevant keywords/hashtags, including: "{keywords_hashtags}"
4. Adopt a tone that matches the following options: 4. Adopt the following tone/style: "{tone_style}"
- Humorous 5. Adhere to the following length requirement: {tweet_length}
- Informative
- Inspirational Make sure to keep the tone consistent with the selected style and platform context.
- Serious
- Casual Here are some examples of call-to-actions to include (if no specific CTA was provided):
5. Be under 100 characters (including spaces and punctuation). - Retweet this if you agree!
- Share your thoughts in the comments!
Here are some examples of call-to-actions to include: - Learn more at [link]
- Retweet this if you agree! - Follow for more {target_audience} content.
- Share your thoughts in the comments!
- Learn more at [link] Output each tweet separated by a newline.
- Follow for more [topic] content """
- Like if you're excited about [topic]
Output each tweet separated by a newline.
"""
try: try:
response = llm_text_gen(prompt) response = llm_text_gen(prompt)

View File

@@ -2,7 +2,6 @@
import os import os
import sys import sys
from pathlib import Path from pathlib import Path
import streamlit as st
import google.generativeai as genai import google.generativeai as genai
from dotenv import load_dotenv from dotenv import load_dotenv
@@ -21,7 +20,7 @@ from tenacity import (
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6)) @retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
def gemini_text_response(prompt, temperature, top_p, n, max_tokens): def gemini_text_response(prompt, temperature, top_p, n, max_tokens, system_prompt):
""" Common functiont to get response from gemini pro Text. """ """ Common functiont to get response from gemini pro Text. """
#FIXME: Include : https://github.com/google-gemini/cookbook/blob/main/quickstarts/rest/System_instructions_REST.ipynb #FIXME: Include : https://github.com/google-gemini/cookbook/blob/main/quickstarts/rest/System_instructions_REST.ipynb
try: try:
@@ -37,7 +36,9 @@ def gemini_text_response(prompt, temperature, top_p, n, max_tokens):
"max_output_tokens": max_tokens, "max_output_tokens": max_tokens,
} }
# FIXME: Expose model_name in main_config # FIXME: Expose model_name in main_config
model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest", generation_config=generation_config) model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest",
generation_config=generation_config,
system_instruction=system_prompt)
try: try:
# text_response = [] # text_response = []
response = model.generate_content(prompt, stream=True) response = model.generate_content(prompt, stream=True)
@@ -45,7 +46,6 @@ def gemini_text_response(prompt, temperature, top_p, n, max_tokens):
for chunk in response: for chunk in response:
# text_response.append(chunk.text) # text_response.append(chunk.text)
print(chunk.text) print(chunk.text)
#st.write(chunk.text)
else: else:
print(response) print(response)
logger.info(f"Number of Token in Prompt Sent: {model.count_tokens(prompt)}") logger.info(f"Number of Token in Prompt Sent: {model.count_tokens(prompt)}")

View File

@@ -27,7 +27,21 @@ def llm_text_gen(prompt):
str: Generated text based on the prompt. str: Generated text based on the prompt.
""" """
try: try:
# Read the config param to create system instruction for the LLM.
gpt_provider, model, temperature, max_tokens, top_p, n, fp = read_return_config_section('llm_config') gpt_provider, model, temperature, max_tokens, top_p, n, fp = read_return_config_section('llm_config')
blog_tone, blog_demographic, blog_type, blog_language, \
blog_output_format, blog_length = read_return_config_section('blog_characteristics')
# Construct the system prompt with the sidebar config params.
system_instructions = f"""
Below are the guidelines to follow:
1). You must respond in {blog_language} language.
2). Tone and Brand Alignment: Adjust your tone, voice, personality for {blog_tone} audience.
3). Make sure your response content length is of {blog_length} words.
4). The type of blog is {blog_type}, write accordingly.
5). The demographic for this content is {blog_demographic}.
6). Your response should be in {blog_output_format} format.
"""
#gpt_provider = check_gpt_provider(gpt_provider) #gpt_provider = check_gpt_provider(gpt_provider)
# Check if API key is provided for the given gpt_provider # Check if API key is provided for the given gpt_provider
@@ -37,7 +51,7 @@ def llm_text_gen(prompt):
if 'google' in gpt_provider.lower(): if 'google' in gpt_provider.lower():
try: try:
logger.info("Using Google Gemini Pro text generation model.") logger.info("Using Google Gemini Pro text generation model.")
response = gemini_text_response(prompt, temperature, top_p, n, max_tokens) response = gemini_text_response(prompt, temperature, top_p, n, max_tokens, system_instructions)
return response return response
except Exception as err: except Exception as err:
logger.error(f"Failed to get response from gemini: {err}") logger.error(f"Failed to get response from gemini: {err}")
@@ -45,7 +59,7 @@ def llm_text_gen(prompt):
elif 'openai' in gpt_provider.lower(): elif 'openai' in gpt_provider.lower():
try: try:
logger.info(f"Using OpenAI Model: {model} for text Generation.") logger.info(f"Using OpenAI Model: {model} for text Generation.")
response = openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp) response = openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp, system_instructions)
return response return response
except Exception as err: except Exception as err:
logger.error(f"Failed to get response from Openai: {err}") logger.error(f"Failed to get response from Openai: {err}")

View File

@@ -14,7 +14,7 @@ from tenacity import (
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6)) @retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
def openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp): def openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp, system_prompt):
""" """
Wrapper function for OpenAI's ChatGPT completion. Wrapper function for OpenAI's ChatGPT completion.
@@ -45,7 +45,8 @@ def openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp):
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY')) client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
response = client.chat.completions.create( response = client.chat.completions.create(
model=model, model=model,
messages=[{"role": "user", "content": prompt}], messages=[{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt}],
max_tokens=max_tokens, max_tokens=max_tokens,
n=n, n=n,
top_p=top_p, top_p=top_p,

View File

@@ -131,8 +131,11 @@ def ai_seo_tools():
"Generate OpenGraph Tags", "Generate OpenGraph Tags",
"Optimize/Resize Image" "Optimize/Resize Image"
] ]
choice = st.selectbox("**👇Select AI SEO Tool:**", options, index=0, format_func=lambda x: f"📝 {x}")
# Using st.radio instead of st.selectbox
choice = st.radio("**👇 Select AI SEO Tool:**", options, index=0, format_func=lambda x: f"📝 {x}")
# Handle choices based on the selected option
if choice == "Generate Structured Data - Rich Snippet": if choice == "Generate Structured Data - Rich Snippet":
ai_structured_data() ai_structured_data()
elif choice == "Generate Meta Description for SEO": elif choice == "Generate Meta Description for SEO":

View File

@@ -0,0 +1,2 @@
alwrity_system_instruction: |