不用找大厂外包,小团队也能做出能用的 AI Agent。本文记录完整的开发方法论。

前言

AI 智能体(Agent)是 2025-2026 年最热门的技术方向之一。但对中小企业来说,大厂的 Agent 方案往往意味着高昂的订阅费和复杂的系统集成成本。

这篇文章不讲理论,只讲一件事:怎么用开源工具,为中小企业开发一个能真正干活的 AI 智能体


一、什么是 AI 智能体?先对齐概念

1.1 智能体 vs 聊天机器人

普通聊天机器人:
  用户 → 对话 → 回答
  只能回答问题,不能执行操作
​
AI 智能体:
  用户 → 理解任务 → 规划步骤 → 调用工具 → 验证结果 → 回复
  能主动执行操作:查数据库、发邮件、调API、操作系统

1.2 智能体的核心能力

┌────────────────────────────────────┐
│            AI 智能体架构             │
│                                    │
│  ┌─────────┐  ┌──────────────┐     │
│  │  记忆系统  │  │  工具调用能力   │     │
│  │ 短期/长期  │  │ API/数据库/文件  │     │
│  └────┬────┘  └──────┬───────┘     │
│       │              │              │
│  ┌────▼──────────────▼───────┐     │
│  │        推理引擎             │     │
│  │   思考 → 规划 → 执行       │     │
│  │   (ReAct / Plan-Execute)  │     │
│  └────────────┬─────────────┘     │
│               │                    │
│  ┌────────────▼─────────────┐     │
│  │        知识库              │     │
│  │    企业业务知识支撑         │     │
│  └──────────────────────────┘     │
└────────────────────────────────────┘

二、企业 Agent 的六个典型场景

在中小企业中,以下六个场景最容易落地:

场景矩阵

场景 业务价值 实现难度 推荐优先级
智能客服 减少80%重复咨询 ★★☆ ⭐⭐⭐ #1
数据查询助手 免写SQL,自然语言查数据 ★★☆ ⭐⭐⭐ #2
文档自动处理 自动分类/摘要/归档 ★★☆ ⭐⭐ #3
流程审批助手 自动通知+催办 ★☆☆ ⭐⭐ #4
报表生成 自动出周报/月报 ★★★ ⭐ #5
邮件自动处理 自动分类+草拟回复 ★★★ ⭐ #6

三、场景一:智能客服 Agent(完整实现)

3.1 需求分析

企业背景:一家50人的五金件外贸公司
痛点:
  - 每天收到50+封英文询价邮件
  - 80%的问题是产品规格、价格、交期的重复查询
  - 业务员花3-4小时/天在重复性回复上
​
Agent 目标:
  - 自动处理重复性询价
  - 从知识库检索产品信息
  - 生成标准化英文回复
  - 复杂问题人工接管

3.2 实现架构

用户邮件 → Agent 入口
                │
        ┌───────▼────────┐
        │  邮件分类器      │
        │  简单/复杂/垃圾   │
        └───────┬────────┘
                │
    ┌───────────┼───────────┐
    │           │           │
    ▼           ▼           ▼
  垃圾        简单询价      复杂询价
  过滤       (自动处理)    (人工接管)
              │           │
        ┌─────▼─────┐     │
        │  意图识别   │     │
        │ 产品/价格/交期 │    │
        └─────┬─────┘     │
              │           │
        ┌─────▼─────┐     │
        │ 知识库检索  │     │
        │ 查产品/价格  │     │
        └─────┬─────┘     │
              │           │
        ┌─────▼─────┐     │
        │ 生成回复   │     │
        │ 英文邮件格式 │     │
        └─────┬─────┘     │
              │           │
        ┌─────▼─────┐     │
        │ 发送邮件   │     │
        └───────────┘     │
                          │
              ◄───────────┘
              │
        ┌─────▼─────┐
        │ 通知业务员  │
        │ "有复杂询价请处理"│
        └───────────┘

3.3 核心代码实现

"""
智能客服 Agent - 完整实现
使用 Dify + Ollama 作为底层,本代码展示 Agent 的核心逻辑
"""
import re
from typing import Literal, Dict, List, Optional
from dataclasses import dataclass
​
# ===== 1. 数据结构定义 =====
​
@dataclass
class Inquiry:
    """客户询价结构"""
    id: str
    from_email: str
    subject: str
    body: str
    category: Optional[str] = None        # 分类结果
    intent: Optional[str] = None           # 意图识别
    product: Optional[str] = None          # 涉及产品
    confidence: float = 0.0                # 信心度
