본문으로 이동

도움말:S3 연구 메모리/아키텍처: 두 판 사이의 차이

S3 연구 메모리
S3 연구 메모리 저장소 문서 동기화
S3 연구 메모리 저장소 문서 동기화
 
121번째 줄: 121번째 줄:
=== 검색 구현 ===
=== 검색 구현 ===


파일럿은 MediaWiki 전체 텍스트 검색 결과를 어댑터에서 구조화 필터로 거릅니다. Action API에는 <code><nowiki>srwhat=text</nowiki></code>를 명시합니다. 이를 생략하면 MediaWiki의 레거시 기본값인 페이지명 검색이 적용되어, <code><nowiki>Lesson:&lt;slug&gt;</nowiki></code> 본문에 저장된 한국어 필드를 찾지 못합니다. MySQL 검색 엔진은 색인과 질의에 같은 UTF-8 정규화 및 짧은 단어 길이 보정을 적용하므로 MariaDB의 최소 단어 길이는 기본값을 사용합니다. 유사점 검색에는 Unicode NFKC 정규화, Unicode 단어, 한국어 2글자 및 3글자 n-gram을 사용합니다. MediaWiki 리비전 내용은 한 번에 최대 50페이지씩 가져옵니다. 초기 데이터 규모에서 운영하기에 충분하며 구성이 단순합니다. MCP 서비스는 작은 검색 인터페이스만 외부에 제공합니다. 나중에 벡터 또는 하이브리드 검색을 붙여도 후보 페이지 ID만 반환하게 하여 별도 기준 저장소가 생기지 않도록 합니다. 파생 인덱스는 위키 리비전만으로 다시 만들 수 있어야 합니다. 필드 및 출처 필터와 이전 버전 호환 <code><nowiki>review_state</nowiki></code> 필터를 보존하고 현재 응답 제한도 그대로 지켜야 합니다.
파일럿은 MediaWiki 전체 텍스트 검색 결과를 어댑터에서 구조화 필터로 거릅니다. Action API에는 <code><nowiki>srwhat=text</nowiki></code>를 명시합니다. 이를 생략하면 MediaWiki의 레거시 기본값인 페이지명 검색이 적용되어, <code><nowiki>Lesson:&lt;slug&gt;</nowiki></code> 본문에 저장된 한국어 필드를 찾지 못합니다. MySQL 검색 엔진은 색인과 질의에 같은 UTF-8 정규화 및 짧은 단어 길이 보정을 적용하므로 MariaDB의 최소 단어 길이는 기본값을 사용합니다. 유사점 검색에는 Unicode NFKC 정규화, Unicode 단어, 한국어 2글자 및 3글자 n-gram을 사용합니다. MediaWiki 리비전 내용은 한 번에 최대 50페이지씩 가져옵니다. 초기 데이터 규모에서 운영하기에 충분하며 구성이 단순합니다. MCP 서비스는 작은 검색 인터페이스만 외부에 제공합니다. 나중에 벡터 또는 하이브리드 검색을 붙여도 후보 페이지 ID만 반환하게 하여 별도 기준 저장소가 생기지 않도록 합니다. 파생 인덱스는 위키 리비전만으로 다시 만들 수 있어야 합니다. 필드 및 출처 필터와 이전 버전 호환 <code><nowiki>review_state</nowiki></code> 필터를 보존하고 현재 응답 제한도 그대로 지켜야 합니다. 내부 경계, 색인 세대, 장애 fallback과 단계별 도입안은 [[Help:S3 연구 메모리/벡터·하이브리드 검색 설계|벡터·하이브리드 검색 설계]]에 정리합니다.


=== 출력 제한 ===
=== 출력 제한 ===


