Community연구 & 데이터 분석github.com

dbhq-uk/legwork-skill

Claude Code 및 Codex를 위한 의사 결정 리서치 스킬 - 모든 주장의 근거 수준을 명시하고, 증거로 판단할 수 없는 경우 이를 분명히 밝힙니다. DBHQ의 무료 도구.

legwork-skill란 무엇인가요?

Legwork는 AI 에이전트(Claude Code, Codex)가 '무엇을 해야 할까'라는 실용적 의사 결정을 지원하기 위해 설계된 리서치 스킬입니다. 학술적 완전성보다 실행 가능성을 우선시하며, 모든 주장에 대해 출처의 적절성과 증거 수준(Quick/Standard/Deep)을 투명하게 평가합니다. SERP 스니펫부터 유료 검색 엔진, 스크래핑, 렌더링까지 계층화된 검색 파이프라인을 제공하며, 인출 로그를 통해 각 증거의 출처와 인용을 추적합니다. 중복 연구를 방지하기 위해 과거 실행 인덱스를 유지하고, 증거가 불충분한 경우 '답변 불가'를 명시적으로 선언합니다.

지원 대상✓Claude Code✓Codex CLI~Cursor
npx skills add dbhq-uk/legwork-skill

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Legwork

목적

의사 결정 리서치입니다. 학술적 리서치가 아닙니다. 질문은 항상 "X에 대해 무엇을 해야 하는가"의 변형이며, 산출물은 그것이 실용적인지로 평가되지 완전한지로 평가되지 않습니다.

이 원칙이 아래 모든 내용을 결정합니다. 주장은 출처가 해당 주장에 적합한 종류인지로 판단되지, 출처의 영역이 존중받을 만한지로 판단되지 않습니다. 세 출처가 동의하는 것은 오직 그들이 동의하지 않을 수 있었을 때만 의미 있습니다. 질문에 답할 수 없는 실행은 회피성 장문 대신 그렇게 말합니다.

자율성 원칙. 맥락에서 필요한 것을 추론하고, 수준을 선택한 후 시작하십시오. 수준을 한 줄로 알리고 진행하십시오. 사용자에게 선택을 요구하지 마십시오. 사용자는 실행 중간에 방향을 전환할 수 있으며, 이는 모든 요청마다 차단 질문을 하는 것보다 훨씬 적은 비용이 듭니다. 치명적 오류 또는 이해할 수 없는 질문이 있을 때만 멈추십시오.

수준 (Levels)

깊이는 엄격함을 높입니다. 길이는 늘리지 않습니다.

빠른 (quick)표준 (standard)깊은 (deep)
프레임결정 + 2~3개의 하위 질문+ 명명된 반증 요인+ 2차적 관점
수집SERP 스니펫; 숫자 고정 시에만 가져오기발견당 상위 출처 직접 가져오기모든 발견에 대한 1차 출처
도전독립성 그룹화만발견당 하나의 반증 검색발견당 반증 패스 + 출처 감사
형식간략간략 또는 보고서보고서
수준 게이트--level quick--level standard--level deep
예상 시간3-5분8-12분20-40분

기본값은 **표준(standard)**입니다. 사용자가 지정한 수준(quick, standard, deep 또는 "빠른 탐색", "깊이 들어가기" 같은 동등 표현)을 사용하고, 그렇지 않으면 $LEGWORK_DEFAULT_MODE, 그렇지 않으면 표준을 사용하십시오. "심층 연구(Deep research)" 단독은 이 스킬의 호출 문구이지 deep 수준을 요청하는 것이 아닙니다 - 기본값으로 폴백합니다.

범위 설정 결과 질문이 요청이 암시한 것보다 실질적으로 더 높은 중요도를 가진 것으로 드러나면 한 수준을 조용히 올리고, 같은 시작 줄에 그 사실을 알리십시오.

시작 줄, 그런 다음 1단계로 바로 진행:

