김영한님의 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 정리한 글입니다. 실습 환경: PostgreSQL + Hibernate 6(jakarta) 1. 프록시 문제 제기: Member를 조회할 때 Team도 함께 조회해야 할까? // 1 회원과 팀을 함께 출력 public void printUserAndTeam(Long memberId) { Member member = em.find(Member.class, memberId); Team team = member.getTeam(); System.out.println("회원 이름: " + member.getUsername()); System.out.println("소속팀: " + team.getName()); } // 2 회원만 출력 public void printUser(Long memberId) { Member member = em.find(Member.class, memberId); System.out.println("회원 이름: " + member.getUsername()); } 1은 Team이 필요하니 같이 가져오면 이득 입니다. 2는 Team을 쓰지도 않는데 같이 가져오면 손해 입니다. 비즈니스 로직마다 필요한 데이터가 다릅니다. JPA는 이 문제를 프록시 와 지연 로딩 으로 해결합니다. 지연 로딩을 이해하려면 먼저 프록시를 알아야 합니다. em.find() vs em.getReference() 메서드 동작 em.find() DB를 통해서 실제 엔티티 객체 를 조회 (바로 SELECT) em.getReference() DB 조회를 미루는 가짜(프록시) 엔티티 객체 를 조회 (SELECT 안 함) Member findMember = em.getReference(Member.class, member.getId()); System.out.println("findMember = " + findMember.getClass()); // findMember = class hellojpa.Member$HibernateProxy$a1b2c3 ← 가짜! System.out.println("findMember.id = " + findMember.getId()); // SELECT 안 나감 (id는 이미 알고 있으니까) System.out.println("findMember.username = " + findMember.getUsername()); // 이 시점에 SELECT 쿼리 실행! 💡 강의 자료에는 프록시 클래스명이 javassist 로 나오지만, Hibernate 6은 ByteBuddy 를 써서 Member$HibernateProxy$... 형태로 출력됩니다. 프록시의 구조 Member (실제 클래스) - id, name - getId(), getName() △ │ 상속 MemberProxy (가짜) - Member target = null ← 실제 객체를 가리킬 참조 - getId(), getName() 실제 클래스를 상속받아서 만들어집니다. (Hibernate가 런타임에 자동 생성) 실제 클래스와 겉모양이 같습니다. 사용하는 입장에서는 진짜 객체인지 프록시인지 구분하지 않고 쓰면 됩니다. (이론상) 프록시는 실제 객체의 참조(target)를 보관 합니다. 프록시의 메서드를 호출하면 실제 객체의 메서드를 대신 호출(위임, delegate) 합니다. 프록시 객체의 초기화 Member member = em.getReference(Member.class, 1L); member.getName(); 1. Client → member.getName() 호출 2. 프록시: "target이 null이네?" → 영속성 컨텍스트에 초기화 요청 3. 영속성 컨텍스트 → DB 조회 4. 실제 Member 엔티티 생성 5. 프록시의 target에 실제 엔티티 연결 → target.getName() 호출 💡 비유: 프록시는 택배 송장 과 같습니다. 송장(프록시)만 받았을 때는 상자를 열어 보지 않습니다. 송장에 적힌 운송장 번호(id) 는 바로 알 수 있습니다. 실제 내용물(name)이 궁금해지는 순간 그제야 창고(DB)에 가서 물건을 가져옵니다. 2. 프록시의 특징 (중요! 실무에서 헷갈리는 부분) 1 프록시 객체는 처음 사용할 때 한 번만 초기화된다 member.getName(); // SELECT 실행 member.getName(); // 이미 초기화됨 → SELECT 없음 2 초기화되어도 프록시가 실제 엔티티로 바뀌는 게 아니다 초기화되면 프록시를 통해서 실제 엔티티에 접근 할 수 있게 될 뿐입니다. getClass() 를 찍어 보면 초기화 후에도 여전히 Member$HibernateProxy$... 입니다. 3 타입 체크 시 == 대신 instanceof 를 써야 한다 프록시는 원본 엔티티를 상속 받은 다른 클래스입니다. Member m1 = em.find(Member.class, member1.getId()); // 실제 객체 Member m2 = em.getReference(Member.class, member2.getId()); // 프록시 System.out.println(m1.getClass() == m2.getClass()); // false 😱 System.out.println(m2 instanceof Member); // true ✅ ⚠️ 실무에서는 내가 받은 객체가 프록시인지 아닌지 모르는 경우가 많습니다. 그래서 엔티티 타입 비교는 항상 instanceof 로 해야 합니다. equals() 를 직접 구현할 때도 getClass() 비교 대신 instanceof 를 쓰고, 필드 대신 getter 로 비교해야 프록시에서도 안전합니다. 4 영속성 컨텍스트에 이미 있으면 getReference()를 해도 실제 엔티티를 반환한다 Member m1 = em.find(Member.class, member.getId()); // 1차 캐시에 실제 객체 저장 Member ref = em.getReference(Member.class, member.getId()); // 실제 객체 반환! System.out.println(ref.getClass()); // class hellojpa.Member System.out.println(m1 == ref); // true 이미 1차 캐시에 실제 객체가 있는데 굳이 프록시를 만들 이유가 없습니다. 💡 반대 상황도 있습니다. Member ref = em.getReference(Member.class, member.getId()); // 프록시 Member find = em.find(Member.class, member.getId()); // 프록시 반환! System.out.println(ref == find); // true 먼저 프록시가 만들어졌다면 em.find() 도 같은 프록시를 반환 합니다. 왜일까요? JPA는 같은 트랜잭션 안에서 같은 엔티티의 == 비교가 항상 true임을 보장 해야 하기 때문입니다. (영속성 컨텍스트의 동일성 보장) 5 준영속 상태에서 프록시를 초기화하면 예외가 발생한다 Member ref = em.getReference(Member.class, member.getId()); em.detach(ref); // 또는 em.close(), em.clear() ref.getUsername(); // 💥 LazyInitializationException org.hibernate.LazyInitializationException: could not initialize proxy - no Session 프록시 초기화는 영속성 컨텍스트의 도움 을 받아서 DB를 조회하는 건데, 영속성 컨텍스트에서 분리됐으니 조회할 방법이 없습니다. 💡 실무에서 정말 자주 만나는 에러입니다. 예: 서비스 계층에서 트랜잭션이 끝난 뒤, 컨트롤러나 뷰에서 member.getTeam().getName() 을 호출하는 경우 트랜잭션이 끝나면 영속성 컨텍스트도 닫히기 때문에 이 에러가 납니다. 해결책은 뒤에서 배울 페치 조인 , 또는 트랜잭션 안에서 필요한 데이터를 미리 DTO로 변환하는 것입니다. 3. 프록시 확인 방법 목적 방법 초기화 여부 확인 emf.getPersistenceUnitUtil().isLoaded(entity) 프록시 클래스 확인 entity.getClass().getName() 출력 → $HibernateProxy$ 포함 여부 강제 초기화 Hibernate.initialize(entity); (Hibernate 제공) 강제 초기화 (JPA 표준) 표준에는 없음 → member.getName() 처럼 메서드를 직접 호출 Member ref = em.getReference(Member.class, member.getId()); System.out.println(emf.getPersistenceUnitUtil().isLoaded(ref)); // false Hibernate.initialize(ref); // 강제 초기화 System.out.println(emf.getPersistenceUnitUtil().isLoaded(ref)); // true 💡 em.getReference() 는 실무에서 직접 쓸 일이 거의 없습니다. 하지만 지연 로딩이 내부적으로 이 프록시를 사용 하기 때문에 원리를 꼭 알아야 합니다. 4. 즉시 로딩과 지연 로딩 지연 로딩 (LAZY) - 프록시로 조회 "Member만 쓰는 로직이 대부분이라면?" @Entity public class Member { @Id @GeneratedValue private Long id; @Column(name = "USERNAME") private String name; @ManyToOne(fetch = FetchType.LAZY) // ★ @JoinColumn(name = "TEAM_ID") private Team team; } Member member = em.find(Member.class, 1L); // SELECT * FROM member WHERE id = 1 ← Team은 조회 안 함 Team team = member.getTeam(); System.out.println(team.getClass()); // Team$HibernateProxy$... (프록시) team.getName(); // SELECT * FROM team WHERE id = ? ← 실제 Team을 사용하는 시점에 조회 1. 로딩 → member1 (실제 엔티티) 2. 지연 로딩 LAZY → team1 (프록시 엔티티) Member를 조회할 때 team 필드에는 프록시를 넣어 둡니다. team.getName() 처럼 실제로 Team의 데이터를 사용하는 시점에 초기화(DB 조회)됩니다. ⚠️ member.getTeam() 만으로는 초기화되지 않습니다. 프록시를 꺼낸 것뿐입니다. getTeam().getName() 처럼 프록시의 메서드를 호출해야 쿼리가 나갑니다. 즉시 로딩 (EAGER) - 함께 조회 "Member와 Team을 항상 같이 쓴다면?" @ManyToOne(fetch = FetchType.EAGER) // ★ @JoinColumn(name = "TEAM_ID") private Team team; Member member = em.find(Member.class, 1L); select m.*, t.* from member m left join team t on m.team_id = t.team_id where m.id = ? Member를 조회할 때 항상 Team도 함께 조회합니다. JPA 구현체는 가능하면 조인을 사용해서 SQL 한 번에 함께 조회합니다. team 에는 프록시가 아니라 실제 엔티티 가 들어갑니다. 5. 프록시와 즉시 로딩 주의 ⚠️ ✅ 가급적 지연 로딩만 사용하세요. (특히 실무에서) 이유 1 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생한다 연관관계가 2~3개일 때는 괜찮지만, 실무에서는 엔티티 하나에 연관관계가 10개 넘게 있기도 합니다. 전부 EAGER면 Member 하나 조회했는데 테이블 10개가 조인 되는 쿼리가 나갑니다. em.find(Member.class, 1L); // → member join team join locker join order join ... 😱 이유 2 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다 (가장 중요!) // Member.team이 EAGER일 때 List<Member> members = em.createQuery("select m from Member m", Member.class) .getResultList(); 실제로 나가는 쿼리: select * from member -- 1번: JPQL 그대로 SQL로 번역 (회원 10명 조회) select * from team where team_id = 1 -- ↓ 그런데 Team이 EAGER네? 채워야 함 select * from team where team_id = 2 select * from team where team_id = 3 ... -- N번: 회원 수만큼 추가 쿼리! 왜 이런 일이 생길까? em.find() 는 JPA가 내부에서 최적화(조인)를 할 수 있습니다. 하지만 JPQL은 작성한 그대로 SQL로 번역 됩니다. select m from Member m 이면 select * from member 만 나갑니다. 결과를 받아 보니 Team이 EAGER 로 설정되어 있습니다. EAGER는 "반환 시점에 반드시 채워져 있어야 한다"는 뜻입니다. 그래서 JPA가 회원마다 Team을 조회하는 쿼리를 추가로 날립니다. 최초 쿼리 1번 + 추가 쿼리 N번 = N+1 문제 💡 회원 1,000명이면 쿼리가 1,001번 나갑니다. 서비스 장애로 이어질 수 있는 대표적인 성능 문제입니다. LAZY로 바꾸면 해결될까? List<Member> members = em.createQuery("select m from Member m", Member.class) .getResultList(); // 쿼리 1번 (Team은 프록시) for (Member m : members) { m.getTeam().getName(); // 루프 돌면서 Team 조회... 결국 N번 } LAZY로 바꾸면 당장은 쿼리 1번 만 나가지만, 나중에 Team을 꺼내 쓰면 결국 N번이 나갑니다. ✅ 진짜 해결책: JPQL 페치 조인 em.createQuery("select m from Member m join fetch m.team", Member.class) 필요한 시점에 딱 필요한 연관관계만 조인해서 한 번에 가져옵니다. 그 밖에 엔티티 그래프 , 배치 사이즈 같은 방법도 있습니다. (객체지향 쿼리 장에서 자세히 다룸) 기본값 정리 → ~ToOne 은 직접 LAZY로 바꿔야 한다 어노테이션 기본값 조치 @ManyToOne EAGER 👉 fetch = FetchType.LAZY 로 변경 @OneToOne EAGER 👉 fetch = FetchType.LAZY 로 변경 @OneToMany LAZY 그대로 @ManyToMany LAZY 그대로 (애초에 안 씀) 💡 외우는 법: ~ToOne 은 하나라서 같이 가져와도 부담이 없을 것 같아 EAGER , ~ToMany 는 많아서 부담되니 LAZY 가 기본값입니다. 하지만 실무에서는 전부 LAZY 로 통일합니다. 6. 지연 로딩 활용 이론적인 활용법 관계 사용 빈도 전략 Member - Team 자주 함께 사용 즉시 로딩 Member - Order 가끔 사용 지연 로딩 Order - Product 자주 함께 사용 즉시 로딩 member1 ──(EAGER) team──→ teamA (실제 엔티티) │ └─(LAZY) orders──→ 주문내역 List (프록시 컬렉션) │ └─(EAGER) product──→ 상품A Member 조회 시 → Team은 같이, 주문 목록은 프록시로 주문 목록을 실제로 사용하는 시점에 → 주문 조회 + 주문의 Product는 즉시 로딩으로 같이 💡 컬렉션도 지연 로딩이 됩니다. Hibernate는 컬렉션을 PersistentBag 같은 래퍼 컬렉션 으로 감싸서 관리합니다. 🚨 실무에서는 이렇게! 모든 연관관계에 지연 로딩을 사용해라! 실무에서 즉시 로딩을 사용하지 마라! 함께 조회가 필요하면 JPQL 페치 조인 이나 엔티티 그래프 기능을 사용해라! 즉시 로딩은 상상하지 못한 쿼리 가 나간다. "Member와 Team을 자주 같이 쓴다"는 판단은 지금 기준 일 뿐입니다. 화면이 늘어나면 Team이 필요 없는 조회도 생깁니다. 기본은 LAZY 로 깔아 두고, 같이 필요한 곳에서만 페치 조인으로 골라서 가져오는 것이 안전합니다. 7. 영속성 전이: CASCADE 언제 쓰나? 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 예: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장 Parent 1 ──── * Child CASCADE 없이 저장하면 @Entity public class Parent { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "parent") private List<Child> childList = new ArrayList<>(); public void addChild(Child child) { // 연관관계 편의 메서드 childList.add(child); child.setParent(this); } } @Entity public class Child { @Id @GeneratedValue private Long id; private String name; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Parent parent; } Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Parent(); parent.addChild(child1); parent.addChild(child2); em.persist(parent); em.persist(child1); // 😩 자식도 하나하나 persist 해야 함 em.persist(child2); CASCADE를 적용하면 @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) private List<Child> childList = new ArrayList<>(); Parent parent = new Parent(); parent.addChild(child1); parent.addChild(child2); em.persist(parent); // ✅ 부모만 persist하면 자식도 함께 저장 parent ── 영속화 ──→ (Cascade.PERSIST, 영속성 전이) ──→ children [child1, child2] ⚠️ CASCADE 주의 영속성 전이는 연관관계 매핑과 아무 관련이 없습니다. 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐 입니다. cascade 옵션은 "부모에게 한 persist() / remove() 를 자식에게도 똑같이 해 줘"라는 뜻입니다. FK나 연관관계의 주인과는 별개입니다. CASCADE 종류 옵션 설명 ALL 모두 적용 ← 자주 씀 PERSIST 영속 (저장할 때만) ← 자주 씀 REMOVE 삭제 MERGE 병합 REFRESH REFRESH DETACH DETACH 언제 써야 할까? ✅ 자식의 소유자가 하나일 때만 쓰세요. (단일 소유자) 상황 CASCADE 게시글 ↔ 첨부파일 (첨부파일은 그 게시글에서만 관리) ✅ OK 주문 ↔ 주문상품 (주문상품은 주문에서만 관리) ✅ OK 상품 ↔ 주문상품 (주문상품을 주문도, 상품도 참조) ❌ 쓰면 안 됨 회원 ↔ 팀 (팀은 독립적으로 관리) ❌ 쓰면 안 됨 조건 2가지: 부모와 자식의 라이프사이클이 거의 같을 때 (같이 생성, 같이 삭제) 자식을 다른 엔티티가 참조하지 않을 때 ⚠️ 왜 위험할까? Child를 다른 엔티티(예: Other )도 참조하고 있는데 Parent에 CascadeType.REMOVE 를 걸었다면, Parent를 삭제할 때 Child도 같이 삭제되어 Other가 참조하던 데이터가 사라집니다. (FK 에러 또는 데이터
AI 에이전트가 테스트를 통과했다고 보고하면 무엇을 더 확인해야 할까요? 로컬 컨테이너와 원격 호스트의 성공은 서로 다른 실행 조건을 증명합니다. 사람이 결과를 검토하려면 성공 여부와 함께 어떤 코드가 어떤 환경에서 실행됐는지 확인해야 합니다. 자동화 결과는 사람이 다음 작업을 결정할 때 근거가 됩니다. 로컬 컨테이너에서 얻은 성공을 읽는 경우와 원격 호스트에서 얻은 성공을 읽는 경우에는 판단의 출발점이 달라집니다. 각각의 결과가 보여 주는 실행 조건이 다르기 때문입니다. 결과를 다음 판단에 쓰려면 이 차이가 보고에서도 드러나야 합니다. 코드의 출처가 실행 장소를 가릅니다 테스트 명령이 읽는 저장소의 래퍼와 설정 파일도 신뢰 판단에 포함됩니다. SkillsMP의 crabbox 설명은 자격 증명이 들어 있는 Testbox에서 이 파일들을 예외로 두지 않습니다. 신뢰하는 소스를 로컬에서 검사하는 기준에는 테스트가 작고 집중되어 있다는 조건이 붙습니다. 필요한 의존성도 로컬에 준비되어 있어야 합니다. 검증이 무거울 때 선택하는 Blacksmith Testbox와 구분하려면, 소스의 신뢰도에 더해 작업 규모와 준비 상태를 함께 봅니다. 외부 기여자나 포크의 코드를 다룰 때는 환경에 비밀정보가 있는지가 중요합니다. 포크 CI에는 비밀정보가 없어야 하고, 직접 AWS를 사용하는 환경에는 별도 정제가 요구됩니다. 관련 설명은 https://skillsmp.com/skill/openclaw-openclaw-agents-skills-crabbox-skill-md 에서 확인합니다. 실행 경로마다 검증하는 환경이 다릅니다 실행 경로를 보고할 때는 이름도 정확하게 구분합니다. crabbox 문서는 Testbox를 AWS Crabbox라고 부르지 않도록 명시합니다. 서로 다른 경로를 비슷한 이름으로 묶으면, 선택한 환경의 차이를 전달하기 어려워집니다. blacksmith-testbox에는 신뢰하는 유지보수자의 소스와 준비된 CI라는 조건이 붙습니다. aws는 신규 PR을 다루거나, 소스를 별도로 동기화하고 환경을 설정한 뒤 결과를 수집하는 직접 실행 경로입니다. local-container를 선택하면 Docker를 사용하는 로컬 대체 경로로 처리합니다. 이 경로의 결과는 원격 검증으로 세지 않습니다. ssh는 운영자가 이미 사용하는 호스트로 연결되는 경로입니다. 여기에 언급된 환경에는 macOS, Windows, WSL2가 포함됩니다. 성공 보고에 실행 조건을 함께 남깁니다 성공한 결과에도 적용 범위가 있습니다. 결과를 읽는 사람이 이 범위를 구별할 수 있도록, 보고에는 성공이 나온 환경이 드러나야 합니다. 제공자와 실행 식별자, 실행 URL로 어느 실행을 가리키는지 남깁니다. 여기에 명령과 결과를 붙여 무엇을 수행했고 어떻게 끝났는지 전달합니다. 환경을 점검하고 필요한 때 확보해 정리합니다 원격 자원은 어떤 순서로 점검하고 사용해야 할까요? crabbox 안내는 바이너리·버전·PATH와 기본 제공자를 확인하고, 무거운 첫 명령이 준비된 뒤 자원을 확보해 실행 식별자를 재사용하고 중지하도록 합니다. 다만 검토한 공개 구간은 빌드 절차 도중 끝나므로, 그 범위만으로 설치 명령이나 운영 절차를 확정할 수는 없습니다. SkillsMP에 표시된 마지막 소스 활동 시각은 2026년 7월 15일 07:52입니다. 검토한 공개 구간은 실행 파일이 없을 때 진행하는 빌드 절차의 중간까지 이어집니다. 설치 명령과 운영 절차를 정할 때는 이 구간에 더해 OpenClaw 저장소의 crabbox 소스와 함께 제공되는 파일들을 살핍니다. 확인할 위치는 https://github.com/openclaw/openclaw/tree/main/.agents/skills/crabbox 입니다. 현재 실행 환경을 점검합니다 — 실행 파일·버전과 PATH의 오래된 복사본 가능성을 살피고, 설정의 기본 제공자를 확인합니다. 첫 명령을 준비한 뒤 확보합니다 — 무거운 첫 명령이 준비된 시점에 자원을 확보하며, 추측에 따른 사전 예열은 하지 않습니다. 확보한 실행을 재사용합니다 — 이후 작업에는 이미 확보한 실행 식별자를 재사용합니다. 사용을 마치면 중지합니다 — 검증이 끝나면 사용한 원격 실행 환경을 중지합니다. 대량으로 만드는 자원에도 종료 조건이 필요합니다 자원 관리에서는 새로 만드는 양과 계속 가동하는 양을 구분해서 읽어야 합니다. GeekNews의 Supabase, Turso 인수 추진 보도에 나온 매주 100만 개 이상은 Supabase의 데이터베이스 생성량입니다. 실제 가동 수를 뜻하는 수치는 아닙니다. 해당 보도는 https://news.hada.io/topic?id=34676 에서 확인합니다. 같은 보도가 소개하는 Turso의 운영 방식에서는 사용 여부에 따라 데이터베이스 상태가 달라집니다. 필요해지면 로드하고, 사용하지 않으면 중단합니다. 생성량을 읽는 일과 별개로, 만들어진 자원을 언제 사용하고 언제 멈추는지 살피게 하는 사례입니다. 이 운영 방식에서 얻는 설계 관점은 원격 테스트 환경에도 연결됩니다. 에이전트가 자원을 쉽게 만들수록 어떤 범위에서 사용할지, 무엇을 기준으로 종료할지 분명하게 정합니다. 검토 기준은 성공 여부와 실행 경계입니다 검토할 때는 실행 장소를 선택한 이유가 코드의 출처와 연결되는지 살핍니다. 이어서 다음 작업에 필요한 실행 조건을 이번 성공이 뒷받침하는지 판단합니다. 원문: webi 기술 블로그 참고한 자료: SkillsMP Agent Skill: crabbox (openclaw) 법원, EFF에 동의: 유타주 VPN 법은 기술적으로 불가능한 일을 요구함 Supabase, Turso 인수 추진
정보처리기사 테스트 기법 블랙박스 화이트박스 커버리지 암기법 정보처리기사에서 테스트 문제는 같은 단원 안에서도 무엇을 기준으로 묻는지 가 다릅니다. 예를 들어 입력 구간의 대표값 → 동치 분할 경계 주변 값 → 경곗값 분석 프로그램 내부에서 어떤 명령을 실행하고 어느 갈림길을 지났는지 확인 → 화이트박스 테스트 처럼 문제에 나온 단서에 따라 답이 달라집니다. 2026년 2회 실기 1번의 답은 동치 분할 테스트 였지만, 이것 하나만 외우면 비슷한 문제를 구분하기 어렵습니다. 따라서 테스트 설계 기법을 블랙박스 테스트 화이트박스 테스트 경험 기반 테스트 로 나누고, 문제에 나온 단서만 보고 답을 찾을 수 있도록 정리해보겠습니다. 💡 안내 이 글은 정보처리기사 실기에서 반복해서 등장하는 테스트 기법 개념을 정리한 학습 자료입니다. 1. 테스트 기법은 기준을 어디에 두는지부터 나눈다 테스트 기법은 테스트 케이스를 어떤 근거로 만드는지 에 따라 크게 세 부류로 나눌 수 있습니다. 먼저 테스트 케이스(Test Case) 는 입력값 실행 조건 예상 결과 를 하나의 묶음으로 정리한 시험 사례입니다. 예를 들어 등급 계산 화면에서 75점을 입력하면 C가 나와야 한다. 라는 내용이 하나의 테스트 케이스가 될 수 있습니다. 문제에서는 내부 코드를 보는가? 요구사항과 결과를 보는가? 테스터의 경험을 사용하는가? 를 먼저 구분해야 합니다. 2. 테스트 기법의 세 가지 분류 분류 무엇을 기준으로 보는가 블랙박스 테스트 명세를 기준으로 입력과 출력 결과를 확인한다. 내부 코드는 보지 않는다. 화이트박스 테스트 프로그램 내부 구조와 코드의 실행 순서, 갈림길 등을 확인한다. 경험 기반 테스트 테스터의 경험, 결함에 대한 지식, 점검 목록 등을 활용한다. 💡 먼저 세 기준으로 구분하세요 명세의 입력과 출력 → 블랙박스 코드 안의 실행 순서와 갈림길 → 화이트박스 과거에 자주 발생한 오류와 테스터의 판단 → 경험 기반 3. 블랙박스 테스트는 입력과 출력의 규칙을 본다 블랙박스 테스트(Black Box Test) 는 프로그램 내부가 어떻게 구현되어 있는지 몰라도 수행할 수 있습니다. 요구사항에 적힌 입력 조건 예상 결과 를 보고 테스트 케이스를 설계하기 때문에 명세 기반 테스트 라고도 합니다. 즉, 프로그램 내부 코드 → 보지 않음 입력과 출력 → 확인 입니다. 4. 블랙박스 테스트 주요 기법 대표적인 블랙박스 테스트 기법은 다음과 같습니다. 동치 분할 테스트 경곗값 분석 결정 테이블 테스트 상태 전이 테스트 원인 결과 그래프 테스트 페어와이즈 테스트 유스케이스 테스트 분류 트리 테스트 비교 테스트 오류 추정 각각 어떤 단서를 보고 구분하는지가 중요합니다. 5. 동치 분할 테스트 동치 분할 테스트(Equivalence Partitioning) 는 같은 방식으로 처리될 것으로 예상되는 입력값들을 하나의 묶음으로 나누는 기법입니다. 이러한 입력값의 묶음을 동치 클래스 라고 합니다. 그리고 각 동치 클래스에서 대표값 하나 를 골라 테스트합니다. 예를 들어 점수 구간이 0점 미만 0 ~ 69점 70 ~ 79점 80 ~ 89점 90 ~ 100점 100점 초과 로 나누어진다면 각각 하나의 동치 클래스로 볼 수 있습니다. 각 구간에서 -10 30 75 85 95 110 처럼 대표값 하나씩을 선택합니다. 핵심 같은 방식으로 처리될 입력을 묶음으로 나눈다. ↓ 각 묶음에서 대표값 하나를 선택한다. ↓ 동치 분할 테스트 6. 경곗값 분석 경곗값 분석(Boundary Value Analysis) 은 입력 범위의 경계 경계 바로 안쪽 경계 바로 바깥쪽 을 집중적으로 테스트하는 기법입니다. 예를 들어 입력 가능 범위가 1 ~ 10 이라면 0 1 2 9 10 11 처럼 경계 주변 값을 테스트합니다. 핵심 최솟값 최댓값 경계 바로 앞 경계 바로 뒤 → 경곗값 분석 7. 결정 테이블 테스트 결정 테이블 테스트(Decision Table Test) 는 여러 조건의 조합과 그에 따른 동작을 표 형태 로 정리하여 테스트합니다. 여기서 조건은 회원인가? 구매 금액이 일정 금액 이상인가? 처럼 참/거짓 또는 여러 값으로 판단할 수 있는 항목입니다. 예를 들어 회원 여부 구매 금액 할인 O 기준 이상 할인 적용 O 기준 미만 일부 할인 X 기준 이상 다른 할인 X 기준 미만 할인 없음 처럼 조건 조합마다 수행할 동작을 표로 표현합니다. 핵심 조건 조합 + 수행 동작 + 표 → 결정 테이블 테스트 8. 상태 전이 테스트 상태 전이 테스트(State Transition Test) 는 시스템이 현재 어떤 상태에 있는지와 특정 사건이 발생했을 때 상태가 어떻게 변하는지를 확인하는 기법입니다. 여기서 상태는 로그인 전 로그인 후 계정 잠금 처럼 현재 처한 상황입니다. 전이는 로그인 전 ↓ 로그인 성공 로그인 후 처럼 상태가 다른 상태로 바뀌는 것을 의미합니다. 핵심 현재 상태 + 사건 + 다음 상태 → 상태 전이 테스트 9. 원인 결과 그래프 테스트 원인 결과 그래프 테스트(Cause-Effect Graphing) 는 입력 조건과 출력 결과의 관계를 그래프 로 표현하는 기법입니다. 입력 조건 = 원인 출력 결과 = 결과 원인과 결과를 선으로 연결하여 AND OR NOT 등의 논리 관계를 표현합니다. 핵심 입력 조건 + 출력 결과 + 논리 관계 + 그래프 → 원인 결과 그래프 테스트 10. 페어와이즈 테스트 페어와이즈 테스트(Pairwise Testing) 는 여러 입력 요인이 있을 때 모든 전체 조합을 시험하는 대신 서로 다른 두 요인의 가능한 값 조합이 최소 한 번씩 나타나도록 테스트 케이스를 구성 하는 방법입니다. 입력 요인은 예를 들어 운영체제 브라우저 언어 네트워크 처럼 조합할 수 있는 항목입니다. 핵심 모든 조합 X 두 요인의 값 쌍을 빠짐없이 → 페어와이즈 테스트 11. 유스케이스 테스트 유스케이스 테스트(Use Case Test) 는 사용자가 시스템을 사용하여 목표를 이루는 전체 흐름을 기준으로 테스트합니다. 여기서 액터(Actor) 는 시스템을 사용하는 사람 또는 외부 시스템 을 의미합니다. 예를 들어 상품 주문 기능이라면 상품 선택 ↓ 장바구니 ↓ 주문 ↓ 결제 같은 기본 흐름을 확인합니다. 또한 결제 실패처럼 대안 흐름 예외 흐름 도 함께 테스트할 수 있습니다. 핵심 사용자 목표 + 기본 흐름 + 대안 흐름 → 유스케이스 테스트 12. 분류 트리 테스트 분류 트리 테스트(Classification Tree Test) 는 입력 조건을 나무의 가지처럼 나누어 분류하는 방법입니다. 예를 들어 운영체제 ├─ Windows ├─ Linux └─ macOS 브라우저 ├─ Chrome ├─ Edge └─ Firefox 처럼 입력 조건을 분류합니다. 그리고 마지막 잎에 위치한 선택값들을 조합하여 테스트 케이스를 만듭니다. 핵심 입력 조건을 트리 형태로 분류 → 분류 트리 테스트 13. 비교 테스트 비교 테스트(Comparison Test) 는 같은 기능을 수행하는 여러 버전 여러 시스템 여러 구현 에 같은 입력값을 넣고 결과를 서로 비교하는 방법입니다. 핵심 같은 입력 ↓ 여러 시스템에 입력 ↓ 결과 비교 → 비교 테스트 14. 오류 추정 오류 추정(Error Guessing) 은 경험상 자주 발생하는 오류를 예상하여 해당 상황을 집중적으로 테스트하는 방법입니다. 예를 들어 이전에 빈 문자열 처리 NULL 처리 0으로 나누기 최댓값 입력 같은 부분에서 오류가 자주 발생했다면 비슷한 상황을 집중적으로 테스트합니다. 핵심 과거 경험 + 자주 발생하는 오류 예상 → 오류 추정 오류 추정의 분류 주의 오류 추정은 최근 테스트 분류에서는 경험 기반 테스트 기법 으로 다루지만, 정보처리기사 기존 교재나 문제 풀이에서는 블랙박스 테스트 기법 목록에 함께 포함하는 경우도 있습니다. 따라서 시험에서는 문제의 보기 지문의 분류 기준 을 따르는 것이 중요합니다. 다만 핵심 의미는 경험을 바탕으로 오류가 날 만한 곳을 예상한다. 라고 기억하면 됩니다. 15. 2026년 2회 실기 1번은 동치 분할 테스트다 2026년 2회 실기 1번에서는 점수에 따라 등급을 출력하는 프로그램과 여러 시험값이 제시되었습니다. 입력 영역을 나누면 다음과 같습니다. 입력 점수 예상 결과 대표값 클래스 0점 미만 오류 -10 무효 0 ~ 69점 D 30 유효 70 ~ 79점 C 75 유효 80 ~ 89점 B 85 유효 90 ~ 100점 A 95 유효 100점 초과 오류 110 무효 대표값은 -10 30 75 85 95 110 입니다. 각 값은 오류 D C B A 오류 라는 서로 다른 결과가 나오는 입력 묶음에서 하나씩 선택한 대표값 입니다. 경계 주변에 값이 몰려 있는 것이 아니라 각 구간을 대표하는 값이 하나씩 있기 때문에 동치 분할 테스트 입니다. 교재에 따라 동등 분할 테스트 동등 클래스 분할 이라고 표현하기도 합니다. 16. 동치 분할과 경곗값 분석은 값의 위치로 구분한다 두 기법은 시험에서 매우 자주 헷갈립니다. 구분 동치 분할 경곗값 분석 관심 대상 같은 결과가 나오는 입력 묶음 결과가 바뀌는 경계 값을 고르는 위치 각 묶음을 대표하는 값 경계와 바로 안쪽·바깥쪽 값 예시 -10, 30, 75, 85, 95, 110 -1, 0, 1, 69, 70, 71 등 기억할 문장 묶음마다 대표 하나 문턱의 앞과 뒤 동치 분할 구간마다 대표값 하나 를 선택합니다. 또한 정상 범위뿐만 아니라 정상 범위 아래 정상 범위 위 에 해당하는 무효 동치 클래스 도 나눕니다. 경곗값 분석 점수 등급을 예로 들면 0 69 70 79 80 89 90 100 과 그 바로 주변 값을 집중적으로 확인합니다. 💡 이렇게 외워보세요 같은 결과끼리 묶고, 묶음마다 대표 하나. 묶음 안에서 대표를 고르면 동치 분할 묶음이 갈리는 문턱을 고르면 경곗값 분석 입니다. 17. 시험에서 자주 틀리는 테스트 기법 조합 용어가 비슷해도 답을 구분하는 결정적인 단서가 있습니다. 문제에서 값의 위치 표현 형식 시험 대상 을 먼저 확인합니다. 동치 분할 vs 경곗값 분석 동치 분할 → 구간마다 대표값 경곗값 분석 → 구간이 바뀌는 경계 주변 원인 결과 그래프 vs 결정 테이블 원인 결과 그래프 → 조건과 결과의 논리 관계를 그래프로 표현 결정 테이블 → 조건 조합과 동작을 표로 표현 즉, 그래프 → 원인 결과 그래프 표 → 결정 테이블 로 구분할 수 있습니다. 상태 전이 vs 유스케이스 상태 전이 → 사건에 따른 상태 변화를 확인 유스케이스 → 사용자가 목표를 이루는 전체 흐름 확인 비교 테스트 vs 오류 추정 비교 테스트 → 여러 시스템의 결과를 비교 오류 추정 → 경험을 바탕으로 오류가 날 상황 예상 18. 화이트박스 테스트는 코드 내부의 흐름을 본다 화이트박스 테스트(White Box Test) 는 프로그램의 소스 코드나 설계의 내부 구조를 기준으로 테스트 케이스를 만듭니다. 블랙박스가 입력과 출력의 명세를 본다면, 화이트박스는 명령이 어떤 순서로 실행되는가? 어떤 갈림길을 지나는가? 어떤 반복문을 실행하는가? 를 확인합니다. 19. 제어 흐름과 실행 경로 화이트박스 테스트를 이해하려면 몇 가지 용어를 알아두면 좋습니다. 제어 흐름 프로그램의 명령이 실행되는 순서를 의미합니다. 시작 ↓ 조건문 ↓ 실행 ↓ 종료 같은 흐름입니다. 제어 흐름도 제어 흐름을 점 화살표 등으로 표현한 그래프입니다. 실행 경로 프로그램의 시작부터 끝까지 실제로 지나가는 하나의 길입니다. 제어 구조 실행 순서를 결정하는 조건문 분기 반복문 같은 프로그램 구조입니다. 20. 화이트박스 테스트 대표 기법 대표적인 화이트박스 테스트 기법은 기초 경로 테스트 조건 테스트 루프 테스트 데이터 흐름 테스트 입니다. 21. 기초 경로 테스트 기초 경로 테스트(Basis Path Test) 는 프로그램의 제어 흐름을 분석하고 독립 경로 를 찾아 테스트하는 방법입니다. 독립 경로는 이미 선택한 다른 경로들의 조합만으로 표현할 수 없는 새로운 실행 경로입니다. 기초 경로 테스트에서는 제어 흐름 그래프와 순환 복잡도 를 이용하여 필요한 독립 경로의 수를 구할 수 있습니다. 핵심 제어 흐름 그래프 독립 경로 순환 복잡도 → 기초 경로 테스트 22. 조건 테스트 조건 테스트(Condition Test) 는 프로그램의 조건문에 들어 있는 개별 조건들을 확인하는 방법입니다. 예를 들어 회원이고 성인이면 허용 이라는 조건이 있다면 회원 여부 성인 여부 등 각각의 조건이 참과 거짓이 되는 경우를 확인합니다. 핵심 조건식 참 / 거짓 → 조건 테스트 23. 루프 테스트 루프 테스트(Loop Test) 는 반복문을 대상으로 테스트하는 기법입니다. 반복문이 0회 1회 여러 번 최대 횟수 등으로 실행될 때 정상적으로 동작하는지 확인합니다. 또한 중첩 반복문 등도 확인합니다. 핵심 반복문 반복 횟수 중첩 → 루프 테스트 24. 데이터 흐름 테스트 데이터 흐름 테스트(Data Flow Test) 는 프로그램의 변수에 값이 어떻게 저장되고 사용되는지를 확인하는 기법입니다. 변수에는 크게 정의 사용 소멸 등의 흐름이 존재합니다. 예를 들어 값을 저장했지만 사용하지 않고 다시 덮어씀 값을 넣기 전에 먼저 읽음 같은 비정상적인 흐름을 확인할 수 있습니다. 핵심 변수 정의 변수 사용 데이터 흐름 → 데이터 흐름 테스트 25. 화이트박스 테스트 핵심 정리 기초 경로 테스트 → 독립 경로 / 순환 복잡도 조건 테스트 → 조건의 참과 거짓 루프 테스트 → 반복문 데이터 흐름 테스트 → 변수의 정의와 사용 이러한 기법은 화이트박스 테스트의 대표적인 설계 방법입니다. 실제 정보처리기사에서는 기법 이름 자체뿐만 아니라 코드의 어느 부분을 얼마나 실행했는가? 를 묻는 커버리지 문제도 자주 등장합니다. 26. 화이트박스 커버리지는 확인한 범위를 나타낸다 커버리지(Coverage) 는 테스트 대상으로 정한 항목 가운데 실제로 테스트한 항목의 비율입니다. 무엇을 기준으로 하느냐에 따라 문장 분기 개별 조건 실행 경로 등 확인해야 하는 범위가 달라집니다. 대표적인 커버리지에는 문장 커버리지 결정 커버리지 조건 커버리지 조건/결정 커버리지 다중 조건 커버리지 MC/DC 등이 있습니다. 이들 커버리지의 차이는 별도로 자세히 비교해서 익히는 것이 좋습니다. 27. 경험 기반 테스트는 이미 아는 위험을 활용한다 경험 기반 테스트는 테스터의 경험 과거 결함 개발자의 흔한 실수 점검 목록 등을 활용해서 테스트합니다. 대표적인 기법은 오류 추정 탐색적 테스트 체크리스트 기반 테스트 입니다. 28. 오류 추정 오류 추정은 과거 결함 개발자의 실수 를 바탕으로 오류가 발생할 만한 곳을 예상하는 방법입니다. 결정 단서 경험 직관 자주 발생한 오류 29. 탐색적 테스트 탐색적 테스트(Exploratory Testing) 는 학습 테스트 설계 테스트 실행 을 동시에 진행하면서 다음 테스트를 조정하는 방법입니다. 즉, 테스트 실행 ↓ 결과 관찰 ↓ 다음 테스트 설계 ↓ 즉시 실행 하는 방식입니다. 또한 테스트 차터(Test Charter) 라는 짧은 안내를 사용할 수 있습니다. 테스트 차터는 이번 탐색에서 무엇을 어떤 목표로 테스트할 것인가 를 정리한 간단한 문서입니다. 핵심 단서 동시에 학습 설계 실행 테스트 차터 → 탐색적 테스트 30. 체크리스트 기반 테스트 체크리스트 기반 테스트(Checklist-based Testing) 는 경험을 통해 만든 점검 목록을 이용하여 하나씩 확인하는 방법입니다. 결정 단서 점검표 확인 목록 경험으로 만든 항목 핵심 점검 목록을 따라 확인 → 체크리스트 기반 테스트 31. 같은 테스트 단원이라도 설계 기법과 범위가 다른 용어 정보처리기사에서는 단위 테스트 통합 테스트 시스템 테스트 인수 테스트 도 자주 등장합니다. 하지만 이것들은 테스트 케이스를 어떻게 설계할 것인가? 보다는 언제, 어떤 범위를 테스트할 것인가? 에 가까운 개념입니다. 따라서 블랙박스·화이트박스 같은 테스트 설계 기법 과 구분해야 합니다. 32. 테스트 수준 테스트 수준 의미 단위 테스트 개별 모듈이나 기능을 따로 시험 통합 테스트 여러 모듈을 연결하여 상호 작용을 시험 시스템 테스트 제품 전체를 시험 인수 테스트 사용자 요구와 사용 목적을 충족하는지 확인 33. 통합 테스트 방식과 도구 통합 테스트에서는 하향식 상향식 스텁 드라이버 등이 자주 등장합니다. 하향식 통합 테스트 상위 기능 ↓ 하위 기능 순서로 모듈을 연결합니다. 즉, 위에서 아래 → 하향식 입니다. 상향식 통합 테스트 하위 기능 ↓ 상위 기능 순서로 모듈을 연결합니다. 즉, 아래에서 위 → 상향식 입니다. 스텁(Stub) 상위 모듈이 호출하는 하위 모듈이 아직 준비되지 않았을 때 그 역할을 대신하는 가짜 모듈입니다. 하향식 → Stub 으로 연결해서 기억하면 쉽습니다. 드라이버(Driver) 하위 모듈을 호출해줄 상위 모듈이 아직 준비되지 않았을 때 대신 호출해주는 가짜 모듈입니다. 상향식 → Driver 로 기억하면 됩니다. 34. 목적과 시점에 따른 테스트 테스트는 수행 목적이나 시점에 따라 다른 이름으로 분류하기도 합니다. 대표적으로 회귀 테스트 알파 테스트 등이 있습니다. 회귀 테스트 회귀 테스트(Regression Test) 는 프로그램을 수정한 후 기존 기능에 새로운 문제가 발생하지 않았는지 다시 확인하는 테스트입니다. 수정 후 기존 기능 재확인 → 회귀 테스트 알파 테스트 알파 테스트(Alpha Test) 는 개발 환경에서 대표 사용자가 시스템을 시험하는 방식입니다. 개발 환경 대표 사용자 → 알파 테스트 35. 결과 판정 - 테스트 오라클 테스트 결과가 맞는지 틀리는지를 판단하기 위해 사용하는 기준을 테스트 오라클(Test Oracle) 이라고 합니다. 즉, 실행 결과가 정답인지 판단하는 기준 입니다. 대표적으로 참 오라클 샘플링 오라클 등이 있습니다. 참 오라클 모든 테스트 대상 입력에 대해 정확한 결과를 알고 있는 방식입니다. 모든 입력의 정답을 알고 있음 → 참 오라클 샘플링 오라클 전체 입력 중 일부 선택된 입력에 대해서만 정확한 결과를 알고 판정합니다. 선택된 입력만 정답을 알고 있음 → 샘플링 오라클 36. 테스트 원리 - 살충제 패러독스 정보처리기사에서 자주 등장하는 테스트 원리 중 하나가 살충제 패러독스(Pesticide Paradox) 입니다. 같은 테스트만 계속 반복하면 새로운 결함을 발견하는 효과가 점점 떨어진다. 는 원리입니다. 즉, 같은 테스트 반복 ↓ 새로운 결함 발견 능력 감소 입니다. 따라서 테스트 케이스도 계속 수정하거나 추가해야 합니다. 37. 문제 단서에서 정확한 답안으로 옮기는 순서 테스트 문제를 풀 때 문제의 모든 문장을 외우려고 하기보다는 무엇을 했는가? 를 먼저 찾는 것이 중요합니다. 예를 들어 대표값을 골랐는가? 경계를 시험했는가? 표로 나타냈는가? 그래프로 나타냈는가? 코드의 참과 거짓을 실행했는가? 를 확인하면 됩니다. 대표 문제 단서 문제의 결정 단서 먼저 판단할 기준 정확한 답안 같은 결과가 나오는 입력 묶음에서 대표값을 고른다 입력 묶음 동치 분할 테스트 최솟값과 최댓값의 바로 안쪽과 바깥쪽을 시험한다 경계 주변 경곗값 분석 조건 조합과 수행 동작을 표로 나타낸다 명세의 조건 조합 결정 테이블 테스트 📌 블랙박스 테스트 최종 정리 동치 분할 → 입력을 같은 처리 결과의 묶음으로 나누고 대표값 선택 경곗값 분석 → 경계와 바로 안쪽/바깥쪽 결정 테이블 → 조건 조합 + 동작 + 표 상태 전이 → 현재 상태 + 사건 + 다음 상태 원인 결과 그래프 → 원인과 결과의 논리 관계를 그래프로 표현 페어와이즈 → 두 요인의 가능한 값 쌍을 최소 한 번씩 유스케이스 → 사용자 목표와 전체 흐름 분류 트리 → 입력 조건을 나무 형태로 분류 비교 테스트 → 같은 입력을 여러 시스템에 넣어 결과 비교 오류 추정 → 경험으로 오류가 날 상황 예상 📌 화이트박스 테스트 최종 정리 기초 경로 테스트 → 독립 경로 / 순환 복잡도 조건 테스트 → 조건의 참/거짓 루프 테스트 → 반복문과 반복 횟수 데이터 흐름 테스트 → 변수 정의와 사용 화이트박스 테스트의 핵심은 코드 내부 구조 실행 순서 갈림길 반복 변수 흐름 입니다. 📌 경험 기반 테스트 최종 정리 오류 추정 → 과거 결함과 경험 탐색적 테스트 → 학습 + 설계 + 실행을 동시에 체크리스트 기반 테스트 → 점검 목록 🧠 가장 먼저 구분할 것 입력 / 출력 / 요구사항 → 블랙박스 코드 내부 / 실행 경로 / 조건 / 반복 → 화이트박스 경험 / 직관 /
Log Friends의 SDK를 고민하면서 지원할 수 있는 환경은 더 많이 보였다. 하지만 고려한 환경을 지금 모두 지원해야 하는 것은 아니었다. 백엔드, 웹 프론트엔드, 모바일까지 구분해 생각하되, 실제 지원 범위는 웹과 백엔드로 정했다. 모바일이 중요하지 않아서가 아니라, 사용할 수 있는 시간과 인력으로 어디까지 구현하고 검증하며 유지할 수 있는지를 먼저 생각했기 때문이다. 이번 글에서 남기고 싶은 것은 테이블을 몇 개 나눴는지가 아니다. 설계에서 고려할 범위와 현재 개발에서 책임질 범위를 구분한 과정 이다. 처음에는 어떤 언어의 SDK를 만들지 생각했다 처음에는 Kotlin SDK, TypeScript SDK처럼 언어를 중심으로 바라봤다. 어떤 언어로 만든 서비스에서 Log Friends를 사용할 수 있게 할지가 먼저였다. 그런데 실행 환경까지 생각하니 언어만으로는 구분이 충분하지 않았다. Kotlin은 Spring Boot 서버와 Android에서 모두 쓰이고, TypeScript는 Node.js 서버와 브라우저에서 모두 쓰인다. 같은 언어라도 수집할 정보와 실행 중 신경 써야 할 일이 다르다. 환경 구분해서 생각한 내용 백엔드 요청·함수 실행·업무 이벤트와 서버 종료 시 전송 웹 프론트엔드 페이지·컴포넌트·사용자 행동과 페이지 종료 시 전송 모바일 앱 화면·앱 생명주기·네트워크 상태에 따른 전송 서버 이벤트에 웹의 page_path 나 component_name 이 필요한지 살펴본 것도 이 구분의 한 계기였다. 공통 이벤트 계약이 있다고 해서 환경별 정보까지 모두 공통으로 취급할 필요는 없었다. 지원 환경이 늘면 유지해야 할 일도 늘어난다 백엔드·웹·모바일을 모두 고려하는 것과 실제로 지원하는 것은 다른 일이었다. SDK 코드를 추가하는 것만으로 지원이 끝나지는 않는다. 각 환경에서 이벤트가 제대로 수집되는지, 전송이 실패했을 때 어떻게 동작하는지 확인해야 한다. 사용법을 문서화하고, 공통 계약을 바꿀 때 기존 동작이 깨지지 않는지도 계속 확인해야 한다. 모바일까지 포함하면 앱 생명주기와 네트워크 변화 같은 조건도 별도로 다뤄야 한다. 공통 전송 코드를 재사용할 수 있어도 환경별 검증과 유지보수까지 없어지는 것은 아니다. 제한된 시간과 인력으로 이 범위를 동시에 가져가면, 지원 목록은 늘어나지만 각 환경을 충분히 확인하는 데 쓸 시간은 줄어들 수 있다고 판단했다. 유지보수 비용을 수치로 측정한 것은 아니지만, 범위를 정할 때 빼놓을 수 없는 조건이었다. 그래서 모바일 지원까지 늘리기보다 웹과 백엔드에서 수집부터 저장·조회까지 이어지는 흐름을 먼저 검증하는 것 을 우선순위로 정했다. 지금 책임질 범위를 코드와 문서에 맞췄다 현재 지원 범위는 다음과 같다. 구분 SDK 업무 이벤트 저장 서버 백엔드 Kotlin/JVM, TypeScript Node backend_custom_events 웹 프론트엔드 TypeScript Browser frontend_custom_events 이벤트 형식과 배치 전송 계약은 공유하고, 웹 UI 전용 컬럼은 프론트엔드 테이블에만 둔다. 저장 위치는 SDK가 아니라 Console이 등록된 Agent의 출처를 보고 결정한다. 모바일도 문서에서만 제외하지 않았다. 현행 TypeScript 패키지의 모바일 공개 진입점을 제거하고 빌드·배포·지원 테스트 대상에서 제외했다. Console도 새 모바일 등록과 수집을 거절하도록 변경했다. 기존 모바일 코드와 과거 데이터는 삭제하지 않았다. 과거 레코드를 읽기 위한 MOBILE 값은 남겨뒀지만, 이를 현재 지원하는 기능으로 안내하지는 않는다. 모바일 앱을 제외하는 대신 당장 지원 환경을 늘릴 수 있는 선택지는 내려놓았다. 그 시간은 웹·백엔드의 동작 확인과 문서 정리에 쓰기로 했다. 모바일은 필요성과 유지 여력을 다시 확인할 때 검토할 수 있지만, 지금 지원을 약속한 상태는 아니다. 휴대전화의 웹 브라우저는 웹 지원 범위에 포함한다. 모바일 앱 SDK 제외와 반응형 웹 지원은 별개다. 어디까지 확인했는가 2026-10-08 로컬 변경 기준으로 다음을 확인했다. TypeScript SDK의 npm run prepublishOnly : lint, 지원 범위 테스트 67개, ESM·CommonJS 빌드, 패키지 검증 통과. npm pack --dry-run : 배포 대상 파일에 모바일 빌드 결과가 없는 것을 확인. Console: 별도 빌드 경로와 Kotlin incremental 비활성화 설정으로 전체 build 통과. 모바일 등록·수집 거절과 서버·브라우저 저장 분기 테스트 포함. 모바일 테스트는 지원 범위에서 제외했으므로 위 결과를 모바일 동작 검증으로 해석하면 안 된다. 저장 분기 테스트도 mock DB 기반이다. 실제 TimescaleDB에서 V15를 적용해 양쪽 SDK의 등록부터 저장까지 확인하는 작업은 남아 있다. npm 배포와 NAS 적용은 하지 않았다. 모바일 공개 API 제거는 하위 호환성이 깨지는 변경이므로, 실제 배포 전에 버전 정책과 제거 안내를 결정해야 한다. 배운 점 처음에는 SDK를 어떤 언어로 제공할지 생각했다. 그다음에는 백엔드·프론트엔드·모바일이라는 실행 환경의 차이가 보였고, 마지막에는 이를 유지할 시간과 인력까지 생각하게 됐다. 설계할 때 여러 환경을 고려하는 것은 필요했다. 하지만 현재 지원 범위까지 전부 넓혀야 하는 것은 아니었다. 고려는 넓게 하되, 지금 검증하고 유지할 수 있는 범위를 선택하는 것 도 개발의 일부였다. 다음은 웹과 서버 이벤트를 실제 테스트 DB에 보내 등록·수집·분리 저장까지 확인하는 것이다. 지금 선택한 두 환경부터 끝까지 확인하려고 한다.
🎯 2026년 목표 분야 목표 ☁️ Cloud 클라우드 환경 운영 경험 쌓기 (상세 내용 추후 작성) 🔐 Security 보안관제 자동화 경험 ✍️ Blog 블로그 꾸준히 작성 📚 자격증 정보처리기사 / 정보보안기사 / AWS-SAA 🏆 장기 자격증 CISA / CISSP (정보보안 관련 경력 요건 충족 후 도전) 💻 Development 개발 공부 꾸준히 진행 🇺🇸 English 영어 공부 🏃 Exercise 꾸준한 운동 🔄 Review 리팩토링 과정 복습 및 Velog 재작성 ☁️ Cloud Security 클라우드 보안 복습 및 Velog 작성 🎓 Next Year 석사 과정 예정 🗺️ 공부 로드맵 - Version 10월 🟢 완료 | 🟡 진행중 | 🔴 미완료 | ⚪ 시작 전 순서 공부 상태 / 목표 진행률 1 🐍 파이썬 🟢 점프 투 파이썬 완강 → 지속적인 복습 + 개인 프로젝트 100% 2 📘 정보처리기사 실기 🟡 10월 25일 시험 / 합격 목표 50% 3 🔐 모의해킹 - 노말틱 ⚪ 정보처리기사 실기 끝나고 11월 시작 0% 4 🇺🇸 영어 ⚪ 11월부터 시작 0% 5 🌐 혼자 공부하는 네트워크 🟢 완강 → 지속적인 복습 100% 6 🔄 리팩토링 과정 ⚪ 복습 + 실습 + 블로그 재작성 0% 7 🐳 Docker ⚪ 모의해킹 완료 후 시작 0% 8 ☁️ AWS 보안 가이드 ⚪ Docker 강의 완료 후 시작 0% 9 ☕ JAVA ⚪ 파이썬 활용 능력이 어느 정도 자리 잡은 후 시작 0% 📅 금주 목표 - 10/05(월) ~ 10/11(일) 🟢 완료 | 🟡 진행중 | 🔴 미완료 | ⚪ 시작 전 분야 목표 진행 상황 진행률 🌐 Network 혼자 공부하는 네트워크 복습 🟡 30% 🐍 Python Project Nmap과 유사한 기능 직접 구현 🟡 50% 📘 정보처리기사 개념 정리 🟡 40% 📘 정보처리기사 2020년도 기출 3회차 풀이 ⚪ 0% 📘 정보처리기사 2021년도 기출 2회차 풀이 ⚪ 0% 📘 정보처리기사 2022년도 기출 2회차 풀이 ⚪ 0% 📘 정보처리기사 2023년도 기출 1회차 풀이 ⚪ 0% 📘 정보처리기사 2024년도 기출 1회차 풀이 ⚪ 0% 📘 정보처리기사 2025년도 기출 1회차 풀이 ⚪ 0% 📘 정보처리기사 2026년도 기출 1회차 풀이 ⚪ 0% ✅ 오늘의 목표 🟢 완료 | 🟡 진행중 | 🔴 미완료 | ⚪ 시작 전 상태 할 일 ⚪ 💰 Household Account 작성 - 23:50 ⚪ 📘 **정보처리기사 개념 정리 + 블로그 정리 ⚪ 📘 정보처리기사 DAY 6 - 문제풀이 ⚪ 🌐 혼자 공부하는 네트워크 복습 DAY 6 🟡 🐍 Python Security Scanner DAY 6 - Nmap 기능 구현 + 블로그 정리 🟡 🐍 Python Security Scanner DAY 6 - 지금까지 작성 한 코드 복기 💻 오늘 완료한 일 상태 완료 내역 ✅ ✅ ✅ ✅ ✅ ✅
무슨 일이 있었나 오픈AI가 2026년 10월 6일 'Sharing AI progress in mathematics'라는 글을 통해 자사 내부 AI 모델이 수학계의 장기 미해결 난제 100개 이상을 풀어냈다고 공식 발표했다. 지난 8월 28일부터 학습을 시작한 내부 모델이, 앞서 공개된 나비에-스토크스 밀레니엄 상 문제 해결에 더해 수학 거의 모든 분야에 걸쳐 10년 이상 풀리지 않은 문제 100여 개를 추가로 해결했다는 내용이다. 오픈AI는 이 같은 주장을 독립적으로 검증하기 위해 '수학과 인공지능 자문단(Advisory Group on Mathematics and Artificial Intelligence)'을 꾸렸다고 밝혔다. 자문단 구성원은 오픈AI로부터 급여를 받지 않는 독립적 지위라는 점을 강조했다. 오픈AI 소속 수학자들조차 AI의 진행 속도에 놀라 내부적으로 '이 결과를 어떻게 공개할지'를 논의했다고 전해진다. 이번 발표는 이번 주 출시된 신형 모델 GPT-6 아스트라(Astra)가 추가로 여러 장기 미해결 수학 문제에서 새로운 결과를 냈다는 내용과도 맞물려 있다. 오픈AI는 아스트라가 수십 년간 풀리지 않은 수학·이론 컴퓨터과학 문제들을 '해결했거나 본질적인 진전을 이뤘다'고 설명했다. 앞서 올여름에는 내부 시스템이 10년 이상 미해결 상태였던 문제 10개를 풀었다고 밝힌 바 있고, 5월에는 미공개 모델이 에르되시 단위거리 추측(Erdős unit-distance conjecture)의 반증을 내놓기도 했다. 다만 이 발표를 둘러싼 논란도 있다. 오픈AI의 초기 발표문에는 "핵심 결과에 대해 최소 10년 이상, 많은 경우 그보다 훨씬 오래 진전이 없었던 미해결 문제들의 답을 공유한다"는 문구가 있었는데, 이후 별다른 설명 없이 조용히 수정됐다. 매체 더버지에 따르면 케임브리지대학의 한 수학자는 오픈AI의 초기 발표가 안드레아스 톰(Andreas Thom)과 가보르 쿤(Gábor Kun) 등 기존 연구자들의 핵심적인 선행 기여를 충분히 밝히지 않았다고 지적했다. 왜 중요한가 이번 사안은 'AI가 정말 독창적인 추론으로 난제를 풀었는가, 아니면 기존 문헌의 결과를 재구성·결합한 것에 가까운가'라는 신뢰성·공로 인정 문제를 정면으로 제기한다. AI 모델이 이미 존재하는 인간 연구자의 성과를 디딤돌로 삼았다면, 그 공로를 어떻게 분배할 것인가는 간단치 않은 문제다. 주요 AI 랩들이 '유명 미해결 문제를 풀었다'는 성과를 역량 과시·마케팅 수단으로 점점 더 많이 활용하는 흐름 속에서, 독립적 검증 기구의 필요성이 커지고 있다. 오픈AI가 자문단을 꾸린 것도 이런 맥락이지만, 급여 지급 구조나 실제 독립성 수준은 앞으로도 검증 대상이 될 전망이다. 보도에 따르면 앤스로픽의 미공개 클로드 연구 모델도 별도로 리만 가설과 관련된 수십 년 묵은 연구에서 주요한 진전을 이뤘다고 알려져, 오픈AI·앤스로픽·구글 딥마인드 등 프런티어 랩들이 유명 수학 난제 해결을 'AGI에 가까운 역량'의 증거로 경쟁적으로 내세우는 더 큰 흐름의 일부임을 보여준다. 이러한 성과가 사실이라면 AI가 순수수학 연구의 협력자로서 빠르게 유용해지고 있다는 신호지만, 과장된 주장은 수학계의 신뢰를 해치고 톰·쿤 공로 논란처럼 반발을 부를 수 있다는 점에서 균형 잡힌 검증이 중요해지고 있다. 원문: https://openai.com/index/sharing-ai-progress-in-mathematics
무슨 일이 있었나 앤스로픽이 2026년 10월 7일 신형 소형 모델 '클로드 하이쿠 5.5(Claude Haiku 5.5)'를 공식 출시했다. API 식별자는 claude-haiku-5-5 이며, 클로드 플랫폼은 물론 AWS·구글 클라우드·마이크로소프트 애저에서도 바로 이용할 수 있다. 앤스로픽은 이 모델을 "지금까지 내놓은 소형 모델 중 가장 저렴하고 가장 빠르며 가장 성능이 뛰어난 모델"이라고 소개했다. 요약, 컨텍스트 압축, 데이터베이스 질의, 분류 같은 대량·저비용 작업에 적합하고, 오퍼스 5.5·소네트 5.5와 함께 서브에이전트로 활용하거나 실시간 고객지원·브라우저 자동화처럼 속도가 중요한 작업에도 쓰도록 설계됐다. 특히 하이쿠 계열 최초로 '조정 가능한 추론 강도(effort)' 설정이 도입돼, 비용과 성능 사이의 균형을 사용자가 직접 조절할 수 있게 됐다. 하이쿠 4.5 대비 벤치마크 향상폭도 상당하다. OSWorld 2.1(오프라인 서브셋) 점수는 15.7%에서 72.4%로, 'Humanity's Last Exam'(도구 미사용)은 10.2%에서 45.9%로, Terminal-Bench 4.0은 0.0%에서 39.2%로 뛰었다. 가격은 100만 토큰당(10만 토큰 이하/초과 기준) 입력 0.10달러/0.50달러, 출력 0.50달러/2.50달러, 캐시 읽기 0.01달러/0.05달러, 캐시 쓰기 0.125달러/0.625달러로 책정됐다. 앤스로픽에 따르면 평균적으로 하이쿠 4.5보다 운영 비용이 약 75% 저렴하다. 함께 발표된 내용으로 소네트 5.5의 캐시 읽기 가격도 100만 토큰당 0.10달러로 절반 인하돼 에이전트 작업 비용을 약 20% 낮췄고, 맥스·팀 구독자에겐 매달 API 크레딧이 제공되며 파이썬·타입스크립트 SDK에는 컴퓨터·브라우저 사용 베타 기능이 추가됐다. 안전성 면에서는 하이쿠 4.5보다 정렬 수준이 개선됐고, 사이버보안 안전장치는 더 엄격해졌으며 생물 안전장치는 다른 최신 모델과 동일한 수준이라고 밝혔다. 왜 중요한가 '소형' 모델임에도 벤치마크가 큰 폭으로 뛴 것은, 한때 플래그십 모델만 가능했던 성능이 빠르게 저가 모델로 내려오고 있음을 보여준다. 이는 AI 성능-비용 경쟁의 최전선이 계속 이동하고 있다는 신호다. 시점도 주목할 만하다. 오픈AI가 GPT-6와 '인텔리전트 UI'를 챗GPT 전체에 적용한 날과 같은 날 발표되면서, 플래그십·보급형 모델 양쪽에서 동시에 벌어지는 오픈AI·앤스로픽·구글의 3각 경쟁 구도가 한층 뚜렷해졌다. 기업 입장에서는 분류·서브에이전트 같은 대량 작업의 비용이 낮아지면 AI 도입의 총비용(TCO)이 줄어 생산 환경 적용이 가속화될 수 있다. 또한 '조정 가능한 추론 강도'는 추론 비용 관리가 전략적 레버가 되는 흐름을 보여준다. 최근 마이크로소프트 CEO 사티아 나델라가 "토큰맥싱(tokenmaxxing)"의 비용 부담을 언급하며 "프런티어 문제가 아니면 프런티어 모델을 쓰지 말라"고 한 발언과 맞닿아 있는 대목으로, 업계 전반이 '모델 크기·비용에 맞는 최적 배치' 전략으로 옮겨가고 있음을 시사한다. 원문: https://www.anthropic.com/claude-haiku-5-5
AI가 코드를 쓰기 시작하자, 제품을 만드는 사람의 일이 바뀌었다 얼마 전 「 개발자는 안 뽑습니다 」라는 글을 읽었다. 제목만 보면 개발자의 시대가 끝난다는 이야기처럼 보이지만, 글의 핵심은 조금 다르다. 개발자가 필요 없어지는 것이 아니라, 제품을 만드는 사람에게 요구되는 능력이 달라지고 있다는 이야기다. 과거에는 아이디어를 실제 제품으로 만드는 일이 쉽지 않았다. 문제를 발견한 사람이 기획서를 작성하면 디자이너가 화면을 만들고, 개발자가 코드를 작성하고, 다시 QA를 거쳐 제품을 출시했다. 아이디어와 실제 제품 사이에는 많은 사람이 필요했고, 상당한 시간이 필요했다. 그 과정에서 가장 희소한 능력 중 하나는 ‘구현할 수 있는 능력’이었다. 그런데 AI가 이 구조를 빠르게 바꾸고 있다. 이제는 기획자나 디자이너, 창업자처럼 직접 개발을 하지 않던 사람도 AI를 이용하면 실제 작동하는 제품을 만들 수 있다. 완벽한 제품은 아니더라도 아이디어를 화면으로 만들고, 데이터를 연결하고, 사용자에게 보여주고, 반응을 확인하는 것까지 가능해졌다. 그래서 제품 개발의 흐름도 조금씩 달라지고 있다. 예전에는 아이디어 → 기획서 → 디자인 → 개발 → 테스트 → 출시 였다면, 앞으로는 문제 발견 → 프로토타입 → 사용자 반응 → 수정 이라는 훨씬 짧은 반복이 가능해진다. 중요한 변화는 개발 속도만 빨라지는 것이 아니다. 제품을 만드는 사람의 역할 자체가 바뀐다는 점이다. 구현 능력보다 중요한 것이 생기기 시작했다 AI 이전에는 “어떻게 만들 것인가”가 중요한 문제였다. 서비스를 만들고 싶어도 개발할 사람이 없으면 시작하기 어려웠다. 하지만 AI가 구현 비용을 빠르게 낮추면서 질문이 달라지고 있다. 무엇을 만들 것인가. 왜 만들어야 하는가. 누구의 어떤 문제를 해결할 것인가. 어떤 기능을 만들지 않을 것인가. 그리고 실제로 만든 것이 효과가 있었는가. 이런 질문의 중요성이 훨씬 커진다. 코딩이 중요하지 않아지는 것이 아니다. 코딩이라는 생산 수단에 접근하기 위해 필요했던 진입장벽이 낮아지고 있는 것이다. 이 차이는 꽤 크다. 과거에는 아이디어가 있어도 구현 능력이 없으면 제품을 만들기 어려웠지만, 이제는 아이디어와 판단력이 있는 사람이 AI의 도움을 받아 직접 실험할 수 있다. 그렇다면 자연스럽게 희소성도 이동한다. ‘만드는 방법을 아는 사람’에서 ‘무엇을 만들어야 하는지 아는 사람’으로. AI Builder라는 새로운 형태의 사람 최근 이런 사람을 ‘AI Builder’라고 부르기 시작한다. AI Builder를 단순히 AI로 코딩하는 사람이라고 생각하면 조금 부족하다. 중요한 것은 AI 도구를 얼마나 많이 사용할 줄 아느냐가 아니다. 현실의 문제를 발견하고, 그것을 제품으로 바꾸고, 실제 사용자에게 전달하고, 결과를 확인할 때까지 전체 과정을 움직일 수 있는 사람이 AI Builder에 가깝다. 그래서 출신 직군도 크게 중요하지 않다. 개발자일 수도 있고, 기획자일 수도 있고, 디자이너일 수도 있고, 마케터나 창업자일 수도 있다. 중요한 것은 자신의 전문 영역을 넘어 제품 전체를 바라볼 수 있는가다. 문제를 발견하고, 가설을 세우고, AI를 이용해 빠르게 구현하고, 사용자에게 보여주고, 결과를 측정하고, 다시 수정한다. 이 과정 전체를 반복할 수 있는 사람이 점점 강해질 것이다. 오히려 ‘현장 경험’의 가치가 커진다 AI 시대에 역설적으로 더 중요해지는 것이 있다. 바로 도메인 지식과 현장 경험이다. AI는 많은 것을 알고 있다. 코드도 작성하고, 화면도 만들고, 문서도 정리한다. 하지만 어떤 문제가 정말 중요한지는 여전히 현실 속에 있다. 고객이 어디에서 불편함을 느끼는지, 어떤 절차 때문에 포기하는지, 사람들이 말로 표현하지 않는 불만은 무엇인지, 업계에서 당연하게 받아들이지만 사실은 비효율적인 것이 무엇인지. 이런 것은 현장에 있는 사람이 훨씬 잘 알 수 있다. 그래서 AI가 강해질수록 인간의 전문성이 필요 없어지는 것이 아니라 전문성의 종류가 달라질 가능성이 높다. 과거에는 특정 도구를 다루는 전문성이 중요했다면, 앞으로는 문제와 사람을 이해하는 전문성이 더 중요해질 수 있다. 무엇을 만들지보다 무엇을 만들지 않는지가 중요해진다 또 하나의 변화가 있다. AI를 이용하면 기능을 만드는 것이 너무 쉬워진다. 몇 년 전이라면 개발 비용 때문에 포기했을 기능도 이제는 며칠, 경우에 따라 몇 시간 안에 프로토타입으로 만들 수 있다. 그런데 이건 좋은 일만은 아니다. 쉽게 만들 수 있다는 것은 쉽게 불필요한 것도 만들 수 있다는 뜻이기 때문이다. 기능을 하나 더 추가하는 비용이 낮아질수록 제품은 오히려 복잡해질 위험이 있다. 그래서 앞으로 좋은 제품을 만드는 사람에게 중요한 능력 중 하나는 ‘만들지 않는 능력’이 될 것이다. 이 기능이 정말 필요한가. 이 문제가 실제로 존재하는가. 사용자가 원하는 것인가, 아니면 우리가 만들고 싶은 것인가. 지금 만들어야 하는가. 이 질문에 계속 답해야 한다. AI 시대에는 제작 능력보다 선택 능력이 더 중요해질 수 있다. Build보다 Measure가 중요해진다 제품을 만드는 비용이 내려가면 자연스럽게 병목도 이동한다. 과거에는 ‘만드는 것’이 병목이었다. 앞으로는 ‘무엇이 효과가 있었는지 알아내는 것’이 병목이 될 가능성이 크다. 제품을 출시했다고 끝나는 것이 아니다. 사람들이 실제로 사용하는가. 처음 방문한 사람이 가입하는가. 가입한 사람이 계속 사용하는가. 어디에서 이탈하는가. 어떤 기능은 사용하지 않는가. 우리가 해결했다고 생각했던 문제가 정말 해결됐는가. 이 데이터를 보고 다시 제품을 바꿔야 한다. 그래서 앞으로의 제품 개발 과정은 단순한 Think → Build → Deploy 가 아니라, Think → Build → Deploy → Measure → Learn → Build 이라는 반복에 가까워질 것이다. AI가 Build를 빠르게 해줄수록 Measure와 Learn의 중요성은 더욱 커진다. AI가 모든 전문가를 대체하는 것은 아니다 여기에는 반드시 주의해야 할 부분도 있다. AI가 만들어낸 제품이 화면에서 정상적으로 작동한다고 해서 좋은 제품인 것은 아니다. 보안, 개인정보, 데이터베이스 구조, 결제, 권한 관리, 대규모 트래픽, 장애 대응, 법률과 규제 같은 문제는 여전히 높은 전문성이 필요하다. AI Builder가 모든 것을 혼자 해야 한다는 의미도 아니다. 오히려 좋은 Builder에게 중요한 능력은 자신이 어디까지 판단할 수 있고 어디부터 전문가가 필요한지를 구분하는 것이다. AI는 전문가를 없애기보다는 전문가가 개입하는 지점을 바꿀 가능성이 크다. 반복적인 구현은 AI가 맡고, 복잡한 판단과 높은 위험이 존재하는 영역에는 더 높은 수준의 전문가가 집중하는 식이다. 결국 회사의 최소 단위도 달라질 수 있다 이 변화가 계속된다면 단순히 개인의 업무 방식만 달라지는 것이 아닐 수 있다. 회사의 형태도 달라질 것이다. 과거에는 하나의 인터넷 서비스를 만들기 위해 기획자, 디자이너, 프론트엔드 개발자, 백엔드 개발자, QA, 데이터 분석가 등 여러 역할이 필요했다. 앞으로는 한 사람이 AI를 통해 이 능력들의 상당 부분을 호출할 수 있다. 그렇다고 여덟 명이 필요했던 회사가 무조건 한 명의 회사가 된다는 뜻은 아니다. 좀 더 정확히 말하면, 한 사람이 여덟 가지 능력에 접근할 수 있게 된다는 것이다. 그리고 필요할 때 전문가와 협업한다. 조직에서 중요한 것은 사람 수가 아니라 판단과 실행의 밀도가 된다. 앞으로 경쟁력이 되는 것은 무엇일까 AI가 더 발전한다고 가정하면 제품을 만드는 사람에게 필요한 능력은 대략 다섯 가지로 정리할 수 있을 것 같다. 첫 번째는 문제를 발견하는 능력이다. 두 번째는 무엇을 만들고 무엇을 만들지 않을지 결정하는 제품 판단력이다. 세 번째는 AI를 단순히 사용하는 것이 아니라 여러 작업을 연결하고 검증하는 능력이다. 네 번째는 특정 분야에 대한 깊은 현장 지식이다. 마지막은 결과에 대한 책임이다. 기능을 만들었다는 것으로 끝나는 것이 아니라 그것이 실제로 사람들의 행동을 바꾸고 문제를 해결했는지 확인하는 것이다. 결국 앞으로 제품을 만드는 사람의 경쟁력은 얼마나 많은 코드를 작성했느냐보다, 얼마나 정확하게 문제를 발견하고, 얼마나 빠르게 실험하고, 얼마나 제대로 결과를 측정하며, 얼마나 집요하게 개선할 수 있는가에 가까워질 것이다. AI가 강해질수록 인간의 판단력이 중요해진다 AI 시대를 이야기할 때 우리는 자꾸 AI가 무엇을 할 수 있는지를 이야기한다. 코드를 작성한다. 디자인을 만든다. 문서를 작성한다. 데이터를 분석한다. 하지만 어쩌면 더 중요한 질문은 반대편에 있을지도 모른다. AI가 많은 일을 할 수 있게 되었을 때 인간은 무엇을 해야 하는가. 나는 그 답이 ‘판단’에 가까워지고 있다고 생각한다. 어떤 문제를 해결할 것인지. 누구를 위해 만들 것인지. 무엇을 중요하게 생각할 것인지. 무엇을 하지 않을 것인지. 그리고 결과에 책임질 것인지. AI가 구현 비용을 낮출수록 이런 질문들의 가치는 오히려 올라간다. 그래서 앞으로 좋은 제품을 만드는 사람은 AI보다 더 많은 것을 아는 사람이 아닐지도 모른다. AI에게 무엇을 맡기고, 자신은 어떤 판단을 해야 하는지를 아는 사람. 그리고 현실의 문제를 끝까지 바라보는 사람. 그런 사람이 앞으로의 Builder가 아닐까.
🧩 GoF 디자인 패턴 정리 정보처리기사 실기에서 자주 출제되는 GoF 디자인 패턴 을 문제 중심으로 정리한다. GoF 디자인 패턴은 목적에 따라 크게 다음 세 종류로 구분한다. 생성 패턴(Creational) 구조 패턴(Structural) 행위 패턴(Behavioral) 📌 연습 문제 1. 생성 패턴 구분 다음 설명에 해당하는 생성 패턴을 순서대로 쓰시오. ᄀ. 서로 어울리는 버튼, 창, 메뉴 같은 제품군을 구체 클래스 없이 한 세트로 만든다. ᄂ. 같은 조립 절차를 사용해 서로 다른 형태의 복잡한 결과물을 만든다. ᄃ. 이미 존재하는 원형 객체를 복제해 새 객체를 얻는다. ᄅ. 클래스의 인스턴스를 하나만 만들고 여러 사용자가 같은 인스턴스에 접근한다. 풀이 ᄀ. 관련 객체들을 한 세트로 생성 서로 관련되거나 의존적인 객체들을 구체적인 클래스를 직접 지정하지 않고 제품군 단위로 생성 한다. 관련 객체 제품군 버튼 + 창 + 메뉴 한 세트로 생성 → Abstract Factory ᄂ. 조립 과정을 이용해 복잡한 객체 생성 같은 생성 절차를 사용하면서 최종 결과물은 다르게 만들 수 있다. 복잡한 객체 단계별 조립 같은 과정 → 다른 결과 → Builder ᄃ. 기존 객체 복제 새로운 객체를 처음부터 만드는 대신 기존 객체를 복사하여 생성한다. 원형 객체 복제 Clone → Prototype ᄅ. 인스턴스를 하나만 생성 프로그램 전체에서 객체를 하나만 생성하고 같은 객체를 공유한다. 인스턴스 1개 공유 전역 접근 → Singleton ✅ 답 ᄀ : Abstract Factory ᄂ : Builder ᄃ : Prototype ᄅ : Singleton 2. Adapter · Bridge 다음 두 상황에 해당하는 구조 패턴을 순서대로 쓰시오. ᄀ. 이미 만들어진 결제 모듈의 인터페이스가 새 서비스의 규격과 맞지 않아 중간 변환 객체를 끼웠다. ᄂ. 리모컨 종류와 가전제품 종류가 앞으로 각각 늘어날 수 있어 두 계층을 분리하고 연결 객체를 뒀다. 풀이 ᄀ. 인터페이스 변환 기존 클래스 자체를 수정하지 않고 중간 객체를 이용하여 원하는 인터페이스로 변환한다. 기존 인터페이스 ↓ 변환 ↓ 새 인터페이스 → Adapter ᄂ. 추상화와 구현 분리 기능을 담당하는 계층과 실제 구현을 담당하는 계층을 분리하여 각각 독립적으로 확장할 수 있게 한다. 추상화 계층 ↔ 구현 계층 서로 독립적으로 확장 → Bridge ✅ 답 ᄀ : Adapter ᄂ : Bridge 3. Proxy · Decorator · Facade 다음 역할에 해당하는 패턴을 순서대로 쓰시오. ᄀ. 실제 객체 앞에서 권한을 검사하고 필요할 때만 실제 객체를 만든다. ᄂ. 기존 인터페이스를 유지하면서 감싼 객체에 기능을 겹쳐 더한다. ᄃ. 복잡한 여러 하위 시스템을 단순한 하나의 진입 창구로 감춘다. 풀이 ᄀ. 실제 객체 대신 대리 객체 사용 클라이언트가 실제 객체에 직접 접근하지 않고 대리 객체를 거치게 한다. 접근 제어 권한 검사 지연 생성 대리 객체 → Proxy ᄂ. 객체를 감싸 기능 추가 기존 객체의 인터페이스는 유지하면서 객체를 감싸 새로운 기능을 추가한다. 기존 객체 ↓ Decorator로 감싸기 ↓ 기능 추가 → Decorator ᄃ. 복잡한 시스템에 단순한 창구 제공 여러 개의 복잡한 하위 시스템을 직접 호출하는 대신 하나의 단순한 인터페이스를 제공한다. 복잡한 여러 시스템 ↓ 하나의 단순한 창구 → Facade ✅ 답 ᄀ : Proxy ᄂ : Decorator ᄃ : Facade 4. Observer · Mediator 한 뉴스 채널의 새 소식이 등록된 구독자 모두에게 자동 전송되는 방식과, 여러 항공기의 요청을 관제탑 하나가 받아 충돌 없이 조정하는 방식에 해당하는 패턴을 순서대로 쓰시오. 풀이 뉴스 채널과 구독자 한 객체의 상태가 변경되면 해당 객체를 구독하고 있는 여러 객체에 자동으로 알린다. Publisher ↓ Observer 1 Observer 2 Observer 3 상태 변화 구독자에게 자동 알림 1 : N → Observer 항공기와 관제탑 객체들이 서로 직접 통신하지 않고 중간의 중재 객체를 통해 통신한다. 항공기 A ─┐ 항공기 B ─┼→ 관제탑 → 조정 항공기 C ─┘ 중앙 중재자 객체 간 직접 통신 감소 → Mediator ✅ 답 Observer, Mediator 5. Strategy · State 내비게이션 사용자가 최소 거리와 최단 시간 계산법 가운데 하나를 선택하는 경우와, 주문 객체가 결제 대기, 결제 완료, 취소라는 내부 상태에 따라 같은 요청에 다르게 반응하는 경우의 패턴을 순서대로 쓰시오. 풀이 알고리즘을 선택 여러 알고리즘을 각각 객체로 만들어 필요에 따라 교체한다. 최단 거리 알고리즘 최단 시간 알고리즘 사용자가 선택 → Strategy 객체 상태에 따라 행동 변화 같은 객체라도 내부 상태가 달라지면 행동이 달라진다. 결제 대기 결제 완료 취소 상태에 따라 행동 변경 → State ✅ 답 Strategy, State 6. 행위 패턴 구분 다음 설명에 해당하는 행위 패턴을 순서대로 쓰시오. ᄀ. 요청을 객체로 만들어 저장, 대기열 처리, 취소를 가능하게 한다. ᄂ. 요청을 처리할 객체를 만날 때까지 처리자 사슬을 따라 넘긴다. ᄃ. 컬렉션 내부 표현을 노출하지 않고 원소에 차례로 접근한다. ᄅ. 객체 구조를 바꾸지 않고 원소에 적용할 새 연산을 별도 객체로 추가한다. ᄆ. 상위 클래스가 알고리즘 골격을 정하고 하위 클래스가 일부 단계를 재정의한다. 풀이 ᄀ. 요청을 객체로 캡슐화 실행할 요청 자체를 하나의 객체로 만든다. 요청 객체화 저장 Queue Undo → Command ᄂ. 처리자에게 계속 전달 현재 객체가 처리할 수 없으면 다음 처리자에게 요청을 넘긴다. 요청 ↓ 처리자 A ↓ 처리자 B ↓ 처리자 C → Chain of Responsibility ᄃ. 컬렉션 순회 컬렉션의 내부 구조를 직접 노출하지 않고 요소를 하나씩 접근한다. hasNext() next() → Iterator ᄅ. 객체 구조는 그대로 두고 연산 추가 기존 객체 구조를 수정하지 않으면서 새로운 연산을 추가한다. 객체 구조 유지 새로운 연산 추가 각 객체 방문 → Visitor ᄆ. 알고리즘의 전체 틀 제공 상위 클래스에서 알고리즘의 전체 흐름을 정의하고 세부 단계만 하위 클래스에서 구현한다. 전체 흐름 → 부모 클래스 일부 단계 → 자식 클래스 → Template Method ✅ 답 ᄀ : Command ᄂ : Chain of Responsibility ᄃ : Iterator ᄅ : Visitor ᄆ : Template Method 📚 2020~2026년 관련 기출문제 📌 2020년 2회 10번 다음 보기가 설명하는 패턴을 쓰시오. 영문 Full-Name으로 작성하시오. 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에게 연락이 가고 자동으로 내용이 갱신되는 방법으로 일대 다의 의존성을 가지며 상호작용하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다. 풀이 핵심 키워드는 한 객체의 상태 변화 다른 객체들에게 자동 전달 1 : N 느슨한 결합 이다. 이는 Observer Pattern 의 특징이다. ✅ 답 Observer Pattern 📌 2020년 4회 2번 목적에 따른 디자인 패턴의 유형에는 생성, 구조, ( ) 이/가 있다. 괄호 ( ) 안에 알맞은 유형을 쓰시오. 풀이 GoF 디자인 패턴은 목적에 따라 세 가지로 분류한다. 생성 패턴 구조 패턴 행위 패턴 ✅ 답 행위 📌 2021년 2회 13번 괄호 ( ) 안에 알맞은 단어를 쓰시오. 디자인 패턴 중에서 ( ) 패턴은 반복적으로 사용되는 객체들의 상호작용을 패턴화한 것으로, 클래스나 객체들이 상호작용하는 방법이다. 알고리즘의 패턴에는 Interpreter, Observer, Command가 있다. 풀이 문제에서 객체들의 상호작용 책임 분배 Observer Command Interpreter 가 등장한다. 이들은 모두 행위 패턴 에 속한다. ✅ 답 행위(Behavioral) 📌 2021년 3회 16번 다음 설명에 해당하는 디자인 패턴을 쓰시오. ( ) 패턴은 객체지향 디자인 패턴이다. 부모(상위) 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이며, 자식(하위) 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴이기도 하다. 부모(상위) 클래스 코드에 구체 클래스 이름을 감추기 위한 방법으로도 사용한다. 풀이 객체 생성 자체는 상위 클래스에서 정의하지만 어떤 객체를 만들 것인가? 는 하위 클래스에서 결정한다. 객체 생성 ↓ 하위 클래스가 결정 → Factory Method ✅ 답 Factory Method 📌 2022년 3회 3번 다음은 디자인 패턴에 대한 설명이다. 괄호 안에 알맞은 답을 작성하시오. (1)은/는 기능을 처리하는 추상화 계층과 실제 구현을 담당하는 구현 계층을 분리하여, 두 계층이 독립적으로 변경될 수 있도록 하는 패턴이다. 구현뿐 아니라 추상화도 독립적인 확장이 필요할 때 사용한다. 기능 계층과 구현 계층을 연결하는 다리 역할을 하며, 기능 확장과 구현 변경을 서로 분리할 수 있다. (2)은/는 한 객체의 상태가 변화하면 그 객체에 의존하는 다른 객체들에게 변화된 상태를 전달해주는 패턴이다. 일대다 관계를 가지며, 주로 분산된 시스템 간에 이벤트를 생성, 발행(Publish)하고 이를 수신(Subscribe)해야 할 때 이용한다. 풀이 1 추상화와 구현 분리 추상화 계층 ↕ 구현 계층 독립적 확장 → Bridge 2 상태 변화 자동 전달 상태 변화 Publish / Subscribe 1 : N → Observer ✅ 답 (1) Bridge (2) Observer Pattern 📌 2023년 1회 11번 다음 설명에 해당하는 디자인 패턴을 쓰시오. 실제 객체를 직접 참조하는 대신 대리 객체를 앞에 둔다. 대리 객체는 접근 제어, 지연 생성, 로깅 같은 부가 작업을 처리한 뒤 실제 객체에 요청을 전달한다. 풀이 핵심 키워드는 대리 객체 접근 제어 지연 생성 로깅 이다. 이는 Proxy 패턴 이다. ✅ 답 Proxy 📌 2023년 2회 11번 디자인 패턴 설명을 읽고 1과 2에 들어갈 패턴을 쓰시오. 1 클래스의 인스턴스를 하나만 만들고 어디서든 그 인스턴스에 접근하게 한다. 2 객체 구조의 원소를 바꾸지 않고 새로운 연산을 추가하며, 각 원소를 방문해 작업을 수행한다. 풀이 1 인스턴스 하나 객체 1개 공유 전역 접근 → Singleton 2 구조를 바꾸지 않고 연산 추가 객체 구조 유지 새로운 연산 추가 원소 방문 → Visitor ✅ 답 1 Singleton 2 Visitor 📌 2024년 1회 20번 다음 설명에 해당하는 GoF 디자인 패턴을 쓰시오. 구체적인 클래스를 지정하지 않고 서로 관련되거나 의존적인 객체들의 제품군을 생성하는 인터페이스를 제공한다. 제품군 전체를 일관되게 교체해야 할 때 사용한다. 풀이 핵심은 구체 클래스 지정 X 관련 객체 제품군 제품군 전체 생성 이다. 이는 Abstract Factory 이다. ✅ 답 Abstract Factory 📌 2024년 2회 10번 다음 설명에 해당하는 GoF 디자인 패턴을 쓰시오. 컬렉션의 내부 표현을 노출하지 않고 원소를 차례대로 접근할 수 있게 한다. hasNext와 next 같은 동작으로 순회 책임을 별도 객체에 맡긴다. 풀이 컬렉션 순차 접근 hasNext() next() 가 핵심이다. 이는 Iterator 패턴 이다. ✅ 답 Iterator 📌 2024년 3회 6번 괄호에 공통으로 들어갈 GoF 디자인 패턴 분류를 쓰시오. ( ) 패턴은 객체들이 상호작용하는 방법과 책임 분배를 정의한다. 객체 사이의 통신 방법을 다루고 알고리즘을 캡슐화해 결합도를 낮춘다. Chain of Responsibility, Command, Observer가 여기에 속한다. 풀이 Chain of Responsibility Command Observer 는 모두 행위 패턴 이다. ✅ 답 행위 📌 2025년 1회 14번 다음 설명에 해당하는 디자인 패턴을 쓰시오. 호환되지 않는 인터페이스를 가진 기존 객체를 감싸 클라이언트가 원하는 인터페이스로 바꿔 준다. 기존 클래스의 내부 코드는 수정하지 않는다. 풀이 기존 객체 수정 X 호환되지 않는 인터페이스 원하는 인터페이스로 변환 따라서 Adapter 이다. ✅ 답 Adapter 📌 2025년 2회 7번 다음 설명에 해당하는 디자인 패턴을 쓰시오. 실제 객체를 바로 사용하지 않는다. 그 객체를 대신하는 대리 객체가 접근을 제어하고 부가 기능도 맡는다. 실제 객체의 생성을 늦추거나 접근 권한을 확인할 때 쓴다. 풀이 대리 객체 접근 권한 지연 생성 이 나오면 Proxy 이다. ✅ 답 Proxy 📌 2026년 1회 2번 다음 설명에 해당하는 디자인 패턴을 각각 쓰시오. 1 기능의 클래스 계층과 구현의 클래스 계층을 분리하고, 두 계층을 연결하여 서로 독립적으로 확장할 수 있게 한다. 2 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에게 상태 변화를 자동으로 알린다. 풀이 1 기능과 구현 분리 추상화 ↔ 구현 독립적 확장 → Bridge 2 상태 변화 자동 알림 한 객체의 상태 변화 ↓ 여러 객체에 알림 → Observer ✅ 답 1 Bridge 2 Observer 📌 2026년 2회 17번 다음 설명에 해당하는 디자인 패턴을 보기에서 골라 쓰시오. 구체적인 클래스를 명시하지 않고 서로 관련되거나 의존적인 객체들의 집합을 생성하기 위한 인터페이스를 제공한다. Kit 라고도 한다. ᄀ. Builder ᄂ. Factory Method ᄃ. Abstract Factory ᄅ. Prototype 풀이 관련 객체들의 집합 제품군 구체 클래스 명시 X Kit 이 나오면 Abstract Factory 이다. ✅ 답 ᄃ. Abstract Factory 📌 GoF 디자인 패턴 분류 GoF 디자인 패턴은 총 23개 이며 크게 세 종류로 나눈다. 분류 목적 생성 패턴 객체를 어떻게 생성할 것인가 구조 패턴 객체와 클래스를 어떻게 구성할 것인가 행위 패턴 객체들이 어떻게 동작하고 협력할 것인가 🏗️ 생성 패턴 객체의 생성 방식 과 관련된 패턴이다. 패턴 핵심 키워드 Abstract Factory 관련 객체 제품군 생성 Builder 단계별 조립 Factory Method 객체 생성을 하위 클래스가 결정 Prototype 기존 객체 복제 Singleton 인스턴스 하나만 생성 생성 = 객체를 어떻게 만들까? 🧱 구조 패턴 클래스나 객체를 어떻게 조합하고 연결할 것인가 와 관련된다. 패턴 핵심 키워드 Adapter 인터페이스 변환 Bridge 추상화와 구현 분리 Composite 부분과 전체를 동일하게 처리 Decorator 객체를 감싸 기능 추가 Facade 복잡한 시스템의 단순 창구 Flyweight 객체 공유로 메모리 절약 Proxy 대리 객체 🎮 행위 패턴 객체 간의 책임 분배와 상호작용 을 다룬다. 패턴 핵심 키워드 Chain of Responsibility 처리자 사슬 Command 요청 객체화 Interpreter 문법 해석 Iterator 컬렉션 순회 Mediator 중재자 Memento 상태 저장·복원 Observer 상태 변화 자동 알림 State 상태에 따라 행동 변경 Strategy 알고리즘 선택·교체 Template Method 알고리즘 골격 정의 Visitor 구조 변경 없이 연산 추가 🧠 생성 패턴 암기 생성 패턴 5개는 추빌팩프싱 처럼 묶어서 기억할 수 있다. 추 → Abstract Factory 빌 → Builder 팩 → Factory Method 프 → Prototype 싱 → Singleton 시험에서는 이름 자체보다 키워드 연결 이 더 중요하다. 제품군 → Abstract Factory 조립 → Builder 하위 클래스 → Factory Method 복제 → Prototype 하나만 → Singleton 🧠 헷갈리기 쉬운 구조 패턴 Adapter vs Bridge Adapter 이미 존재하는 두 인터페이스가 서로 맞지 않을 때 사용한다. 기존 인터페이스 → 변환 → 원하는 인터페이스 Adapter = 변환기 Bridge 처음부터 기능과 구현을 분리해서 둘 다 독립적으로 확장한다. 추상화 ↔ 구현 Bridge = 두 계층을 연결하는 다리 Proxy vs Decorator 둘 다 객체를 감싼다 는 점 때문에 헷갈리기 쉽다. Proxy 목적은 접근 제어 이다. 권한 검사 지연 생성 접근 제어 대리 객체 Decorator 목적은 기능 추가 이다. 기존 객체 + 기능 + 기능 + 기능 따라서 Proxy = 대신 접근 Decorator = 기능 추가 라고 기억하면 된다. Facade Facade는 여러 복잡한 기능을 하나의 단순한 창구로 제공한다. 복잡한 시스템 여러 개 ↓ Facade ↓ 사용자 Facade = 안내 데스크 라고 생각하면 쉽다. 🧠 Observer vs Mediator Observer 한 객체의 변화가 여러 객체에게 자동 전파 된다. 1 → N 유튜브 채널 → 구독자 뉴스 채널 → 구독자 Mediator 여러 객체가 서로 직접 통신하지 않고 중앙 중재자 를 거친다. A ─┐ B ─┼→ Mediator C ─┘ 관제탑 채팅방 서버 중앙 조정자 🧠 Strategy vs State 둘 다 동작이 바뀐다는 점에서 헷갈릴 수 있다. Strategy 사용할 알고리즘을 선택한다. 최단 거리 최단 시간 통행료 최소 → Strategy 즉 Strategy = 어떤 방법을 사용할까? State 객체의 현재 상태 때문에 행동이 달라진다. 대기 결제 완료 취소 즉 State = 지금 상태가 무엇인가? 🧠 행위 패턴 핵심 키워드 시험에서는 설명 속 단어를 보고 바로 패턴을 떠올리는 것이 중요하다. 요청 객체화 저장 / 취소 / Queue → Command 처리할 때까지 다음 객체로 전달 → Chain of Responsibility hasNext / next 컬렉션 순회 → Iterator 중앙에서 객체들을 조정 → Mediator 상태 변화 자동 알림 1 : N Publish / Subscribe → Observer 상태에 따라 행동 변경 → State 알고리즘 선택 / 교체 → Strategy 알고리즘 골격은 부모 세부 단계는 자식 → Template Method 객체 구조 변경 X 새로운 연산 추가 → Visitor 🔥 시험 직전 최종 암기 생성 Abstract Factory → 관련 객체 제품군 Builder → 단계별 조립 Factory Method → 하위 클래스가 생성 결정 Prototype → 복제 Singleton → 인스턴스 하나 구조 Adapter → 인터페이스 변환 Bridge → 추상화 / 구현 분리 Decorator → 기능 추가 Facade → 단순한 통합 창구 Proxy → 대리 객체 / 접근 제어 행위 Observer → 상태 변화 자동 알림 Mediator → 중앙 중재자 Strategy → 알고리즘 선택 State → 상태에 따라 행동 변경 Command → 요청 객체화 Chain of Responsibility → 처리자 사슬 Iterator → 순차 접근 Visitor → 구조 변경 없이 연산 추가 Template Method → 부모가 골격, 자식이 세부 구현 🔥 한 줄로 기억하기 객체를 만든다 → 생성 패턴 객체를 연결하고 조립한다 → 구조 패턴 객체가 서로 행동하고 협력한다 → 행위 패턴
지난 글에서는 플레이어가 무엇을 반복해서 하는지 알아보기 위해 행동의 횟수보다 행동 사이의 관계를 기록하기 시작했다 는 이야기를 했다. 공격한 뒤 물체를 던지는지. 던진 뒤 다른 물체를 집는지. 대시한 뒤 다시 공격을 이어가는지. 이런 반복되는 관계를 어느 정도 구분할 수 있게 되면서 다음 문제가 생겼다. 그럼 이 습관을 실제 게임의 능력으로 어떻게 바꿀까? 분석 결과를 보여주는 것만으로는 게임이 달라지지 않는다. 플레이어가 계속 비슷한 방식으로 싸우고 있다면, 그 행동 자체가 새로운 전투 규칙으로 돌아오게 만들고 싶었다. 처음에는 이 부분도 생각보다 단순하게 해결할 수 있을 것 같았다. 처음에는 패턴 하나에 스킬 하나를 만들었다 예를 들어 이런 플레이어가 있다고 해보자. 물체를 던진다 ↓ 다른 물체를 집는다 ↓ 다시 근접 공격한다 이 행동을 반복한다면 그 흐름을 그대로 이용하는 능력을 만들 수 있다. 실제로 처음 만든 능력도 비슷했다. 물체를 던져 적에게 충격을 준 뒤 잠시 그 충격을 기억한다. 그다음 새로운 물체를 집거나 받아내면 기억해둔 충격을 그 물체에 연결한다. 그리고 그 물체로 다음 근접 공격을 성공시키면 이전 투척의 힘 일부가 같이 전달된다. 투척 적중 ↓ 충격을 기억 ↓ 새로운 물체 획득 ↓ 다음 근접 공격 강화 처음 이게 실제로 동작했을 때는 꽤 만족스러웠다. 단순히 투척을 많이 했다 → 투척 공격력 +20% 가 아니라, 플레이어가 원래 하던 행동은 그대로 남아 있으면서 그 행동 사이에 새로운 연결 하나가 생겼기 때문 이다. 다른 방식도 만들어봤다. 한 적을 때린 뒤 별개의 공격으로 다른 적을 때리면, 두 적의 위치 관계를 기억해서 둘 사이에 새로운 효과가 생기게 했다. 적 A 공격 ↓ 적 B 공격 ↓ 두 위치 사이에 효과 발생 여기까지는 꽤 괜찮았다. 그런데 세 번째, 네 번째 패턴을 생각하기 시작하면서 이상한 점이 보였다. AI 게임을 만들고 있는데, 내가 모든 답을 만들고 있었다 플레이어가 공격 후 투척을 자주 한다면 그에 맞는 스킬을 만든다. 대시 후 공격을 자주 한다면 또 다른 스킬을 만든다. 여러 적 사이를 오가며 싸운다면 또 하나를 만든다. 몇 개 정도는 충분히 할 수 있다. 문제는 계속 늘어날 때다. 행동이 늘고, 물체가 늘고, 대상이 늘고, 시간 조건이 늘고, 공간 관계까지 들어오기 시작하면 가능한 조합도 빠르게 많아진다. 그리고 그때마다 내가 “이 패턴에는 이 스킬.” 이라고 완성된 답을 하나씩 추가하고 있었다. 생각해보니 조금 이상했다. AI가 플레이어를 읽고 새로운 능력을 만들어주는 게임을 만들겠다고 시작했는데, 정작 가능한 플레이 스타일과 그 결과는 내가 전부 미리 만들고 있었다. 이 구조라면 나중에 AI가 들어오더라도 결국 내가 만들어둔 답안 중 하나를 고르는 역할밖에 하지 못한다. 그래서 완성된 스킬을 계속 추가하는 대신, 스킬 자체를 표현할 수 있는 작은 언어를 만들어보기로 했다. 스킬 대신 ‘스킬을 만드는 문법’을 만든다 하나의 능력을 잘게 나눠보면 생각보다 몇 가지 질문으로 정리할 수 있었다. 무슨 행동에서 시작되는가? ↓ 무엇을 기억하는가? ↓ 무엇과 연결하는가? ↓ 어디에 적용하는가? ↓ 어떤 효과가 생기는가? 예를 들어, “물체를 던져 맞힌 충격을 기억했다가 다음에 집은 물체의 공격으로 전달한다” 라는 능력도 이렇게 쪼개볼 수 있다. 투척 적중 ↓ 이전 충격 기억 ↓ 다음 물체와 연결 ↓ 다음 성공 공격까지 유지 ↓ 기억한 힘을 전달 다른 능력은 같은 재료를 전혀 다르게 사용할 수 있다. 대시 ↓ 대시 시작 위치 기억 ↓ 다음 근접 공격 위치와 연결 ↓ 두 위치 사이 ↓ 새로운 효과 발생 또는 적 A 공격 ↓ 적 B 공격 ↓ 다시 적 A 공격 ↓ 기억한 적 B의 위치 ↓ 효과 발생 각각만 보면 전혀 다른 스킬처럼 보인다. 하지만 내부적으로는 행동을 감지하고, 무언가를 기억하고, 다른 대상이나 위치와 연결하고, 그 결과를 새로운 효과로 바꾼다 는 비슷한 언어로 표현할 수 있다. 내가 원했던 건 바로 이쪽이었다. 완성된 스킬을 계속 만드는 대신, 여러 스킬을 표현할 수 있는 언어를 만드는 것. 그리고 언젠가 AI가 스킬을 만든다면, 아무것도 없는 곳에서 게임 규칙을 마음대로 발명하는 게 아니라 이 언어 안에서 의미 있는 조합을 찾게 하고 싶었다. 그렇다고 AI에게 모든 걸 자유롭게 만들게 할 수는 없었다 처음부터 LLM에게 이렇게 요청할 수도 있다. “이 플레이어에게 어울리는 재미있는 스킬 하나 만들어줘.” 아마 그럴듯한 아이디어는 꽤 잘 나올 것이다. 하지만 아이디어와 실제 게임 규칙은 다르다. 모델이 존재하지 않는 기능을 사용할 수도 있다. 앞에서 기억하지 않은 대상을 뒤에서 참조할 수도 있다. 서로 연결할 수 없는 두 효과를 붙일 수도 있다. A가 B를 부르고, B가 다시 A를 불러서 효과가 끝없이 반복될 수도 있다. 무언가를 기억하게 해놓고 언제 그 기억을 지워야 하는지 정의하지 않을 수도 있다. 게임에서는 이런 문제가 단순한 문장 오류로 끝나지 않는다. 잘못하면 실제 전투 상태가 망가지거나, 한 번의 행동에서 끝없이 효과가 발생할 수도 있다. 그래서 한 가지 경계를 만들었다. AI가 무언가를 제안할 수는 있지만, 그 제안이 곧 게임의 규칙이 되지는 않는다. 조합할 수 있다는 것과, 실행할 수 있다는 것은 달랐다 그래서 스킬 문법 뒤에 Compiler 를 두었다. 스킬 조합이 들어오면 바로 실행하지 않고 먼저 검사한다. 실제로 존재하는 기능들로 이루어져 있는지. 앞 단계에서 나온 결과를 다음 단계가 받을 수 있는지. 기억해야 하는 상태가 있다면 언제 생성되고 언제 사라지는지. 효과가 자기 자신을 다시 부르는 구조는 없는지. 한 번의 행동에서 너무 많은 효과를 만들어내지는 않는지. 그리고 마지막으로, 실제로 플레이어에게 설명할 수 있는 능력인지 까지 확인한다. 개념적으로는 이런 흐름에 가깝다. Skill 조합 ↓ 게임 규칙과 맞는가? ↓ 상태와 연결이 유효한가? ↓ 끝없이 반복되지 않는가? ↓ 실제로 실행 가능한가? ↓ 플레이어에게 설명 가능한가? ↓ 게임에 적용 이 과정을 만들면서 생각보다 중요했던 게 하나 더 있었다. 게임에서 실제로 일어나는 것과 플레이어가 읽는 설명이 서로 달라지면 안 된다는 점 이다. 예를 들어 실제 효과는 3초 동안 유지되는데 스킬 설명에는 4초라고 적혀 있다면, Adaptive System을 플레이어가 믿기 어렵다. 그래서 지금은 실제 능력과 UI 설명이 따로 존재하지 않는다. 같은 검증된 결과에서 실제 효과도 만들고, 플레이어가 읽는 설명도 만든다. 스킬 이름이나 설명 역시 LLM이 즉석에서 자유롭게 작성하도록 하지 않았다. 게임의 문체와 실제 동작을 사람이 통제할 수 있도록 미리 만들어둔 표현을 사용한다. 결국 사람이 만드는 것과 AI가 고르는 것을 나누게 됐다 여기까지 만들고 나니 AI에게 어디까지 맡기고 싶은지도 조금 명확해졌다. 사람이 해야 하는 일은 게임에서 가능한 것의 경계를 만드는 것 이다. 어떤 행동이 존재하는지. 무엇을 기억할 수 있는지. 어떤 관계가 가능한지. 어떤 효과를 실제 게임에서 지원하는지. 그리고 그 조합이 안전한지. 반대로 AI에게 기대했던 건, 그 가능한 조합들 중 지금 이 플레이어의 행동과 의미 있게 연결되는 것을 찾는 일 이었다. 즉 내가 만들고 싶었던 건 AI가 게임의 법칙을 마음대로 쓰는 구조가 아니었다. 사람이 게임의 언어를 만들고, AI는 그 언어 안에서 플레이어에게 맞는 문장을 찾는다. 이쪽에 더 가까웠다. 이제야 Local LLM을 시험할 준비가 됐다 여기까지 오고 나서야 처음 생각했던 실험을 제대로 해볼 수 있게 됐다. 플레이어가 무엇을 반복하고 있는지는 게임이 계산한다. 그 행동을 능력으로 표현할 수 있는 문법도 있다. 잘못된 조합을 막을 수 있는 Compiler도 있다. 실제 효과와 UI 설명도 같은 결과에서 나온다. 즉 모델이 실수하더라도 게임 자체가 무너지지 않도록 필요한 경계는 어느 정도 만들어졌다. 그리고 이제 남은 질문은 하나였다. 이 조합 문제를 정말 Local LLM이 규칙 기반 방식보다 더 잘 풀 수 있을까? 다음 글에서는 실제 Local LLM을 게임에 넣고, 처음에는 완성된 능력 중 하나를 고르게 해보고, 그다음에는 능력 자체를 조합하게 해보고, 마지막에는 내부적인 복잡함까지 최대한 걷어낸 뒤 다시 시험해본 이야기를 적어보려고 한다. 결과는 처음 기대했던 방향과는 꽤 달랐다.
무슨 일이 있었나 오픈AI가 2026년 10월 7일, 챗GPT의 일반 대화창(Chat 탭)에 GPT-6와 '인텔리전트 UI(Intelligent UI)'를 전격 적용했다. 플러스·프로·비즈니스·엔터프라이즈 이용자는 오늘부터, 무료·Go 이용자는 내일부터 순차 적용된다(엔터프라이즈는 관리자 설정에 따라 달라질 수 있다). 인텔리전트 UI는 챗GPT가 텍스트만 내놓던 방식에서 벗어나 질문 맥락에 맞춰 텍스트·이미지·인터랙티브 요소를 조합해 응답을 구성하는 기능이다. 예컨대 숫자 계산 질문에는 채팅창 안에서 바로 값을 조정할 수 있는 '대화형 계산기'가 나타나는 식이다. 그래프나 차트로 복잡한 개념을 설명하거나, 누를 수 있는 버튼·입력 폼 같은 상호작용 도구도 답변에 바로 포함된다. 이번에 적용되는 모델은 유료 등급엔 GPT-6 Sol, 무료·Go 등급엔 GPT-6 Luna다. 모델이 '생각'을 마치기 전부터 단계적으로 유용한 정보를 먼저 보여주는 응답 방식도 함께 도입됐다. 다만 이번 변경은 Chat 탭에만 적용되며, 업무용 'Work'나 코딩 도구 'Codex'를 구동하는 모델에는 영향이 없다. GPT-6 계열은 지난 9월 3일 아스트라(Astra)가 먼저 출시됐고, 9월 22일 Sol·Luna가 챗GPT Work·Codex·API에 추가됐다. 이번 발표는 그 연장선에서 일반 대화 인터페이스까지 GPT-6 체제로 전환을 완료했다는 의미를 갖는다. 왜 중요한가 이는 오픈AI가 챗봇을 순수 텍스트 대화창에서 '생성형 인터페이스'로 전환하려는 신호로 읽힌다. 구글의 AI 플레이그라운드, 앤스로픽의 아티팩트 기능처럼 경쟁사들도 이미 텍스트를 넘어선 상호작용형 결과물 제공 경쟁에 뛰어든 상태라, 이번 발표는 '챗봇 UI 전쟁'을 한층 가속화할 전망이다. 우려의 목소리도 있다. 매체 기즈모도는 시각 요소가 추가되면 토큰 소모가 빨라지고, 그림이나 차트 자체가 새로운 환각(hallucination) 발생 지점이 될 수 있다고 지적했다. 서치엔진저널은 차트나 비교표 형태로 제시되는 답변에서 출처 표기가 어떻게 이뤄질지 오픈AI가 명확히 밝히지 않았다는 점도 짚었다. 일반 이용자에게는 질문에 대한 답이 훨씬 시각적이고 직관적으로 바뀐다는 장점이 있지만, 기업 환경에서는 관리자 정책에 따라 접근 여부가 갈리는 만큼 당장 모든 조직이 혜택을 보긴 어렵다. 결국 이번 변화는 LLM과의 상호작용 방식 자체를 '대화'에서 '즉석 생성 인터페이스'로 넓히려는 시도로, 구글 제미나이·앤스로픽 클로드와의 사용자 경험 경쟁에도 직접적인 영향을 줄 것으로 보인다. 원문: https://openai.com/index/gpt-6-for-everyone
RSI 구간 일반적인 해석 매매 관점 0 10 극단적 과매도 투매에 가까운 상태 기술적 반등 가능성 매우 높음 10 20 강한 과매도 매도세가 매우 강함 반등 후보 구간 20 30 과매도 매도세 우위 반등 여부 관찰 30 40 약한 과매도/약세 아직 약세 성격 섣부른 매수 주의 40 50 중립 약세 매수·매도 힘의 균형 추세 확인 필요 50 중립 방향성 기준점 상승/하락 추세 판단에 중요 50 60 중립 강세 매수세가 조금씩 우위 상승 추세 초기 확인 60 70 강한 상승 모멘텀 매수세 강함 상승 추세 지속 가능성 70 80 과매수 매수세가 상당히 강함 단기 조정 가능성 80 90 강한 과매수 매우 강한 상승 과열 주의 90 100 극단적 과매수 비정상적으로 강한 상승 급락·조정 위험 크게 증가 레인보우로보틱스 차트를 보면서 앞으로의 주가방향 및 흐름을 추적해 보도록 하겠습니다. 3일간 양봉이 나오면서, 이전 영상에서 말씀드렸던, 46만원을 10월 6일 뚫고, 10월 7일 조정을 받는 모습입니다. 10월 2일 20일 이평선 위로 올라선 모습으로, 방향성이 하락에서, 상승으로 전환하는 모습으로 보여 집니다. 10월 7일 기준 RSI 51.64로 중립~강세 구간이며, 볼랜져밴드 0.72로 상단에 위치하고 있습니다. 여기서 2가지 흐름이 나올 수 있는데, 첫번째로, 하루, 이틀 조정이 나오면서 20일 이평선에서 지지 받고 올라가는 흐름입니다. 두번째로, 10월 7일 하락 분을 금일 회복하는 양봉이 나오고 바로 반등하는 흐름입니다. 두 흐름 다 반등 흐름으로, 대응 전략으로, 10월 8일 부터 20일 이평선 43,700원 평단가를 목표로 분할 매수 추천드립니다. 추가로, 20일 이평선을 이탈할 경우, 2번 지지 받았던 41만이 강한 지지선이며, 해당 흐름은 앞, 두 흐름보다 확률이 낮아 보입니다. 요약하자면, 하락 후 반등 흐름으로, 10월 8일 부터 20일 이평선 43,700원 평단가를 목표로 분할 매수 추천 매도 시점으로 피보나치 0.5 구간인 52만~53만에 매도 추천드립니다. 감사합니다. 이상 골든 엉클이었습니다!