---
title: heart_beat_lawyer3
canonical_url: "https://www.modelscope.cn/studios/fangliang911/heart_beat_lawyer3"
md_url: "https://www.modelscope.cn/studios/fangliang911/heart_beat_lawyer3.md"
repository: fangliang911/heart_beat_lawyer3
chinese_name: "令人心动的Offer法律季"
last_updated: 2024-10-30
sdk_type: gradio
sdk_version: 4.19.1
downloads: 0
stars: 1
---

# heart_beat_lawyer3

> heart_beat_lawyer3 - fangliang911 在 ModelScope 创建的在线 Demo。令人心动的offer法律季的灵感来源于同名电视节目，本作品通过情境教学的理念，让学习者在实践中学习法律。

fangliang911/heart_beat_lawyer3 是 ModelScope 魔搭社区上的在线可交互 Demo（创空间），基于 gradio 4.19.1 构建，中文名为「令人心动的Offer法律季」。

- **Repository**: fangliang911/heart_beat_lawyer3
- **SDK**: gradio
- **SDK version**: 4.19.1
- **Downloads**: 0
- **Stars**: 1
- **Last updated**: 2024-10-30

Source: https://www.modelscope.cn/studios/fangliang911/heart_beat_lawyer3

---

### CCF开源创新大赛

ModelScope 开源模型应用挑战赛 - 中药方剂智能化筛选与优化 - 复赛

本项目基于 ModelScope Agent 开发，旨在创建一个智能助手，能够实现中药方剂的智能筛选与优化。该助手能够分析用户输入的病症信息，并提供相应的中药开发建议。使用 XGPU 进行了部署，具体托管于魔搭的创空间平台。

### 对话演示

![play](/semi-final/image/play.png)

#### 1. 工具的注册

在本项目中，初赛微调的模型被作为工具使用。我们参考了 modelscope_agent/tools 中的一些工具进行搭建，确保工具的有效性和准确性。

```
python复制代码import requests
import json
from typing import Dict, Optional
from modelscope_agent.tools.base import BaseTool, register_tool

@register_tool('create_chinese_medicine')
class CreateChineseMedicine(BaseTool):
    description = '根据病症描述生成新型中药的开发建议'
    name = 'create_chinese_medicine'
    parameters: list = [{
        'name': 'text',
        'type': 'string',
        'description': '病症的名称',
        'required': True
    }]

    def __init__(self, cfg: Optional[Dict] = None):
        super().__init__(cfg)
        # 远程 API 调用
        self.api_url = 'http://localhost:8888/call/'

    def call(self, params: str, **kwargs) -> str:
        params = self._verify_args(params)
        if isinstance(params, str):
            return '参数错误'
        # 准备输入数据
        text = params['text']
        data = {"input": text + '给出几种新型中药制剂'}
        headers = {'Content-Type': 'application/json'}
        # 调用 API
        response = requests.post(self.api_url, json=data, headers=headers)
        # 返回 API 响应
        return response.content.decode('utf-8')
```

工具中使用的 API 是在初赛阶段对模型进行微调后，经过部署所提供的服务接口。该接口能够高效地处理用户请求，并返回相应的中药建议。

#### 2. API 的构建

本项目使用 FastAPI 搭建了 API 接口，确保了系统的高效性和可扩展性。模型通过 Swift 部署，但由于技术原因，模型的推理速度相对较慢，因此需要优化。以下是具体代码示例。

```
python复制代码import torch
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from modelscope import AutoModelForCausalLM, GenerationConfig, AutoTokenizer
from swift import Swift
from swift.llm import get_template, TemplateType, to_device
import asyncio

app = FastAPI()

device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"使用设备: {device}")

model_name = "qwen/qwen2-7b-instruct"
lora_weights_path = "aaaasss/chinese_medical_create_qwen"

base_model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.bfloat16, device_map='auto', trust_remote_code=True)
model = Swift.from_pretrained(base_model, lora_weights_path)

tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
template = get_template(TemplateType.chatglm3, tokenizer, max_length=1024)

class InputData(BaseModel):
    input: str

async def generate_response(input_text: str) -> str:
    await asyncio.sleep(0)  # 模拟异步处理

    examples, tokenizer_kwargs = template.encode({'query': input_text})

    if 'input_ids' in examples:
        input_ids = torch.tensor(examples['input_ids'])[None]
        examples['input_ids'] = input_ids
        token_len = input_ids.shape[1]

    generation_config = GenerationConfig(
        max_new_tokens=1024,
        temperature=0.3,
        top_k=25,
        top_p=0.8,
        do_sample=True,
        repetition_penalty=1.0,
        num_beams=10,
        pad_token_id=tokenizer.pad_token_id,
        eos_token_id=tokenizer.eos_token_id
    )
    
    examples = to_device(examples, device)

    generate_ids = model.generate(
        generation_config=generation_config,
        **examples
    )
    generate_ids = template.get_generate_ids(generate_ids, token_len)
    response = tokenizer.decode(generate_ids, **tokenizer_kwargs)

    return response

@app.post("/call/")
async def generate(data: InputData):
    input_text = data.input
    if not input_text:
        raise HTTPException(status_code=400, detail="输入文本不能为空")

    response = await generate_response(input_text)
    return {"response": response}

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8888)
```

#### 3. Agent 的构建

在构建智能体时，我们将其封装为一个函数，以便于后续调用。我们使用 Qwen-Max 作为智能体的核心“脑”，使其具备强大的推理能力。

```
python复制代码from modelscope_agent.agents import RolePlay

def create_agent():
    role_template = '你将扮演一个小助手，会根据用户的指令来调动工具完成任务'
    llm_config = {
        'model': 'qwen-max',
        'model_server': 'dashscope',
    }
    function_list = ['create_chinese_medicine']

    bot = RolePlay(function_list=function_list, llm=llm_config, instruction=role_template)
    return bot

# 初始化智能体对象
bot = create_agent()
```

#### 4. 对话界面的实现

为了提供良好的用户体验，我们使用 Gradio 构建了友好的对话界面，便于用户与智能助手进行交互并获取中药方剂的相关信息。

```
python复制代码import gradio as gr
from model_download import model_download
from agent import bot
import os
import subprocess

def call_large_model(input_text):
    response = bot.run(input_text, remote=False, print_info=True)
    text = ''
    for chunk in response:
        text += chunk
    return text

# 对话生成，历史记录
def generate_response(input_text, history):
    response = call_large_model(input_text)
    history = history + [[input_text, response]]
    return history

# 清除聊天记录
def clear_history():
    return []

# Gradio 界面
with gr.Blocks() as demo:
    gr.Markdown("<h1 style='text-align: center;'>新型中药开发小助手</h1>")
    with gr.Row():
        chatbot = gr.Chatbot(label="对话框")
    with gr.Row():
        with gr.Column():
            user_input = gr.Textbox(label="输入您的问题", placeholder="推理速度很慢，请耐心等待")
            submit_button = gr.Button("提交", variant="primary")
            clear_button = gr.Button("清除聊天记录", variant="secondary")
    # 按钮绑定
    submit_button.click(generate_response, inputs=[user_input, chatbot], outputs=[chatbot])
    clear_button.click(clear_history, outputs=[chatbot])

model_download()
api_process = subprocess.Popen(['python', 'API.py'])
print('下载完成')
demo.launch()
# 可选：在 Gradio 退出时终止 API 进程
demo.launch(share=True)
api_process.terminate()
```
