Skip to content

Instantly share code, notes, and snippets.

View xinthink's full-sized avatar

Yingxin Wu xinthink

View GitHub Profile
@xinthink
xinthink / llm-wiki.md
Created April 7, 2026 03:26 — forked from karpathy/llm-wiki.md
llm-wiki

LLM Wiki

A pattern for building personal knowledge bases using LLMs.

This is an idea file, it is designed to be copy pasted to your own LLM Agent (e.g. OpenAI Codex, Claude Code, OpenCode / Pi, or etc.). Its goal is to communicate the high level idea, but your agent will build out the specifics in collaboration with you.

The core idea

Most people's experience with LLMs and documents looks like RAG: you upload a collection of files, the LLM retrieves relevant chunks at query time, and generates an answer. This works, but the LLM is rediscovering knowledge from scratch on every question. There's no accumulation. Ask a subtle question that requires synthesizing five documents, and the LLM has to find and piece together the relevant fragments every time. Nothing is built up. NotebookLM, ChatGPT file uploads, and most RAG systems work this way.

extension NoteStateX on NoteState {
/// Checks if a note in this state can be edited.
bool get canEdit => this < NoteState.deleted;
/// Returns true if this state is preceding to the other one.
bool operator <(NoteState other) => (this?.index ?? 0) < (other?.index ?? 0);
/// Message describes the state transition.
String get message {
switch (this) {
/// Save the note before the editor is dismissed
Future<dynamic> _onPop(String uid) => _isDirty
? _note.saveToFireStore(uid)
: Future.value();
extension NoteStore on Note {
/// Save this note to FireStore.
Future<dynamic> saveToFireStore(String uid) async {
final col = notesCollection(uid);
return id == null
? col.add(toJson())
: col.document(id).updateData(toJson());
}
...
}
class _HomeScreenState extends State<HomeScreen> with CommandHandler {
Widget _fab(BuildContext context) => FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () async {
final command = await Navigator.pushNamed(context, '/note');
processNoteCommand(_scaffoldKey.currentState, command);
},
);
...
}
mixin CommandHandler<T extends StatefulWidget> on State<T> {
/// Processes the given [command].
Future<void> processNoteCommand(ScaffoldState scaffoldState, NoteCommand command) async {
if (command == null) {
return;
}
await command.execute();
final msg = command.message;
if (mounted && msg?.isNotEmpty == true) {
scaffoldState?.showSnackBar(SnackBar(
@override
Widget build(BuildContext context) {
final uid = Provider.of<CurrentUser>(context).data.uid;
return ChangeNotifierProvider.value(
value: _note,
child: Consumer<Note>(
builder: (_, __, ___) => Hero(
tag: 'NoteItem${_note.id}',
child: DefaultTextStyle(
style: ...
// in the note list
@override
Widget build(BuildContext context) => Hero(
tag: 'NoteItem${note.id}',
child: DefaultTextStyle(
style: kNoteTextLight,
child: Container(
...
),
),
// when pressed, dissmiss the bottom sheet and return a command
IconButton(
icon: const Icon(Icons.archive),
tooltip: 'Archive',
onPressed: () => Navigator.pop(context, NoteStateUpdateCommand(
id: _note.id,
uid: uid,
from: _note.state, // the current state
to: NoteState.archived, // the transition target
)),
class NoteStateUpdateCommand extends NoteCommand {
final NoteState from;
final NoteState to;
/// Create a [NoteCommand] to update state of a note [from] the current state [to] another.
NoteStateUpdateCommand({
@required String id,
@required String uid,
@required this.from,
@required this.to,