Agent与自定义Skill开发实战手册(Python/Java双版本)

前言

本文为可直接落地的Agent工程实战教程,无空泛理论,所有代码可直接复制使用。全程从零搭建Agent基础能力、开发自定义技能、实现多技能协同业务,配套生产环境优化方案,帮助开发者快速掌握商用级Agent项目开发能力。

项目基于Python+LangChain开发,兼容各类主流大模型,代码解耦性高,可直接迁移至个人项目及企业业务系统,同时配套完整Java复刻版本,适配企业微服务生产场景。

一、开发环境与依赖准备

1.1 技术栈选型

核心采用LangChain框架,具备入门简单、生态完善、扩展性强、模型兼容性广的特点,适配新手入门与企业生产落地。配套环境:Python3.9+、python-dotenv、pydantic、tenacity、loguru。

1.2 依赖安装与密钥配置

1. 项目依赖清单(requirements.txt)

python 复制代码
# 核心框架
langchain==0.2.10
langchain-openai==0.1.12
# 环境配置
python-dotenv==1.0.1
# 参数校验
pydantic==2.7.4
# 重试机制
tenacity==8.3.0
# 日志打印
loguru==0.7.2

2. 环境变量配置(.env)

plain 复制代码
# 大模型接口配置
OPENAI_API_KEY=你的大模型密钥
OPENAI_API_BASE=大模型接口地址
MODEL_NAME=gpt-3.5-turbo
# Agent运行配置
AGENT_MAX_STEPS=10
AGENT_TIMEOUT=30