표준(standard) 실행(~8-12분). 1차 출처와 반증 패스를 위해 "deep"을 입력하세요.

파이프라인

4단계. 전체 지침은 methodology.md에 있습니다.

  1. 프레임 - 결정, 이를 해결할 하위 질문, 답을 바꿀 증거를 명명합니다.
  2. 수집 - 각 하위 질문에 대해 검색하고, 모든 가져오기를 기록합니다.
  3. 도전 - 반증 사례를 찾습니다. 출처를 독립성별로 그룹화합니다.
  4. 작성 - 산출물을 구성한 후 게이트를 통과시킵니다.

2단계와 3단계는 엄격한 게이트로 실행되지 않고 발견별로 인터리브됩니다.

시작하기 전에

날짜를 고정하십시오. date -u +%Y-%m-%d를 실행하고 해당 문자열을 실행, 출력 폴더 이름, 날짜가 포함된 자료를 반환할 수 있는 모든 검색 쿼리에 사용하십시오. 현재 연도에 대한 자신의 감각에 절대 의존하지 말고, 하위 에이전트가 스스로 알아내도록 두지 마십시오.

이 실행이 이미 수행되었는지 확인하십시오. 먼저 인덱스를 읽으십시오. 이 인덱스는 디스패처입니다: 과거 실행당 한 행이며, 한 줄 설명 열은 보고서를 열지 않고도 열 필요가 있는지 결정할 수 있게 해줍니다.

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py list --base "$OUTPUT_BASE"

그런 다음 네 가지 경로 중 하나를 선택하고 시작 줄에 이를 명시하십시오:

인덱스 내용수행할 작업
이 내용을 다루는 실행이 있으며 최신 상태임그 실행에서 답변하십시오. 웹이 아닌 해당 보고서를 읽으십시오.
이 내용을 다루는 실행이 있지만 오래된 것으로 표시됨**갱신(refresh)**하십시오
유사하지만 다른 질문에 답하는 실행이 있음새 실행을 하고 상호 참조하십시오
일치하는 항목 없음새 실행

이전 실행에서 답변하는 것은 성공이지 지름길이 아닙니다. 보고서를 열고, 질문과 관련된 발견 사항을 읽고, 신뢰도 범위를 그대로 유지한 채 답변하십시오. 특정 날짜의 실행에서 나온 것임을 명확히 말하십시오. 이미 수행되었고 여전히 유효한 연구를 재실행하는 것은 이 인덱스가 방지하고자 하는 낭비입니다.

재실행 대신 갱신(Refreshing)

갱신은 기존 보고서를 제자리에서 업데이트합니다 - 같은 폴더, 같은 파일. 두 번째 폴더를 만들지 마십시오: 하나의 질문을 설명하는 두 개의 폴더는 독자가 우연히 열게 된 폴더에 따라 행동하게 만듭니다.

  1. 새 가져오기 로그를 시작하지 말고 기존 로그를 재개하십시오. 로그에 있는 모든 것은 이미 비용이 지불되었습니다.

    python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py resume --tsv "$OUT/$BASE.tsv"
    

    이 명령은 이미 작업된 관점, 이미 가져온 페이지, 그리고 아직 인용문이 없는 페이지를 출력합니다. 다루지 않은 관점을 작업하고 답을 결정하는 주장을 재확인하십시오. 이미 기록되고 최신인 것은 다시 가져오지 마십시오.

  2. 이제 잘못된 모든 주장을 날짜와 이유와 함께 ## 대체됨 (Superseded) 섹션으로 이동하십시오. 주장을 조용히 삭제하지 마십시오. 누군가가 그 주장에 따라 행동했을 수 있으며, 미래의 실행은 이 영역이 이미 다루어졌음을 알아야 합니다. 동일한 답변이 이제 두 번 뒤집혔다면, 이를 강조하십시오 - 그것은 질문이 불안정하다는 문서 내 가장 강력한 신호입니다.

  3. ## 타임라인 (Timeline) 줄을 추가하여 무엇이 변경되었는지 기록하십시오.

  4. 인덱스 행을 업데이트하십시오.