​
# ===== 2. 邮件分类器 =====
​
class EmailClassifier:
    """第一步:判断邮件是否需要自动处理"""
    
    # 简单询价的特征模式
    SIMPLE_PATTERNS = [
        r"(what|how much|price|cost|quote|specification).*\?",
        r"(产品|价格|规格|报价|多少钱|参数).*[??]",
        r"(do you have|could you send|please provide).*(catalog|price|spec)",
        r"(please|pls|kindly).*(send|provide|share|quote)",
        r"inquiring about|looking for|interested in",
    ]
    
    # 复杂询价:需要人工判断的
    COMPLEX_KEYWORDS = [
        "custom", "customize", "特殊定制", "OEM",
        "negotiate", "discount", "bulk order", "长期合作",
        "complaint", "issue", "problem", "defect", "质量问题",
    ]
    
    def classify(self, inquiry: Inquiry) -> str:
        text = (inquiry.subject + " " + inquiry.body).lower()
        
        # 简单询价:匹配到特征模式
        for pattern in self.SIMPLE_PATTERNS:
            if re.search(pattern, text, re.IGNORECASE):
                inquiry.confidence = 0.85
                return "simple"
        
        # 复杂询价:包含复杂关键词
        for keyword in self.COMPLEX_KEYWORDS:
            if keyword.lower() in text:
                inquiry.category = "complex"
                inquiry.confidence = 0.9
                return "complex"
        
        # 默认:简单处理
        inquiry.confidence = 0.5
        return "simple"
​
# ===== 3. 意图识别 =====
​
class IntentRecognizer:
    """第二步:识别客户具体意图"""
    
    INTENT_MAP = {
        "product_spec": {
            "keywords": ["spec", "specification", "规格", "参数", "尺寸", "size", "weight", "功率", "power"],
            "template": "产品规格查询"
        },
        "price": {
            "keywords": ["price", "cost", "how much", "报价", "价格", "多少钱", "quote"],
            "template": "价格查询"
        },
        "lead_time": {
            "keywords": ["delivery", "lead time", "交期", "ship", "多久", "how long", "available"],
            "template": "交期查询"
        },
        "moq": {
            "keywords": ["moq", "minimum quantity", "起订", "最小订", "minimum order"],
            "template": "起订量查询"
        },
        "sample": {
            "keywords": ["sample", "样品", "打样", "free sample"],
            "template": "样品咨询"
        },
        "catalog": {
            "keywords": ["catalog", "brochure", "产品目录", "product list", "datasheet"],
            "template": "产品目录请求"
        }
    }
    
    def recognize(self, inquiry: Inquiry) -> List[str]:
        text = (inquiry.subject + " " + inquiry.body).lower()
        intents = []
        
        for intent_name, config in self.INTENT_MAP.items():
            if any(kw.lower() in text for kw in config["keywords"]):
                intents.append(intent_name)
        
        inquiry.intent = ",".join(intents) if intents else "general_inquiry"
        return intents
​
# ===== 4. 产品名称提取 =====
​
class ProductExtractor:
    """从邮件中提取产品型号"""
    
    # 预定义产品型号模式
    PRODUCT_PATTERNS = [
        r'\b(A|B|C|X|T)\s*[-]?\s*\d{1,4}\b',  # A-300, B100, T2000
        r'\b(model|型号|type|product)[:\s]*\w+[-]?\w*\b',
    ]
    
    def extract(self, text: str, product_list: List[str]) -> Optional[str]:
        # 方法1:正则匹配
        for pattern in self.PRODUCT_PATTERNS:
            matches = re.findall(pattern, text, re.IGNORECASE)
            if matches:
                return matches[0] if isinstance(matches[0], str) else matches[0][0]
        
        # 方法2:产品列表精确匹配
        text_lower = text.lower()
        for product in product_list:
            if product.lower() in text_lower:
                return product
        
        return None
