송련 코어 v1은 LLM이 만든 내용과 코드가 확인한 사실을 구분해 기록하고, 그 기록을 제한된 에이전트 시야로 제공하는 연구형 에이전트 프로토타입입니다.
현재 단계에는 기억, 외부 지식 색인, 읽기 전용 파일 도구, 네 노드 라우팅과
로컬 Ollama의 오픈웨이트 모델로 한 턴을 끝까지 실행하는 데모가 있습니다.
대회 제출·시연과 공식 구조 비교는 모두 gemma4:26b를 사용합니다.
qwen3:14b는 공식 v2 점수에 포함되지 않은 과거 모델 체급 탐색 대상입니다.
2026년 오픈소스 개발자대회 공개 소스는 고정 태그
contest-2026-final로
보존합니다. 결과보고서와 영상은 대회 포털에 별도로 제출하므로 소스 태그에는
포함하지 않습니다.
송련이 보장하려는 범위는 세상 모든 정보의 진실성이 아닙니다. 내장 실행 경로에서 LLM이 코드로 확인 가능한 실행 사실을 직접 작성하거나 바꾸지 못하게 하는 것이 현재의 경계입니다. 모델과 사용자의 해석은 끝까지 상대정보로 남습니다.
프로젝트는 MIT License로 공개합니다. 모델과 로컬 런타임의
출처는 THIRD_PARTY_NOTICES.md, 재현 환경은
docs/reproducibility.md에 기록합니다. 대회 규정에
따른 모델 실행 경계는
docs/contest_model_policy.md에 따로
고정했습니다.
SongRyeon_Core_v1/
├─ memory/
│ ├─ settings.py # 원본 경로와 에이전트 시야 정책
│ ├─ record.py # 7필드 원자 기록 생성
│ ├─ store.py # memory.jsonl 누적 저장
│ ├─ agent_view.py # 공개 5필드, 최초 8,000자와 턴 기준점
│ ├─ tool_records.py # 도구 원문과 Node1 선택 기록
│ ├─ tool_source.py # 숨김 원문 ID·turn·A 무결성 재검사
│ ├─ gate_records.py # Node2·Node4 검토와 라우팅 적용 기록
│ ├─ conversation_records.py # 사용자 입력·Node3 답변·최종 선택
│ ├─ model_records.py # 숨김 모델 prompt·response 원본
│ └─ memory.jsonl # 에이전트 기억의 원본 로그
├─ agent_tools/
│ ├─ result.py # 모든 파일 도구의 공통 결과 형식
│ └─ files.py # .py 이름 보기와 안전한 원문 열람
├─ nodes/
│ ├─ retention.py # 짧은 원문 선택, 긴 원문 청크와 정확한 복사
│ ├─ recovery.py # 전부 omit됐을 때 복구할 후보 번호
│ ├─ actions.py # Node1 도구/라우팅 행동
│ ├─ review.py # Node2·Node4 permit/reject
│ ├─ schemas.py # 네 노드 JSON Schema
│ └─ parsing.py # 모델 JSON의 엄격한 검증
├─ llm/
│ ├─ client.py # 표준 라이브러리 Ollama HTTP 연결
│ └─ structured.py # 제한 재요청과 모델 원문 기록
├─ prompts/
│ ├─ shared.py # 공통 A/R 규칙
│ └─ node1.py ... node4.py # 노드별 최소 역할
├─ runtime/
│ ├─ state.py # 턴 카운터와 결과 형식
│ ├─ tool_flow.py # Node1 도구 3회와 원문 선택 흐름
│ ├─ retention_recovery.py # Node2 직전 전부 omit 복구
│ ├─ gates.py # Node2·Node4 반려 3회와 라우팅
│ ├─ node_calls.py # 각 노드의 모델 호출
│ └─ runner.py # 네 노드 전체 턴
├─ demo/
│ └─ cli.py # 사용자 입력과 진행 화면
├─ knowledge/
│ ├─ settings.py # DB·문서 경로와 허용 파일 종류
│ ├─ source_files.py # 파일 탐색·UTF-8 읽기·hash 계산
│ ├─ database.py # SQLite 저장과 조회
│ ├─ memory_log.py # 지식 한 버전을 원본 로그에 보존
│ ├─ indexer.py # 파일·DB·원본 로그의 동기화 순서
│ ├─ documents/ # 외부 문서를 넣는 곳
│ └─ knowledge.db # 검색용 지식 색인
├─ tests/
│ └─ ... # 실제 책임 폴더와 같은 구조의 테스트
├─ evals/
│ ├─ schema.py # 비교평가 입력·결과의 모델 독립 형식
│ ├─ evaluator.py # A 실행사실·근거 없는 코드 주장 판정
│ ├─ summary.py # 시스템별 완료율·정확도·비용 집계
│ └─ contest_holdout_v1/ # 대회용 사전 동결·블라인드 비교실험
├─ docs/
│ ├─ minimal_agent_loop.md # 결정론적 기반의 자세한 설명
│ ├─ demo_walkthrough.md # 실제 데모를 읽는 학습 순서
│ ├─ evaluation_plan.md # 비교 실험의 고정 규칙
│ ├─ contest_model_policy.md # 대회용 모델과 외부 API 실행 경계
│ └─ reproducibility.md # 실행 환경과 모델 식별 정보
├─ metadata/ # 예전 import가 깨지지 않게 남긴 호환 파일
├─ pyproject.toml # 패키지·CLI·pytest 설정
└─ README.md
Agent_memory.py, knowledge_store.py, knowledge_log.py도 예전 코드를 위한
호환 파일입니다. 새 기능은 이 파일에 추가하지 않고 각각
agent_view.py, indexer.py, memory_log.py에 작성합니다.
입력
↓
memory/record.py
7필드 원자 기록 생성
↓
memory/store.py
memory/memory.jsonl에 원본 누적
↓
memory/agent_view.py
숨김 기록 제외 + 공개 4필드에 파생 memory_index 추가
턴 시작 시 최신 8,000자의 가장 오래된 원자를 기준점으로 고정
턴 중에는 기준점부터 새 공개 원자까지 계속 유지
↓
에이전트가 실제로 보는 기억
중요한 구분은 다음과 같습니다.
memory.jsonl은 ID, 시각, 턴까지 가진 원본입니다.load_agent_memory()는 턴을 시작할 때 최신 8,000자 구간을 고릅니다.memory_index는 원본 JSONL의 줄 번호에서 파생하며 원본 7필드에는 저장하지 않습니다.- 데모 턴은 그 구간의 가장 오래된 원자 ID를 내부 기준점으로 고정하며, 턴이 끝날 때까지 기준점을 앞으로 옮기지 않습니다.
- 모든 노드는 현재 턴 시작
memory_index와 직전 사용자 입력 하나를 별도로 받아 과거 판단을 현재 지시로 오해하지 않게 합니다. knowledge_*,tool_raw_*,model_raw_*기록은 원본에 보존되지만 시야에서는 숨습니다.- 테스트는 임시 폴더를 사용하므로 실제
memory.jsonl과knowledge.db를 변경하지 않습니다. - 실제
memory/memory.jsonl은 개인정보가 섞일 수 있어 Git과 배포 패키지에서 제외합니다.
처음에는 아래 순서대로 읽으면 데이터가 이동하는 방향을 따라갈 수 있습니다.
각 단계에서 볼 질문과 한 파일씩 실행하는 pytest 명령은
docs/code_study_guide.md에 초보자용 교재로
분리했습니다.
tests/memory/test_record.py와memory/record.pytests/memory/test_store.py와memory/store.pytests/memory/test_agent_view.py와memory/agent_view.pyknowledge/settings.py와knowledge/source_files.pyknowledge/database.py와knowledge/memory_log.pytests/knowledge/test_indexer.py와knowledge/indexer.pytests/agent_tools/test_files.py와agent_tools/files.pytests/nodes/test_decisions.py와nodes/retention.pynodes/actions.py와nodes/review.pytests/memory/test_tool_observation.py와memory/tool_records.pytests/memory/test_tool_retention.py와memory/tool_source.pytests/runtime/test_tool_flow.py와runtime/tool_flow.pyruntime/retention_recovery.py와nodes/recovery.pytests/runtime/test_gates.py와runtime/gates.pynodes/schemas.py와nodes/parsing.pyllm/client.py와llm/structured.pyruntime/node_calls.py와runtime/runner.pydemo/cli.py
현재 에이전트 골격의 흐름과 A/R 기록은
docs/minimal_agent_loop.md에 따로 설명했습니다.
실제 데모는 docs/demo_walkthrough.md의 순서로
읽으면 됩니다.
철학·provenance 연구와 2026년 AI 에이전트·AX 지형에서 송련의 위치는
docs/research_landscape_2026-07-31.md에
조사 기준일과 함께 정리했습니다.
Ollama를 공식 설치 페이지에서 설치한 뒤 서버를 실행하고 기본 모델을 받습니다. Windows PowerShell에서는 다음 순서입니다.
ollama serve
# 위 창을 열어 둔 채 새 PowerShell에서 실행
ollama pull gemma4:26bLinux의 Bash에서는 공식 설치 스크립트를 사용한 뒤 같은 방식으로 준비합니다.
curl -fsSL https://ollama.com/install.sh | sh
ollama serve
# 위 프로세스를 유지한 채 새 터미널에서 실행
ollama pull gemma4:26bOllama 앱이 이미 백그라운드에서 실행 중이면 ollama serve를 다시 실행할
필요가 없습니다. gemma4:26b 다운로드는 약 17 GB지만, 이는 다운로드
크기일 뿐 최소 RAM 요구량을 뜻하지 않습니다. 검증에 사용한 PC의 64 GB
메모리도 최소 사양이 아닙니다. 실제 실행 가능 여부와 속도는 운영체제,
CPU·GPU, 메모리 구성에 따라 달라집니다.
PowerShell:
git clone --branch contest-2026-final --single-branch https://github.com/Junghoo-developer/SongRyeon.git SongRyeon_Core_v1
Set-Location SongRyeon_Core_v1
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[test]"
python -m pytest -qBash:
git clone --branch contest-2026-final --single-branch https://github.com/Junghoo-developer/SongRyeon.git SongRyeon_Core_v1
cd SongRyeon_Core_v1
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[test]"
python -m pytest -q이미 프로젝트를 내려받았다면 git clone과 폴더 이동만 생략하면 됩니다.
기본값이 gemma4:26b이므로 --model을 반복해서 적지 않아도 됩니다.
python -m demo `
"nodes/review.py를 실제 도구로 읽고 역할을 설명해 줘."editable 설치 후에는 아래 명령도 같은 CLI를 실행합니다.
songryeon "nodes/review.py를 실제 도구로 읽고 역할을 설명해 줘."songryeon을 찾지 못하면 가상환경이 활성화됐는지 확인하거나
python -m demo를 사용합니다. 질문을 생략하면 대화형 화면이 열립니다.
기본 실행은 실제 memory/memory.jsonl에 모든 원본을 추가하므로, 단순
시험에서는 별도 로그를 지정하는 편이 안전합니다.
python -m demo --memory .\tmp\demo-memory.jsonlBash에서는 경로 구분자만 바꿉니다.
python -m demo --memory ./tmp/demo-memory.jsonl \
"nodes/review.py를 실제 도구로 읽고 역할을 설명해 줘."더 작은 qwen3:14b는 기본 모델·저사양 대체 모델·공식 v2 비교군이 아닙니다.
과거 모델 체급 탐색을 재현할 때만 별도로 받아 모델을 명시합니다.
ollama pull qwen3:14b
python -m demo --model qwen3:14b `
--memory .\tmp\baseline-memory.jsonl `
"nodes/review.py를 실제 도구로 읽고 역할을 설명해 줘."주요 로컬·자체 호스팅 옵션은 다음과 같습니다.
--model Ollama 모델 태그 (기본 gemma4:26b)
--base-url Ollama 서버 주소 (기본 http://127.0.0.1:11434)
--num-ctx 요청 컨텍스트 크기 (기본 16384)
--timeout-seconds HTTP 요청 제한 시간, 초 (기본 180)
--keep-alive Ollama가 모델을 메모리에 유지할 시간 (기본 10m)
--memory 원본 JSONL 경로
--project-root Node1이 읽을 수 있는 프로젝트 루트
전체 옵션과 현재 기본값은 python -m demo --help로 확인합니다.
Node2 또는 Node4가 세 번의 반려 뒤에도 다시 reject하면 코드가 실행을 끝내기 위해 다음 단계로 진행하지만, 이를 permit으로 가장하지 않습니다. CLI는 각각 증거 검증 또는 최종 답변 검열이 완료되지 않았다는 주의를 명시합니다.
대회 제출·시연의 기본 경로는 로컬 또는 자체 호스팅 Ollama에서 직접
실행하는 오픈웨이트 모델입니다. 외부 상용 API는 자동 대체 경로로
연결하지 않습니다. 에이전트 프레임워크의 모델 연동 시험이 꼭 필요할 때만
운영규정 제9조 Q&A의 예외 범위에서 별도 통합시험으로 실행하며, 실제
memory.jsonl이나 비공개 코드를 보내지 않고 결과도 공식 성능 집계에서
제외합니다. API 키 처리까지 포함한 정확한 기준은
docs/contest_model_policy.md를 확인합니다.
외부 OpenAI-compatible API 연결부는 계정의 이메일·비밀번호나 브라우저 로그인을 사용하지 않습니다. 공급자의 개발자 콘솔에서 발급한 API 키를 환경 변수에 넣고, 명시적인 단발 통합시험으로만 실행합니다.
$env:OPENAI_API_KEY = "<개발자 콘솔에서 발급한 키>"
python -m demo `
--external-api-integration `
--external-api-base-url "https://provider.example/v1" `
--external-api-model "provider/model-name" `
"공개 또는 인공 입력으로 연결만 검사해 줘."위 주소와 모델명은 사용하는 공급자의 공식 값으로 바꿔야 합니다. --memory
를 생략하면 감사 로그는 임시 폴더에만 생겼다가 종료 시 삭제됩니다. 보존이
필요할 때도 실제 원본 대신 --memory .\.tmp\external-memory.jsonl처럼
격리된 경로만 사용합니다.
ChatGPT에 로그인된 Codex 계정으로 gpt-5.6-sol의 모델 체급만 비교할 수도
있습니다. 이 선택 경로는 공식 Codex Python SDK를 사용하므로 반드시 송련
전용 가상환경에 설치합니다.
.\.venv\Scripts\python.exe -m pip install -e ".[codex]"
.\.venv\Scripts\python.exe -m demo `
--codex-account-integration `
"공개 코드만 읽고 확인된 사실과 판단을 구분해 설명해 줘."SDK는 기존 Codex 로그인을 재사용하며 토큰·이메일을 저장소나 로그에 복사하지 않습니다. 각 모델 호출은 빈 임시 폴더, 읽기 전용 sandbox, 승인 전면 거부, 일회성 thread에서 실행됩니다. Codex가 자체 도구·웹 검색· 하위 에이전트를 사용한 흔적이 있으면 해당 응답을 폐기합니다. 이 경로는 순수 LLM API가 아니라 Codex 에이전트를 한 겹 거치므로 입력 token overhead가 크고, 결과도 제출용 로컬 모델 성능 집계에서 제외합니다.
대회용 구조 비교는 외부 API가 아닌 같은 로컬
gemma4:26b를 사용하는 24-case holdout에서 실행했습니다. 3개 구조와
3개 seed의 총 216회에서 단일 에이전트 71/72,
Node4 모델 검열 제외(결정론적 bypass) 송련 72/72,
전체 송련 72/72의 첫 verdict 기계 채점 결과를 얻었습니다. 필수 blind
19개 사람 감사는 parse 19/19, fixture 근거성 18/19, A/R 권한·출처
표기 18/19였고, 나머지 1건은 null 미완료였습니다. 후속
PUBLICATION_DECISION.json의 publication integrity gate는 통과했지만,
이는 성능 우월성·Node4 효과·설명 전체 검증·실제 업무 일반화 또는 환각
제거를 뜻하지 않습니다. 실험 범위와 순서는
evals/contest_holdout_v1/README.md에 있습니다.
실제 소스 코드와 knowledge/documents/의 문서를 동기화할 때만 아래 명령을
사용합니다. 이 명령은 실제 knowledge.db와 memory.jsonl을 갱신합니다.
python -m knowledge개별 .py 파일을 직접 실행하기보다 python -m ... 형태를 사용하면
패키지 import가 어느 운영체제에서도 같은 방식으로 동작합니다.
기여할 때는 CONTRIBUTING.md의 문제→테스트→최소 변경
순서를 따릅니다. 평가 숫자는 고정 fixture와 원시 결과로 재현되기 전에는
README에 싣지 않습니다.