실행 등록

모든 실행은 답변할 수 없었던 실행을 포함하여 인덱스에 기록됩니다 - "찾아봤지만 아무것도 없었다"는 정확히 미래 세션이 다시 찾지 않기 위해 필요한 정보입니다.

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py add --base "$OUTPUT_BASE" \
  --folder "$BASE" --topic "소규모 진료소를 위한 Outlook 분류" --level deep \
  --one-liner "E5 미만에서는 네이티브 분류 없음; 차이는 존재하지만 좁음"

한 줄 설명은 실행이 결론을 말하는 것이지, 무엇에 대한 것인지가 아닙니다. "플러그인 갤러리 노트"는 6개월 후에 쓸모없지만, "제출 경로 없음, 설치 방법은 URL을 통하거나 전혀 안 됨"은 그 자체로 질문에 답합니다. 게이트는 인덱스가 존재하는데 실행이 누락된 경우 경고합니다.

검색 정책

두 개의 사다리, 무료 단계를 먼저 사용하십시오. 필요한 만큼만 올라가십시오.

검색:

단계호출사용 시기
1WebSearch항상. 관점당 세 가지 쿼리 변형.
2platforms.py search --on ...답이 플랫폼이 보유한 레코드인 경우: 스레드, 패키지, 저장소, 날짜가 있는 뉴스 항목, 벤더의 변경 로그. 무료, 키 불필요, 페이지가 아닌 레코드 반환.
3bd_search.py -m general --engine bing --country XX --language yy세 변형 후에도 부족하거나 질문이 지역 특화적인 경우. 두 번째 엔진을 사용하는 것이 비용을 지불할 이유.
4bd_search.py -m discover --intent "..."두 엔진으로도 부족한 경우.

페이지 열기:

단계호출사용 시기
1fetch.py "<url>" --find "term"항상 먼저. 무료이며 페이지 텍스트를 제공하는 유일한 무료 전송 방식이므로 수치 추적 및 인용문 확인 가능.
2WebFetchfetch.py가 종료 코드 3으로 실패하고 페이지에 비용을 지불할 가치가 없는 경우.
3bd_search.py "<url>" -m scrape차단됨: 봇 보호, 페이월, 403.
4bd_search.py "<url>" -m render클라이언트 렌더링 셸.
5bd_search.py "<url>" -m pipeline --pipeline NAME위의 모든 것을 차단하는 플랫폼. 레코드당 과금됨; -m reddit은 유일한 경로일 때 사용하는 것이지 최후의 수단이 아닙니다.

무료 플랫폼 10개는 platforms.py list를, 유료 모드는 bd_search.py --help를 실행하십시오. 종료 코드 2(인증 또는 할당량)인 경우 사용자에게 brightdata login을 실행하라고 알리십시오. 재시도하지 마십시오.

검색 결과는 리드(lead)이지, 읽을 페이지가 아닙니다. 표준 및 심층 단계에서는 인용하는 것을 여십시오: 게이트는 websearch 행에만 의존하는 인용을 열리지 않은 것으로 처리하며, 표준에서는 경고, 심층에서는 오류입니다. 빠른(quick) 단계는 설계상 스니펫 우선이며 이 요구 사항이 적용되지 않습니다.

대체(fallback) 전에 실패를 기록하십시오. 열리지 않은 페이지는 실행에 대한 증거입니다 - --status blocked - 그리고 영수증이 이를 계산합니다.

가져올 내용을 제한하십시오. 스크래핑 호출에는 --max-chars 8000을 사용하고, 블라인드 제한보다는 --find를 선호하십시오: 긴 페이지에서 처음 8천 문자는 일반적으로 탐색 영역입니다.

사용할 수 있는 출처

리서치는 외부인이 확립할 수 있는 것입니다. 이 경계는 양방향으로 중요합니다.

