Metadata-Version: 2.4
Name: csm-llm-qa
Version: 0.1.0
Summary: RAG-powered Q&A library for the CSM (Communicable State Machine) / LabVIEW knowledge base.
Author: NEVSTOP-LAB
License-Expression: MIT
Project-URL: Homepage, https://github.com/NEVSTOP-LAB/CSM-LLM-QA
Project-URL: Issues, https://github.com/NEVSTOP-LAB/CSM-LLM-QA/issues
Project-URL: Changelog, https://github.com/NEVSTOP-LAB/CSM-LLM-QA/releases
Keywords: rag,llm,deepseek,csm,labview,qa
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openai>=1.0
Requires-Dist: chromadb>=0.4.0
Requires-Dist: sentence-transformers>=2.2.0
Requires-Dist: charset-normalizer>=3.0.0
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-mock>=3.10.0; extra == "test"
Dynamic: license-file

# CSM-LLM-QA

> 通用 RAG 问答 Python 库 —— 基于 CSM Wiki / LabVIEW 知识库，封装 LLM 调用与向量检索，对外仅暴露一个简洁的 `CSM_QA` 类。

---

## 安装

```bash
pip install csm-llm-qa
```

依赖：`openai>=1.0`、`chromadb>=0.4`、`sentence-transformers>=2.2`、`charset-normalizer>=3.0`。

---

## 60 秒上手

```python
from csm_llm_qa import CSM_QA

qa = CSM_QA(api_key="sk-deepseek-xxx")           # 默认 provider=deepseek
answer = qa.ask("CSM 框架中的状态机如何切换？")
print(answer)
```

带历史对话：

```python
from csm_llm_qa import CSM_QA, Message

qa = CSM_QA(api_key="sk-xxx")
history = [
    Message(role="user", content="CSM 是什么？"),
    Message(role="assistant", content="CSM 是 Communicable State Machine ..."),
]
answer = qa.ask("那它和 JKI SM 的区别？", history=history)
```

需要更多元信息？

```python
result = qa.ask_detailed("CSM 状态机如何切换？", history=history)
print(result.answer)         # 文本
print(result.contexts)       # 命中的 RAG 片段
print(result.usage)          # token 用量
print(result.prompt_messages)  # 实际发往 LLM 的 messages（调试用）
```

---

## API 参数

```python
CSM_QA(
    api_key,                                # 必填
    *,
    provider="deepseek",                    # "deepseek" 或 "openai_compatible"
    model=None,                             # None → 取 provider 默认
    base_url=None,                          # None → 取 provider 默认
    temperature=0.5,
    max_tokens=2048,
    max_retries=3,
    request_timeout=60.0,

    wiki_dir="csm-wiki/remote",             # 知识库目录
    vector_store_dir=".csm_llm_qa/vector_store",
    embedding_provider="local",             # "local"（本地）或 "openai"
    embedding_model="BAAI/bge-small-zh-v1.5",
    embedding_api_key=None,
    embedding_base_url=None,
    top_k=6,
    similarity_threshold=0.72,

    system_prompt=None,                     # None → 内置 CSM/LabVIEW prompt
    wiki_base_url="https://github.com/NEVSTOP-LAB/CSM-Wiki/blob/main",  # 关键信息回答时的链接前缀
    auto_sync_wiki=True,                    # 首次运行若向量库为空，自动同步
)
```

### 支持的 LLM 供应商

| `provider`            | 默认 `base_url`                    | 默认 `model`     | 备注                              |
| --------------------- | ---------------------------------- | ---------------- | --------------------------------- |
| `deepseek`            | `https://api.deepseek.com`         | `deepseek-chat`  | DeepSeek 官方                      |
| `openai_compatible`   | 必须传                             | 必须传           | OpenAI 官方、Moonshot、智谱、本地 vLLM/Ollama 等任意 OpenAI 兼容服务 |

示例：使用 OpenAI 官方

```python
qa = CSM_QA(
    api_key="sk-xxx",
    provider="openai_compatible",
    base_url="https://api.openai.com/v1",
    model="gpt-4o-mini",
)
```

### 从环境变量构造

```python
qa = CSM_QA.from_env()
# 识别的环境变量（统一以 LLM_* 前缀，无别名）：
# LLM_API_KEY / LLM_PROVIDER / LLM_MODEL / LLM_BASE_URL
```

---

## 知识库

把任意 Markdown 文档放入 `csm-wiki/remote/` 目录即可（支持子目录、UTF-8 / GBK / Big5 自动识别）。

- 首次构造 `CSM_QA` 时若向量库为空：
  - 若 `csm-wiki/remote/` 目录不存在但 `csm-wiki/wiki_source.json` 存在，会自动从远程仓库克隆 wiki 并建立索引。
  - 若 `csm-wiki/remote/` 已存在，则直接对目录做增量同步。
  - 若两者均不存在，则跳过同步（无 RAG 上下文，仅凭 LLM 本身回答）。
- 之后可通过命令行手动增量同步：

```bash
python -m csm_llm_qa.sync_wiki                 # 增量
python -m csm_llm_qa.sync_wiki --force         # 强制重建
python -m csm_llm_qa.sync_wiki --wiki ./docs --store ./.csm_llm_qa/vector_store

# 通过 wiki_source.json 检查远程更新并按需拉取
python -m csm_llm_qa.sync_wiki --remote
```

或在代码中：

```python
qa.sync_wiki(force=False)
```

---

## 提示词

库内置一段针对 **CSM/LabVIEW + RAG** 的中文 system prompt（详见 [`csm_llm_qa/prompts.py`](csm_llm_qa/prompts.py) 的 `DEFAULT_SYSTEM_PROMPT`）。

如需替换为通用领域 / 英文 / 自定义风格，传入 `system_prompt=` 即可：

```python
qa = CSM_QA(api_key="sk", system_prompt="You are a helpful general-purpose assistant.")
```

---

## 贡献 / 开发

请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。

---

## License

MIT
