Why I love SolveIt
I have been using SolveIt since late 2024 as part of the first cohort of students, and honestly could not recommend it more. After spending more time with the platform, its growing functionality and tools, certain features stand out to me as genuinely unique in AI tooling.
Concise by design
SolveIt responses are concise. I find some other platforms almost unusable because of the length of their replies. It is too much effort to read through pages of response and you simply do not take it all in. SolveIt is different. Even in Learning mode, SolveIt is far more concise than other platforms. In Concise mode it is razor sharp.
I once tried replicating the SolveIt style with another provider. At the time SolveIt only supported Anthropic models and they were down, so I tried giving another platform detailed instructions including acting as a Socratic teacher. We were working together to create a recipe. At the end of a long session I just wanted it to summarise the recipe and the steps. It refused. Truly Socratic, it would not break character. I had to tell it I would be very hungry if it did not give me the recipe so I could actually use it. That problem is solvable with a clause in the prompt, but it illustrates the gap. SolveIt knows when to teach and when to deliver.
Concise responses also mean efficient token usage, which matters for both cost and environmental reasons. Less time reading filler, more time building.
Then there are the two modes, Learning and Concise. I almost always use Learning mode. It can feel like coding with training wheels on, but training wheels with resistance. It drags you back, forces you to think about what you are doing. The grind of getting the initial thoughts, planning and encoding right is the point. That is where you learn. The payoff is that you build genuine understanding rather than dependency. As the dialog grows, the resistance fades and the momentum is yours.
Model selection within a single dialog is powerful. I can start with a stronger model to establish good context, then switch to a less expensive model as the dialog grows or bounce back and forth when precision matters.
Editing the dialog and context
The ability to edit previous message history is, for me, the most important feature. Most AI tools treat conversation history as fixed. You send a response, realise the AI misunderstood something three steps back and you are stuck in an increasingly broken thread. SolveIt lets you go back, fix the earlier message and continue. The context repairs itself. This alone changes how I work.
Editing also keeps the context concise. By trimming tangents and correcting misunderstandings at source, you reduce the total token count. I suspect this also helps with the lost-in-the-middle problem that plagues long contexts. Not only because your context is shorter, but because you have carefully edited the flow so the conversation does not drift off track. I only have my own observations to back this up, but the difference in coherence over long dialogs is noticeable.
In SolveIt the context can get smarter, not dumber, as it increases. As the dialog grows, SolveIt becomes more honed into your way of thinking. It is aligning itself with your thoughts and reinforcing the direction your brain is going.
I often wonder why other providers do not allow editing of the conversation history. LM Studio lets you do it locally, but most cloud platforms lock the history. I suspect they see editable context as an attack vector. LLMs are autoregressive and editable history could theoretically lead them past safeguards. But in SolveIt, that autoregressive nature is precisely why editing works so well. You can almost teach the model the direction you want to go. You can let it get something wrong once, then correct the earlier message yourself to show how it should be done on the second attempt. Even if the model failed the first time, the corrected context guides it properly the next. You steer rather than restart.
It is like debugging your own thought process. When you edit a response to match what you actually meant, you are not just fixing a mistake. You are conditioning the autoregressive flow of the entire dialog. The next response is generated based on the corrected version, not the flawed one. Get trapped in "that is wrong, try again" cycles with other tools and you reinforce the wrong path. Each failed attempt becomes part of the context, making the next attempt more likely to fail in similar ways. SolveIt lets you rewrite the history.
Over a long dialog this builds into something where the context is so aligned with your thinking that the conversation starts to flow as if from a single mind rather than human and LLM.
Close reading
Close reading is where SolveIt becomes something else entirely. The idea is simple: treat a video lecture like a dense text, reading it slowly with an AI partner that challenges you. See the excerpt at the end of this post for an example. I extract transcripts from YouTube, SolveIt tools to embed video segments and key screenshots inline and FastAnki to generate personalised Anki cards from my specific confusions. The same approach works for research articles, papers and any long text. Anywhere you need to read deeply rather than skim.
Code cells are part of the conversation in SolveIt, not a separate tool. You run code inline, see the output and keep talking about it with the AI seeing what you see. When concepts need precision or a numerical check, you reach for the Python kernel rather than a text answer. LLMs are probabilistic text predictors and arithmetic in a text response is unreliable. The right tool for the right task.
The loop works in small chunks. Watch a short segment, explain your understanding back, get challenged if you are wrong, discuss until it clicks. No hand-waving past confusion. Then generate Anki cards from the gaps you discovered. Spaced repetition locks it in. If the Anki cards surface new questions, you return to the dialog, ask those questions and the understanding loop continues.
The rules matter. Ask stupid questions, they are where learning happens. Set anti-sycophancy, the AI should push back. Stay honest to source pacing, do not jump ahead. Think in small chunks because slow learning compounds.
The deeper principle is what makes it work. Passive watching is fast, intuitive and gives an illusion of understanding. Close reading is slow, deliberate and effortful. Anki then trains the fast intuition back from the deliberate work. The friction is the learning.
With SolveBlog, close reading now goes full circle. You can turn the output of your close reading sessions into a blog post with ease. Writing about what you have learned reinforces your own understanding and helps you share that learning with others. The loop extends beyond your own head.
Mastery
SolveIt is not selling productivity, it is selling mastery. The human remains the agent. The tools get better, the loops get tighter, but that never changes. If SolveIt were a car, its bumper sticker would read: Warning. Human still driving.
Thanks to Jeremy and all the team at Answer.AI for creating such a wonderful tool.
A few of the similes and metaphors in this post may have come from SolveIt interviews and descriptions of other machine learning work. They are apt here. Debugging your thought process and the bumper sticker are mine.
An excerpt from one of my close reading sessions of a fast.ai lesson.
To demonstrate how close reading can work, here is an excerpt from a real close reading session on the fast.ai Practical Deep Learning for Coders part 2: Deep Learning Foundations to Stable Diffusion, Lesson 24: Attention & transformers. The topic is attention mechanisms but the workflow is what matters.
This method was adapted from a notebook shared by Answer.AI's Rens Dimmendaal, with a few tweaks and adding in Anki cards.
🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠
add_video_embed(video_id='DH5bp6zTPB4', start_secs=4143, end_secs=4403)
```json { "id": "toolu_013ebJdrWqF7qAgMZhNeMX9Y", "call": { "function": "add_video_embed", "arguments": { "video_id": "DH5bp6zTPB4", "start_secs": "4143", "end_secs": "4403" } }, "result": "None" } ```get_segment_subs(start_secs=4143, end_secs=4403)
```json { "id": "toolu_01Hg56yUbuaw8gUsxH3u4wAq", "call": { "function": "get_segment_subs", "arguments": { "start_secs": "4143", "end_secs": "4403" } }, "result": "\"[69:03] final projection again just to give it\\n[69:05] the opportunity to map things you know\\n[69:08] to to some different scale you know\\n[69:11] shift it also if necessary\\n[69:13] uh transpose the last two back to where\\n[69:16] they started from and then reshape it\\n[69:18] back to where it started from and then\\n[69:20] add it remember I said it's going to be\\n[69:21] X Plus add it back to the original so\\n[69:24] this is actually kind of self-attention\\n[69:27] res resnet style if you like diffusers\\n[69:31] if I remember correctly does include the\\n[69:33] X Plus in theirs but um somadd_notes(content='## Section: Self-attention module with X Plus addi…')
```json { "id": "toolu_01R3jFoqAEBZ9asQUybo7e27", "call": { "function": "add_notes", "arguments": { "content": "## Section: Self-attention module with X Plus addition (1:09:03\u20131:13:23)\n\n**Key points:**\n- Final output: transpose back, reshape back to original shape, then **add to original X** (residual connection)\n- This is \"self-attention ResNet style\" \u2014 diffusers includes the X+, some implementations (like PyTorch) don't\n- The module just needs to know number of channels (for the 4 projections and group norm)\n\n**Optimization trick:**\nInstead of 3 separate projections (Q, K, V), use ONE projection from `ni` \u2192 `ni*3`, then `.chunk(3)` to split. More concise and faster (less CPU-GPU back and forth).\n\n**TeDone! Video and notes added for "Self-attention module with X Plus addition" (1:09:03–1:13:23).
Key takeaway: the residual connection (X + attention(X)) is important — it lets the network learn "how much attention to add" rather than replacing the original.
Watch and let me know what questions come up!
Section: Self-attention module with X Plus addition (1:09:03–1:13:23)
Key points:
- Final output: transpose back, reshape back to original shape, then add to original X (residual connection)
- This is "self-attention ResNet style" — diffusers includes the X+, some implementations (like PyTorch) don't
- The module just needs to know number of channels (for the 4 projections and group norm)
Optimization trick:
Instead of 3 separate projections (Q, K, V), use ONE projection from ni → ni*3, then .chunk(3) to split. More concise and faster (less CPU-GPU back and forth).
Testing: Copy weights from your implementation to diffusers' attention block — if outputs match, your implementation is correct.
sqkv = nn.Linear(ni, ni*3)
st = sqkv(t)
st.shapeq,k,v = torch.chunk(st, 3, dim=-1)
q.shape
([email protected](1,2)).shapeclass SelfAttention(nn.Module):
def __init__(self, ni):
super().__init__()
self.scale = math.sqrt(ni)
self.norm = nn.BatchNorm2d(ni)
self.qkv = nn.Linear(ni, ni*3)
self.proj = nn.Linear(ni, ni)
def forward(self, inp):
n,c,h,w = inp.shape
x = self.norm(inp).view(n, c, -1).transpose(1, 2)
q,k,v = torch.chunk(self.qkv(x), 3, dim=-1)
s = ([email protected](1,2))/self.scale
x = s.softmax(dim=-1)@v
x = self.proj(x).transpose(1,2).reshape(n,c,h,w)
return x+inp
sa = SelfAttention(32)
sa(x).shape
🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠
Two questions:
Why do we add the attention output back to the original X (the residual connection)?
Why is combining Q, K, V into one
ni → ni*3projection and then chunking faster than three separate projections?
🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠
Yes to both!
Residual connection: Without
X +, the attention output completely replaces X. The residual lets the model learn "what to add" rather than "what to replace with" — and helps gradients flow during training.One big matmul: GPUs love large operations. Three separate matmuls = three kernel launches + overhead. One matmul + chunk = one kernel launch, better parallelism.
Ready for the next section? "Multi-headed attention simplifies information gathering" (1:13:23–1:15:46)
🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠
Ha! Good observation. Yes — if they're literally computed as one big matrix then split into three chunks, they're really just "projection 1, 2, 3" at the implementation level. The Query/Key/Value naming is a post-hoc explanation, not how the math actually works.
🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠
Summary: Attention & Self-Attention
Why attention?
- Convolutions have limited receptive fields — distant pixels need many layers to communicate
- Attention lets any pixel attend to any other pixel in one operation
- More useful at high resolution (pixels far apart) than low resolution
How attention works:
- Flatten image from (N,C,H,W) → (N, H×W, C) — pixels become a sequence
- Create three projections: Q, K, V (or just "projection 1, 2, 3")
- Compute similarity:
Q @ K.T→ (H×W, H×W) weights matrix - Scale by
1/√dto keep values stable - Softmax to get weights summing to 1
- Multiply by V to get weighted information
- Add back to original X (residual connection)
Q, K, V roles:
- Q: "What am I looking for?"
- K: "What do I have?"
- V: "What I contribute when attended to" (same for any query)
Key insights:
- Self-attention = Q, K, V all from same input
- Like a fuzzy dictionary lookup — soft matching, weighted blend of values
- Raw dot product (not cosine) — magnitude matters
- Implementation trick: one
ni → ni*3projection + chunk is faster than three separate ones
Ready for multi-headed attention next?
🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠🧠
Good catch! Since the last sync we covered:
- Group Norm — normalizes across groups of channels, per sample
- Layer Norm — group norm with just one group (all channels)
- Batch Norm vs Group Norm vs Layer Norm — comparison
- The fourth projection (proj) — why it's there after attention
- Residual connection in self-attention — why add X back
- Combining Q,K,V into one projection — optimization trick
- Bias in attention — why some implementations include/exclude it
Want me to add cards for all of these?
🧠🧠🧠🧠
add_fb_card(front='What is Group Norm?', back='Normalizes across groups of channels within each s…', deck='FastAiP2')
```json { "id": "toolu_0162urvNooMxBxca48HmhxTr", "call": { "function": "add_fb_card", "arguments": { "front": "What is Group Norm?", "back": "Normalizes across groups of channels within each sample independently. Like batch norm but doesn't depend on batch size \u2014 preferred when batches are small.", "deck": "FastAiP2" } }, "result": "1769549433168" } ```add_fb_card(front='What is Layer Norm?', back='Group norm with just one group — normalizes across…', deck='FastAiP2')
```json { "id": "toolu_01GsdjcrcnMHtvzDE6xJBQpN", "call": { "function": "add_fb_card", "arguments": { "front": "What is Layer Norm?", "back": "Group norm with just one group \u2014 normalizes across ALL channels within each sample. What transformers typically use.", "deck": "FastAiP2" } }, "result": "1769549433182" } ```add_fb_card(front='How do Batch Norm, Group Norm, and Layer Norm diff…', back='Batch norm: across all samples, per channel. Group…', deck='FastAiP2')
```json { "id": "toolu_0156poAHsycaUcCyfU57zfLh", "call": { "function": "add_fb_card", "arguments": { "front": "How do Batch Norm, Group Norm, and Layer Norm differ?", "back": "Batch norm: across all samples, per channel. Group norm: across groups of channels, per sample. Layer norm: across all channels, per sample (group norm with 1 group).", "deck": "FastAiP2" } }, "result": "1769549433195" } ```add_fb_card(front='Why is there a fourth projection (proj) after atte…', back='Gives the model a chance to transform/scale the at…', deck='FastAiP2')
```json { "id": "toolu_01Gd479s7ocDshBoYDLcdsou", "call": { "function": "add_fb_card", "arguments": { "front": "Why is there a fourth projection (proj) after attention computes softmax([email protected])@V?", "back": "Gives the model a chance to transform/scale the attention output before adding to the residual. Also combines heads in multi-headed attention.", "deck": "FastAiP2" } }, "result": "1769549433207" } ```add_fb_card(front='Why add X back to the attention output (residual c…', back='Lets the model learn "what to add" rather than "wh…', deck='FastAiP2')
```json { "id": "toolu_018ymJViBMTnUzBtw1u67NFx", "call": { "function": "add_fb_card", "arguments": { "front": "Why add X back to the attention output (residual connection)?", "back": "Lets the model learn \"what to add\" rather than \"what to replace with.\" Also helps gradients flow during training.", "deck": "FastAiP2" } }, "result": "1769549433381" } ```add_fb_card(front='Why combine Q, K, V into one projection (ni → ni*3…', back='Faster on GPU — one large matmul + chunk = one ker…', deck='FastAiP2')
```json { "id": "toolu_019C4TekB6aWF4XfjD4xsnJo", "call": { "function": "add_fb_card", "arguments": { "front": "Why combine Q, K, V into one projection (ni \u2192 ni*3) then chunk, instead of three separate projections?", "back": "Faster on GPU \u2014 one large matmul + chunk = one kernel launch, vs three separate matmuls = three kernel launches + overhead.", "deck": "FastAiP2" } }, "result": "1769549433393" } ```sync()
```json { "id": "toolu_015LpRFn3NPwyWSWMYr8sxMx", "call": { "function": "sync", "arguments": {} }, "result": "host_number: 23\nserver_media_usn: 356" } ```Added 6 cards and synced:
- What is Group Norm
- What is Layer Norm
- Batch/Group/Layer Norm comparison
- Fourth projection (proj) purpose
- Residual connection in self-attention
- Q,K,V combined projection optimization
Ready for the next section? "Multi-headed attention simplifies information gathering" (1:13:23–1:15:46)
The close reading continues in small sections
Then there's continued loops of this watching/reading in small chunks, with the benefit of the context of what I've learnt and understood so far.
The result is I've added personalised Anki cards for repetitive spaced learning, which I can tweak later if needed.