AI 资讯
What AGENTS.md Gives Coding Agents That README Files Do Not
Here's the failure mode I keep running into. A team gives a coding agent a repo, a task, and maybe a README. The agent can find files and write code, but it still has to guess the operating rules. It guesses the package manager. It guesses which checks matter. It guesses whether generated files are safe to edit. It guesses what "done" means. A README is usually for humans: what the project is, how to run it, and where the important docs live. A coding agent needs different context. Setup rules. Test commands. Boundaries. Completion criteria. That's the gap AGENTS.md fills. The official AGENTS.md guidance describes it as a predictable place for coding-agent instructions: setup commands, test commands, code style, security considerations, and nested instructions for large monorepos. I find the split useful in a more boring way. The README answers, "What is this project?" AGENTS.md answers, "What should an agent know before touching it?" That second question is where the work usually gets fragile. Where Goose Fits Goose makes this less theoretical because it isn't just a chat box. It's an open source local AI agent with a desktop app, CLI, API, MCP extensions, and skills. Without AGENTS.md , I find myself writing prompts like this: Update the docs, but don't touch generated files, use pnpm, run the lint and test commands, keep the PR small, and tell me what you couldn't verify. With AGENTS.md , the prompt can get shorter: Update the quickstart docs for the new config flag. Goose can run the task in the repo. The repo can carry the standing instructions. I noticed this on a small docs/config update where generated files sat near source files. Without repo instructions, the prompt had to carry the package manager, generated-file boundary, checks, and the "tell me what you could not verify" rule. Once those rules lived in AGENTS.md , the prompt became just the task. Not magic. Just fewer chances to forget the boring parts. Where Skills Fit I would add one more layer once
AI 资讯
AI's Impact on Junior Developer Roles: A New Era
The Evolution of Junior Developer Roles in the Age of AI In the tech industry, a pressing question has emerged: Is the role of junior developers disappearing? With the rapid advancement of artificial intelligence (AI), particularly generative models like ChatGPT, there's growing concern about the future of entry-level software development jobs. While some predict a decline, the reality is more nuanced. AI is transforming these roles, not eliminating them, creating new opportunities for junior developers who adapt to the changing landscape. TL;DR AI advancements are reshaping junior developer roles rather than removing them. AI tools reduce the need for routine coding tasks but create opportunities for those focusing on higher-order skills like problem-solving and collaboration. Junior developers should embrace AI tools to enhance creative problem-solving. Companies must adapt talent strategies to nurture junior developers for future senior roles. The Transformation of Junior Developer Roles AI's Impact on Routine Coding Tasks Artificial intelligence has significantly automated routine coding tasks. AI models, such as ChatGPT, can generate code snippets, debug errors, and optimize performance. This capability shifts junior developers' focus from these tasks, traditionally a large part of their responsibilities. Code Generation : AI can produce boilerplate code, reducing the time spent on repetitive tasks. Error Detection : AI-driven tools identify and propose fixes for common coding errors, streamlining debugging. Performance Optimization : AI algorithms can automatically enhance code efficiency, which previously required manual intervention. Changing Nature of Junior Developer Roles The employment rate for junior developers aged 22-25 has declined nearly 20% from its peak in 2022. This trend indicates a shift in how entry-level positions are perceived and utilized within tech companies. With AI handling routine tasks, the role of a junior developer is evolving to em
AI 资讯
Building CogneeCode - AI Developer Memory Assistant
🧠 Building CogneeCode - AI Developer Memory Assistant The Problem Every developer faces the problem of lost context. "Why did I make this decision 3 months ago?" "How did I fix this bug last week?" Current AI tools forget everything between sessions. This is a real problem that wastes hours of developer time. My Solution CogneeCode is an AI developer memory assistant that builds a permanent knowledge graph using Cognee Cloud . It remembers every decision, bug fix, and code context you give it. What It Does ✅ Log architectural decisions with tags and context ✅ Log bug fixes with error messages and solutions ✅ Ask natural language questions about your codebase ✅ Get answers with evidence citations from the knowledge graph ✅ Semantic search across all memories ✅ Visual timeline of all decisions and bug fixes ✅ Analytics dashboard showing memory insights ✅ Knowledge graph visualization Tech Stack Backend: Flask (Python) Memory Layer: Cognee Cloud LLM: Groq Llama 3.3 Frontend: Vanilla HTML + CSS + JS Icons: Tabler Icons Cognee Cloud APIs Used remember() - Save decisions and bug fixes with metadata recall() - Natural language queries with evidence citations search() - Semantic search across memories visualize() - Knowledge graph visualization improve() - Memory graph enrichment forget() - Remove outdated memories Why This Matters When you return to a project after months, all your reasoning and solutions are still there, searchable in natural language. No more "Why did I do this?" or "How did I fix this bug?" Demo Watch the video: https://youtu.be/TNcBIBuPW7c Links 🔗 GitHub: https://github.com/JOSESAMUEL14/cogneecode 🔗 Live Demo: https://josesamuel.pythonanywhere.com AI Assistance Disclosure Built with assistance from Claude and Gemini AI. Built for WeMakeDevs x Cognee Hackathon 2026 Category: Best Use of Cognee Cloud ⭐ Star the repo if you find it useful!
开发者
개발 지식 없이도 외주 앱 개발 과정을 직접 점검하는 방법
개발 역량이 없어도 외주 개발사의 진행 상황을 명확하게 파악하고 피드백을 줄 수 있다. 필요한 건 기술 지식이 아니라, 올바른 협업 구조다. 이 글은 비개발자 제품 관리자가 바로 적용할 수 있는 투명한 피드백 루프와 점검 방식을 소개한다. 외주 개발에서 비개발자가 소외되는 이유는 무엇인가? 외주 개발사와 일을 시작하면 처음 며칠은 소통이 활발하다. 요구사항 정리, 계약, 착수 미팅까지는 순탄하다. 문제는 그 이후다. 개발이 시작되면 대화의 언어가 바뀐다. "API 연결 중", "백엔드 스키마 설계 단계", "프론트 컴포넌트 분리 작업"처럼 전공자가 아니면 체감하기 어려운 표현들이 보고서를 채운다. 이 상태에서 비개발자가 할 수 있는 질문은 사실상 하나뿐이다. "잘 되고 있나요?" 그리고 돌아오는 답도 하나다. "네, 잘 되고 있습니다." 이 구조는 어느 개발사가 나쁜 의도를 가져서 생기는 문제가 아니다. 개발자는 기술 언어로 사고하고, 비개발자는 결과와 흐름으로 사고한다. 이 두 언어 사이에 다리가 없을 때 소외가 생긴다. 그리고 이 소외는 감정의 문제가 아니라 실질적인 리스크다. 방향이 틀어진 채 몇 주가 흐르면, 다시 맞추는 비용은 처음보다 훨씬 커진다. 비개발자가 개발 과정을 직접 점검할 수 있는 구조가 필요한 이유가 여기 있다. 비개발자가 진행 상황을 파악할 수 있는 협업 구조란? 투명한 협업 구조는 "보고를 더 자주 받는 것"이 아니다. 받는 정보의 언어와 형식을 바꾸는 것이다. 포텐랩은 매주 진행 상황을 공유하는 주간 피드백 루프를 팀 표준으로 운영한다. 이 루프의 핵심은 세 가지다. 무엇이 완료됐는가 : 이번 주에 실제로 만들어진 것, 확인 가능한 것. 다음 주에 무엇을 만드는가 : 다음 단계에서 기대할 수 있는 결과물. 막힌 것이 있는가 : 결정이 필요하거나 확인이 필요한 사항. 이 세 가지가 매주 비개발자도 읽을 수 있는 언어로 정리된다면, 소통 구조는 이미 절반 이상 해결된 것이다. 기술 용어 없이 "로그인 화면 완성, 다음 주엔 상품 목록 화면 작업"이라고 쓸 수 있다면, 비개발자는 지금 어디쯤 왔는지 감을 잡을 수 있다. 주간 피드백 루프를 실제로 설계하는 방법 주간 루프가 형식적인 보고에 그치지 않으려면 구조가 있어야 한다. 아래는 포텐랩이 프로젝트마다 적용하는 주간 피드백 사이클의 구성이다. 1단계 — 주간 업데이트 문서 공유 매주 정해진 요일에 개발팀이 업데이트 문서를 공유한다. 이 문서에는 완료된 기능, 다음 주 작업 항목, 그리고 결정이 필요한 사항이 포함된다. 형식은 슬랙 메시지든, 노션 페이지든 팀이 합의한 채널이면 된다. 중요한 건 형식보다 주기와 언어다. 매주 같은 날, 비개발자가 읽을 수 있는 언어로. 2단계 — 화면으로 확인 가능한 결과물 공유 텍스트 보고만으로는 실제로 무엇이 만들어졌는지 체감하기 어렵다. 그래서 주간 업데이트에는 화면 캡처, 동영상 클립, 또는 테스트용 링크가 함께 제공된다. "로그인 기능 완료"라는 문장보다 실제 작동하는 화면을 보는 것이 훨씬 구체적인 판단 근거가 된다. 3단계 — 비개발자가 직접 테스트하는 시간 개발팀이 보여주는 것만 보는 게 아니라, 비개발자가 직접 써보는 단계가 필요하다. 이 과정에서 "버튼이 너무 작다", "이 순서가 직관적이지 않다" 같은 피드백이 나온다. 기술 지식이 없어도 할 수 있는 피드백이고, 이런 피드백이 제품의 방향을 바로잡는다. 4단계 — 다음 주 작업 범위 합의 이번 주 결과를 확인한 뒤, 다음 주에 무엇을 만들지 함께 정한다. 이 단계에서 비개발자는 우선순위를 조정할 수 있다. "이 기능보다 저 기능이 먼저 필요하다"는 판단을 매주 할 수 있는 구조다. 우선순위는 비개발자가 가장 잘 아는 영역이다. 비개발자가 개발 진행 상황을 점검하는 실질적인 기준은? 개발 진행 상황을 평가할 때 기술적 판단을 할 필요는 없다. 다음 세 가지 기준으로 충분히 점검할 수 있다. 점검 항목 확인 방법 좋은 신호 주의가 필요한 신호 완료 결과물 화면 또는 테스트 링크로 직접 확인 매주 눈에 보이는 결과물이 있음 텍스트 보고만 있고
AI 资讯
Every Requirement Gets a Verdict. I Had Been Reviewing Without One.
You merge the PR. The build passes. The code does what you expected it to do. You move on. That is review for most engineers. A final read. A feeling that things looked right before the branch closed. I did it the same way for years. Three phases had already run before this one. Think had scoped the work, Plan had written the requirements, Build had shipped a diff that matched the plan exactly. I trusted that the chain held. I had never actually checked. Then I ran the Review phase, and checking turned out to mean something specific: not does this work, but does this requirement hold up, and what is my evidence. I went in expecting to approve it or send it back. The phase gave me three answers instead: covered, partial, missing. I found out what they meant one requirement at a time, starting with the one I almost got wrong. I had been giving impressions, not verdicts The notification scheduler used a queue to manage dispatch. Every call to the external provider went through it. The provider was never exposed directly. The requirement said the provider must be notified. It was notified, exactly the way I had pictured it. I almost called it covered and moved to the next line. The Review phase stopped me there. But the requirement said must be notified , not how. The queue had introduced a call order and a timing the requirement never anticipated. Nothing was broken. Something had changed shape, quietly, and nobody had written that shape down. I sat with that for longer than I expected to. Not because the code was wrong. Because I could not immediately tell you whether the change mattered. The same pass gave the shim from Plan a different verdict on the same page: covered. Mapped to the requirement it existed to satisfy, no gap between what was promised and what was in the diff. One requirement held exactly the shape it was given. The other had quietly grown a new one. Same review. Same pass. Two verdicts. Partial is not a softer word for broken. It is the verdict for
AI 资讯
For AI coding, the kids are alright
The AI Engineer World's Fair has attracted a lot of adults, and they brought their kids too, for...
AI 资讯
Building fast as a CS student using AI tools — what's your stack? I'm a 3rd year CS student and I've been obsessed with one question lately: how fast can a solo builder actually ship something real using AI tools.What's your go-to stack for prototyping 👇
AI 资讯
The System Design Framework I Used to Solve 100+ Problems
Hello Devs, for months, I felt confident about system design interviews. I'd watched endless YouTube videos. I'd studied architecture diagrams. I could explain how Netflix builds recommendation systems. I understood Kafka, Redis, load balancers, and microservices. I'd memorized the designs of Twitter, Uber, YouTube, and TinyURL. Then I sat down for my first real system design interview and froze. The interviewer asked: "How would you design a notification system?" I had memorized notification systems. I knew about push notifications, email queues, delivery workers, and retry logic. I could recite architectural patterns. But suddenly, none of that helped. I didn't know which questions to ask first. I started designing before understanding the actual requirements. I built architecture for problems that didn't exist. I missed obvious bottlenecks. I couldn't articulate why I made specific trade-offs. When the interviewer pushed back, I had no framework to adjust. I failed that interview. But that failure taught me something crucial: System design interviews aren't about knowing technologies. They're about knowing how to think. After that, I went back and systematically practiced 20 system design problems. Not passively watching solutions. Actually designing. Making mistakes and refining my approach. And somewhere around problem 12, a pattern emerged. The best candidates didn't know more technologies than anyone else. They had a framework . They asked the same questions in the same order. They structured their thinking consistently. They could handle curveballs because their framework was flexible. They reasoned through trade-offs explicitly. Here's the framework that finally made it click for me. The Problem with Memorization Before I share the framework, let me explain why memorizing designs fails. When you memorize " How to Design Twitter," you learn: Use relational databases for users and tweets Use NoSQL for timelines Cache with Redis Use message queues for fanout S
AI 资讯
Startups Don't Need "Perfect" Code. They Need "Malleable" Code
Why adaptability beats perfection in startup software development The Startup Trap: Building for a Future That Doesn't Exist Yet Many startup founders make the same mistake. They spend months building the "perfect" product architecture. The code is clean. The design patterns are flawless. The test coverage is near 100%. The infrastructure can scale to millions of users. There's just one problem: They don't have any users. In the startup world, survival depends on learning faster than competitors, not on creating the most elegant codebase. Product-market fit is uncertain. Customer needs change weekly. Business models evolve. Features that seemed critical last month become irrelevant the next. In that environment, the biggest advantage isn't perfect code. It's malleable code . Code that can bend, adapt, and evolve as the business learns. What Is Malleable Code? Malleable code is software that is easy to change. It isn't necessarily perfect. It isn't over-engineered. It isn't designed to solve every future problem. Instead, it's designed to support continuous experimentation. Malleable code allows teams to: Launch MVPs quickly Test assumptions rapidly Respond to customer feedback Pivot when necessary Add new features without major rewrites Remove failed features with minimal effort Think of it this way: Perfect code optimizes for certainty. Malleable code optimizes for uncertainty. And startups operate almost entirely in uncertainty. When you're still searching for product-market fit, the ability to adapt is often more valuable than technical elegance. Why "Perfect" Code Often Hurts Startups Software engineers love solving technical problems. It's natural. Building a scalable architecture feels productive. Refactoring code feels productive. Designing the perfect system feels productive. But startup success isn't measured by code quality. It's measured by business outcomes. Questions such as: Are customers using the product? Are they paying for it? Are they returning? A
AI 资讯
Omnia Ipsum: Unified placeholder content for Symfony
Rethinking fake content in Symfony projects A prototype web page displaying pure placeholder content When building early UI prototypes or shaping design systems in Symfony, placeholder content becomes a constant companion. Lorem ipsum text. Dummy profile photos. Placeholder videos. Silent audio. Temporary avatars. Realistic fake user data. Every project needs them — and yet most setups rely on a patchwork of libraries, links and hardcoded values. Omnia Ipsum aims to fix that by giving Symfony developers a single, elegant toolkit for placeholder content of all kinds. In this article, I will walk you through the motivation behind the project, the conceptual patterns it follows, and its most advanced features — all designed to make your prototyping workflow faster, cleaner and more maintainable. Motivation: Why a placeholder library? Most Symfony projects start the same way: You add lorem ipsum text manually into Twig templates. You grab placeholder images from an external service. You generate avatars using yet another site. You paste in temporary YouTube or stock video URLs. You install Faker separately whenever realistic data is needed. The result is inconsistent, fragmented and difficult to maintain. And even worse: placeholder content often leaks into production unless guarded carefully. The idea behind Omnia Ipsum was simple: “If your UI needs placeholder content, it should come from one place — predictable, configurable, and accessible directly from Twig.” This cuts down on boilerplate, cognitive overhead, and the "temporary chaos" of early-stage templates. Quick Start Prerequisite Go to github.com/symfinity/recipes and follow the instructions to add the required recipe repository. Installation composer require --dev symfinity/omnia-ipsum Usage Use the Twig functions immediately: <img src= " {{ omnia_image ( 600 , 400 ) }} " alt= "Placeholder" > <img src= " {{ omnia_avatar ( 'John Doe' , 100 ) }} " alt= "Avatar" > <video src= " {{ omnia_video ( 1920 , 1080 ) }}
AI 资讯
Font Manager: Multi-format Font export for Symfony
The Problem Typography should be one of the simplest parts of a project. In reality, it often ends up scattered across multiple layers: Bootstrap: $font-family-base variables Tailwind: JavaScript configuration TypeScript: type definitions Design systems: W3C Design Tokens The same font information gets copied and maintained in several places. Every update means touching multiple files, hoping everything stays in sync. It's repetitive, error-prone, and easy to get wrong. So I built Font Manager. Define your fonts once and export them in whatever format your project needs — CSS, Bootstrap variables, Tailwind configuration, TypeScript definitions, design tokens, and more. The Solution A simple Twig function: {{ font_manager ( 'Ubuntu' , '400 700' ) }} Configuration: symfinity_font_manager : export : formats : - scss_bootstrap - tailwind_config - typescript_definitions One lock command: php bin/console fonts:lock Every format, automatically generated. Perfectly synced. Bootstrap Example Before: // Manually copy font name $font-family-base : 'Ubuntu' , sans-serif ; // ❌ Duplication @import 'bootstrap/scss/bootstrap' ; After: symfinity_font_manager : export : formats : [ scss_bootstrap ] php bin/console fonts:lock // app.scss @import './assets/styles/fonts-bootstrap' ; // ← Auto-generated @import 'bootstrap/scss/bootstrap' ; Bootstrap uses your fonts automatically. No manual mapping. No duplication. Tailwind Example symfinity_font_manager : export : formats : [ tailwind_config ] // tailwind.config.js const fonts = require ( ' ./assets/fonts-tailwind.config.js ' ); // ← Auto-generated module . exports = { theme : { extend : { fontFamily : fonts . fontFamily } } }; <p class= "font-sans" > Your custom font, via Tailwind. </p> TypeScript Example symfinity_font_manager : export : formats : [ typescript_definitions ] import { fonts , type FontFamily } from ' ./assets/fonts ' ; applyFont ( element , ' sans ' ); // ✓ Valid applyFont ( element , ' invalid ' ); // ✗ TypeScript erro
AI 资讯
We Build Faster Than We Decide
AI has made it easier to produce working software. That part is real. It can write code, draft documents, research a topic, scaffold a prototype, and debug a problem faster than most teams can finish writing a decent ticket. But faster building doesn't automatically mean better product decisions. That's the part I keep coming back to. For decades, software teams optimized around delivery. Requirements, design, development, QA, release. Waterfall softened into Agile. Agile grew into DevOps. The practices changed, but the assumption underneath stayed pretty stable: building software is expensive, so plan carefully before you start. That made sense because, for a long time, it was true. Now that assumption is breaking. AI is doing to software what calculators did to accounting. It isn't eliminating the job. It's moving the job up a level. The syntax, boilerplate, first draft, and some of the debugging are getting offloaded. The work doesn't disappear. The bottleneck moves. Learning is still expensive Here's what didn't get cheaper: understanding what people actually need getting stakeholders aligned deciding what evidence would change your mind putting something real in front of users reading the signal without fooling yourself The old question was: Can we build it fast enough? The new question is: Do we understand the problem well enough? That sounds like a small shift, but it changes the work. It changes what strong engineers spend time on. It changes what product people need from engineering. It changes how teams should define "done." If the code ships but nobody learns anything, did the team actually move forward? Sometimes yes. Often no. Users don't know until they can touch it People are not great at specifying requirements up front. Not because they're difficult. Because they're human. Most of us don't know how we feel about something until we can react to a version of it. A mockup. A prototype. A rough slice. A real workflow with sharp edges. So the fastest pat
产品设计
Do localhost para o mundo
Por muito tempo eu acreditei que programação e desenvolvimento de software como sinônimos. Na...
AI 资讯
Spec-Driven Development in 2026: What It Is, the Tooling, and How Teams Actually Use It
A field guide to the practice that's reshaping how software gets built with AI agents. TL;DR — Spec-Driven Development (SDD) makes a precise, executable specification the source of truth and treats code as a generated, verifiable artifact. The spec declares intent ; the code realizes it. In 2026 it went mainstream because AI agents are great at writing code and terrible at guessing what you meant. Jump to: Why now · Specs vs. executable specs · Maturity model · Workflow · Tooling · EARS · Worked example · Caveats · Bottom line Why now? The "vibe coding" backlash The movement defines itself against "vibe coding" — the term Andrej Karpathy popularized in early 2025 for loosely prompting an AI and shipping whatever comes back. Vibe coding is great for throwaway prototypes and miserable for anything that has to be maintained. SDD is the disciplined counterweight: if AI writes most of the code, then the specification becomes the highest-leverage artifact a human produces . The skill that matters shifts from typing the implementation to defining the intent precisely enough that a machine can't get it wrong. Raw specs vs. executable specs This is the single most important distinction in the whole topic — and the one most "SDD explainers" skip. Traditional design docs SDD specs Read by Humans Humans and agents Enforcement Advisory — devs may diverge Executable — tests fail on drift Lifecycle Goes stale, becomes archaeology Living, continuously validated Lives in A wiki nobody opens The repo + CI/CD "Traditional specs are read by humans, while SDD specs are executed as BDD scenarios, API contract tests, or model simulations." — Deepak Babu Piskala, Spec-Driven Development: From Code to Contract in the Age of AI Coding Assistants (arXiv, Jan 2026) [2602.00180] Spec-Driven Development:From Code to Contract in the Age of AI Coding Assistants The rise of AI coding assistants has reignited interest in an old idea: what if specifications-not code-were the primary artifact of softw
AI 资讯
A Few Months Ago, Agentic Development Felt Overwhelming
A few months ago, I was overwhelmed by everything happening in AI. Every week there was a new coding assistant, a new workflow, or someone claiming they built an app in just a few hours. It felt like if you weren't keeping up, you'd be left behind. I tried almost everything. Cursor. ChatGPT. Claude Code. Lovable. At first, I kept switching between tools, hoping one of them would magically make me a better developer. It didn't. The biggest lesson I learned wasn't about choosing the best AI tool. It was learning how to work with AI. These days, I don't start by asking AI to write code. I start by explaining the problem. I describe the feature, the business requirements, the edge cases, and what I want the final result to look like. Sometimes I ask ChatGPT to help me plan the implementation first. Once everything is clear, I pass that plan to an agentic coding assistant and start building. That one change made a huge difference. I spend less time writing boilerplate and more time thinking about architecture, user experience, and solving the actual problem. AI still gets things wrong, so I review everything before it goes into production. But instead of writing every single line myself, I'm guiding the process. Looking back, the first few months were the hardest. Now it just feels normal. The tools will keep changing, but I think the real skill is learning how to communicate with AI and use it as part of your development process. That's something worth investing in.
AI 资讯
Why Taking Feedback Positively Can Transform Your Career as a Developer
Why Taking Feedback Positively Can Change Your Career As developers, engineers, designers, and professionals, we all want to improve. We spend countless hours learning new technologies, building projects, and gaining experience. Yet many people overlook one of the most powerful tools for growth: feedback. Unfortunately, feedback often feels personal. When someone points out mistakes in our code, resume, communication, or project, our first reaction is sometimes defensive. We feel offended, frustrated, or misunderstood. I've experienced this myself. But over time, I learned that the ability to accept feedback positively is one of the most valuable skills anyone can develop. Feedback Is Not an Attack One of the biggest misconceptions is believing that criticism is an attack on our abilities. When a senior engineer reviews your code and suggests improvements, they are not saying you're a bad developer. When a recruiter rejects your resume, they are not saying you're incapable. When users report problems in your open-source project, they are not trying to discourage you. Most of the time, people are simply showing you where improvements can be made. The sooner we separate our ego from our work, the faster we grow. Every Rejection Contains Information Many professionals view rejection as failure. I view it differently now. A rejection is data. If ten companies reject the same resume, the market is telling you something. If users consistently struggle with a feature, they're revealing a usability problem. If interviewers repeatedly point out the same weakness, they're highlighting a skill gap. The goal isn't to feel bad about the feedback. The goal is to learn from the information hidden inside it. Growth Begins Where Comfort Ends Positive feedback feels good. Constructive feedback creates growth. Nobody enjoys hearing that their architecture can be improved, their communication needs work, or their project has flaws. But those uncomfortable conversations often lead to th
AI 资讯
AI Can Write the Code. Who Gives It the Context?
When you talk to ChatGPT about a subject you understand well, you quickly notice something. The first answer is rarely the final answer. You add context. You correct an assumption. You explain what has already been tried. You point out that one proposed solution conflicts with another part of the system. After a few iterations, the answer becomes useful. The same thing happens when AI writes code for real products. The difference is that a slightly incorrect explanation in a chat is usually harmless. Slightly incorrect code can become part of your product, pass a superficial review, and remain there for years. This is why successful AI adoption in software engineering is not primarily about generating more code. It is about context engineering : giving AI enough context, constraints, and feedback to generate code that belongs in your system. The First Answer Is Usually Not Enough AI coding tools are very good at producing plausible solutions. That word matters: plausible. The code may compile. The tests may pass. The implementation may even look clean when reviewed in isolation. But software does not exist in isolation. A change must fit the broader system architecture : the current architecture existing domain rules security requirements operational constraints established conventions previous technical decisions future product direction An AI assistant does not automatically understand those things. It knows the code it can see and the engineering context you provide. Everything outside that window must be inferred. And inference is where divergence begins. If you trust the first response without validating its assumptions, you are usually not accelerating engineering. You are accelerating uncertainty. Lack of Context Creates Duplication One of the first visible effects is duplication. AI does not necessarily know that your application already has: a validation helper for the same domain rule an established authorization pattern a shared API client a retry mechani
AI 资讯
I Replaced 5 Social Media APIs With One Key (and My Code Got Way Simpler)
A while back I was building a side project that needed public data from a few social platforms. Nothing crazy — profiles, posts, some engagement numbers. I figured I'd just grab each platform's official API. Reader, I did not "just grab each platform's official API." Here's what that road actually looked like, and how I ended up consolidating everything down to one key and roughly ten lines of shared code. The five-API nightmare Instagram (Meta Graph API). Great if you own the account. Useless for pulling public data about accounts you don't. Endless app review. TikTok. The research API is academics-only with a long application. For commercial use, basically nothing. X (Twitter). Used to be wonderful. Now $100/month to start, more for anything serious. YouTube. Honestly the best of the bunch — generous and well-documented. Credit where due. LinkedIn. Partner-only. For most people, no useful public access at all. So to cover five platforms I was looking at: five sets of credentials, five auth flows, five rate-limit models, five totally different response shapes, two flat-out rejections, and a monthly bill. For a side project. What I actually wanted getProfile ( " tiktok " , " someuser " ) getProfile ( " instagram " , " someuser " ) getProfile ( " twitter " , " someuser " ) Same call shape, same auth, same error handling. That's it. I don't care that each platform structures things differently internally — I want one boundary that hides that from me. The consolidation I switched to SociaVault , which puts public data from all of these behind one API and one key. My entire client became this: const API_KEY = process . env . SOCIAVAULT_API_KEY ; const BASE = " https://api.sociavault.com " ; async function sv ( path , params = {}) { const url = new URL ( BASE + path ); Object . entries ( params ). forEach (([ k , v ]) => url . searchParams . set ( k , v )); const res = await fetch ( url , { headers : { " X-API-Key " : API_KEY } }); if ( ! res . ok ) throw new Error ( ` $
AI 资讯
The Dependency Injection Quest: How I Turned Spaghetti Code Into a Lightsaber 🚀
The Quest Begins (The “Why”) Picture this: I’m knee‑deep in a legacy codebase that feels like the Death Star’s trash compactor—every time I try to add a feature, the walls close in and I’m squashed by tight coupling. I’d just spent three hours tracking down a bug that only showed up when the payment gateway was mocked in a test. The culprit? A new PaymentGateway() buried deep inside an OrderService class. It was like trying to defeat Darth Vader with a butter knife—no matter how hard I swung, the Dark Force (aka hidden dependencies) kept pulling me back. I realized I was instantiating collaborators inside the very classes that should be oblivious to their implementation details . The result? Tests that needed a real database, a real Stripe account, and a sacrificial goat to run. Any change to a third‑party API meant hunting down every new scattered across the project. Onboarding a new teammate felt like handing them a map written in ancient Sumerian. Honestly, I was ready to quit coding and become a professional napper. Then, during a late‑night coffee‑fueled refactor session, I stumbled upon a tiny line of documentation that whispered: “Depend on abstractions, not concretions.” It sounded like Yoda giving me a pep talk. The Revelation (The Insight) The magic spell I uncovered is Dependency Injection (DI) —specifically, constructor injection . Instead of a class creating its own collaborators, we hand them in from the outside. Think of it as giving a Jedi their lightsaber rather than making them forge one in the middle of a battle. Why does this feel like discovering the Force? Testability explodes – you can swap in fakes, mocks, or stubs without touching production code. Flexibility skyrockets – swapping a payment provider becomes a one‑line config change, not a scavenger hunt. Clarity reigns – the constructor becomes an honest inventory of what a class needs to do its job. The moment I applied it, the codebase felt lighter, like Luke finally trusting the Force ins
AI 资讯
Spec-Driven Development: Let the Spec Drive the Code (With a Real Example)
By Sergio Colque Ponce — Software Engineering, Universidad Privada de Tacna. Full source code: github.com/srg-cp/spec-driven-development If you have used an AI coding agent — Copilot, Claude Code, Gemini CLI — you have probably lived this moment: you describe a feature, the agent produces code that compiles and looks right, and then it quietly does the wrong thing. The agent is not weak; the input was ambiguous. We have been treating coding agents like search engines when they behave more like very literal pair programmers. Spec-Driven Development (SDD) is the answer to that problem: instead of jumping straight to code, you write down what you want and why , refine it, and only then let the implementation follow. The specification — not the code — becomes the center of the project. What Spec-Driven Development actually is The idea is old (anyone who has written a Product Requirements Document will recognize it), but it has become practical again thanks to tools like GitHub's open-source Spec Kit . Spec Kit organizes the work into a small set of Markdown artifacts, each feeding the next: Constitution — the non-negotiable principles of the project (security rules, coding standards, architectural constraints). Spec — what you are building and why , with no implementation detail. Plan — the technical blueprint derived from the spec (stack, structure, decisions). Tasks — the plan broken into small, ordered, verifiable steps. Implement — the agent (or you) builds the tasks, with the previous artifacts as structured context. The workflow is usually summarized as Spec → Plan → Tasks → Implement , and the same process is meant to work regardless of language, framework, or which of the 30+ supported agents you use. The real shift is not "more documents." It is this: when requirements change, you update the spec, regenerate the plan, and let the implementation follow — instead of patching code and hoping the intent survives. The spec is a living artifact, not a dusty Word file