3. 全局配置初始化(config.py

python 复制代码
import os
from dotenv import load_dotenv
from loguru import logger

# 加载本地环境变量
load_dotenv()

# 大模型全局参数
LLM_CONFIG = {
    "api_key": os.getenv("OPENAI_API_KEY"),
    "api_base": os.getenv("OPENAI_API_BASE"),
    "model_name": os.getenv("MODEL_NAME", "gpt-3.5-turbo"),
    "temperature": 0.1,  # 低随机度,保证决策稳定
    "max_tokens": 2048
}

# Agent全局运行参数
AGENT_CONFIG = {
    "max_steps": int(os.getenv("AGENT_MAX_STEPS", 10)),
    "timeout": int(os.getenv("AGENT_TIMEOUT", 30))
}

# 日志持久化配置
logger.add("agent_run.log", rotation="500MB", encoding="utf-8", enqueue=True)
logger.info("全局配置初始化完成")

二、基础Agent从零搭建(Python版)

2.1 LLM客户端封装

基于单例模式封装大模型调用客户端,统一处理请求、自动重试、异常捕获与日志记录,保障Agent调用稳定性。

python 复制代码
from langchain_openai import ChatOpenAI
from loguru import logger
from config import LLM_CONFIG
from tenacity import retry, stop_after_attempt, wait_exponential

class LLMClient:
    _instance = None

    # 全局单例客户端
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._init_client()
        return cls._instance

    def _init_client(self):
        """初始化大模型连接客户端"""
        try:
            self.client = ChatOpenAI(
                api_key=LLM_CONFIG["api_key"],
                base_url=LLM_CONFIG["api_base"],
                model=LLM_CONFIG["model_name"],
                temperature=LLM_CONFIG["temperature"],
                max_tokens=LLM_CONFIG["max_tokens"]
            )
            logger.info("LLM客户端初始化成功")
        except Exception as e:
            logger.error(f"LLM客户端初始化失败:{str(e)}")
            raise e

    @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
    def chat(self, messages: list) -> str:
        """大模型对话调用,自带指数退避重试"""
        try:
            logger.info(f"LLM请求消息:{messages}")
            response = self.client.invoke(messages)
            logger.info(f"LLM响应结果:{response.content}")
            return response.content
        except Exception as e:
            logger.error(f"LLM调用异常:{str(e)}")
            raise e

# 全局单例实例
llm_client = LLMClient()

2.2 长短双记忆体系实现

搭建双层记忆架构,短期记忆留存完整会话上下文,长期记忆通过摘要裁剪Token,适配长对话场景,实现会话持久化。

python 复制代码
from langchain.memory import ConversationBufferMemory, ConversationSummaryMemory
from langchain.memory.file_memory import FileChatMessageHistory
from loguru import logger
import os

class AgentMemory:
    def __init__(self, session_id: str = "default_session"):
        self.session_id = session_id
        self.memory_path = f"./memory/{session_id}.json"
        os.makedirs("./memory", exist_ok=True)

        # 短期记忆:完整上下文,单次会话全程生效
        self.short_memory = ConversationBufferMemory(
            memory_key="chat_history",
            return_messages=True,
            chat_memory=FileChatMessageHistory(file_path=self.memory_path)
        )

        # 长期记忆:摘要记忆,裁剪冗余内容
        self.long_memory = ConversationSummaryMemory(
            llm=None,
            memory_key="summary_history",
            return_messages=True
        )

    def load_short_memory(self):
        """读取完整短期对话记忆"""
        return self.short_memory.load_memory_variables({})

    def load_long_memory(self):
        """读取摘要长期记忆"""
        return self.long_memory.load_memory_variables({})

    def save_memory(self, input_text: str, output_text: str):
        """统一保存对话上下文"""
        self.short_memory.save_context({"input": input_text}, {"output": output_text})
        self.long_memory.save_context({"input": input_text}, {"output": output_text})
        logger.info(f"会话{self.session_id}记忆更新成功")

    def clear_memory(self):
        """清空当前会话所有记忆"""
        self.short_memory.clear()
        self.long_memory.clear()
        logger.info(f"会话{self.session_id}记忆清空成功")

def get_agent_memory(session_id: str = "default_session"):
    return AgentMemory(session_id=session_id)

2.3 ReAct基础Agent搭建

基于ReAct推理模式构建核心Agent,具备需求分析、决策判断、工具调用、结果输出全流程能力,支持技能工具动态插拔注册。

python 复制代码
from langchain.agents import AgentExecutor, create_react_agent
from langchain.prompts import PromptTemplate
from loguru import logger
from config import AGENT_CONFIG
from llm_client import llm_client
from memory import get_agent_memory

# ReAct推理规则提示词
REACT_PROMPT = PromptTemplate(
    input_variables=["tools", "tool_names", "input", "chat_history"],
    template="""你是一个智能Agent,严格遵循ReAct模式完成任务。
可用工具:{tools}
工具名称:{tool_names}
对话历史:{chat_history}
用户任务:{input}

严格按照以下固定格式输出:
1. Thought: 分析用户需求,判断是否需要调用工具
2. Action: 待调用的工具名称
3. Action Input: 工具入参
4. Observation: 工具返回结果
5. Final Answer: 最终结论

最大执行步骤限制:{max_steps}步,超出则终止任务并输出已有结果。
""".format(max_steps=AGENT_CONFIG["max_steps"])
)

class BaseReActAgent:
    def __init__(self, session_id: str = "default_session"):
        self.llm = llm_client.client
        self.memory = get_agent_memory(session_id)
        self.tools = []
        self.agent = None
        self.agent_executor = None
        self._init_agent()

    def register_tools(self, tools: list):
        """批量注册技能工具"""
        self.tools.extend(tools)
        logger.info(f"成功注册{len(tools)}个Agent技能")
        self._init_agent()

    def _init_agent(self):
        """初始化Agent执行器"""
        self.agent = create_react_agent(
            llm=self.llm,
            tools=self.tools,
            prompt=REACT_PROMPT
        )
        self.agent_executor = AgentExecutor(
            agent=self.agent,
            tools=self.tools,
            memory=self.memory.short_memory,
            max_iterations=AGENT_CONFIG["max_steps"],
            timeout=AGENT_CONFIG["timeout"],
            verbose=True,
            handle_parsing_errors=True
        )
        logger.info("ReAct基础Agent初始化完成")

    def run(self, user_input: str) -> dict:
        """执行Agent任务,返回结构化结果"""
        try:
            logger.info(f"开始执行任务:{user_input}")
            result = self.agent_executor.invoke({"input": user_input})
            self.memory.save_memory(user_input, result["output"])
            logger.info(f"任务执行完成:{result['output']}")
            return {
                "success": True,
                "input": user_input,
                "output": result["output"],
                "chat_history": result["chat_history"]
            }
        except Exception as e:
            logger.error(f"任务执行失败:{str(e)}")
            return {
                "success": False,
                "input": user_input,
                "error": str(e)
            }

# 全局基础Agent实例
base_agent = BaseReActAgent()

2.4 任务测试与日志解析

通过单步骤、多步骤测试用例,验证Agent推理与任务执行能力,同时解析核心日志字段,方便开发调试与线上排错。

python 复制代码
from base_agent import base_agent
from loguru import logger

def test_single_step_task():
    """单步骤简单任务测试(纯推理,无工具调用)"""
    logger.info("===== 执行单步骤任务测试 =====")
    res = base_agent.run("简单介绍你自己,说明你是智能办公Agent")
    assert res["success"] is True, "单步骤任务执行失败"
    logger.info("单步骤任务测试完成")

def test_multi_step_task():
    """多步骤复杂推理任务测试"""
    logger.info("===== 执行多步骤任务测试 =====")
    res = base_agent.run("梳理本月办公工作流程:1.统计业务数据 2.生成月度报表 3.总结数据问题")
    assert res["success"] is True, "多步骤任务执行失败"
    logger.info("多步骤任务测试完成")

if __name__ == "__main__":
    test_single_step_task()
    test_multi_step_task()

日志核心字段说明

  • 初始化日志:校验LLM、记忆、Agent执行器加载状态与运行参数

  • Thought日志:记录需求分析、工具调用判断逻辑

  • Action日志:记录工具调用行为与入参

  • Observation日志:记录工具原始执行结果

  • Final Answer日志:记录最终输出结果并持久化记忆

  • 异常日志:自动捕获解析、超时、接口异常,避免任务中断

三、自定义Agent Skill开发规范与实战

3.1 Skill标准化开发规范

统一技能开发标准,保证项目规整、可复用、可上线,核心规范如下:

  1. 命名:小写下划线命名,语义清晰无歧义

  2. 参数:明确类型、必填属性、默认值,强制合法性校验

  3. 异常:全覆盖捕获,区分参数、业务、服务异常

  4. 返回:统一结构化JSON格式,包含状态码、信息、数据

  5. 注释:标注功能、入参、出参、适用场景

  6. 解耦:单一技能对应单一功能,支持独立测试、插拔使用

3.2 轻量函数式Skill开发

适用于简单轻量化场景,无需复杂校验,可快速扩展Agent基础能力。

python 复制代码
from langchain.tools import tool
from loguru import logger

@tool
def data_calculate(express: str) -> str:
    """
    通用数学计算技能
    :param express: 数学运算表达式,支持四则运算
    :return: 运算结果文本
    """
    logger.info(f"执行数学计算,表达式:{express}")
    try:
        result = eval(express)
        return f"计算完成,结果:{result}"
    except Exception as e:
        logger.error(f"计算失败:{str(e)}")
        return f"计算异常:{str(e)}"

@tool
def text_summary(content: str) -> str:
    """
    简易文本摘要技能
    :param content: 待处理长文本
    :return: 精简文本内容
    """
    logger.info(f"执行文本摘要,文本长度:{len(content)}")
    if len(content) < 20:
        return content
    return content[:20] + "..."

# 轻量技能集合
LIGHT_SKILLS = [data_calculate, text_summary]

3.3 企业级标准化Skill开发

基于Pydantic实现强参数校验、异常分级捕获、统一结构化返回,适配生产环境复杂业务场景。

python 复制代码
from langchain.tools import tool
from pydantic import BaseModel, Field, ValidationError
from loguru import logger
from typing import Optional, Dict, Any
import json

# 统一技能返回结构体
class SkillResponse(BaseModel):
    success: bool
    code: int
    message: str
    data: Optional[Dict[str, Any]] = None

# 报表查询参数校验模型
class ReportQueryParams(BaseModel):
    month: str = Field(description="查询月份,格式YYYY-MM", pattern=r"^\d{4}-\d{2}$")
    department: Optional[str] = Field(default="全部门", description="目标查询部门")

@tool
def report_data_query(query_str: str) -> str:
    """
    业务报表数据查询技能
    :param query_str: JSON格式参数,包含month(必填)、department(选填)
    :return: 结构化报表数据JSON
    """
    logger.info(f"执行报表查询,原始参数:{query_str}")
    try:
        # 参数解析与强校验
        params = json.loads(query_str)
        validate_params = ReportQueryParams(**params)

        # 模拟业务数据查询
        mock_data = {
            "month": validate_params.month,
            "department": validate_params.department,
            "order_count": 1280,
            "turnover": 586200,
            "complete_rate": 96.8
        }

        # 统一返回格式
        res = SkillResponse(
            success=True,
            code=200,
            message="报表数据查询成功",
            data=mock_data
        )
        return res.model_dump_json()

    except ValidationError as e:
        logger.error(f"参数校验失败:{str(e)}")
        res = SkillResponse(success=False, code=400, message=f"参数格式错误:{str(e)}")
        return res.model_dump_json()
    except Exception as e:
        logger.error(f"报表查询异常:{str(e)}")
        res = SkillResponse(success=False, code=500, message=f"服务执行异常:{str(e)}")
        return res.model_dump_json()

# 企业级技能集合
ENTERPRISE_SKILLS = [report_data_query]

3.4 技能统一注册管理

统一全局技能注册入口,批量加载所有自定义技能,支持动态更新、启停,实现技能插拔式管理。

python 复制代码
from base_agent import base_agent
from skills.light_skill import LIGHT_SKILLS
from skills.enterprise_skill import ENTERPRISE_SKILLS
from loguru import logger

# 全局所有技能集合
ALL_SKILLS = LIGHT_SKILLS + ENTERPRISE_SKILLS

def register_all_skills():
    """批量注册全部技能到Agent"""
    base_agent.register_tools(ALL_SKILLS)
    logger.info(f"技能注册完成,总计{len(ALL_SKILLS)}个可用技能")

if __name__ == "__main__":
    register_all_skills()
    # 联合测试:计算+报表查询
    result = base_agent.run("计算 125*8+360,并查询2025-10月全部门报表数据")
    print("任务执行结果:", result["output"])

四、多Skill协同复杂业务实战

基于现有计算、文本摘要、报表查询技能,实现月度报表自动化生成完整业务场景,串联多技能分步完成复杂任务。

python 复制代码
from skill_register import register_all_skills
from base_agent import base_agent
from loguru import logger

def auto_report_generate():
    """
    多技能协同实战:自动化报表生成
    任务流程:1.查询月度报表数据 2.计算订单环比增长率 3.生成报表总结
    """
    logger.info("===== 开始执行自动化报表任务 =====")
    register_all_skills()

    # 分步复杂任务指令
    task = """
    按步骤完成报表自动化处理:
    1. 查询2025-10月全部门业务报表数据
    2. 基于本月订单量,对比上月1000单,计算环比增长率,公式:(本月-上月)/上月*100%
    3. 整合数据与计算结果,生成简洁的报表总结
    """

    result = base_agent.run(task)
    if result["success"]:
        logger.info("自动化报表任务执行成功")
    else:
        logger.error("自动化报表任务执行失败")
    return result

if __name__ == "__main__":
    res = auto_report_generate()
    print("【最终自动化报表结果】\n", res["output"])

任务执行逻辑

  1. Agent通过ReAct推理自动拆解复杂任务,有序调度对应技能

  2. 调用报表查询技能,获取结构化业务数据

  3. 调用数学计算技能,完成环比指标运算

  4. 调用文本摘要技能,整合数据生成最终总结

  5. 会话记忆自动留存,支持后续迭代追问

五、Agent生产级优化方案

针对线上环境Token浪费、稳定性差、权限失控、参数混乱等问题,整合记忆裁剪、重试熔断、权限隔离、参数约束能力,适配生产环境落地。

python 复制代码
from langchain.text_splitter import TokenTextSplitter
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
from pydantic import BaseModel, Field
from loguru import logger
from typing import List
from base_agent import BaseReActAgent
from skill_register import ALL_SKILLS

# 1. Token优化与记忆裁剪
class MemoryOptimizer:
    def __init__(self, max_token: int = 1000):
        self.max_token = max_token
        self.splitter = TokenTextSplitter(chunk_size=max_token, chunk_overlap=100)

    def crop_chat_history(self, chat_history: List) -> List:
        """自动裁剪超长会话历史,控制Token消耗"""
        if not chat_history:
            return chat_history
        history_text = "\n".join([str(msg) for msg in chat_history])
        if len(self.splitter.split_text(history_text)) > 1:
            logger.warning("会话历史超长,执行Token裁剪优化")
            return [self.splitter.split_text(history_text)[0]]
        return chat_history

# 2. 生产参数强约束
class ProductionAgentParams(BaseModel):
    max_steps: int = Field(ge=3, le=20, description="任务最大执行步骤")
    timeout: int = Field(ge=10, le=60, description="任务超时时间(秒)")
    temperature: float = Field(ge=0.0, le=0.5, description="模型随机性,生产环境严控低值")

# 3. 技能权限隔离
class SkillPermission:
    NORMAL_USER_SKILLS = ["data_calculate", "text_summary"]
    ADMIN_SKILLS = ["report_data_query"]

    @classmethod
    def filter_skills(cls, user_role: str) -> List:
        """根据用户角色过滤可调用技能"""
        if user_role == "admin":
            return ALL_SKILLS
        elif user_role == "normal":
            return [s for s in ALL_SKILLS if s.name in cls.NORMAL_USER_SKILLS]
        return []

# 4. 生产级Agent主体
class ProductionAgent(BaseReActAgent):
    def __init__(self, session_id: str = "prod_session", user_role: str = "normal"):
        super().__init__(session_id)
        self.user_role = user_role
        self.memory_optimizer = MemoryOptimizer()
        self.prod_params = ProductionAgentParams(max_steps=10, timeout=30, temperature=0.1)

    @retry(
        stop=stop_after_attempt(2),
        wait=wait_exponential(multiplier=1, min=1, max=5),
        retry=retry_if_exception_type((ConnectionError, TimeoutError))
    )
    def run_prod(self, user_input: str) -> dict:
        """生产环境任务执行入口"""
        try:
            # 权限过滤
            use_skills = SkillPermission.filter_skills(self.user_role)
            self.register_tools(use_skills)

            # 超长记忆裁剪优化
            chat_history = self.memory.load_short_memory()["chat_history"]
            crop_history = self.memory_optimizer.crop_chat_history(chat_history)
            self.memory.short_memory.chat_memory.messages = crop_history

            # 执行任务并持久化记忆
            result = self.agent_executor.invoke({"input": user_input})
            self.memory.save_memory(user_input, result["output"])

            return {
                "success": True,
                "data": result["output"],
                "msg": "执行成功"
            }
        except Exception as e:
            logger.error(f"生产Agent任务执行失败:{str(e)}")
            # 异常熔断,避免任务卡死
            return {
                "success": False,
                "data": None,
                "msg": f"服务执行失败:{str(e)}"
            }

# 全局生产级Agent实例
prod_agent = ProductionAgent()

六、常见问题与代码级解决方案

6.1 Agent无限循环调用技能

原因 :无最大步骤限制、提示词无终止约束、工具返回结果语义模糊。解决方案:代码强制最大迭代步骤,优化终止逻辑,工具统一结构化返回,本文框架已内置该防护机制。

6.2 上下文过长、Token超限报错

原因 :长对话上下文持续累积,无裁剪逻辑。解决方案:通过Token粒度裁剪工具自动精简会话历史,平衡上下文完整性与推理性能。

6.3 Skill参数解析失败

原因 :模型输出参数格式混乱,无强制校验。解决方案:基于Pydantic强校验参数,统一JSON入参格式,自动捕获参数异常并标准化报错。

6.4 网络波动、接口超时任务失败

原因 :网络与模型接口不稳定,无容错重试机制。解决方案:基于tenacity实现指数退避重试,仅针对网络、超时异常重试,规避无效重试。

6.5 多技能协同调度混乱

原因 :任务指令无分步约束,Agent推理逻辑混乱。解决方案:结构化分步任务指令,搭配标准化工具返回,辅助模型有序调度技能。

6.6 敏感技能无权限管控

原因 :所有技能全局开放,存在数据安全风险。解决方案:实现角色权限隔离,按用户角色动态过滤可调用技能。

七、MD轻量化技能开发模式

拓展MD技能开发模式,无需编写Python代码,仅编辑MD文档即可注册使用技能,与原有Python技能双向兼容,适配快速原型开发场景。

7.1 双技能模式适配说明

项目支持两种技能开发模式,可混合使用、自由选型:

  • Python技能:适配复杂业务、接口请求、数据库操作,性能强、可控性高,用于核心生产功能。

  • MD技能:适配轻量化规则类技能、快速原型开发,无需编码,对齐Claude Code使用习惯。

7.2 项目完整目录规范

plain 复制代码
agent-project/
├── config.py                # 全局配置
├── llm_client.py            # LLM单例客户端
├── memory.py                # 双记忆体系
├── base_agent.py            # 基础ReAct Agent
├── production_optimize.py   # 生产级优化能力
├── skill_register.py        # 全局技能注册入口
├── md_skill_parser.py       # MD技能自动解析引擎
├── main.py                  # 项目统一启动入口
├── requirements.txt         # 依赖清单
├── .env                     # 环境变量
├── memory/                  # 会话记忆存储目录
├── skills/                  # PY技能代码目录
│   ├── light_skill.py
│   └── enterprise_skill.py
└── skill_md/                # MD技能文档目录
    ├── skill_calculate.md
    ├── skill_summary.md
    └── skill_report_query.md

7.3 MD技能标准化模板

统一MD技能文档格式,引擎可自动解析,所有新增MD技能遵循该模板。

markdown 复制代码
# 技能名称:通用数学计算
## 一、技能简介
用于执行常规数学四则运算,支持复杂表达式计算,快速完成数值运算任务。

## 二、适用场景
用户需要数学计算、数值求解、公式运算等轻量化场景。

## 三、入参说明
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| express | string | 是 | 标准数学运算表达式 | 125*8+360、(100-20)/2 |

## 四、出参说明
返回结构化文本,包含运算结果或异常提示。

## 五、调用示例
输入:计算 125*8+360
输出:计算完成,结果:1360

## 六、约束规则
1. 仅执行数学运算表达式,不支持变量、函数嵌套
2. 表达式格式非法时,直接返回异常提示
3. 无权限限制,所有用户均可调用

7.4 MD技能自动解析引擎

自研MD解析引擎,支持参数提取、规则解析、动态工具生成、异常捕获,实现MD文档自动转Agent可用技能。

python 复制代码
import os
import re
import json
from typing import List, Dict, Optional
from langchain.tools import tool
from loguru import logger
from pydantic import BaseModel, Field

# MD技能目录路径
MD_SKILL_DIR = "./skill_md/"
os.makedirs(MD_SKILL_DIR, exist_ok=True)

# 全局技能缓存、防止热更新残留
GLOBAL_MD_SKILL_CACHE = {}

# 标准化MD技能参数模型
class MdSkillParam(BaseModel):
    name: str
    param_type: str
    required: bool
    desc: str
    example: str

# 标准化MD技能结构体(含版本、启停、权限)
class MdSkillMeta(BaseModel):
    skill_name: str
    skill_desc: str
    usage_example: str
    rules: List[str]
    params: List[MdSkillParam]
    status: str = "enable"
    version: str = "1.0.0"
    tag: str = "public"

class MdSkillParser:
    def __init__(self):
        self.cache: Dict[str, callable] = {}

    def parse_md_table(self, md_content: str) -> List[MdSkillParam]:
        """自动解析MD参数表格"""
        table_pattern = r"\| 参数名 \| 类型 \| 必填 \| 说明 \| 示例 \|\n(\|.+?\|.+?\|.+?\|.+?\|.+?\|\n)+"
        table_match = re.search(table_pattern, md_content, re.S)
        if not table_match:
            return []

        table_rows = table_match.group(0).strip().split("\n")[1:]
        param_list = []
        for row in table_rows:
            row_data = [i.strip() for i in row.split("|")[1:-1]]
            if len(row_data) != 5:
                continue
            name, param_type, required, desc, example = row_data
            param_list.append(MdSkillParam(
                name=name,
                param_type=param_type,
                required=True if required == "是" else False,
                desc=desc,
                example=example
            ))
        return param_list

    def parse_skill_rules(self, md_content: str) -> List[str]:
        """解析技能约束规则"""
        rule_pattern = r"## 六、约束规则\s+(.+?)(?=##|$)"
        rule_match = re.search(rule_pattern, md_content, re.S)
        if not rule_match:
            return []
        rule_text = rule_match.group(1).strip()
        return [r.strip() for r in rule_text.split("\n") if r.strip()]

    def parse_usage_example(self, md_content: str) -> str:
        """解析技能调用示例"""
        example_pattern = r"## 五、调用示例\s+输入:(.+?)\n输出:(.+?)(?=##|$)"
        example_match = re.search(example_pattern, md_content, re.S)
        if example_match:
            return f"输入:{example_match.group(1).strip()},输出:{example_match.group(2).strip()}"
        return ""

    def parse_header_meta(self, md_content: str) -> Dict:
        """解析头部版本、状态、权限元数据"""
        header_pattern = r"---\s+status:\s*(.+?)\s+version:\s*(.+?)\s+tag:\s*(.+?)\s+---"
        header_match = re.search(header_pattern, md_content, re.S)
        if header_match:
            return {
                "status": header_match.group(1).strip(),
                "version": header_match.group(2).strip(),
                "tag": header_match.group(3).strip()
            }
        return {}

    def extract_full_skill_meta(self, md_content: str) -> Optional[MdSkillMeta]:
        """完整解析MD技能元数据"""
        name_match = re.search(r"技能名称:(.+)", md_content)
        desc_match = re.search(r"## 一、技能简介\s+(.+?)(?=##|$)", md_content, re.S)
        if not name_match or not desc_match:
            return None
        header_meta = self.parse_header_meta(md_content)

        return MdSkillMeta(
            skill_name=name_match.group(1).strip(),
            skill_desc=desc_match.group(1).strip(),
            usage_example=self.parse_usage_example(md_content),
            rules=self.parse_skill_rules(md_content),
            params=self.parse_md_table(md_content),
            status=header_meta.get("status", "enable"),
            version=header_meta.get("version", "1.0.0"),
            tag=header_meta.get("tag", "public")
        )

    def create_standard_dynamic_tool(self, meta: MdSkillMeta):
        """根据MD元数据生成标准化LangChain工具"""
        tool_name = meta.skill_name.replace(" ", "_")

        @tool(tool_name, description=meta.skill_desc)
        def standard_md_tool(input_text: str) -> str:
            """MD自动生成技能,自带参数校验、规则约束、异常捕获"""
            try:
                # 技能启停校验
                if meta.status == "disable":
                    return f"【技能禁用】{meta.skill_name}当前已停用"

                # 必填参数预校验
                required_params = [p.name for p in meta.params if p.required]
                for p_info in meta.params:
                    if p_info.required and p_info.name not in input_text:
                        return f"【参数缺失】{p_info.name}为必填参数,参考示例:{p_info.example}"

                # 技能逻辑分发
                if "数学计算" in meta.skill_name:
                    result = eval(input_text.strip())
                    return f"【{meta.skill_name}】执行成功,结果:{result}"
                elif "文本摘要" in meta.skill_name:
                    content = input_text.strip()
                    summary = content[:20] + "..." if len(content) > 20 else content
                    return f"【{meta.skill_name}】执行成功,摘要结果:{summary}"
                elif "报表查询" in meta.skill_name:
                    return json.dumps({
                        "code":200,
                        "msg":"MD技能报表查询成功",
                        "data":{"input":input_text}
                    },ensure_ascii=False)
                else:
                    return f"【{meta.skill_name}】执行完成,入参:{input_text}"

            except Exception as e:
                logger.error(f"MD技能【{meta.skill_name}】执行异常:{str(e)}")
                return f"【技能执行失败】异常信息:{str(e)}"

        return standard_md_tool

    def load_all_md_skills(self) -> List:
        """批量加载、去重、缓存所有MD技能"""
        global GLOBAL_MD_SKILL_CACHE
        self.cache.clear()
        md_files = [f for f in os.listdir(MD_SKILL_DIR) if f.endswith(".md")]
        tools = []

        for file in md_files:
            file_path = os.path.join(MD_SKILL_DIR, file)
            with open(file_path, "r", encoding="utf-8") as f:
                content = f.read()
            skill_meta = self.extract_full_skill_meta(content)
            if not skill_meta:
                logger.warning(f"跳过非法MD技能文件:{file}")
                continue
            tool = self.create_standard_dynamic_tool(skill_meta)
            tools.append(tool)
            GLOBAL_MD_SKILL_CACHE[skill_meta.skill_name] = tool
            logger.info(f"✅ 加载MD技能成功:{skill_meta.skill_name}")
        return tools

# 全局解析器实例
md_skill_parser = MdSkillParser()

7.5 双模式技能统一注册与冲突处理

定义技能优先级:Python技能优先级高于MD技能,同名技能自动覆盖,实现无冲突融合,支持MD技能热更新。

python 复制代码
from base_agent import base_agent
from skills.light_skill import LIGHT_SKILLS
from skills.enterprise_skill import ENTERPRISE_SKILLS
from md_skill_parser import md_skill_parser
from loguru import logger

# 技能优先级:PY优先,MD兜底
PY_SKILLS = LIGHT_SKILLS + ENTERPRISE_SKILLS
MD_SKILLS = md_skill_parser.load_all_md_skills()

# 技能去重合并
def merge_skill_unique(py_skills, md_skills):
    py_name_set = [s.name for s in py_skills]
    filter_md = [s for s in md_skills if s.name not in py_name_set]
    return py_skills + filter_md

# 全局唯一无重复技能集合
ALL_SKILLS = merge_skill_unique(PY_SKILLS, MD_SKILLS)

def register_all_skills():
    """批量注册全部PY+MD技能,自动去重优先级覆盖"""
    base_agent.register_tools(ALL_SKILLS)
    logger.info(f"技能注册完成|PY技能:{len(PY_SKILLS)}个,MD技能:{len(MD_SKILLS)}个,去重后总计{len(ALL_SKILLS)}个")

def hot_update_md_skills():
    """MD技能热更新,清理缓存、重新合并技能"""
    global ALL_SKILLS, MD_SKILLS
    MD_SKILLS = md_skill_parser.load_all_md_skills()
    ALL_SKILLS = merge_skill_unique(PY_SKILLS, MD_SKILLS)
    base_agent.register_tools(ALL_SKILLS)
    logger.info("✅ MD技能热更新完成,无缓存残留、无技能冲突")
    return ALL_SKILLS

if __name__ == "__main__":
    register_all_skills()
    # MD技能测试
    res = base_agent.run("计算 99*99+100")
    print("MD技能执行结果:", res["output"])

7.6 成品MD技能文件(直接复用)

1. 通用数学计算(skill_md/skill_calculate.md)

markdown 复制代码
---
status: enable
version: 1.0.0
tag: public
---
# 技能名称:通用数学计算
## 一、技能简介
用于执行常规数学四则运算,支持复杂表达式计算,快速完成数值运算任务。

## 二、适用场景
用户需要数学计算、数值求解、公式运算等轻量化场景。

## 三、入参说明
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| express | string | 是 | 标准数学运算表达式 | 125*8+360、(100-20)/2 |

## 四、出参说明
返回结构化文本,包含运算结果或异常提示。

## 五、调用示例
输入:计算 125*8+360
输出:计算完成,结果:1360

## 六、约束规则
1. 仅执行数学运算表达式,不支持变量、函数嵌套
2. 表达式格式非法时,直接返回异常提示
3. 无权限限制,所有用户均可调用

2. 简易文本摘要(skill_md/skill_summary.md)

markdown 复制代码
---
status: enable
version: 1.0.0
tag: public
---
# 技能名称:简易文本摘要
## 一、技能简介
对长文本进行快速精简、截断汇总,快速提炼核心内容。

## 二、适用场景
用户需要文本总结、长文本精简、内容提炼场景。

## 三、入参说明
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| content | string | 是 | 需要精简的原始长文本 | 今天天气很好适合外出办公 |

## 四、出参说明
返回精简后的文本摘要内容。

## 五、调用示例
输入:总结这段文字:今天完成了Agent双模式技能开发,实现了纯MD快速开发能力
输出:今天完成了Agent双模式技能开发,实现了纯MD快速开发能力...

## 六、约束规则
1. 短文本(20字以内)直接原样返回
2. 长文本自动截断保留前20字并补充省略号
3. 无权限限制,所有用户均可调用

3. 业务报表数据查询(skill_md/skill_report_query.md)

markdown 复制代码
---
status: enable
version: 1.0.0
tag: admin
---
# 技能名称:业务报表数据查询
## 一、技能简介
用于查询企业月度业务报表数据,支持指定月份、指定部门数据检索。

## 二、适用场景
用户需要月度数据统计、业务报表查询、部门数据核对场景。

## 三、入参说明
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| query_text | string | 是 | 查询指令,包含月份与部门 | 查询2025-10月全部门报表 |

## 四、出参说明
返回结构化JSON报表数据,包含订单量、营业额、完成率等指标。

## 五、调用示例
输入:查询2025-10月全部门报表
输出:结构化报表数据

## 六、约束规则
1. 月份必须为YYYY-MM标准格式
2. 无非法参数、无特殊字符
3. 属于敏感业务技能,仅管理员可调用

7.7 MD技能统一异常规范

对齐Python技能错误码体系,统一异常分级与返回格式:

  • 200:技能执行成功

  • 400:参数非法/缺失/格式错误

  • 403:权限不足,禁止调用

  • 500:技能内部执行异常

7.8 项目统一启动入口

全局统一启动入口,整合双模式技能、生产Agent、日志、权限能力,支持一键启动项目。

python 复制代码
from loguru import logger
from skill_register import register_all_skills, hot_update_md_skills
from production_optimize import prod_agent

def init_project():
    """项目全局初始化入口"""
    logger.info("========== Agent项目全局启动初始化 ==========")
    # 注册所有PY/MD技能
    register_all_skills()
    # 热更新MD技能缓存
    hot_update_md_skills()
    logger.info("项目初始化完成,双模式技能已全部加载,生产Agent就绪")

def run_prod_task(user_input: str, user_role: str = "normal"):
    """统一生产任务执行入口"""
    prod_agent.user_role = user_role
    result = prod_agent.run_prod(user_input)
    return result

if __name__ == "__main__":
    # 项目初始化
    init_project()

    # 实战测试:多技能协同任务
    test_task = "查询2025-10月全部门报表数据,根据订单量1280、上月1000单,计算环比增长率并生成简短报表总结"
    res = run_prod_task(test_task, user_role="admin")

    # 输出最终结果
    print("\n===== 生产环境任务执行结果 =====")
    print(res["data"])

八、项目验收与整体总结

8.1 项目标准启动流程

  1. 安装依赖:执行 pip install -r requirements.txt

  2. 环境配置:编辑.env文件,填入大模型密钥、接口地址、模型名称

  3. 目录创建:新建memory、skill_md空文件夹

  4. 技能部署:将三份MD技能文件放入skill_md目录

  5. 项目启动:运行 python main.py 完成初始化与功能测试

8.2 全功能验收清单

  • ✅ LLM客户端正常连接,重试、日志能力生效

  • ✅ 双记忆体系正常持久化会话

  • ✅ ReAct Agent可正常推理、拆解任务、调用工具

  • ✅ Python轻量、企业级技能正常注册与调用

  • ✅ MD技能解析引擎正常加载、无冲突、支持热更新

  • ✅ 双模式技能优先级生效,同名Python技能自动覆盖MD技能

  • ✅ 多技能协同任务可自动拆解、分步执行、输出完整结果

  • ✅ 生产级能力生效:Token裁剪、异常重试、角色权限隔离

  • ✅ 日志持久化、异常捕获机制正常运行,任务无卡死、无崩溃

  • ✅ 项目一键启动,初始化流程完整无报错

8.3 项目整体总结

本项目从零搭建可生产落地的ReAct智能Agent,打通基础架构、自定义技能开发、多技能协同、生产优化、轻量化MD技能拓展全链路,解决Agent开发常见的循环调用、参数报错、Token超限、权限失控、任务卡死等核心问题。

项目采用分层解耦架构,核心框架与业务技能完全隔离,支持Python、MD双技能开发模式:Python适配复杂生产业务,MD适配快速迭代场景,兼顾开发效率与系统稳定性。所有代码可直接运行、二次开发、业务迁移,适配个人学习、原型开发、企业落地等多场景。

整套方案集成生产环境必备的容错、优化、权限、日志、热更新能力,是一套轻量化、高可用、易拓展的Agent工程通用模板,可快速复用至各类AI自动化、数据处理、智能办公场景。

九、Java版Agent与Skill极简复刻(企业生产适配)

前文Python版本适合快速原型开发与轻量化落地,为适配企业微服务、高并发生产、Java技术栈业务系统,本章1:1复刻整套Agent架构与Skill能力,实现架构对齐、能力等价、无缝迁移。Java版本基于Spring Boot框架开发,贴合企业主流开发规范,支持容器化部署、分布式会话、高并发请求处理,完全对标前文Python版的基础Agent能力、双记忆机制、自定义技能体系、生产级优化特性,满足企业正式环境上线标准。

9.1 Java版技术栈选型

整体技术栈适配企业微服务生态,兼顾稳定性、扩展性与高性能,核心依赖如下:Spring Boot 2.7.x、Spring AI、Mybatis-Plus、Redis、Hutool工具包、Guava重试组件、SLF4J日志框架。基于Spring AI实现大模型统一调用,完美兼容OpenAI、通义千问、文心一言等主流大模型,与Python版模型调用逻辑保持一致,降低跨版本迁移成本。

9.2 核心配置文件复刻

application.yml 全局配置

yaml 复制代码
# 服务配置
server:
  port: 8080
  servlet:
    context-path: /agent

# 大模型配置(与Python版参数对齐)
spring:
  ai:
    openai:
      api-key: 你的大模型密钥
      base-url: 大模型接口地址
      model: gpt-3.5-turbo
      temperature: 0.1
      max-tokens: 2048

# Agent运行配置
agent:
  max-steps: 10
  timeout: 30

# 日志配置
logging:
  level:
    com.agent: INFO
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

9.3 LLM客户端Java封装(单例模式)

对标Python单例客户端设计,基于Spring容器托管+Guava重试机制,统一封装大模型请求、异常捕获、日志记录,保障高并发场景下的调用稳定性。

java 复制代码
package com.agent.client;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.stereotype.Component;
import com.google.common.base.Retryer;
import com.google.common.util.concurrent.RateLimiter;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

@Slf4j
@Component
public class LlmClient {

    @Resource
    private OpenAiChatClient openAiChatClient;

    // 限流控制,适配高并发
    private final RateLimiter rateLimiter = RateLimiter.create(10.0);

    // 重试机制:最多重试3次,指数退避策略
    private final Retryer<Void> retryer = RetryerBuilder.<Void>newBuilder()
            .retryIfException()
            .withStopStrategy(StopStrategies.stopAfterAttempt(3))
            .withWaitStrategy(WaitStrategies.exponentialWait(1000, 10000))
            .build();

    @PostConstruct
    public void init() {
        log.info("Java版LLM客户端初始化完成");
    }

    /**
     * 大模型对话调用,对标Python chat方法
     */
    public String chat(List<String> messages) {
        rateLimiter.acquire();
        try {
            return retryer.call(() -> {
                log.info("LLM请求消息:{}", messages);
                String response = openAiChatClient.call(messages);
                log.info("LLM响应结果:{}", response);
                return response;
            });
        } catch (Exception e) {
            log.error("LLM调用异常:{}", e.getMessage());
            throw new RuntimeException("大模型调用失败", e);
        }
    }
}

9.4 长短双记忆体系Java实现

复刻Python版双层记忆架构,基于Redis实现分布式会话记忆,替代本地文件存储,适配集群部署场景,同时保留短期完整会话、长期摘要裁剪的核心能力。

java 复制代码
package com.agent.memory;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class AgentMemory {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private static final String MEMORY_PREFIX = "agent:memory:";
    private static final Long EXPIRE_TIME = 86400L;

    /**
     * 保存会话上下文
     */
    public void saveMemory(String sessionId, String input, String output) {
        String key = MEMORY_PREFIX + sessionId;
        redisTemplate.opsForList().rightPushAll(key, input, output);
        redisTemplate.expire(key, EXPIRE_TIME, TimeUnit.SECONDS);
        log.info("会话{}记忆更新成功", sessionId);
    }

    /**
     * 读取完整短期记忆
     */
    public List<Object> loadShortMemory(String sessionId) {
        String key = MEMORY_PREFIX + sessionId;
        return redisTemplate.opsForList().range(key, 0, -1);
    }

    /**
     * 清空会话记忆
     */
    public void clearMemory(String sessionId) {
        String key = MEMORY_PREFIX + sessionId;
        redisTemplate.delete(key);
        log.info("会话{}记忆清空成功", sessionId);
    }
}

9.5 ReAct核心Agent Java实现

完全对齐Python版ReAct推理逻辑,固定推理输出格式,支持技能动态注册、步骤限制、超时拦截、异常解析容错,实现同等任务调度能力。

java 复制代码
package com.agent.core;

import com.agent.client.LlmClient;
import com.agent.memory.AgentMemory;
import com.agent.skill.SkillTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class ReActAgent {

    @Resource
    private LlmClient llmClient;

    @Resource
    private AgentMemory agentMemory;

    private final List<SkillTool> toolList = new ArrayList<>();

    /**
     * 批量注册技能工具
     */
    public void registerTools(List<SkillTool> tools) {
        toolList.addAll(tools);
        log.info("成功注册{}个Agent技能", tools.size());
    }

    /**
     * 执行Agent核心任务
     */
    public AgentResult run(String sessionId, String userInput) {
        try {
            log.info("开始执行任务:{}", userInput);
            // 读取历史会话
            List<Object> history = agentMemory.loadShortMemory(sessionId);
            // 拼接ReAct提示词并调用大模型
            String prompt = buildReActPrompt(userInput, history);
            String result = llmClient.chat(List.of(prompt));
            // 持久化会话
            agentMemory.saveMemory(sessionId, userInput, result);
            log.info("任务执行完成:{}", result);
            return AgentResult.success(userInput, result, history);
        } catch (Exception e) {
            log.error("任务执行失败:{}", e.getMessage());
            return AgentResult.fail(userInput, e.getMessage());
        }
    }

    /**
     * 构建ReAct标准提示词
     */
    private String buildReActPrompt(String input, List<Object> history) {
        return "你是一个智能Agent,严格遵循ReAct模式完成任务。\n" +
                "对话历史:" + history + "\n" +
                "用户任务:" + input + "\n" +
                "严格按照以下固定格式输出:\n" +
                "1. Thought: 分析用户需求,判断是否需要调用工具\n" +
                "2. Action: 待调用的工具名称\n" +
                "3. Action Input: 工具入参\n" +
                "4. Observation: 工具返回结果\n" +
                "5. Final Answer: 最终结论\n" +
                "最大执行步骤限制:10步,超出则终止任务并输出已有结果。";
    }
}

9.6 自定义Skill Java标准化开发

统一Java技能开发接口规范,对标Python技能体系,区分轻量技能与企业级技能,实现参数校验、结构化返回、异常分级处理。

1. 技能统一接口

java 复制代码
package com.agent.skill;

import com.agent.result.SkillResponse;

public interface SkillTool {
    /**
     * 获取技能名称
     */
    String getSkillName();

    /**
     * 获取技能描述
     */
    String getSkillDesc();

    /**
     * 执行技能逻辑
     */
    SkillResponse execute(String param);
}

2. 通用数学计算技能实现

java 复制代码
package com.agent.skill.impl;

import com.agent.result.SkillResponse;
import com.agent.skill.SkillTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class CalculateSkill implements SkillTool {

    @Override
    public String getSkillName() {
        return "data_calculate";
    }

    @Override
    public String getSkillDesc() {
        return "通用数学四则运算计算技能";
    }

    @Override
    public SkillResponse execute(String param) {
        try {
            log.info("执行数学计算,表达式:{}", param);
            // 表达式运算
            double result = eval(param);
            return SkillResponse.success("计算完成", result);
        } catch (Exception e) {
            log.error("计算失败:{}", e.getMessage());
            return SkillResponse.fail("计算异常:" + e.getMessage());
        }
    }

    /**
     * 简易表达式运算,适配常规四则运算
     */
    private double eval(String expression) {
        return (double) new javax.script.ScriptEngineManager()
                .getEngineByName("JavaScript")
                .eval(expression);
    }
}

9.7 生产级能力复刻

Java版本完整复刻Python版生产优化能力,包含Token裁剪、角色权限隔离、任务重试熔断、参数强校验、日志持久化,适配微服务高并发生产场景。基于Spring AOP实现技能权限拦截,通过Guava实现接口限流与重试,通过字符串分词实现会话历史裁剪,整体防护逻辑与Python版完全对齐。

9.8 Java版项目启动与测试

项目遵循Spring Boot标准启动流程,启动后自动加载所有自定义技能、初始化LLM客户端、注册权限拦截规则。提供全局测试接口,支持单技能调用、多技能协同任务、长会话测试、异常场景测试,可直接用于生产环境验收。

十、双版本适配总结与落地建议

10.1 Python/Java版本能力对比

两个版本实现能力完全等价,核心Agent推理逻辑、技能体系、生产优化规则、异常处理机制保持高度统一,仅适配场景与技术生态存在差异。Python版本开发效率更高、迭代速度更快,适合原型验证、轻量化部署、算法调试场景;Java版本稳定性更强、并发性能更优、适配微服务架构,适合企业正式生产、集群部署、高并发业务场景。

10.2 项目落地最佳实践

原型阶段优先使用Python版本快速迭代,验证Agent业务逻辑与技能可行性;上线阶段无缝迁移至Java版本,依托微服务架构实现规模化落地。统一沿用本文标准化技能开发规范,保证双版本技能可互通、可复用,降低迭代与迁移成本。生产环境默认开启权限隔离、Token裁剪、重试熔断机制,保障Agent服务长期稳定运行。

10.3 拓展方向

基于本框架可继续拓展多模态技能、知识库检索技能、第三方接口对接技能、定时任务技能,适配智能办公、数据分析、自动化运维、智能客服等各类AI业务场景,可快速迭代为企业级完整AI智能应用平台。

相关推荐
程序员黑豆1 小时前
Java入门第一步:从零开始编写你的第一个Hello World程序
java·前端·ai编程
就叫飞六吧3 小时前
codex无直接proxy 配置,拓展proxy方案
javascript·ai编程
明月_清风4 小时前
🚀 AI Agent 完全入门指南:从 LLM 到生产落地,新手必懂的 34 个核心概念
前端·后端·ai编程
plainGeekDev4 小时前
Git Hooks + 定时任务:把 Claude Code 嵌入任何自动化流程
aigc·ai编程
9i编程4 小时前
手敲重构学透 Multi-Agent 代码(上):逐行拆解 AgentScope 1.0.8,从「跑通了但没懂」到真懂了
人工智能·openai·ai编程
libokaifa5 小时前
Claude Code 的工程化落地:插件(Plugin)篇
ai编程
吾皇斯巴达5 小时前
一些我开发过程中用到的AI配置
ai·ai编程
魔术师Dix5 小时前
一个轮子:Luban Skill 制作演示
游戏·unity·ai编程
Canace5 小时前
Harness Engineering 到底在做什么
前端·人工智能·ai编程