모든 MCP 목록 작업에는 작은 기본 페이지 크기, 엄격한 최댓값, 커서 기반 페이지 나누기, 필드 선택, UTF-8 직렬화 응답의 바이트 상한이 있습니다. 스캔 응답에는 <code><nowiki>partial</nowiki></code>, <code><nowiki>scanned</nowiki></code>, <code><nowiki>scan_limit</nowiki></code>가 들어갑니다. <code><nowiki>partial=true</nowiki></code>이면 검색 결과가 완전하지 않은 것으로 처리해야 합니다. 기본 결과에는 ID, 제목, 한 줄짜리 <code><nowiki>reusable_lesson</nowiki></code>, 출처, confidence, 짧은 근거 인용이 들어갑니다. <code><nowiki>get_lesson</nowiki></code>도 같은 간단한 기본값을 쓰며 인용과 관계를 각각 나누어 반환합니다. 본문 필드는 필요할 때만 직접 선택합니다.
모든 MCP 목록 작업에는 작은 기본 페이지 크기, 엄격한 최댓값, 커서 기반 페이지 나누기, 필드 선택, UTF-8 직렬화 응답의 바이트 상한이 있습니다. 스캔 응답에는 <code><nowiki>partial</nowiki></code>, <code><nowiki>scanned</nowiki></code>, <code><nowiki>scan_limit</nowiki></code>가 들어갑니다. <code><nowiki>partial=true</nowiki></code>이면 검색 결과가 완전하지 않은 것으로 처리해야 합니다. 기본 결과에는 ID, 제목, 한 줄짜리 <code><nowiki>reusable_lesson</nowiki></code>, 출처, confidence, 짧은 근거 인용이 들어갑니다. <code><nowiki>get_lesson</nowiki></code>도 같은 간단한 기본값을 쓰며 인용과 관계를 각각 나누어 반환합니다. 본문 필드는 필요할 때만 직접 선택합니다.
일곱 도구는 모두 닫힌 <code><nowiki>outputSchema</nowiki></code>를 공개합니다. 성공 응답의 <code><nowiki>structuredContent</nowiki></code>는 이 스키마로 검증하며, 기존 클라이언트가 읽는 compact JSON text도 같은 내용으로 유지합니다.

2026년 7월 16일 (목) 23:32 기준 최신판

이 페이지는 저장소 문서에서 자동으로 동기화됩니다. 위키에서 직접 편집하지 마세요.

용도와 범위

S3 연구 메모리는 프로젝트가 끝난 뒤에도 다시 쓸 수 있는 Lesson을 저장합니다. 작업 추적기, 실행 로그, 산출물 저장소, 원시 지표 데이터베이스로 쓰지 않습니다. 원본 근거는 알맞은 저장소나 객체 스토리지에 두고, Lesson에는 주장과 적용 조건, 해석, 원본을 다시 찾는 데 필요한 인용을 기록합니다.

flowchart LR
    H["브라우저 사용자<br/>읽기는 공개, 쓰기는 이름이 있는 계정"] -->|"https://s3wiki.yonsei.ac.kr/"| P["Caddy HTTPS 진입점"]
    C["모든 MCP 클라이언트"] -->|"https://s3wiki.yonsei.ac.kr/mcp<br/>읽기는 공개, 쓰기는 공유 Bearer 토큰"]| P
    P -->|"/mcp 이외의 모든 경로"| W["Semantic MediaWiki + Page Forms"]
    P -->|"/mcp 및 /mcp/*"| M["중앙 mcp-http"]
    M -->|"인증된 제한형 MediaWiki API 어댑터"| W
    W --> D[("MariaDB: 기준 페이지, 의미 속성, 리비전")]
    W --> U[("업로드 볼륨")]
    M --> S["교체 가능한 검색 어댑터"]
    S -->|"파일럿"| W
    S -. "추후 선택 사항" .-> V["벡터 인덱스: 파생 데이터이며 기준 저장소가 아님"]

Lesson 내용은 MediaWiki에만 저장합니다. 중앙 MCP 서비스는 데이터를 저장하지 않고 정책만 적용하는 어댑터입니다. 별도의 지식 저장소가 아닙니다. 따라서 MariaDB와 업로드 볼륨을 함께 백업하며, MCP 전송 상태는 복구 대상에 포함하지 않습니다. Caddy는 TLS 종료와 경로 전달만 맡습니다. 인증서 상태는 Docker 볼륨에 남지만 기준 Lesson 데이터에는 속하지 않습니다.

