"매 첫 시도는 draft, 매 refinement는 product". Refinement는 초안을 critique → revise loop로 다듬어 quality를 끌어올리는 patterns의 family — LLM self-refine, type narrowing, design iteration 모두 매 같은 핵심 idea를 공유.
매 핵심
매 LLM Self-Refine (2024 Madaan et al. → 2026 mainstream)
Generate → Critique → Refine loop. Single model이 매 세 role을 모두 수행.
매 효과: math, code, dialog 매 +5–20% accuracy without extra training.
Reflexion (Shinn 2023)은 verbal RL — 매 episode 끝에 매 self-critique를 episodic memory로 저장.
2026 standard: Claude Opus 4.7 / GPT-5 매 native "extended thinking" mode가 매 refine을 internal로 흡수 → external loop는 매 high-stakes (legal, medical) 에서만.
매 Type Refinement (TypeScript / Flow / Python typing)
Narrowing: union type 의 매 instance를 specific subtype 으로 좁힘 (typeof, instanceof, discriminated union).
Refinement type: predicate-attached type — {x: number | x > 0}. Liquid Haskell, F* 매 사용.
2026 TS 5.x: satisfies operator + control-flow analysis 매 강력 — 매 manual cast 의 거의 elimination.
AI-aided: spec → Claude → multiple impl candidates → human picks → refine.
매 응용
RAG answer 의 self-refine으로 hallucination ↓.
Code generation 매 compile error → refine loop.
TS API 의 progressive type narrowing.
Product spec 의 PM ↔ AI iterative tightening.
💻 패턴
Self-Refine loop (Anthropic SDK)
fromanthropicimportAnthropicclient=Anthropic()MODEL="claude-opus-4-7"defself_refine(task:str,max_iter:int=3)->str:answer=client.messages.create(model=MODEL,max_tokens=2048,messages=[{"role":"user","content":task}],).content[0].textforiinrange(max_iter):critique=client.messages.create(model=MODEL,max_tokens=1024,system="You are a strict critic. List concrete flaws or reply 'NO_ISSUES'.",messages=[{"role":"user","content":f"Task: {task}\n\nDraft:\n{answer}"}],).content[0].textif"NO_ISSUES"incritique:returnansweranswer=client.messages.create(model=MODEL,max_tokens=2048,messages=[{"role":"user","content":f"Task: {task}\nDraft: {answer}\nCritique: {critique}\nRevise."}],).content[0].textreturnanswer
Reflexion-style episodic memory
classReflexion:def__init__(self):self.memory:list[str]=[]# accumulated lessonsdefstep(self,task:str)->str:ctx="\n".join(f"- {m}"forminself.memory[-5:])attempt=llm(f"Task: {task}\nPast lessons:\n{ctx}\nAct.")feedback=environment(attempt)ifnotfeedback.success:lesson=llm(f"Why did this fail? Task: {task}\nAttempt: {attempt}\nFeedback: {feedback}")self.memory.append(lesson)returnattempt
TypeScript discriminated union narrowing
typeResult<T>=|{kind:'ok';value: T}|{kind:'err';error: Error};functionunwrap<T>(r: Result<T>):T{if(r.kind==='err')throwr.error;// narrow → 'ok' branch
returnr.value;// typed as T, no cast
}
defbest_of_n(prompt:str,n:int=5)->str:candidates=[llm(prompt,temperature=1.0)for_inrange(n)]ranking=llm(f"Pick best of these:\n{candidates}\nReturn index 0..{n-1}")returncandidates[int(ranking.strip())]