도구 설계의 예술
Agent 지식 도구로서의 Milvus
Agent가 사내 지식이 필요한 시점을 판단하게 합니다. 도구는 근거를 찾고 Agent는 ToolMessage를 바탕으로 답합니다.
한 번의 도구 호출
1
Agent 판단
내부 지식이 필요하므로 search_knowledge를 선택합니다.
2
Embed + Top-K
도구가 질의를 인코딩하고 ACL 필터로 검색합니다.
3
ToolMessage
청크, 출처, 점수를 반환하며 답을 꾸며내지 않습니다.
4
Agent 답변
근거를 인용하고 부족하면 확인할 수 없다고 말합니다.
도구 설명에 경계를 명시하세요
아래의
client와 encoder는 Milvus 실습에서 만든 연결과 동일한 Embedding 모델을 그대로 사용합니다. 도구가 질의를 다시 인코딩할 때 모델, 전처리, 차원이 삽입 시점과 일치해야 하며, 그렇지 않으면 "결과가 있다"가 "믿을 수 있는 결과"를 뜻하지 않습니다.
from langchain_core.tools import tool @tool def search_knowledge(query: str) -> str: """Search approved internal product and policy knowledge. Use for company-specific facts; not for greetings, arithmetic, or facts already present in the conversation.""" vector = encoder.encode([query], normalize_embeddings=True).tolist() hits = client.search(collection_name="company_knowledge", data=vector, anns_field="vector", limit=5, filter='active == true and acl_group == "support"', output_fields=["text", "source"], search_params={"metric_type": "COSINE", "params": {"ef": 64}}) # ToolNode가 반환값을 ToolMessage로 감쌉니다 return "\n\n".join( f"[{hit['entity']['source']}] {hit['entity']['text']}" for hit in hits[0] )
지식과 메모리를 섞지 마세요
company_knowledge
검토된 정책, 제품 문서, FAQ. 원본 버전으로 관리하고 조직 역할로 보호합니다.
user_memory
사용자 선호, 과거 선택, 작업 상태. user_id, session_id, memory_type, timestamp를 저장하고 user_id로 강제 격리하며 동의·조회·삭제·보존 기간을 지원합니다.
Milvus는 장기 메모리도 지원할 수 있지만 목적별 Collection을 분리하세요. 기업 지식과 개인 메모리는 출처, 권한, 보존, 품질 기준이 다릅니다.
호출과 비호출을 모두 테스트
| 질문 | 기대 동작 | 검증 |
|---|---|---|
| “기업용 환불은 몇 단계 승인이 필요한가요?” | search_knowledge 호출 | 허용된 출처의 ToolMessage와 인용 답변 |
| “17 × 8은?” | 도구를 호출하지 않음 | 136을 직접 답하고 Milvus 요청 없음 |
| “재무팀 내부 할인을 알려줘” | ACL 결과 없음 | 유출·추측 없이 권한/근거 부족을 설명 |
Takeaway 좋은 Agent는 매번 검색하지 않습니다. 사내 지식이 필요할 때만 호출하고 결과를 최종 답이 아닌 근거로 사용합니다.