AI 应用如何高效优雅地恢复中断?—— "连接解耦 + 状态持久化"
掘金
如果你做过 AI 对话、流式生成、或者 AI Agent 这类"跑得比较久"的功能,大概率被这样一个问题折磨过: 本文想讲清楚一件事:一个健壮的 AI 应用,应该把"用户的连接"和"实际的任务"这两条
Score: 57.13Confidence: 54%
View offerLoading the catalog…
THE AI OPPORTUNITY INDEX
Find your next AI tool. Explore free access, trials, and credits — all in one place.
掘金
如果你做过 AI 对话、流式生成、或者 AI Agent 这类"跑得比较久"的功能,大概率被这样一个问题折磨过: 本文想讲清楚一件事:一个健壮的 AI 应用,应该把"用户的连接"和"实际的任务"这两条
Score: 57.13Confidence: 54%
View offer掘金
Spring AI 工具调用不是反射一下就结束:用 2.0.1 跑通失败恢复与调用上限 目录 先说结论 从 ChatResponse 到 ToolResponseMessage:执行链在哪 最小实验:
Score: 57.12Confidence: 54%
View offeriThome 新聞
製造業推動後量子密碼學(Post-Quantum Cryptography,PQC)轉型,面臨的問題不只是更換加密演算法。網路安全業者Forescout從營運技術(OT)環境分析PQC轉型,指出OT環境的密碼學機制不只用於保護網路連線,也分布在韌體數位簽章、安全開機及裝置身分等功能。企業因此需要找出既有設備及系統使用哪些密碼學機制,並確認這些機制能否升級;無法升級的設備,未來可能需要採取額外防護措施甚至汰換。
Score: 57.1Confidence: 54%
View offeriThome 新聞
資安業者Fortinet旗下FortiGuard Labs揭露Linux後門程式ClingSTUN,攻擊者鎖定暴露於公開網路且尚未修補已知漏洞的設備發動攻擊。設備感染ClingSTUN後,攻擊者可持續存取遭入侵系統,並將其變成可遠端控制的代理節點。
Score: 57.1Confidence: 54%
View offeriThome 新聞
OpenAI宣布將擴大ChatGPT廣告測試,10月稍晚將在美國的圖片生成功能中測試新的視覺廣告,以圖片呈現商品或服務,並與使用者生成的圖片分開顯示。OpenAI也擴充廣告成效追蹤及投放安全機制,讓廣告主了解廣告是否帶來購買等後續行動,同時避免廣告出現在敏感或不適合的對話旁。 新的視覺廣告會在使用者生成圖片時出現,可使用商品照片、使用情境或服務相關圖片呈現,並會明確標示為廣告,不會混入使用者要求ChatGPT生成的圖片。首波測試僅限美國及部分廣告主,OpenAI表示,廣告也不會影響ChatGPT產生的回答。
Score: 56.63Confidence: 54%
View offeriThome 新聞
當車輛具備更多連線能力,攻擊面也隨之增加。如何確認車輛軟體、通訊介面與更新流程具備安全防護能力,已成為全球車廠與供應鏈必須面對的新要求。 聯合國歐洲經濟委員會(UNECE)世界車輛法規協調論壇(WP.29)近年推出UN R155與UN R156,分別針對車輛資安管理系統(CSMS)與軟體更新管理系統(SUMS)建立要求,成為車輛進入部分國際市場的重要規範。 車輛資安要求的改變,也影響車廠開發流程。 以ISO/SAE 21434為例,該標準針對道路車輛資安工程提出要求,涵蓋車輛電子電氣系統從概念設計、開發、生產,到使用、維護與淘汰等完整生命週期的資安風險管理。
Score: 56.63Confidence: 54%
View offervelog
자동화 시스템을 이해하고 통제하려면 무엇부터 살펴야 할까요? 무엇을 읽을 수 있는지, 어디까지 판단하는지, 어떤 조건에서 행동하는지 살펴야 합니다. 자동화가 개입하면 이 경계가 기능의 개수보다 시스템을 이해하고 통제하는 데 중요한 기준이 됩니다. 자동화 기능을 늘릴 때는 사용자가 그 동작을 이해할 기준도 필요합니다. 배포 상황을 묻는 일과 과거 기록을 찾는 일 SkillsMP의 discord-clawd 설명에서는 전송 전의 대상 확인과 실행 후의 보고가 짝을 이룹니다. 보내기 전에는 누구에게 전달할지 확인합니다. 실행한 뒤에는 대상과 전달 모드를 알려 줍니다. 이렇게 하면 대상 선택과 전달 방식, 실행 결과를 각각 살펴볼 수 있습니다. ( https://skillsmp.com/skill/openclaw-openclaw-agents-skills-discord-clawd-skill-md ) 배포 상황에 관한 두 요청은 작업을 구별하기 위한 설명용 예시입니다. 유지보수 담당자에게 묻는 요청에서는 새로운 대화를 시작해야 합니다. 예전에 논의한 내용을 찾는 요청에서는 이미 남은 기록을 읽어야 합니다. 다루는 주제가 같아도 사용자가 원하는 결과에 따라 필요한 작업이 달라집니다. 문서에 대상 확인을 요구하는 것과 코드가 잘못된 대상으로의 전송을 막는 것은 서로 다른 문제입니다. 사용자에게 명시적인 게시 요청을 받지 않은 강제 전송을 거부하는지도 별도로 살펴야 합니다. 스킬 설명만으로는 이 두 조건을 코드가 강제하는지 알 수 없습니다. OHTTP가 나누는 정보와 보호의 조건 GeekNews의 Cloudflare OHTTP 게이트웨이 소개에서 릴레이가 받는 요청 본문은 암호문입니다. 릴레이에는 클라이언트 IP 같은 연결 정보가 보입니다. 반면 게이트웨이는 요청의 암호화를 풀어 앱 서버에 전달합니다. 요청을 전달하는 과정에서 각 역할이 접하는 정보가 달라지는 구조입니다. ( https://news.hada.io/topic?id=34719 ) 이 정보 분리에는 운영 조건이 붙습니다. 기사에서는 릴레이와 앱 서버를 서로 공모하지 않는 별도 주체가 운영해야 한다고 설명합니다. 앱 서버가 Cloudflare 뒤에 있다면 외부 릴레이와 Cloudflare OHTTP Gateway를 조합하는 방식을 제시합니다. 암호화 방식뿐 아니라 누가 각 역할을 운영하는지도 설계에 포함됩니다. 기사에 따르면 Workers나 Cloudflare 프록시 호스트에서 들어온 요청은 복호화를 거부합니다. 같은 사업자 안에서 역할이 겹치는 상황을 막기 위한 조건입니다. 그러나 개발자가 요청 본문에 이메일이나 사용자 이름을 넣으면 앱 서버는 그 내용을 받습니다. 연결 정보의 분리와 본문에 담을 식별 정보의 선택은 각각 살펴야 합니다. GeekNews 소개 당시 게이트웨이는 비공개 베타 상태였습니다. 가을에 유료 부가 기능으로 내놓겠다는 내용은 당시의 출시 계획입니다. 현재 정식 출시 여부는 이 소개만으로 알 수 없으므로, 제품 상태를 읽을 때는 소개 시점과 계획의 성격을 함께 보아야 합니다. 창 배치를 제안하는 모델과 변경하는 코드 GeekNews의 tmux를 OS로 만들자에 소개된 구상은 데스크톱을 끝없이 펼쳐지는 작업 공간으로 봅니다. 물리 모니터는 그 공간의 일부를 보여 줍니다. 모니터 연결이 달라져도 창의 순서와 어떤 작업에 속한 창인지를 유지하려는 생각입니다. ( https://news.hada.io/topic?id=34720 ) 이 구상은 tmux에서 세션을 유지하고 작업을 중심으로 사용하는 경험을 일반 사용자에게 확장하려는 Linux 실험입니다. 로컬 언어 모델인 LLM은 창 배치안을 만들고 미리보기를 보여 주는 역할을 맡습니다. 실제 변경은 사용자 승인을 거친 뒤 결정론적 코드가 맡도록 설계합니다. 모델이 창을 직접 조작하지 못하게 하고, 고정해 둔 창도 변경하지 못하게 합니다. 초기 실험에서는 행동 데이터 수집이 프라이버시와 충돌했고, 캔버스가 끝없이 쌓이는 문제도 나타났습니다. 입력이 없는 유휴 상태를 근거로 창을 숨기자 읽기를 방해했습니다. 사용자가 키보드나 마우스를 움직이지 않아도 읽기는 계속될 수 있습니다. 따라서 입력이 없다는 신호를 작업 종료로 해석해도 되는지 판단해야 합니다. 새 도구의 설명에서 실행 조건까지 점검하기 세 사례를 참고해 새 에이전트 도구를 어떤 순서로 점검할 수 있을까요? 먼저 설명문에 기록 읽기와 새 대화 중 도구의 역할, 대상 확정 시점, 결과에 남길 전달 정보를 명시합니다. 이어서 넘길 데이터가 필요한 범위인지 확인하고, 중요한 실행 조건이 문서 밖에서도 검사되는지 점검합니다. 점검할 대상은 사례마다 다릅니다. 새 도구에 적용할 때도 어떤 경계를 정하려는지 먼저 분명히 해야 합니다. 도구 설명을 구체화합니다 — 작업 역할과 대상 확정 시점, 결과에 남길 전달 정보를 명시합니다. 넘길 데이터를 살핍니다 — 도구에 전달할 데이터가 작업에 필요한 범위인지 확인합니다. 실행 단계의 검사를 살핍니다 — 중요한 실행 조건이 문서 밖에서도 검사되는지 점검합니다. 무엇을 근거로 누가 실행하는지 드러내기 적용할 기준은 기능이 다루는 대상에 맞춰 잡아야 합니다. 메시지를 보내는 도구에는 전달 조건이, 요청을 중계하는 구조에는 정보의 분리가 필요합니다. 창 배치를 제안하는 모델에는 실제 변경으로 이어지는 조건이 필요합니다. 각 사례에서 나누는 대상을 구체적으로 짚는 것이 설계 점검의 출발점입니다. 원문: webi 기술 블로그 참고한 자료: SkillsMP Agent Skill: discord-clawd (openclaw) Cloudflare OHTTP 게이트웨이 tmux를 OS로 만들자
velog
60일차 1. 배운 내용 멀티 에이전트 시스템의 평가 및 피드백 멀티 에이전트 시스템에서도 기준에 따른 평가와 피드백 루프가 시스템 유지 보수 및 개선에 필요하다. 적절한 정책에 따른 기준들이 존재하면 예외 사항에 대한 대처와 성능에 대한 개선을 자동적으로 이뤄지게 할 수 있다. 2. 실제 작업한 내용 실습 평가 및 피드백에 대한 간단한 실습으로 평가에 대한 기준, 평가 에이전트, 피드백 루프, 실패 시 대응, 부분 복구, 트레이스의 간단한 예제를 살펴보았다. 팀 프로젝트 팀장으로서 3일 프로젝트를 앞두고 주제를 정하고 협업이 잘 이뤄지도록 회의를 주도했다. 1,2차와 다르게 시간이 별로 없지만 지금까지 잘 배운 것들을 사용한다면 괜찮을 거라 생각하고 있다. 3. 소감 프로젝트 회의를 하는 데에 팀원들의 의욕 넘치는 모습이 좋았던 것 같다. 그리고 회의를 잘 따라와 줘서 감사한 마음이 들었다. 내 자신이 보기에는 좀 어려운 주제인데 팀장으로서 크게 벗어나는 부분만 조율하면 팀원들의 역량으로 할 수 있을 것 같다.
Score: 54.4Confidence: 49%
View offervelog
오늘은 평소보다 거지 같은 세상을 살아가야 한다는 사실이 너무나 화가 났다. 길거리에서 시끄럽고 짜증 나게 구는 이름 모를 사람 네 명 정도도 패고 싶었는데, 감옥에 갈 수도 있다는 걸 떠올리며 패지 않았다. 감옥에는 절대 가고 싶지 않다. 내가 싫어하는 주거 환경의 특징은 역겨운 냄새가 남 4인 이상의 인원이 한 방을 쓰는 기숙사 형태 기숙사 사감과 빡센 규칙이 있음 인데, 감옥은 내가 싫어하는 모든 주거 환경의 특징을 모두 갖추었을 듯하기 때문이다. 열심히 치료해서 간헐적 폭발 장애에서 벗어나고 싶다.
Score: 54.39Confidence: 49%
View offervelog
```sh python3 - <<'PY' import torch print("torch:", torch. version ) print("CUDA:", torch.version.cuda) print("GPU:", torch.cuda.get_device_name(0)) for name in ("float4_e2m1fn_x2", "float4_e2m1fn"): print(name, getattr(torch, name, None)) print("_scaled_mm:", hasattr(torch, "_scaled_mm")) PY grep -A 15 -B 3 -Ei 'fp4. FAIL|RuntimeError|TypeError|NotImplementedError|unsupported' /var/log/b300_validation/stage1_hw_ /08_fp8_fp4_parallel_qualification.log | tail -80
Score: 54.39Confidence: 49%
View offervelog
김영한님의 자바 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 에러 또는 데이터
velog
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 인수 추진
Score: 54.4Confidence: 49%
Score: 54.39Confidence: 49%
Score: 54.39Confidence: 49%