​
# ===== 5. 知识库检索 =====
​
class KnowledgeBaseSearcher:
    """从企业知识库检索产品信息"""
    
    def search_product(self, product_name: str, intent: str) -> Dict:
        """根据产品名称和意图,查询知识库"""
        
        # 构建结构化查询
        search_queries = {
            "product_spec": f"{product_name} 规格参数 技术参数",
            "price": f"{product_name} 价格 报价 价格表",
            "lead_time": f"{product_name} 交期 交货时间 生产周期",
            "moq": f"{product_name} 起订量 最小订单量 MOQ",
            "sample": f"{product_name} 样品 样品政策",
            "catalog": f"{product_name} 产品目录 产品清单",
        }
        
        query = search_queries.get(intent, f"{product_name} 产品信息")
        
        # 调用向量检索(以 Dify API 为例)
        search_results = self._call_dify_knowledge_api(query)
        
        return self._format_results(search_results, intent)
    
    def _call_dify_knowledge_api(self, query: str) -> List[Dict]:
        """调用 Dify 知识库 API 进行检索"""
        # 实际场景中使用 Dify SDK 或 REST API
        # 这里展示请求结构
        import requests
        
        response = requests.post(
            "http://localhost:3000/v1/knowledge/retrieve",
            headers={
                "Authorization": "Bearer {your_api_key}",
                "Content-Type": "application/json"
            },
            json={
                "query": query,
                "knowledge_base_id": "your_kb_id",
                "top_k": 5,
                "score_threshold": 0.5
            }
        )
        
        return response.json().get("results", [])
    
    def _format_results(self, results: List[Dict], intent: str) -> Dict:
        """格式化检索结果,为回复生成准备"""
        formatted = {
            "found": len(results) > 0,
            "content": results,
            "intent": intent,
        }
        return formatted
​
# ===== 6. 回复生成器 =====
​
class ReplyGenerator:
    """生成标准化英文回复"""
    
    TEMPLATES = {
        "product_spec": """
Dear {customer_name},
​
Thank you for your inquiry about {product_name}.
​
Here are the specifications:
​
{specifications}
​
Please let me know if you need any further information.
​
Best regards,
{company_name} Team
        """,
        "price": """
Dear {customer_name},
​
Thank you for your interest in {product_name}.
​
The price for {product_name} is as follows:
{price_info}
​
Please note:
- The above price is {price_terms}
- MOQ: {moq}
​
For bulk orders, please contact us for a customized quote.
​
Best regards,
{company_name} Team
        """,
        "lead_time": """
Dear {customer_name},
​
Thank you for your inquiry.
​
The estimated lead time for {product_name}:
​
{lead_time_info}
​
Please note that lead times may vary during peak seasons.
​
Best regards,
{company_name} Team
        """,
        "general": """
Dear {customer_name},
​
Thank you for your inquiry about {product_name}.
​
{answer_content}
​
If you have any further questions, please don't hesitate to reach out.
​
Best regards,
{company_name} Team
        """
    }
    
    def generate(self, inquiry: Inquiry, knowledge: Dict) -> str:
        intent = knowledge.get("intent", "general")
        template = self.TEMPLATES.get(intent, self.TEMPLATES["general"])
        
        # 用大模型生成具体回复内容
        answer_content = self._llm_generate(inquiry, knowledge)
        
        # 填入模板
        reply = template.format(
            customer_name=self._extract_name(inquiry.body),
            product_name=inquiry.product or "our products",
            company_name="Your Company",
            specifications=answer_content.get("specifications", ""),
            price_info=answer_content.get("price", ""),
            price_terms="FOB Shanghai",
            moq=answer_content.get("moq", "100 units"),
            lead_time_info=answer_content.get("lead_time", ""),
            answer_content=answer_content.get("summary", ""),
        )
        
        return reply.strip()
    
    def _llm_generate(self, inquiry: Inquiry, knowledge: Dict) -> Dict:
        """调用大模型生成回复的具体内容"""
        # 实际实现:调用 Ollama API
        prompt = f"""
        根据知识库信息,生成邮件回复所需的关键信息。
        
        客户询问:{inquiry.body}
        知识库检索结果:{knowledge.get('content', [])}
        
        请提取并整理:
        1. 产品规格参数
        2. 价格信息
        3. 交期信息
        4. 回复概述
        """
        
        # 实际调用 Ollama API
        import requests
        response = requests.post(
            "http://localhost:11434/api/generate",
            json={
                "model": "qwen2.5:7b",
                "prompt": prompt,
                "stream": False
            }
        )
        
        # 解析结果(简化处理)
        return {"summary": response.json()["response"]}