S3RM_WIKI_DIRECT_URL을 명시한 서버는 같은 MediaWiki 화면을 직접 HTTP 포트로도 열 수 있습니다. 정확히 설정한 Host만 이 주소를 선택하고 정식 링크와 백그라운드 작업은 MW_SERVER_URL의 HTTPS 도메인을 계속 사용합니다. 이 입구는 위키 프런트엔드 하나를 추가하는 것이 아니라 동일 프로세스의 요청 URL 선택이며, MCP나 Lesson 저장소를 하나 더 만들지 않습니다.

연구실 공용 MCP 연결

에이전트는 장기 실행 서비스 mcp-http 한 개와 Streamable HTTP 엔드포인트 https://s3wiki.yonsei.ac.kr/mcp 한 곳만 사용합니다. 각 컴퓨터에서 별도 어댑터나 지식 사본을 실행하지 않습니다. 모든 클라이언트는 같은 어댑터를 거쳐 내부 http://mediawiki/api.php에 접근합니다. 한 클라이언트가 저장한 Lesson은 복제나 내보내기 없이 다음 검색부터 다른 클라이언트에도 보입니다. 동시에 저장할 때는 MediaWiki 리비전과 편집 충돌 검사가 쓰기 순서를 정합니다.

원격 연결에는 다음 네 가지 제한을 둡니다.

  1. S3RM_MCP_PUBLIC_URL로 외부에 공개할 /mcp 주소를 고정하고 정확한 Host 및 Origin 허용 목록을 만듭니다.
  2. 기본 token 모드에서는 초기화, 도구 목록 조회, 검색 도구 네 개는 인증 없이 쓸 수 있고 변경 도구 세 개만 공유 Bearer token을 확인합니다. open 모드는 세 변경 도구도 공개합니다. 선택 사항인 github 모드는 GitHub 로그인을 상류 인증으로 사용하고 MCP 연결 전체에 자체 OAuth token을 요구합니다.
  3. 공개 URL의 정확한 Host와 Origin은 자동으로 허용합니다. 명시적인 역방향 프록시 값이 더 필요하면 쉼표로 구분한 S3RM_MCP_ALLOWED_HOSTSS3RM_MCP_ALLOWED_ORIGINS에 추가합니다. 와일드카드는 허용하지 않습니다.
  4. MCP 프로세스는 최소 권한 agent 계정으로 MediaWiki에 로그인합니다. 유효한 쓰기 토큰이 있어도 변경 도구 세 개와 이 계정에 부여된 위키 권한을 넘을 수 없습니다.

./scripts/configure-public-domain.sh s3wiki.yonsei.ac.kr --expected-ip 165.132.118.220을 실행하면 MCP의 호스트 직접 연결 포트가 127.0.0.1에 묶이고 HTTPS가 필수가 되며 Compose domain 프로필이 켜집니다. Caddy는 80번과 443번 포트를 열어 TLS를 종료하고, 경로를 삭제하거나 바꾸지 않은 채 /mcp를 전달합니다. token 모드에서 토큰이 없는 클라이언트는 공개 검색을 쓸 수 있고, 토큰을 헤더에 넣을 수 있는 클라이언트는 제한된 변경 도구 세 개도 쓸 수 있습니다. open 모드는 호스팅 커넥터에도 세 변경 도구를 공개합니다. github 모드는 같은 프로세스의 OAuth discovery, 동적 client 등록, GitHub callback, token·refresh·revoke 경로를 사용합니다. Lesson 저장소는 계속 MediaWiki 하나뿐입니다.

GET /healthz는 컨테이너 상태 확인에 쓰는 작은 비인증 경로입니다. 위키 상태나 설정값을 내보내지 않으며 에이전트 도구도 아닙니다. 현재 /mcp는 인증 없이 초기화와 도구 조회를 처리하고 search_lessons, get_lesson, find_related_lessons, find_analogies를 실행합니다. create_lesson_draft, link_lessons, attach_evidence에는 Bearer 토큰이 필요합니다.

