Claude로 블로그 초안을 작성하게 했는데
WordPress에 발행하니까 ##, **, ``` 같은 기호가 그대로 글에 노출됐다.
Claude 마크다운 HTML 변환이 제대로 안 된 것이다.
분명히 HTML로 출력하라고 지시했는데 마크다운 잔여물이 섞여 나오면서 발행된 글이 엉망이 됐다.
오늘은 이 문제를 어떻게 잡았는지 정리한다.
문제 상황 — 마크다운 기호가 WordPress에 그대로 노출
현재 블로그 글 작성에 대리/팀장 2단계 AI 에디터 구조를 쓰고 있다.
대리 프롬프트가 초안을 작성하면 팀장 프롬프트가 HTML로 정리해서 최종 출력하는 방식이다.
문제는 대리가 마크다운으로 초안을 쓰는데, 팀장이 이걸 HTML로 변환해서 출력해야 하는 상황에서 발생했다.
팀장에게 “HTML만 사용하라”고 지시해도 가끔 마크다운 기호가 섞여서 나왔다.
특히 코드블록을 감싸는 ```나 굵게 표시하는 ** 같은 게 잔여물로 남았다.
WordPress는 마크다운을 자동으로 HTML로 변환해주지 않는다.
그래서 마크다운 기호가 그대로 본문에 노출됐다.
제목 앞에 ##이 붙어있고, 강조 텍스트 양쪽에 **가 보이는 상태로 글이 발행된 것이다.
원인 파악 — 프롬프트 지시만으로는 100% 막을 수 없다
Claude에게 “마크다운 사용 금지, HTML 태그만 사용”이라고 명시적으로 지시했다.
대부분의 경우 잘 따랐다. 하지만 100%는 아니었다.
특히 문제가 된 케이스는 두 가지였다.
첫째, 코드블록이다. 코드를 출력할 때 Claude가 습관적으로 ```로 감싸는 경우가 있었다.
둘째, 인라인 코드다. 변수명이나 함수명을 언급할 때 backtick으로 감싸는 버릇이 나왔다.
이건 Claude의 학습 데이터 특성 때문인 것 같다.
마크다운 형식의 텍스트를 엄청나게 많이 학습했기 때문에
프롬프트로 막아도 엣지 케이스(edge case, 예외적인 경우)에서 마크다운 패턴이 튀어나온다.
프롬프트 지시를 아무리 강화해도 완벽하게 막기는 어려웠다.
해결 방법 1 — 팀장 프롬프트에 마크다운 금지 강화
먼저 팀장 프롬프트에 마크다운 사용 금지 규칙을 더 명시적으로 추가했다.
단순히 “마크다운 금지”가 아니라 구체적으로 어떤 기호를 쓰면 안 되는지 나열했다.
예를 들어 이런 식이다. “##, ###, **, __, `, ``` 등의 마크다운 문법을 절대 사용하지 마라.
제목은 <h2>, <h3> 태그로, 굵게는 <strong> 또는 <b> 태그로, 코드는 <code> 태그와 <pre> 태그로 표현하라.
이렇게 하니까 마크다운 잔여물이 확실히 줄었다.
하지만 여전히 가끔 튀어나왔다.
프롬프트만으로는 한계가 있었다.
해결 방법 2 — 후처리 코드로 마크다운 잔여물 제거
결국 코드로 후처리하기로 했다.
n8n 워크플로우에서 팀장 프롬프트 출력 이후에 Code 노드를 하나 추가했다.
이 노드에서 마크다운 잔여물을 HTML로 변환하거나 제거하는 작업을 한다.
n8n에서 Claude API를 연결해서 쓰고 있다면 HTTP Request 노드 다음에 Code 노드를 붙이면 된다.
핵심 로직은 두 가지다.
첫째, 코드블록 변환이다. ``` 세 개로 감싸진 부분을 <pre>와 <code> 태그 조합으로 바꾼다.
둘째, 인라인 코드 변환이다. backtick 하나로 감싸진 부분을 <code> 태그로 바꾼다.
Claude 마크다운 HTML 변환 핵심 코드
아래는 실제로 사용 중인 코드다. 복사해서 n8n Code 노드에 그대로 붙여 쓸 수 있다.
// Claude 마크다운 HTML 변환 후처리 코드
// 코드블록 변환 (``` 으로 감싸진 부분)
html = html.replace(/```[\s\S]*?```/g, (match) => {
const code = match.replace(/```[a-z]*/g, '').replace(/```/g, '').trim();
return `<pre><code>${code}</code></pre>`;
});
// 인라인 코드 변환 (` 하나로 감싸진 부분)
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
코드 설명을 간단히 하면 이렇다.
첫 번째 replace는 정규식(regular expression, 텍스트 패턴을 찾는 문법)으로 ``` 사이의 모든 내용을 찾는다.
그리고 ``` 기호와 뒤에 붙은 언어 표시(javascript, python 같은)를 제거한 뒤 <pre>와 <code> 태그로 감싼다.
두 번째 replace는 backtick 하나로 감싸진 텍스트를 찾아서 <code> 태그로 바꾼다.
이렇게 하면 인라인 코드도 깔끔하게 처리된다.
추가로 정리할 수 있는 마크다운 패턴
위 코드 외에도 필요에 따라 추가 패턴을 정리할 수 있다. 예를 들어 굵게 표시(**)나 기울임(*)이 남아있다면 이런 코드를 추가하면 된다.
// 굵게 표시 변환
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
// 기울임 표시 변환
html = html.replace(/\*([^*]+)\*/g, '<em>$1</em>');
// 마크다운 제목 제거 (## 같은 거)
html = html.replace(/^#{1,6}\s/gm, '');
이 패턴들은 상황에 따라 선택적으로 적용하면 된다. 모든 케이스에 다 넣을 필요는 없고, 실제로 문제가 발생하는 패턴만 추가하는 게 낫다.
결과 확인 — 발행 품질이 확실히 올라갔다
이 후처리 노드를 추가한 뒤로 WordPress에 마크다운 기호가 노출되는 일이 사라졌다.
프롬프트 지시와 코드 후처리를 같이 쓰니까 이중으로 방어가 된다.
특히 코드블록 처리가 깔끔해졌다.
예전에는 ``` 기호가 그대로 보이거나 줄바꿈이 이상하게 되는 경우가 있었는데,
지금은 <pre>와 <code> 태그로 정확히 변환되어서 WordPress에서도 코드가 제대로 보인다.
글 자동화 시스템에서 이미지 처리도 자동화했다면 Unsplash API로 이미지 자동 삽입하는 방법도 참고해 볼 만하다.
이번 작업에서 느낀 점
Claude 마크다운 HTML 변환 문제를 겪으면서 느낀 건 이거다.
프롬프트로 막는 것과 코드로 막는 것을 같이 써야 한다.
Claude가 아무리 지시를 잘 따라줘도 엣지 케이스는 항상 있다.
학습 데이터의 영향인지 가끔 마크다운 패턴이 튀어나오는 건 어쩔 수 없는 것 같다. 그래서 후처리 레이어를 하나 두는 게 안전하다.
후처리 노드 하나가 발행 품질을 크게 높여줬다.
몇 줄 안 되는 코드인데 효과는 확실했다. 비슷한 문제를 겪고 있다면 프롬프트 강화와 코드 후처리를 같이 적용해보길 권한다.
자주 묻는 질문
Q1. WordPress에 마크다운 플러그인을 설치하면 해결되지 않나?
마크다운 플러그인을 쓰면 마크다운이 HTML로 변환되긴 한다.
하지만 이미 HTML과 마크다운이 섞여있는 상태에서 플러그인을 쓰면 예상치 못한 결과가 나올 수 있다.
HTML로 통일하는 게 더 안전하다.
Q2. 프롬프트만 잘 쓰면 후처리 없이도 되지 않나?
대부분의 경우는 된다. 하지만 100%는 아니다.
특히 코드를 많이 다루는 글에서 마크다운 잔여물이 나올 확률이 높다.
안전하게 가려면 후처리를 같이 쓰는 게 좋다.
Q3. n8n 말고 다른 자동화 도구에서도 같은 방식을 쓸 수 있나?
정규식 기반 문자열 치환이라 어떤 도구든 JavaScript나 Python을 실행할 수 있으면 같은 로직을 쓸 수 있다.
Make나 Zapier의 코드 스텝에서도 비슷하게 구현 가능하다.
Q4. Claude 외에 GPT도 같은 문제가 있나?
GPT도 마찬가지다. HTML만 쓰라고 해도 가끔 마크다운이 섞여 나온다.
LLM이 마크다운 형식의 데이터를 많이 학습했기 때문에 비슷한 현상이 발생한다.
Q5. 후처리 코드가 정상 HTML까지 망가뜨리지 않나?
위에서 소개한 정규식은 마크다운 패턴만 타겟팅한다.
이미 HTML로 작성된 부분에는 영향을 주지 않는다.
다만 본문에 backtick 문자를 일반 텍스트로 쓸 일이 있다면 주의가 필요하다.