​
# ===== 7. Agent 主控制器 =====
​
class CustomerServiceAgent:
    """智能客服 Agent 主控器"""
    
    def __init__(self):
        self.classifier = EmailClassifier()
        self.intent_recognizer = IntentRecognizer()
        self.product_extractor = ProductExtractor()
        self.kb_searcher = KnowledgeBaseSearcher()
        self.reply_generator = ReplyGenerator()
        self.product_list = [
            "A-300", "A-310", "B-200", "C-100", "X-5000"
        ]  # 从知识库动态加载
        
        # 统计指标
        self.stats = {
            "total": 0,
            "auto_handled": 0,
            "escalated": 0,
            "avg_confidence": 0.0,
        }
    
    def process(self, email: Dict) -> Dict:
        """处理一封邮件,返回处理结果"""
        self.stats["total"] += 1
        
        # Step 1: 构建询价对象
        inquiry = Inquiry(
            id=email["id"],
            from_email=email["from"],
            subject=email["subject"],
            body=email["body"],
        )
        
        # Step 2: 邮件分类
        category = self.classifier.classify(inquiry)
        if category == "complex":
            self.stats["escalated"] += 1
            return {
                "status": "escalated",
                "inquiry_id": inquiry.id,
                "message": "复杂询价,已通知人工处理"
            }
        
        # Step 3: 意图识别
        intents = self.intent_recognizer.recognize(inquiry)
        
        # Step 4: 产品提取
        product = self.product_extractor.extract(
            inquiry.body + " " + inquiry.subject,
            self.product_list
        )
        inquiry.product = product
        
        # Step 5: 知识库检索
        primary_intent = intents[0] if intents else "general_inquiry"
        knowledge = self.kb_searcher.search_product(
            product or "general", 
            primary_intent
        )
        
        # Step 6: 生成回复
        reply = self.reply_generator.generate(inquiry, knowledge)
        
        # Step 7: 信心度检查
        if inquiry.confidence < 0.6:
            # 信心不足,标记为人工审核
            return {
                "status": "pending_review",
                "inquiry_id": inquiry.id,
                "auto_reply": reply,
                "confidence": inquiry.confidence,
                "message": "信心度不足,建议人工审核后发送"
            }
        
        self.stats["auto_handled"] += 1
        return {
            "status": "auto_handled",
            "inquiry_id": inquiry.id,
            "reply": reply,
            "confidence": inquiry.confidence,
            "intent": inquiry.intent,
            "product": inquiry.product,
        }
​
​
# ===== 8. 使用示例 =====
​
if __name__ == "__main__":
    agent = CustomerServiceAgent()
    
    # 模拟一封询价邮件
    test_email = {
        "id": "email-001",
        "from": "john@example.com",
        "subject": "Inquiry about A-300 price and delivery",
        "body": """
        Dear Sir/Madam,
        
        I'm interested in your A-300 model.
        Could you please provide the price for 500 units?
        Also, what is the delivery time?
        
        Best regards,
        John
        """
    }
    
    result = agent.process(test_email)
    
    print(f"处理结果: {result['status']}")
    print(f"信心度: {result.get('confidence', 'N/A')}")
    print(f"识别意图: {result.get('intent', 'N/A')}")
    print(f"识别产品: {result.get('product', 'N/A')}")
    if 'reply' in result:
        print(f"\n自动回复:\n{result['reply']}")
    
    print(f"\n统计: {agent.stats}")

四、场景二:数据查询 Agent