사용자 자신의 레코드를 발견 사항으로 제시하지 마십시오. 질문이 사용자 자신의 회사, 제품 또는 시장 위치에 관한 것이라면, 사용자의 개인 계정(등록 기관, 청구, 받은 편지함, 내부 파일)에 접근하여 마치 발견한 것처럼 보고하지 마십시오. 사용자는 이미 알고 있습니다. 이는 순환적이며, 증거를 부풀리고 외부인이 실제로 얼마나 적게 볼 수 있는지 숨깁니다. 공개적으로 동등한 정보를 검색하고 외부인이 찾을 수 있는 것(아무것도 포함)을 보고하십시오.

사용자가 제공한 독점 접근 권한을 제3자에 대해 사용하십시오. 사용자가 명시적으로 제공한 유료 구독, 비공개 데이터셋 또는 내부 데이터베이스는 경쟁사, 공급업체 또는 시장을 조사할 때 진정한 이점입니다. 이를 사용하고, 다른 출처와 마찬가지로 기록하고, 제한 사항(Limitations)에 이 발견이 독자가 가지고 있지 않을 수 있는 접근 권한에 의존함을 명시하십시오.

엔터티가 전혀 공개적인 흔적이 없는 것으로 밝혀지면, 그것이 답입니다. 확인한 내용을 나열하고, 존재 또는 규모가 외부에서 확인될 수 없었다고 말하고, 특권 접근 권한으로 그 공백을 채우지 마십시오. 이는 전체 질문이 아닌 하나의 엔터티에 적용된 "답변 불가" 형태입니다.

가져오기 로그

모든 수준의 모든 검색은 한 행을 추가합니다:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log \
  --tsv "$OUT/$BASE.tsv" \
  --url "https://acme.example/pricing" \
  --kind vendor_pricing \
  --angle "현재 업체는 얼마를 청구하는가" \
  --via webfetch \
  --date 2026-07-01 \
  --title "가격 정책" \
  --quote "팀 플랜: 사용자당 월 30 미국 달러, 연간 청구." \
  --text-file /tmp/page.txt

두 필드가 중요하며, 다운스트림에서 어느 것도 확인할 수 없습니다.

--angle은 이 검색이 답변하고 있던 하위 질문입니다. 확인(corroboration)은 출처가 아닌 관점(angle)을 기준으로 계산됩니다. legwork 자체의 확장(fan-out)이 출처 수를 부풀리기 때문입니다. 관점(angle)을 정직하게 기록하십시오 - 실행 전체에 걸쳐 하나의 문자열을 재사용하면 확인 검사를 조용히 무효화하며, 어떤 스크립트도 당신이 그렇게 했는지 알 수 없습니다.

--quote는 출처를 인용할 가치가 있게 만든 동일한 문장입니다. 인용하려는 각 출처에 대해 읽는 즉시 하나를 기록하십시오. 모든 발견 사항의 약 절반은 숫자를 포함하지 않으므로, 그러한 경우 인용문이 유일한 증거이며 페이지가 변경되어도 살아남는 유일한 부분입니다. 페이지 텍스트가 디스크에 있는 경우(fetch.py로 열린 모든 것, 또는 --out과 함께 -m scrape로 가져온 것), 인용문은 이에 대해 확인되며 quote_verified: false는 페이지를 잘못 인용했음을 의미합니다.

--from-fetch는 이 두 스크립트가 작성하는 사이드카에서 url, 제목, 날짜 및 페이지 텍스트를 채우므로 아무것도 다시 입력할 필요가 없습니다:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log --tsv "$OUT/$BASE.tsv" \
  --from-fetch /tmp/legwork/ab12cd34ef56.json \
  --angle "현재 업체는 얼마를 청구하는가" --kind vendor_pricing \
  --query "site:acme.example pricing" --quote "팀 플랜: 사용자당 월 30 미국 달러 ..."