파일럿은 공유 토큰 다이제스트 한 개와 공용 MediaWiki 에이전트 계정 한 개를 사용합니다. MediaWiki에는 서비스 계정과 모든 페이지 리비전이 기록됩니다. 토큰을 사용한 컴퓨터, 모델, 사람은 구분하지 않습니다. 파일럿에서 협업하고 변경을 되돌리는 데는 이 기록으로 충분합니다. 개인별 토큰 폐기나 확인된 작성자 구분이 필요해지면 제한된 도구 권한은 그대로 두고 OAuth/OIDC 또는 별도 전송 ID를 추가할 수 있습니다. 클라이언트가 보낸 author 필드나 메모는 참고 정보일 뿐, 확인된 신원은 아닙니다.

기준 페이지 계약

브라우저 화면은 한국어로 표시합니다. 기준 식별자, 템플릿 매개변수 이름, 속성 이름, 이전 버전 호환 상태값, 근거 종류, 관계 토큰, Lesson: 이름공간은 영문 기계 계약을 그대로 씁니다. 한국어 Page Forms 라벨과 매핑 템플릿은 화면에 보일 때만 이 값을 번역합니다. MediaWiki의 기본 이름공간과 화면 문구가 한국어로 바뀌어도 기존 MCP 클라이언트와 저장된 리비전은 그대로 작동합니다.

각 Lesson은 Lesson: 이름공간의 페이지 한 건입니다. 전체 페이지 제목을 고정 식별자로 씁니다. 예를 들면 Lesson:gpu_allocator_fragmentation입니다. 화면에 보이는 제목은 식별자를 바꾸지 않고 수정할 수 있습니다.

페이지에는 다음 매개변수를 정확히 사용하는 Lesson 템플릿 한 개가 들어갑니다.

필드
title 화면에 표시할 Lesson 제목
question 작업을 시작하게 된 질문
attempt 시도한 방법
context 하드웨어, 워크로드, 버전, 규모, 제약 조건
observation 직접 관찰한 내용
interpretation 관찰한 결과가 나온 이유에 대한 해석
reusable_lesson 짧게 정리한 재사용 가능한 내용
applicability 다시 적용할 수 있는 조건과 범위
confidence low, medium, high 중 하나
evidence 사람이 읽을 수 있는 근거 개요
record_origin 바꿀 수 없는 출처 분류인 lab, imported, synthetic 중 하나
author 처음 작성한 사람 또는 계정
reviewer 이전 버전 호환 필드. 일반 작성에서는 비워 둠
review_state 이전 버전 호환 필드. 값은 Draft, Reviewed, Stable, Superseded이며 일반 작성에서는 Draft를 사용
created_at UTC ISO-8601 생성 시각
updated_at UTC ISO-8601 마지막 수정 시각

근거 첨부는 반복 가능한 Lesson evidence 템플릿으로 저장합니다. 필드는 id, citation, 선택 항목인 url, kind, note, added_by, added_at입니다. URL이 없어도 citation은 반드시 입력합니다. 브라우저에서 새 Lesson을 작성할 때는 구조화된 근거 한 건 이상이 필요합니다. MCP에서는 Lesson 생성과 근거 첨부를 별도의 제한된 작업으로 처리합니다.

관계는 반복 가능한 Lesson relation 템플릿으로 저장합니다. 필드는 from, relation, to, 선택 항목인 note, created_by, created_at입니다. 사용할 수 있는 relation 값은 다음으로 제한합니다.

  • supports
  • contradicts
  • analogous_to
  • failed_because
  • works_when
  • suggests
  • supersedes

관계에는 방향이 있습니다. 조회할 때 analogous_to는 대칭 관계처럼 보여 주지만, 출처를 남기기 위해 저장된 양쪽 끝점은 명시적으로 유지합니다. 같은 간선을 중복해서 저장하면 MCP 도메인 계층이 거부합니다. 브라우저와 에이전트 모두 이미 존재하는 Lesson만 관계 대상으로 지정할 수 있습니다.

저장과 수정

저장에 성공한 Lesson은 기준 위키에 바로 반영되며 브라우저와 MCP에서 즉시 검색할 수 있습니다. 수정 이력과 근거는 다음과 같이 관리합니다.

  • MediaWiki 리비전으로 모든 변경을 남기고 되돌릴 수 있습니다.
  • 구조화된 근거로 주장의 출처를 확인할 수 있습니다.
  • confidence에 현재 근거의 수준을 표시합니다.
  • 형식이 정해진 관계로 지지, 반박, 유사점, 적용 조건, 대체 관계를 표시합니다.
  • Page Forms, MCP 모델, 도메인 계층에서 같은 스키마를 검사합니다.

