[{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/ai/","section":"Tags","summary":"","title":"Ai","type":"tags"},{"content":"For one of my AIDA (AI-drevne applikationer) assignments, I had to build a small AI-driven application that evaluates student assignments using a custom rubric and the OpenAI API. The app accepts an assignment submission, runs it through a structured rubric, and returns detailed feedback — strengths, weaknesses, per-criterion scores, and follow-up questions.\nThe whole thing was built with Claude Code, starting with Plan mode.\nThe Assignment # The task was to integrate an LLM into a real backend — not just call the API and print the response, but design proper prompts, define a rubric with proficiency levels, and return structured JSON feedback that could actually be used. The focus was on prompt engineering and LLM integration patterns rather than building something production-ready.\nUsing Plan Mode First # Before writing any code, I ran Claude Code in Plan mode and described what I needed. It came back with a proposed tech stack: FastAPI, Pydantic, and uvicorn.\nI hadn\u0026rsquo;t used any of these before. FastAPI for the backend, Pydantic for defining structured schemas for both the rubric and the LLM responses, and uvicorn as the ASGI server. It also suggested separating concerns cleanly — llm_client.py for the OpenAI calls, prompts.py for prompt templates, rubric.py for the criteria logic, and schemas.py for the data models.\nThe plan made sense. I approved it and let Claude Code execute.\nWhat Got Built # The result is a Python backend with five endpoints:\nGET /rubric — returns the full grading rubric GET /grades — returns the grade scale GET /samples/{student_id} — serves example assignment submissions POST /evaluate — takes a submission, calls the OpenAI API, and returns structured feedback GET / — serves a simple HTML frontend to test it all The feedback format includes an overall assessment, per-criterion scores with explanations, identified strengths and weaknesses, and 4–6 follow-up questions in JSON — exactly what the assignment required.\nIt Worked on the First Try # The entire thing ran correctly the first time I started it. No debugging sessions, no dependency issues, no broken endpoints. That was surprising — FastAPI and Pydantic were both new to me, but the generated code was clean and the structure was solid.\nWhat I Took Away # Plan mode changes how you start a project. Instead of jumping straight into code, you get a moment to see the full architecture before any files are created. When the plan involves tools you don\u0026rsquo;t know yet, you can ask questions or redirect — and then let the agent handle the execution.\nFastAPI and Pydantic turned out to be a great combination for this kind of LLM integration. Pydantic makes it straightforward to define exactly what shape you expect the LLM to return, which is one of the harder parts of prompt engineering in practice.\nThe project is available on GitHub.\n","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/posts/aida-grading-app/","section":"Posts","summary":"","title":"Building an AI Grading App with FastAPI","type":"posts"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/claude/","section":"Tags","summary":"","title":"Claude","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/coding-agents/","section":"Tags","summary":"","title":"Coding-Agents","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/fastapi/","section":"Tags","summary":"","title":"Fastapi","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/categories/learning/","section":"Categories","summary":"","title":"Learning","type":"categories"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/openai/","section":"Tags","summary":"","title":"Openai","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/productivity/","section":"Tags","summary":"","title":"Productivity","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/categories/projects/","section":"Categories","summary":"","title":"Projects","type":"categories"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/prompt-engineering/","section":"Tags","summary":"","title":"Prompt-Engineering","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/pydantic/","section":"Tags","summary":"","title":"Pydantic","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/categories/school/","section":"Categories","summary":"","title":"School","type":"categories"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/","section":"Thor Schou","summary":"","title":"Thor Schou","type":"page"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/tools/","section":"Tags","summary":"","title":"Tools","type":"tags"},{"content":"Coding agents have become a regular part of how I build things — and this portfolio is a good example. A lot of the setup, automation, and content here was built with the help of AI coding agents.\nWhat Is a Coding Agent? # A coding agent is more than a code autocomplete tool. Instead of just suggesting the next line, an agent can take a task, read through your codebase, make changes across multiple files, run commands, and iterate until the task is done.\nThe key difference from a regular AI assistant is autonomy. You describe what you want, and the agent figures out the steps — reading files, writing code, and fixing its own mistakes along the way.\nHow I Use Them # My main tool is Claude Code, which runs directly in the terminal and has access to my project files. I use it for:\nSetting up new features from scratch (like the Dify RAG sync workflow) Writing GitHub Actions workflows I\u0026rsquo;ve never written before Debugging configuration issues where I\u0026rsquo;m not sure what\u0026rsquo;s wrong Generating first drafts of blog posts and refining them together The workflow feels like pair programming. I describe the goal, the agent proposes an approach, I approve or redirect, and it executes.\nWhat Actually Works Well # The biggest win is crossing unfamiliar territory faster. As a student, I often need to work with tools I\u0026rsquo;ve never used before. An agent lets me get something working first and understand it second — which turns out to be a great way to learn.\nIt\u0026rsquo;s also good at tasks that are tedious but not creative — boilerplate, config files, repetitive edits across files. Things I could do myself but would rather not.\nWhat Doesn\u0026rsquo;t Work # Agents struggle when the goal is vague. If I say \u0026ldquo;make the site look better\u0026rdquo;, that goes nowhere useful. The more specific and concrete the task, the better the result.\nThey also can\u0026rsquo;t tell if something feels right — a layout change might be technically correct but visually off. For anything UI-related, I still have to check it myself.\nWhat I Learned # Using coding agents has made me better at breaking work into clear, concrete tasks. That skill turns out to be useful whether you\u0026rsquo;re talking to an AI or a teammate. The agent forces you to be precise about what you actually want — which is a surprisingly good habit to build.\n","date":"27 April 2026","externalUrl":null,"permalink":"/Portfolio/posts/coding-agents/","section":"Posts","summary":"","title":"Using Coding Agents in My Workflow","type":"posts"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/blowfish/","section":"Tags","summary":"","title":"Blowfish","type":"tags"},{"content":"One of the coolest features on this portfolio is the AI chatbot in the bottom right corner. It\u0026rsquo;s not just a regular chatbot — it uses RAG (Retrieval-Augmented Generation) to answer questions specifically about me, my projects and my posts.\nWhat is RAG? # RAG stands for Retrieval-Augmented Generation. Instead of relying solely on what an AI model already knows, RAG lets the model search through a knowledge base of your own documents before answering. This means the bot can answer questions about my specific projects and experience rather than making things up.\nThe Stack # Dify — an open-source platform for building AI-powered apps OpenAI gpt-4o-mini — the language model powering the responses GitHub Actions — automatically syncs new posts to the knowledge base Hugo — the static site generator serving the portfolio How It Works # I write a new blog post in markdown and push it to GitHub A GitHub Action automatically uploads the markdown file to Dify\u0026rsquo;s knowledge base If the file already exists, it deletes the old version first to avoid duplicates The chatbot can now answer questions about the new post Each post includes a canonical URL so the bot can link directly to it Setting It Up # The chatbot is embedded into the Hugo site using a single script in layouts/partials/extend-footer.html. Dify provides this embed script after you publish your chatbot app.\nThe auto-sync workflow lives in .github/workflows/sync-dify.yml and triggers on every push that changes files in the content/ folder.\nWhat I Learned # Building this taught me how RAG works in practice — how documents get chunked, embedded as vectors, and retrieved based on semantic similarity to a user\u0026rsquo;s query. It also showed me how powerful GitHub Actions can be for automating workflows beyond just deployment.\n","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/posts/rag-chatbot/","section":"Posts","summary":"","title":"Building a RAG Chatbot for My Portfolio","type":"posts"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/chatbot/","section":"Tags","summary":"","title":"Chatbot","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/dify/","section":"Tags","summary":"","title":"Dify","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/git/","section":"Tags","summary":"","title":"Git","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/github-actions/","section":"Tags","summary":"","title":"Github-Actions","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/github-pages/","section":"Tags","summary":"","title":"Github-Pages","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/hugo/","section":"Tags","summary":"","title":"Hugo","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/java/","section":"Tags","summary":"","title":"Java","type":"tags"},{"content":"This is my first post on my portfolio. I\u0026rsquo;m currently studying software development at Cphbusiness and this portfolio is built with Hugo and the Blowfish theme, deployed automatically via GitHub Actions.\nWhat I\u0026rsquo;ve learned so far # Setting up a Hugo static site Using Git and GitHub for version control Deploying to GitHub Pages with CI/CD Building a RAG chatbot with Dify and OpenAI ","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/posts/first-project/","section":"Posts","summary":"","title":"My First Project","type":"posts"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/portfolio/","section":"Tags","summary":"","title":"Portfolio","type":"tags"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/tags/rag/","section":"Tags","summary":"","title":"Rag","type":"tags"},{"content":"In this post I document how I set up my portfolio using Hugo and the Blowfish theme.\nWhat I used # Hugo static site generator Blowfish theme GitHub Actions for CI/CD GitHub Pages for hosting Steps # Installed Hugo and blowfish-tools via npm Created a new site with blowfish-tools new portfolio Connected to GitHub and set up automatic deployment Added a RAG chatbot powered by Dify and OpenAI What I learned # Setting up a static site with automatic deployment is surprisingly straightforward once you understand how GitHub Actions works. Every push to main automatically rebuilds and redeploys the site.\n","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/posts/hugo-setup/","section":"Posts","summary":"","title":"Setting Up Hugo with Blowfish","type":"posts"},{"content":"","date":"17 April 2026","externalUrl":null,"permalink":"/Portfolio/categories/tutorials/","section":"Categories","summary":"","title":"Tutorials","type":"categories"},{"content":"Hi, I\u0026rsquo;m Thor Asbjørn Schou, a Datamatiker student at Cphbusiness in Lyngby.\nI\u0026rsquo;m passionate about building things with code — from web applications to automation tools.\nSkills # Java HTML, CSS, JavaScript Git \u0026amp; GitHub ","externalUrl":null,"permalink":"/Portfolio/about/","section":"Thor Schou","summary":"","title":"About Me","type":"page"},{"content":"","externalUrl":null,"permalink":"/Portfolio/series/","section":"Series","summary":"","title":"Series","type":"series"}]