"""
自然语言查询数据库 Agent
用户:上个月销售额最高的5个产品是什么?
Agent:生成SQL → 执行查询 → 格式化结果 → 回复
"""
import sqlite3
​
class DataQueryAgent:
    """自然语言 → SQL → 结果,让不懂SQL的人也能量化分析"""
    
    def __init__(self, db_path: str):
        self.conn = sqlite3.connect(db_path)
        self.schema = self._get_schema()
    
    def _get_schema(self) -> str:
        """获取数据库表结构(用于Prompt)"""
        cursor = self.conn.cursor()
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
        tables = cursor.fetchall()
        
        schema_desc = []
        for (table_name,) in tables:
            cursor.execute(f"PRAGMA table_info({table_name})")
            columns = cursor.fetchall()
            schema_desc.append(f"表 {table_name}: {', '.join(c[1] for c in columns)}")
        
        return "\n".join(schema_desc)
    
    def query(self, question: str) -> str:
        """自然语言查询入口"""
        # Step 1: NL2SQL
        sql = self._nl2sql(question)
        
        # Step 2: 安全校验
        if not self._validate_sql(sql):
            return "查询被拒绝:检测到不安全的SQL操作"
        
        # Step 3: 执行查询
        try:
            cursor = self.conn.cursor()
            cursor.execute(sql)
            results = cursor.fetchall()
            columns = [desc[0] for desc in cursor.description]
        except Exception as e:
            return f"查询执行失败: {str(e)}\n生成的SQL: {sql}"
        
        # Step 4: 格式化结果
        return self._format_results(question, sql, columns, results)
    
    def _nl2sql(self, question: str) -> str:
        """用大模型将自然语言转为SQL"""
        prompt = f"""
        数据库结构:
        {self.schema}
        
        用户问题:{question}
        
        请生成对应的SQL查询语句。要求:
        1. 只返回SQL语句,不要任何解释
        2. 只生成SELECT语句
        3. 如果问题涉及聚合,使用GROUP BY
        4. 如果问题涉及排序,使用ORDER BY
        5. 默认LIMIT 20
        
        SQL:
        """
        # 调用 Ollama API
        import requests
        response = requests.post(
            "http://localhost:11434/api/generate",
            json={
                "model": "qwen2.5:7b",
                "prompt": prompt,
                "stream": False
            }
        )
        
        sql = response.json()["response"].strip()
        # 去掉可能的 markdown 代码块标记
        sql = sql.replace("```sql", "").replace("```", "").strip()
        return sql
    
    def _validate_sql(self, sql: str) -> bool:
        """安全校验:禁止危险操作"""
        sql_upper = sql.upper().strip()
        forbidden = ["DROP", "DELETE", "INSERT", "UPDATE", "ALTER", "TRUNCATE", "CREATE"]
        return not any(kw in sql_upper for kw in forbidden)
    
    def _format_results(self, question: str, sql: str, 
                        columns: List[str], results: List) -> str:
        """格式化查询结果为可读文本"""
        # 对于聚合查询,用大模型生成自然语言总结
        if len(results) > 5:
            summary_prompt = f"""
            用户问题:{question}
            查询结果列名:{columns}
            查询结果(前5行):{results[:5]}
            
            请用自然语言总结查询结果。
            """
            response = requests.post(
                "http://localhost:11434/api/generate",
                json={
                    "model": "qwen2.5:7b",
                    "prompt": summary_prompt,
                    "stream": False
                }
            )
            return response.json()["response"]
        
        # 小结果集:直接格式化
        output = f"查询结果(共{len(results)}条):\n\n"
        for i, row in enumerate(results, 1):
            output += f"{i}. " + " | ".join(f"{col}={val}" for col, val in zip(columns, row))
            output += "\n"
        return output

五、生产部署检查清单

上线前检查:
​
安全性:
  - [ ] SQL 注入防护
  - [ ] 敏感信息过滤(邮箱/电话/身份证号脱敏)
  - [ ] API 密钥环境变量管理
  - [ ] 操作日志记录
​
可靠性:
  - [ ] 异常捕获与降级策略(LLM 不可用时人工兜底)
  - [ ] 超时控制(单次推理最长30秒)
  - [ ] 重试机制(最多3次)
  - [ ] 置信度阈值(低于0.6的转人工)
​
性能:
  - [ ] 缓存热门问题的答案
  - [ ] 知识库增量更新(无需全量重建)
  - [ ] 并发请求队列管理
​
监控:
  - [ ] 处理量统计(日/周/月)
  - [ ] 自动处理率监控
  - [ ] 平均响应时间
  - [ ] 错误率告警
  - [ ] 用户满意度反馈收集
​
迭代:
  - [ ] 未命中案例定期分析
  - [ ] 人工审核反馈回流
  - [ ] 知识库质量评估
  - [ ] 每周效果报告

六、常见问题与对策

问题 原因 对策
Agent 执行了错误操作 意图识别不准 增加确认步骤,关键操作二次确认
回答与实际不符 知识库信息过时 建立知识库定期审核更新机制
响应时间过长 工具调用链路过长 异步处理+进度通知,减少串行依赖
大模型幻觉 Context 不够充分 增加引用验证,明确"不知道就说不知道"
用户数据被大模型记忆 隐私泄漏风险 本地化部署,敏感数据脱敏后传给模型

七、总结

中小企业开发 AI Agent 的核心原则:

  1. 从单一场景切入 —— 先做智能客服或数据查询,不要一上来就搞"全公司智能化"

  2. 控制工具数量 —— 第一个 Agent 只给 2-3 个工具,等稳定后再扩展

  3. 信心度分级 —— 简单操作自动执行,复杂操作人工审核,永远有退路

  4. 指标驱动迭代 —— 每周看自动处理率、准确率、用户反馈,数据说了算

一个好的 Agent 不是一蹴而就的,是迭代出来的。先用起来,再优化。


原文首发:CSDN · 杰哥AI 标签:#AI智能体 #Agent开发 #企业AI #Python #Dify

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