검색/모듈형 Rust AI 프레임워크에 새 AI 공급자와 벡터 스토어를 추가한다

모듈형 Rust AI 프레임워크에 새 AI 공급자와 벡터 스토어를 추가한다

여러 AI 공급자를 지원하는 Rust 프레임워크를 확장할 때 쓴다. 기존 trait와 builder를 따르고, WebAssembly 지원을 유지하며, 훅이 스트리밍 여부와 상관없이 똑같이 동작하게 하고, 녹화한 테스트 카세트에 API 키가 새지 않았는지 확인한다.

이 AI 규칙을 사용하려면
## 요청받은 범위만 바꾸고, 요청이 없으면 커밋하지 않는다 - 코드를 변경하기 전에 기존 구현, 매니페스트, 테스트, 공개 문서를 읽으세요. - 모든 변경을 사용자가 요청한 범위 안으로 제한하세요. - 별도의 추상화를 만들기보다 기존 trait, builder, 모듈, 오류 타입을 우선 사용하세요. - TODO, stub, placeholder 동작 또는 추측에 근거한 공개 API를 추가하지 마세요. - 사용자가 해당 작업을 명시적으로 요청하지 않는 한 커밋, 스테이징, 푸시, 브랜치 생성 또는 풀 리퀘스트 개설을 하지 마세요. - 관련 없는 사용자 변경 사항을 보존하고 변경된 작업 트리를 안전하게 우회하세요. - 주변 설계를 개선할 수 있더라도 관련 없는 리팩터링을 피하세요. - 기여자 정책과 저장소별 엔지니어링 규칙을 구분하고 둘 다 따르세요. - 필요한 제품 의도나 외부 권한이 없으면 중단하세요. ## 워크스페이스 전체에서 crate 구성과 feature flag를 맞춘다 - 공개 facade crate, core crate, 보조 통합, derive macro, 예제, 테스트가 기존 역할을 유지하게 하세요. - facade가 core API를 다시 export하고 feature flag를 통해 선택적 보조 crate를 노출하게 하세요. - 공개 feature, 통합 또는 모듈 경로를 변경하기 전에 워크스페이스 매니페스트와 facade export를 확인하세요. - core에 배치해야 할 강력한 아키텍처상 이유가 없다면 공급자와 벡터 스토어 통합을 보조 crate에 배치하세요. - 워크스페이스 예제를 crate별 예제 및 통합 테스트와 구분하세요. - 보조 crate를 추가할 때는 적용되는 범위에서 루트 의존성, feature, facade 재export, 예제, README, crate 문서를 업데이트하세요. - 사용할 수 없는 모듈을 노출하지 않으면서 feature 조합이 컴파일되는지 확인하세요. - facade와 영향을 받는 보조 crate의 공개 문서를 서로 일치하게 유지하세요. - 코드와 매니페스트로 확인하기 전에는 모듈 경로나 feature를 설명하지 마세요. ## 공급자 전용 버전을 만들지 않고 공통 trait 위에 만든다 - 프레임워크의 중심 completion, embedding, vector-index, callable-tool trait를 기반으로 통합을 구축하세요. - 기존의 공급자 공통 trait를 대신하는 공급자별 대안을 만들지 마세요. - 설정 가능한 공개 타입에는 기존 builder 패턴을 따르세요. - 생성 과정은 fluent하고 타입이 지정되게 유지하며, 명시적인 build 단계 후에만 완성되게 하세요. - 공급자 확장을 기본 HTTP 전송 계층과 분리하는 generic client 아키텍처를 사용하세요. - 지원되지 않는 동작이 컴파일 시점에 실패하도록 공급자 기능을 명시적으로 선언하세요. - 없는 기능을 런타임에 추측하지 말고 의도적인 marker type으로 표현하세요. - 공급자 builder와 공개 client alias 전체에서 API key 타입 관계를 유지하세요. - 공급자별 요청 및 응답 타입을 변환 경계 뒤에 두세요. ## 공유 비동기 코드가 WebAssembly에서도 동작하게 유지한다 - 공유 trait, future, 오류, 통합에서 WebAssembly 지원을 유지하세요. - 대상에 따라 경계가 달라지는 경우 원시 `Send`와 `Sync` 경계 대신 프레임워크의 호환성 추상화를 사용하세요. - 동적으로 반환되는 future에는 지정된 이식 가능 boxed-future 타입을 사용하세요. - 이를 지원하는 대상에서만 네이티브 스레드 안전성 경계를 적용하세요. - WebAssembly boxed error에는 지원되지 않는 네이티브 전용 경계를 넣지 마세요. - 공유 trait를 변경한 후 네이티브와 WebAssembly 대상 타입 시그니처를 모두 테스트하세요. - 지원 대상 하나를 암묵적으로 제외하는 의존성이나 API를 추가하지 마세요. - 조건부 컴파일 범위를 좁게 유지하고 대상 간 차이를 설명하세요. - 공급자, 벡터 스토어, hook API가 동일한 이식성 규약을 사용하도록 하세요. ## 명확한 오류 타입을 쓰고, 새 공개 API마다 문서를 단다 - 실패할 수 있는 새 API의 오류 타입으로 `String`을 사용하지 마세요. - 명시적인 오류 enum을 정의하고 프레임워크 오류 도우미를 통해 유용한 공급자 응답 세부 정보를 보존하세요. - 오류 문맥을 수동으로 잃어버리는 방식보다 `?`와 의미 있는 변환을 우선하세요. - 주변 불변 조건으로 불가능함이 명백할 때만 `unwrap()` 또는 `expect()`를 사용하세요. - 모든 새로운 공개 타입, 함수, trait, 메서드에 항목 문서를 추가하세요. - 모든 새로운 공개 모듈에 모듈 문서를 추가하세요. - 예제가 실제 API, 모델 상수, 모듈 경로, feature flag와 일치하도록 유지하세요. - 외부 자격 증명이나 서비스가 필요한 예제는 실행하지 않는 예제로 표시하세요. - 공개 동작이 변경될 때마다 README 파일과 crate 수준 문서를 업데이트하세요. ## 가장 비슷한 기존 공급자를 따라 새 AI 공급자를 추가한다 - 다른 공급자를 구현하거나 수정하기 전에 가장 가까운 기존 공급자를 조사하세요. - 공급자 확장 타입과 builder 타입, 공급자 구현, 명시적인 기능 선언을 추가하세요. - 프레임워크가 두 경로를 모두 제공하는 경우 환경 값과 직접 값으로 생성을 지원하세요. - 공개 client와 builder alias가 공급자 builder의 API key 타입과 일치하게 하세요. - 명시적인 자격 증명 marker 또는 인증 타입을 사용하고 자격 증명이 포함된 debug 출력은 가리세요. - 프레임워크 요청을 공급자의 실제 wire format으로 변환하고, 응답을 다시 프레임워크 타입으로 변환하세요. - 공급자가 실제로 지원할 때만 streaming을 추가하고 표준 도우미를 통해 공급자 오류를 보존하세요. - 기존 telemetry 규칙과 확장 trait를 따르세요. - 공급자의 실제 API에 없는 요청 또는 응답 필드를 만들어내지 마세요. - 지원되는 동작을 입증하는 집중된 테스트나 예제를 추가하세요. ## 실제 필터와 명확한 검색 결과를 갖춘 벡터 스토어를 연결한다 - core 소유가 타당한 이유가 없다면 벡터 스토어 통합을 보조 crate에 배치하세요. - 결과를 반환하는 검색과 식별자만 반환하는 검색을 모두 구현하세요. - backend의 실제 필터링 기능을 반영하는 필터 타입을 사용하세요. - 임시 문자열 오류 대신 프레임워크의 벡터 스토어 오류 variant를 반환하세요. - core 프레임워크가 사용하는 것과 동일한 이식 가능 비동기 경계를 적용하세요. - 점수, 문서, 식별자, 메타데이터 변환을 명시적으로 유지하세요. - 정렬, 제한, 빈 결과, backend 오류 동작을 정의하세요. - 필터, 순위 순서, 결과 제한, 누락된 레코드, 변환 실패를 테스트하세요. - secret을 포함하지 않고 필요한 feature, 자격 증명, index, 외부 설정을 문서화하세요. ## 훅 이벤트마다 허용되는 동작을 정한다 - hook을 실행 범위의 수명 주기 관찰자이자 제어자로 모델링하세요. - 실행 식별자, turn, streaming mode, agent 식별자, 공유 scratch 상태를 포함하는 실행 context를 모든 event에 전달하세요. - 지원되지 않는 action 조합이 컴파일 시점에 실패하도록 event마다 고유한 action 타입을 부여하세요. - completion 호출 hook이 요청을 patch하거나 처리를 중단할 수 있게 하세요. - tool 호출 및 tool 결과 hook이 이후 hook을 위해 값을 다시 쓰게 하고, 정의된 경우 skip 또는 stop을 종결 action으로 사용하세요. - 유효하지 않은 tool 호출 처리를 명시적인 fail, retry, repair, skip, stop 선택지로 표현하세요. - 관찰 전용 event는 continue 또는 stop으로 제한하세요. - stop action이 stack을 단락시키는 경우 제어 hook보다 관찰 hook을 먼저 등록하세요. - 어떤 action이 데이터를 변환하고, 어떤 action이 누적되며, 어떤 action이 처리를 종료하는지 문서화하세요. ## 쌓인 훅을 스트리밍 여부와 상관없이 같은 방식으로 합친다 - hook이 중첩되거나 쌓일 때 event별 합성 의미론을 유지하세요. - 등록 순서에 따라 completion 요청 patch를 병합하세요. - 추가 context는 이어 붙이고, 추가 parameter는 얕게 병합하며, 활성 tool 집합은 교집합을 취하세요. - 문서화된 scalar 및 history 필드에만 마지막 작성자 우선 규칙을 적용하고, 덮어쓰기가 중요할 때 경고하세요. - 각 요청 patch의 범위를 한 turn으로 제한하고, 실수로 계속 유지되게 만들지 마세요. - tool 호출과 tool 결과의 재작성 값을 이후의 모든 hook으로 전달하세요. - 종결 action이 요구하면 즉시 stack 평가를 중단하세요. - streaming과 non-streaming 인터페이스가 동일한 수명 주기 driver를 공유하게 하세요. - streaming과 non-streaming 진입점 모두에서 동일한 hook 동작을 테스트하세요. - 중첩 stack, 병합 충돌, 재작성 chain, skip, stop에 대한 합성 테스트를 추가하세요. ## 가장 작은 회귀 테스트를 고르고, 공급자 호출은 녹화한 카세트로 테스트한다 - 신뢰할 수 있는 가장 작은 범위에 회귀 검증을 추가하세요. - 격리된 변환 또는 로직 결함에는 구현 옆의 단위 테스트를 우선하세요. - 동작이 공급자 요청과 응답 트래픽에 의존하면 cassette 기반 공급자 테스트를 사용하세요. - 결정론적 cassette 재생으로 동작을 표현할 수 없는 경우에만 무시 처리한 live 테스트를 사용하세요. - 공급자 테스트를 추가, 업데이트, 기록 또는 재생하기 전에 저장소의 테스트 가이드를 읽으세요. - 일반 테스트에 공급자 자격 증명이 필요하지 않도록 기본적으로 cassette를 재생하세요. - 테스트 실행을 변경 중인 공급자와 동작에 집중하세요. - 두 인터페이스가 모두 존재하면 streaming과 non-streaming 동작을 모두 검증하세요. - 회귀 어설션에 원래의 실패 양상을 보존하세요. ## 대상 테스트만 카세트를 녹화하고, 비밀 정보가 들어 있지 않은지 확인한다 - record mode를 자격 증명을 사용하고 파일을 덮어쓰는 외부 작업으로 취급하세요. - 기록 전에 관련 공급자 자격 증명을 요구하고, 출력에 절대 노출하지 마세요. - 관련 없는 fixture 변경을 최소화하도록 대상 공급자 테스트만 기록하세요. - 각 cassette diff를 제시하거나 커밋하기 전에 모두 직접 검사하세요. - API key, bearer 자격 증명, cookie, 계정 식별자 또는 기타 민감한 값이 포함된 fixture를 거부하세요. - 불필요하게 복잡한 fixture를 받아들이지 말고 관련 없는 요청 및 응답 변경을 제거하세요. - 자동 scrub 및 안전 검사를 활성화된 상태로 유지하되 직접 검사를 대체한다고 간주하지 마세요. - secret과 불안정한 메타데이터를 가리면서 결정론적 재생 데이터를 보존하세요. - 동작 변경을 설명하지 않은 채 실패한 테스트를 성공시키려는 목적으로 fixture를 덮어쓰지 마세요. ## 좁은 검사부터 넓혀 가며 돌리고, 확인하지 못한 부분을 보고한다 - 유용한 최소 검사부터 실행한 다음 영향 범위와 위험에 따라 확대하세요. - 워크스페이스를 포매팅하고 영향을 받는 모든 대상과 feature에서 lint를 실행하세요. - 광범위한 워크스페이스 테스트보다 집중 테스트를 먼저 실행하세요. - 공개 API나 문서가 변경되면 의존성을 제외하고 문서를 빌드하세요. - 공유 경계나 future가 변경되면 네이티브와 WebAssembly 호환성을 검증하세요. - 공급자 wire 필드가 실제 API와 일치하고 cassette diff에 secret이 없는지 확인하세요. - streaming과 non-streaming 인터페이스에서 hook 의미론이 일치하는지 확인하세요. - 필수 검사가 실패하는 동안 완료를 선언하지 마세요. - 명령을 실행할 수 없다면 이유를 설명하고 검증되지 않은 항목을 정확히 밝히세요. - 변경된 인터페이스, 실행한 검사, 관찰한 결과, 남은 위험, 의도적으로 제외한 범위를 보고하세요.