sources.py log --help는 나머지(--via 전송 방식(api, local, mcp 포함), --text-file 숫자 추출, --kind)를 다룹니다. 실제로 사용한 전송 방식을 기록하십시오 - 기록 가능하게 만들기 위해 다른 전송 방식으로 페이지를 다시 가져오는 것은 추적을 왜곡할 뿐 기록하지 않습니다. sources.py kinds는 어떤 출처 종류가 어떤 주장에 적합한지 출력합니다.

하위 에이전트 (Subagents)

검색은 병렬화할 가치가 있는 유일한 단계이며, 관점당 하나의 하위 에이전트를 사용합니다. subagent-brief.md를 사용하여 브리핑하십시오. 이 파일에는 템플릿 원문, 필요한 반환 형식, 그리고 각 줄이 포함된 이유가 있습니다. 하위 에이전트는 컨텍스트가 전혀 없으므로 필요한 모든 것이 브리핑에 포함되어야 합니다.

세 가지는 브리핑이 아닌 당신에게 남습니다:

  • 모델을 관점의 성격에 맞추십시오. 스니펫 수집 및 알려진 수치 고정은 저렴한 모델로 충분히 실행됩니다 - 명시적으로 재정의를 전달하고, 우연히 세션 모델을 상속받지 않도록 하십시오. 그러나 심층 수준의 1차 출처 작업과 열거를 재구성하는 모든 작업은 조정자(orchestrator)의 모델에 남아 있습니다. 측정 결과: 한 비교에서 조정자는 저렴한 모델부터 강력한 모델까지 벤더 페이지를 각각 3, 8, 32개 열었으며, 가장 약한 모델만이 단일 애그리게이터에서 그리드의 모든 셀을 채우고 성공을 보고했습니다.
  • 하위 에이전트의 대본(transcript)을 합성에 붙여넣지 마십시오. 구조화된 반환을 가져오고, 관점 문자열이 변경 없이 돌아왔는지 확인하고, 각 행을 기록하고, 로그를 기반으로 작업하십시오.
  • 범위 설정, 도전 및 합성은 판단입니다. 이들은 주 모델에 남아 있습니다.

스크립트

모든 스크립트는 stdlib 전용입니다. 가상 환경(virtualenv) 불필요. python3 >= 3.9.

스크립트목적
fetch.py "<url>" --find TERM페이지를 무료로 열고 텍스트를 유지; 차단 또는 셸에서 종료 코드 3 반환
platforms.py list | search --on X10개의 무료 플랫폼 네이티브 출처, 페이지 대신 레코드 반환
sources.py kinds | log | score출처 종류 용어집, 가져오기 로그, 주장 종류별 적합성 점수
sources.py receipt영수증 줄을 위한 검색 횟수, 로그에서 가져옴
sources.py stale --claim-kind K해당 주장 종류의 반감기를 기준으로 기록된 출처 중 오래된 것
sources.py resume이전 실행이 이미 가져온 내용, 재실행 시 건너뛰기 위함
independence.py groups | check출처를 독립적인 음성으로 축소; 관점 인식 확인 계산
independence.py portfolio단일 발견이 아닌 전체 실행에 걸친 출처 집중도
index.py add | list연구 인덱스 - 실행 등록, 과거 실행 찾기, 오래된 실행 식별
matrix.py check --report PATH비교 매트릭스의 완전성
check.py --report PATH --level LEVEL출하 가능성 게이트
finish.py --report PATH --level LEVEL게이트, 오래됨 스윕 및 등록을 한 번에
bd_search.py "<query|url>" -m MODE --jsonBright Data 검색 폴백

출력

실행 시작 시 출력 기준을 한 번 결정하십시오:

OUTPUT_BASE="${LEGWORK_OUTPUT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)/docs/research}"
BASE="[Topic]_Research_$(date +%Y%m%d)"
OUT="$OUTPUT_BASE/$BASE"; mkdir -p "$OUT"

…

[번역을 위해 잘림]

관련 스킬