第 16 期:实战 — 构建企业知识问答系统

Updated on 4/6/2026

[Translation Pending]\n\n## 系统架构

graph TB
    subgraph "数据入库层"
        Docs[企业文档] --> Upload[批量上传]
        Upload --> Chunk[智能分段]
        Chunk --> Embed[Embedding]
        Embed --> VDB[(Weaviate 向量库)]
    end
    
    subgraph "应用层 (Dify Chatflow)"
        User[员工提问] --> QC[Question Classifier]
        QC -->|专业问题| KR[Knowledge Retrieval]
        QC -->|闲聊| Chat[直接对话]
        KR --> VDB
        KR --> LLM[LLM 生成回答]
        LLM --> Source[附加引用来源]
        Source --> Answer[Answer 节点]
        Chat --> Answer
    end
    
    subgraph "前端展示层"
        Answer --> WebApp[Dify Web App]
        Answer --> API[嵌入企业内网]
        Answer --> WeCom[企业微信机器人]
    end

步骤一:批量导入文档

import os
import requests

CONSOLE_TOKEN = "your-console-token"
DATASET_ID = "your-dataset-id"
BASE_URL = "http://localhost/console/api"

def upload_documents(folder_path: str):
    """批量上传文件夹中的所有文档"""
    for filename in os.listdir(folder_path):
        if filename.endswith(('.pdf', '.txt', '.md', '.docx')):
            filepath = os.path.join(folder_path, filename)
            
            with open(filepath, 'rb') as f:
                response = requests.post(
                    f"{BASE_URL}/datasets/{DATASET_ID}/document/create-by-file",
                    headers={"Authorization": f"Bearer {CONSOLE_TOKEN}"},
                    files={"file": (filename, f)},
                    data={
                        "indexing_technique": "high_quality",
                        "process_rule": '{"mode": "automatic"}'
                    }
                )
            
            if response.status_code == 200:
                print(f"✅ 上传成功: {filename}")
            else:
                print(f"❌ 上传失败: {filename} - {response.text}")

upload_documents("/path/to/company/docs")

步骤二:配置 Chatflow

LLM 节点的 System Prompt 设计:

# 角色
你是「XX公司」的内部知识助手,负责回答员工关于公司政策、产品技术、流程规范的问题。

# 上下文
{{#knowledge_retrieval.result#}}

# 回答规则
1. 仅基于上述"上下文"中的信息回答
2. 如果上下文中没有相关信息,回复:"抱歉,我在现有文档中没有找到相关信息。建议联系 [email protected]。"
3. 如有引用,标注文档来源
4. 使用清晰的 Markdown 格式
5. 回答要专业但易懂

步骤三:嵌入企业内网

<!-- 在企业内网页面嵌入 Dify Chatbot -->
<iframe
  src="http://dify.internal.company.com/chatbot/your-app-token"
  style="width: 100%; height: 600px; border: none; border-radius: 12px;"
  allow="microphone">
</iframe>

<!-- 或使用浮动按钮 -->
<script>
  window.difyChatbotConfig = {
    token: 'your-app-token',
    baseUrl: 'http://dify.internal.company.com'
  };
</script>
<script src="http://dify.internal.company.com/embed.min.js" defer></script>

步骤四:引用溯源

# 解析回答中的引用来源
def format_answer_with_sources(api_response: dict) -> str:
    answer = api_response["answer"]
    sources = api_response.get("metadata", {}).get("retriever_resources", [])
    
    if sources:
        answer += "\n\n---\n📚 **参考来源:**\n"
        for i, src in enumerate(sources, 1):
            answer += f"{i}. {src['document_name']} (相关度: {src['score']:.2f})\n"
    
    return answer