같은 주장을 고칠 때는 기존 Lesson의 리비전을 추가합니다. 주장이 크게 달라졌다면 새 Lesson을 만들고 contradictssupersedes처럼 알맞은 관계로 연결합니다. 이전 판단도 검색할 수 있도록 삭제하지 않습니다.

reviewerreview_state는 이전 리비전을 읽기 위한 고정 호환 필드입니다. 화면, 검색 순서, 공개 여부에는 쓰지 않습니다.

MCP 검색 도구는 인증 없이 쓸 수 있습니다. 공유 쓰기 자격 증명이 있으면 다음 작업만 할 수 있습니다.

  • lab Lesson 생성
  • 기존 Lesson에 검증된 관계 한 건 추가
  • 기존 Lesson에 인용이 있는 근거 한 건 추가

서버 관리 필드는 클라이언트가 선택하거나 바꿀 수 없습니다. 페이지 삭제, 이동, 보호, 관리도 허용하지 않습니다. supersedes 관계를 추가해도 대상 Lesson은 변경되지 않습니다. 클라이언트가 예상하지 않은 필드를 보내면 도메인 계층이 거부하고, MediaWiki 계정에도 관리 권한을 부여하지 않습니다.

Lesson이 바뀔 때마다 updated_at은 이전 값보다 반드시 늦어야 합니다. 에이전트가 근거나 관계를 추가하면 새 항목의 출처 시각에도 같은 값을 사용합니다.

검색 구현

파일럿은 MediaWiki 전체 텍스트 검색 결과를 어댑터에서 구조화 필터로 거릅니다. Action API에는 srwhat=text를 명시합니다. 이를 생략하면 MediaWiki의 레거시 기본값인 페이지명 검색이 적용되어, Lesson:<slug> 본문에 저장된 한국어 필드를 찾지 못합니다. MySQL 검색 엔진은 색인과 질의에 같은 UTF-8 정규화 및 짧은 단어 길이 보정을 적용하므로 MariaDB의 최소 단어 길이는 기본값을 사용합니다. 유사점 검색에는 Unicode NFKC 정규화, Unicode 단어, 한국어 2글자 및 3글자 n-gram을 사용합니다. MediaWiki 리비전 내용은 한 번에 최대 50페이지씩 가져옵니다. 초기 데이터 규모에서 운영하기에 충분하며 구성이 단순합니다. MCP 서비스는 작은 검색 인터페이스만 외부에 제공합니다. 나중에 벡터 또는 하이브리드 검색을 붙여도 후보 페이지 ID만 반환하게 하여 별도 기준 저장소가 생기지 않도록 합니다. 파생 인덱스는 위키 리비전만으로 다시 만들 수 있어야 합니다. 필드 및 출처 필터와 이전 버전 호환 review_state 필터를 보존하고 현재 응답 제한도 그대로 지켜야 합니다. 내부 경계, 색인 세대, 장애 fallback과 단계별 도입안은 벡터·하이브리드 검색 설계에 정리합니다.

출력 제한

모든 MCP 목록 작업에는 작은 기본 페이지 크기, 엄격한 최댓값, 커서 기반 페이지 나누기, 필드 선택, UTF-8 직렬화 응답의 바이트 상한이 있습니다. 스캔 응답에는 partial, scanned, scan_limit가 들어갑니다. partial=true이면 검색 결과가 완전하지 않은 것으로 처리해야 합니다. 기본 결과에는 ID, 제목, 한 줄짜리 reusable_lesson, 출처, confidence, 짧은 근거 인용이 들어갑니다. get_lesson도 같은 간단한 기본값을 쓰며 인용과 관계를 각각 나누어 반환합니다. 본문 필드는 필요할 때만 직접 선택합니다.

일곱 도구는 모두 닫힌 outputSchema를 공개합니다. 성공 응답의 structuredContent는 이 스키마로 검증하며, 기존 클라이언트가 읽는 compact JSON text도 같은 내용으로 유지합니다.