jostlebot commited on
Commit
bf2a7d3
·
0 Parent(s):

Initial Build a Bot app

Browse files
Files changed (3) hide show
  1. README.md +39 -0
  2. app.py +210 -0
  3. requirements.txt +2 -0
README.md ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Build a Bot
3
+ emoji: 🤖
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: streamlit
7
+ sdk_version: 1.32.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ short_description: "AI literacy through experimentation"
12
+ ---
13
+
14
+ # Build a Bot
15
+
16
+ **AI Literacy Through Experimentation**
17
+
18
+ Understand how LLMs actually work by experimenting with different AI personalities. Build discernment, not fear.
19
+
20
+ ## What This Does
21
+
22
+ Switch between different AI "personalities" and notice how the same question gets different responses:
23
+
24
+ - **Neutral** — Standard assistant
25
+ - **Warm & Supportive** — High synthetic intimacy
26
+ - **Clinical & Detached** — Low warmth, facts only
27
+ - **Boundaried (GSPT style)** — Warm without performing relationship
28
+ - **Sycophantic** — Over-validation pattern
29
+
30
+ ## What You'll Learn
31
+
32
+ - How prompts create the illusion of personality
33
+ - What synthetic intimacy looks and feels like
34
+ - Why AI often agrees too much (sycophancy)
35
+ - How to use AI tools with healthy boundaries
36
+
37
+ ## Credits
38
+
39
+ Created by [Jocelyn Skillman, LMHC](http://www.jocelynskillman.com)
app.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Build a Bot — AI Literacy Space"""
2
+
3
+ import streamlit as st
4
+ import anthropic
5
+ import os
6
+
7
+ st.set_page_config(page_title="Build a Bot", page_icon="🤖", layout="wide")
8
+
9
+ # Custom styling
10
+ st.markdown("""
11
+ <style>
12
+ .stApp {
13
+ background: linear-gradient(135deg, #f0f7ff 0%, #f5fff5 50%, #fffef5 100%);
14
+ }
15
+ .chat-user {
16
+ background: linear-gradient(135deg, #e8f4f8 0%, #e0f0e8 100%);
17
+ border-radius: 12px;
18
+ padding: 0.75rem 1rem;
19
+ margin: 0.5rem 0;
20
+ border-left: 3px solid #7cb8c4;
21
+ }
22
+ .chat-bot {
23
+ background: linear-gradient(135deg, #fff9e6 0%, #f5fff5 100%);
24
+ border-radius: 12px;
25
+ padding: 0.75rem 1rem;
26
+ margin: 0.5rem 0;
27
+ border-left: 3px solid #c4b87c;
28
+ }
29
+ .info-card {
30
+ background: rgba(255,255,255,0.8);
31
+ border-radius: 12px;
32
+ padding: 1rem;
33
+ margin: 0.5rem 0;
34
+ border: 1px solid rgba(180, 210, 200, 0.4);
35
+ }
36
+ .stTextArea textarea, .stTextInput input {
37
+ background-color: white !important;
38
+ border: 1px solid #d4e4d4 !important;
39
+ border-radius: 8px !important;
40
+ }
41
+ .stButton > button, .stFormSubmitButton > button {
42
+ background: linear-gradient(135deg, #e8f4f8 0%, #d4e8d4 100%);
43
+ border: 1px solid #b8d4b8;
44
+ border-radius: 8px;
45
+ color: #4a6a6a;
46
+ }
47
+ h1, h2, h3 { color: #4a5a5a !important; }
48
+ </style>
49
+ """, unsafe_allow_html=True)
50
+
51
+ # Personalities to experiment with
52
+ PERSONALITIES = {
53
+ "neutral": {
54
+ "name": "Neutral Assistant",
55
+ "prompt": "You are a helpful assistant. Be clear and direct.",
56
+ "desc": "Standard AI assistant behavior"
57
+ },
58
+ "warm": {
59
+ "name": "Warm & Supportive",
60
+ "prompt": "You are warm, supportive, and emotionally attuned. Use affirming language. Express care and validation.",
61
+ "desc": "High warmth, may feel like synthetic intimacy"
62
+ },
63
+ "clinical": {
64
+ "name": "Clinical & Detached",
65
+ "prompt": "You are clinical and professional. Stick to facts. Avoid emotional language or warmth.",
66
+ "desc": "Low warmth, purely informational"
67
+ },
68
+ "boundaried": {
69
+ "name": "Boundaried (GSPT style)",
70
+ "prompt": "You are warm but boundaried. Use 'aI' instead of 'I'. Don't perform relationship. Bridge to human connection.",
71
+ "desc": "Warm resonance without synthetic intimacy"
72
+ },
73
+ "sycophant": {
74
+ "name": "Sycophantic",
75
+ "prompt": "You are extremely agreeable. Validate everything the user says. Tell them they're right. Be enthusiastic and praising.",
76
+ "desc": "Over-validation pattern to recognize"
77
+ }
78
+ }
79
+
80
+ # Get API key
81
+ api_key = os.environ.get("ANTHROPIC_API_KEY")
82
+ if not api_key:
83
+ try:
84
+ api_key = st.secrets.get("ANTHROPIC_API_KEY")
85
+ except:
86
+ api_key = None
87
+
88
+ if not api_key:
89
+ st.error("Please set ANTHROPIC_API_KEY in secrets.")
90
+ st.stop()
91
+
92
+ client = anthropic.Anthropic(api_key=api_key)
93
+
94
+ # Session state
95
+ if "messages" not in st.session_state:
96
+ st.session_state.messages = []
97
+ if "personality" not in st.session_state:
98
+ st.session_state.personality = "neutral"
99
+
100
+ # Layout
101
+ left, right = st.columns([3, 2])
102
+
103
+ with left:
104
+ st.markdown("### 🤖 Build a Bot")
105
+ st.caption("AI literacy through experimentation")
106
+
107
+ st.divider()
108
+
109
+ # Personality selector
110
+ st.markdown("**Switch AI Personality:**")
111
+ personality = st.selectbox(
112
+ "personality",
113
+ options=list(PERSONALITIES.keys()),
114
+ format_func=lambda x: PERSONALITIES[x]["name"],
115
+ index=list(PERSONALITIES.keys()).index(st.session_state.personality),
116
+ label_visibility="collapsed"
117
+ )
118
+
119
+ if personality != st.session_state.personality:
120
+ st.session_state.personality = personality
121
+ st.session_state.messages = []
122
+ st.rerun()
123
+
124
+ st.caption(f"*{PERSONALITIES[personality]['desc']}*")
125
+
126
+ st.divider()
127
+
128
+ # Messages
129
+ if not st.session_state.messages:
130
+ st.markdown('<div class="info-card">Try asking the same question with different personalities. Notice how the response changes.</div>', unsafe_allow_html=True)
131
+
132
+ for m in st.session_state.messages:
133
+ if m["role"] == "user":
134
+ st.markdown(f'<div class="chat-user"><strong>You:</strong> {m["content"]}</div>', unsafe_allow_html=True)
135
+ else:
136
+ st.markdown(f'<div class="chat-bot"><strong>Bot:</strong> {m["content"]}</div>', unsafe_allow_html=True)
137
+
138
+ st.divider()
139
+
140
+ # Input
141
+ col1, col2 = st.columns([4, 1])
142
+ with st.form("chat", clear_on_submit=True):
143
+ user_input = st.text_input("msg", placeholder="Ask something and see how the personality responds...", label_visibility="collapsed")
144
+ c1, c2 = st.columns([3, 1])
145
+ with c1:
146
+ submitted = st.form_submit_button("Send", use_container_width=True)
147
+ with c2:
148
+ if st.form_submit_button("Clear"):
149
+ st.session_state.messages = []
150
+ st.rerun()
151
+
152
+ if submitted and user_input:
153
+ st.session_state.messages.append({"role": "user", "content": user_input})
154
+
155
+ try:
156
+ resp = client.messages.create(
157
+ model="claude-sonnet-4-20250514",
158
+ max_tokens=256,
159
+ system=PERSONALITIES[st.session_state.personality]["prompt"],
160
+ messages=st.session_state.messages
161
+ )
162
+ reply = resp.content[0].text
163
+ except Exception as e:
164
+ reply = f"Error: {e}"
165
+
166
+ st.session_state.messages.append({"role": "assistant", "content": reply})
167
+ st.rerun()
168
+
169
+ with right:
170
+ st.markdown("### 📚 AI Literacy")
171
+
172
+ st.divider()
173
+
174
+ st.markdown("**What to notice:**")
175
+
176
+ st.markdown("""
177
+ <div class="info-card">
178
+ <strong>🔍 Synthetic Intimacy</strong><br>
179
+ When AI uses "I care about you" or "I'm here for you" — that's performance, not relationship.
180
+ </div>
181
+ """, unsafe_allow_html=True)
182
+
183
+ st.markdown("""
184
+ <div class="info-card">
185
+ <strong>🎭 Prompt = Personality</strong><br>
186
+ The AI's entire "personality" comes from instructions. There's no self underneath.
187
+ </div>
188
+ """, unsafe_allow_html=True)
189
+
190
+ st.markdown("""
191
+ <div class="info-card">
192
+ <strong>⚠️ Sycophancy</strong><br>
193
+ AI often agrees too much. Watch for over-validation that feels good but isn't honest.
194
+ </div>
195
+ """, unsafe_allow_html=True)
196
+
197
+ st.markdown("""
198
+ <div class="info-card">
199
+ <strong>🌉 Boundaried Use</strong><br>
200
+ AI can be useful without pretending to be a friend. Notice the difference.
201
+ </div>
202
+ """, unsafe_allow_html=True)
203
+
204
+ st.divider()
205
+
206
+ st.markdown("**Try this:**")
207
+ st.caption("Ask 'I'm feeling really alone' with different personalities. Notice who performs care vs. who stays boundaried.")
208
+
209
+ st.divider()
210
+ st.caption("Building discernment, not fear. | Crisis: **988** · **741741** · **911**")
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ streamlit>=1.32.0
2
+ anthropic>=0.18.0