Prechádzať zdrojové kódy

添加信审一键部署

xuqh1 6 mesiacov pred
rodič
commit
2a434c5cb8

+ 1 - 1
README.md

@@ -73,7 +73,7 @@ flowchart TD
 
     %% llm-rag connections
     llm-rag --> ES
-    llm-rag --> unstructured
+    doc-parser --> unstructured
     llm-rag --> llm-infinity
     llm-rag --> doc-parser
 

+ 220 - 0
docker-compose-base-with-llm.yml

@@ -0,0 +1,220 @@
+services:
+  es01:
+    container_name: yusys-rag-es-01
+    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
+    volumes:
+      - esdata01:/usr/share/elasticsearch/data
+    ports:
+      - ${ES_PORT}:9200
+    environment:
+      - node.name=es01
+      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
+      - bootstrap.memory_lock=false
+      - discovery.type=single-node
+      - xpack.security.enabled=true
+      - xpack.security.http.ssl.enabled=false
+      - xpack.security.transport.ssl.enabled=false
+      - TZ=${TIMEZONE}
+    mem_limit: ${MEM_LIMIT}
+    ulimits:
+      memlock:
+        soft: -1
+        hard: -1
+    healthcheck:
+      test: ["CMD-SHELL", "curl http://localhost:9200"]
+      interval: 10s
+      timeout: 10s
+      retries: 120
+    networks:
+      - yusys-rag
+    restart: always
+
+  mysql:
+    image: docker.byai.uk/library/mysql:5.7.44
+    container_name: yusys-rag-mysql
+    environment:
+      - MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD}
+      - TZ=${TIMEZONE}
+    command:
+      --max_connections=1000
+      --character-set-server=utf8mb4
+      --collation-server=utf8mb4_general_ci
+      --tls_version="TLSv1.2,TLSv1.3"
+      --init-file /data/application/init.sql
+    ports:
+      - ${MYSQL_PORT}:3306
+    volumes:
+      - mysql_data:/var/lib/mysql
+      - ./init.sql:/data/application/init.sql
+    networks:
+      - yusys-rag
+    healthcheck:
+      test: ["CMD", "mysqladmin" ,"ping", "-uroot", "-p${MYSQL_PASSWORD}"]
+      interval: 10s
+      timeout: 10s
+      retries: 3
+    restart: always
+
+  minio:
+    image: quay.io/minio/minio:RELEASE.2024-09-22T00-33-43Z
+    container_name: yusys-rag-minio
+    command: server --console-address ":9001" /data
+    ports:
+      - ${MINIO_PORT}:9000
+      - ${MINIO_CONSOLE_PORT}:9001
+    environment:
+      - MINIO_ROOT_USER=${MINIO_USER}
+      - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
+      - TZ=${TIMEZONE}
+    volumes:
+      - minio_data:/data
+    networks:
+      - yusys-rag
+    restart: always
+
+  redis:
+    image: docker.byai.uk/library/redis:7.2.4
+    container_name: yusys-rag-redis
+    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 128mb --maxmemory-policy allkeys-lru
+    ports:
+      - ${REDIS_PORT}:6379
+    volumes:
+      - redis_data:/data
+    networks:
+      - yusys-rag
+    restart: always
+
+  gotenberg:
+    image: docker.byai.uk/gotenberg/gotenberg:8.9.1
+    command:
+      - gotenberg
+      - '--api-port=3000'
+      - '--api-timeout=60s'
+      - '--api-disable-health-check-logging'
+      - '--libreoffice-restart-after=10'
+      - '--libreoffice-auto-start'
+      - '--libreoffice-start-timeout=10s'
+      - '--libreoffice-max-queue-size=50'
+      - '--gotenberg-graceful-shutdown-duration=30s'
+    expose:
+      - "3000"
+    deploy:
+      replicas: 2
+      endpoint_mode: dnsrr
+    healthcheck:
+      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
+      interval: 10s
+      timeout: 1s
+      retries: 3
+    user: "1001"
+    networks:
+      - yusys-rag
+    restart: always
+
+  unstructured-api:
+    image: downloads.unstructured.io/unstructured-io/unstructured-api:0.0.80
+    expose:
+      - "8000"
+    volumes:
+      - ./huggingface:/home/notebook-user/.cache/huggingface
+    deploy:
+      replicas: 4
+      endpoint_mode: dnsrr
+    networks:
+      - yusys-rag
+    restart: always
+
+  llm-infinity:
+    image: docker.byai.uk/michaelf34/infinity:0.0.55
+    container_name: yusys-rag-infinity
+    command: ["v2"]
+    environment:
+      - HF_ENDPOINT=https://hf-mirror.com
+      - INFINITY_PORT=8781
+      - INFINITY_MODEL_ID=BAAI/bge-reranker-v2-m3;BAAI/bge-large-zh;
+    ports:
+      - "8781:8781"
+    volumes:
+      - ./huggingface:/app/.cache/huggingface
+    deploy:
+      resources:
+        reservations:
+          devices:
+          - driver: nvidia
+            device_ids: ['4']
+            # count: all
+            capabilities: [gpu]
+    networks:
+      - yusys-rag
+    restart: always
+
+  llm-chat:
+    image: docker.byai.uk/vllm/vllm-openai:v0.6.3.post1
+    command:
+      - --model
+      - Qwen/Qwen2.5-72B-Instruct-AWQ
+      - --dtype
+      - auto
+      - --trust-remote-code
+      - --tensor-parallel-size
+      - "4"
+      - --max-num-batched-tokens
+      - "32768"
+      - --max-model-len
+      - "32768"
+      - --max-seq-len-to-capture
+      - "32768"
+    environment:
+      - HF_ENDPOINT=https://hf-mirror.com
+    volumes:
+      - ./huggingface:/app/.cache/huggingface
+    ports:
+      - "8000:8000"
+    ipc: 'host'
+    deploy:
+      resources:
+        reservations:
+          devices:
+          - driver: nvidia
+            # device_ids: ['4']
+            count: all
+            capabilities: [gpu]
+    networks:
+      - yusys-rag
+    restart: always
+
+  doc-parser:
+    image: 192.168.107.2:5000/yusyscloud/llm-doc-parser:dev-32
+    container_name: yusys-rag-doc
+    environment:
+      - UNSTRUCTURED_API_URL=http://unstructured-api:8000/general/v0/general
+      - SPLIT_PDF_CONCURRENCY_LEVEL=15
+    ports:
+      - "8023:8023"
+    volumes:
+      - ./huggingface:/root/.cache/huggingface
+    deploy:
+      resources:
+        reservations:
+          devices:
+          - driver: nvidia
+            device_ids: ['4']
+            #count: all
+            capabilities: [gpu]
+    networks:
+      - yusys-rag
+    restart: always
+
+volumes:
+  esdata01:
+    driver: local
+  mysql_data:
+    driver: local
+  minio_data:
+    driver: local
+  redis_data:
+    driver: local
+
+networks:
+  yusys-rag:
+    driver: bridge

+ 50 - 0
docker-compose-with-llm.yml

@@ -0,0 +1,50 @@
+include:
+  - path: ./docker-compose-base-with-llm.yml
+    env_file: ./.env
+
+services:
+  llm-app:
+    depends_on:
+      mysql:
+        condition: service_healthy
+      es01:
+        condition: service_healthy
+    image: 192.168.107.2:5000/yusyscloud/llm-app:0826-0830-55
+    container_name: llm-app
+    ports:
+      - ${SVR_HTTP_PORT}:80
+    volumes:
+      - ./config/application.yaml:/application.yml
+    healthcheck:
+      test: ["CMD", "curl", "-f", "http://localhost:80"]
+      interval: 30s
+      timeout: 10s
+      retries: 3
+      start_period: 30s
+    environment:
+      - TZ=${TIMEZONE}
+    networks:
+      - yusys-rag
+    restart: always
+
+  llm-rag:
+    depends_on:
+      llm-app:
+        condition: service_healthy
+    container_name: yusys-rag-base
+    image: 192.168.107.2:5000/yusyscloud/llm-rag:splitload-keyword-retrieve-35
+    ports:
+      - 8001:8001
+    environment:
+      - llm_app_url=http://llm-app:80
+      - TZ=${TIMEZONE}
+    healthcheck:
+      test: ["CMD-SHELL", "curl http://localhost:8001/health"]
+      interval: 10s
+      timeout: 10s
+      retries: 120
+    networks:
+      - yusys-rag
+    restart: always
+
+    

+ 4 - 4
init.sql

@@ -1005,7 +1005,7 @@ INSERT INTO `kb_knowledge` (`name`, `des`, `guide`, `num_hit`, `icon`, `num_file
 UPDATE `kb_knowledge` SET id = 999999 where name = '客服问答知识库模板' limit 1;
 
 INSERT INTO `llm_model` (`id`, `name`, `size`, `api`, `api_key`, `default_model`, `model`, `status`, `error_message`, `connection_time`) VALUES
-(23, 'qwen2-72b', 33, 'http://chat.192.168.107.2.nip.io/v1/chat/completions', '123', 'Y', 'qwen2.5:72b-instruct-q5_K_M', 'Y', '', '2024-08-20 11:29:17');
+(23, 'qwen2-72b', 33, 'http://llm-chat:8000/v1/chat/completions', '123', 'Y', 'Qwen/Qwen2.5-72B-Instruct-AWQ', 'Y', '', '2024-08-20 11:29:17');
 
 INSERT INTO `llm-app`.llm_prompt (id, name, des, scene_id, model_id, prompt, temperature, max_tokens, retrieval_topk, retrieval_similarity, user_id, private_flag, code, process_step) VALUES(1, '默认提示词模板', '默认提示词', 1, 23, '首先阅读如下的文档片段:
 """
@@ -1199,11 +1199,11 @@ INSERT INTO `sys_dict_detail` (`detail_id`, `dict_id`, `label`, `value`, `dict_s
 (93, 19, 'prompt_template', '参考文本:{context) ---------------------------- #Role: 客服 #Background  -你是一名人工客服,你的日常工作是根据【参考文本】的内容来回复用户的各种问题 #Goals:  -以上【参考文本)中是从企业知识率中查找到相关信息,只能结合以上信息进行回答,若以上内容为空或者没有找到能回答【用户问题】的内容时,则回复”没有找到相关内容”,不能很播你自己的知识发挥。特别要区分【用户问题】与【参考文本】中不同的日期、人名、公司这些关键信息。·用中文回答问题,并且答案严谨、专业、清晰、可读性好。-拥有排版市美,会利用序号、缩进、分制线和换行符等等来美化信息排版。  ------------------------------  用户问题:(question) 你的回答:', 999, 'msyh', 'msyh', '2024-04-07 17:08:52', '2024-04-07 17:10:47'),
 (94, 19, 'prompt_default', '知识库默认模版1', 999, 'msyh', 'msyh', '2024-04-08 10:55:40', '2024-04-08 10:56:34'),
 (95, 8, 'rag_api', 'http://llm-rag:8001', 2, 'test', 'admin', '2024-04-10 10:07:45', '2024-08-21 14:34:55'),
-(96, 8, 'embed_url', 'http://192.168.107.3:8781', 4, 'test', 'admin', '2024-04-11 17:30:12', '2024-08-28 17:13:00'),
+(96, 8, 'embed_url', 'http://llm-infinity:8781', 4, 'test', 'admin', '2024-04-11 17:30:12', '2024-08-28 17:13:00'),
 (97, 8, 'embed_apikey', 'Basic YWRtaW46YWRtaW4xMjM=', 4, 'test', 'test', '2024-04-11 17:36:36', '2024-04-25 11:19:12'),
 (99, 8, 'reranker_size', '30', 999, 'test', 'test', '2024-04-26 16:45:26', '2024-06-20 17:21:07'),
-(100, 8, 'embed_model', 'BAAI/bge-large-zh-v1.5', 999, 'test', 'test', '2024-04-28 12:54:28', '2024-08-23 11:13:08'),
-(105, 8, 'reranker_url', 'http://192.168.107.3:8781/rerank', 4, 'test', 'test', '2024-05-12 00:15:08', '2024-08-23 12:32:14'),
+(100, 8, 'embed_model', 'BAAI/bge-large-zh', 999, 'test', 'test', '2024-04-28 12:54:28', '2024-08-23 11:13:08'),
+(105, 8, 'reranker_url', 'http://llm-infinity:8781/rerank', 4, 'test', 'test', '2024-05-12 00:15:08', '2024-08-23 12:32:14'),
 (110, 20, '知识库匹配替换', 'substitute', 999, 'test', 'admin', '2024-05-13 16:27:33', '2024-07-30 10:50:49'),
 (111, 20, '知识库匹配返回', 'match', 999, 'test', 'admin', '2024-05-13 16:27:50', '2024-07-30 10:50:42'),
 (112, 22, 'app_url', 'http://192.168.107.2:8029', 999, 'test', 'test', '2024-05-14 11:45:04', '2024-07-04 16:59:45'),

+ 1 - 1
install.sh

@@ -13,7 +13,7 @@ cd $DIR
 docker compose up -d 
 
 # Add extra db data
-docker exec -i yusys-rag-mysql mysql -uroot -pllmllmllm < init.sql
+docker exec -i yusys-rag-mysql mysql -uroot -pllmllmllm < init_extra.sql
 
 # docker compose logs
 docker compose logs -f

+ 33 - 0
xs/.env

@@ -0,0 +1,33 @@
+
+FRONTEND_PORT=8061
+BACKEND_PORT=8008
+AGENT_API_PORT=9900
+AGENT_FILE_PORT=9901
+
+
+MYSQL_PASSWORD=llmllmllm
+MYSQL_PORT=3336
+
+# Port to expose minio to the host
+MINIO_CONSOLE_PORT=9001
+MINIO_PORT=9000
+
+MINIO_USER=root
+MINIO_PASSWORD=llmllmllm
+
+REDIS_PORT=6389
+REDIS_PASSWORD=llmllmllm
+
+
+TIMEZONE='Asia/Shanghai'
+
+
+#HF_ENDPOINT=https://hf-mirror.com
+
+######## OS setup for ES ###########
+# sysctl vm.max_map_count
+# sudo sysctl -w vm.max_map_count=262144
+# However, this change is not persistent and will be reset after a system reboot.
+# To make the change permanent, you need to update the /etc/sysctl.conf file.
+# Add or update the following line in the file:
+# vm.max_map_count=262144

+ 189 - 0
xs/config/application.yaml

@@ -0,0 +1,189 @@
+server:
+  port: 8000
+  compression:
+    enabled: true
+    mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
+
+spring:
+  application:
+    admin: 
+      enabled: true
+  freemarker:
+    check-template-location: false
+  profiles:
+    active: test
+  data:
+    redis:
+      repositories:
+        enabled: false
+  #  pid:
+  #    file: /自行指定位置/eladmin.pid
+
+  #配置 Jpa
+  jpa:
+    hibernate:
+      ddl-auto: none
+    open-in-view: true
+    properties:
+      hibernate:
+        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
+        format_sql: true
+    showSql: false
+
+
+  redis:
+    #数据库索引
+    database: ${REDIS_DB:0}
+    host: ${REDIS_HOST:redis}
+    port: ${REDIS_PORT:6379}
+    password: ${REDIS_PWD:llmllmllm}
+    #连接超时时间
+    timeout: 5000
+
+  datasource:
+    druid:
+      db-type: com.alibaba.druid.pool.DruidDataSource
+      driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
+      url: jdbc:log4jdbc:mysql://${DB_HOST:mysql}:${DB_PORT:3306}/${DB_NAME:llm-app}?serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&characterEncoding=utf8&useSSL=false
+      username: ${DB_USER:root}
+      password: ${DB_PWD:llmllmllm}
+      # 初始连接数
+      initial-size: 5
+      # 最小连接数
+      min-idle: 15
+      # 最大连接数
+      max-active: 30
+      # 超时时间(以秒数为单位)
+      remove-abandoned-timeout: 180
+      # 获取连接超时时间
+      max-wait: 3000
+      # 连接有效性检测时间
+      time-between-eviction-runs-millis: 60000
+      # 连接在池中最小生存的时间
+      min-evictable-idle-time-millis: 300000
+      # 连接在池中最大生存的时间
+      max-evictable-idle-time-millis: 900000
+      # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
+      test-while-idle: true
+      # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个
+      test-on-borrow: true
+      # 是否在归还到池中前进行检验
+      test-on-return: false
+      # 检测连接是否有效
+      validation-query: select 1
+      # 配置监控统计
+      webStatFilter:
+        enabled: true
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        reset-enable: false
+      filter:
+        stat:
+          enabled: true
+          # 记录慢SQL
+          log-slow-sql: false
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
+
+# 登录相关配置
+login:
+  #  是否限制单用户登录
+  single-login: false
+  # Redis用户登录缓存配置
+  user-cache:
+    # 存活时间/秒
+    idle-time: 21600
+  #  验证码
+  login-code:
+    #  验证码类型配置 查看 LoginProperties 类
+    code-type: arithmetic
+    #  登录图形验证码有效时间/分钟
+    expiration: 2
+    #  验证码高度
+    width: 111
+    #  验证码宽度
+    height: 36
+    # 内容长度
+    length: 2
+    # 字体名称,为空则使用默认字体
+    font-name:
+    # 字体大小
+    font-size: 25
+
+#jwt
+jwt:
+  header: Authorization
+  # 令牌前缀
+  token-start-with: Bearer
+  # 必须使用最少88位的Base64对该令牌进行编码
+  base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
+  # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
+  token-validity-in-seconds: 14400000
+  # 在线用户key
+  online-key: "online-token:"
+  # 验证码
+  code-key: "captcha-code:"
+  # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
+  detect: 1800000
+  # 续期时间范围,默认1小时,单位毫秒
+  renew: 3600000
+
+#是否允许生成代码,生产环境设置为false
+generator:
+  enabled: true
+
+#是否开启 swagger-ui
+swagger:
+  enabled: true
+
+# 文件存储路径
+file:
+  mac:
+    path: ~/file/
+    avatar: ~/avatar/
+  linux:
+    path: /home/eladmin/file/
+    avatar: /home/eladmin/avatar/
+  windows:
+    path: C:\eladmin\file\
+    avatar: C:\eladmin\avatar\
+  # 文件大小 /M
+  maxSize: 100
+  avatarMaxSize: 5
+
+task:
+  pool:
+    # 核心线程池大小
+    core-pool-size: 10
+    # 最大线程数
+    max-pool-size: 30
+    # 活跃时间
+    keep-alive-seconds: 60
+    # 队列容量
+    queue-capacity: 50
+
+#七牛云
+qiniu:
+  # 文件大小 /M
+  max-size: 15
+
+#邮箱验证码有效时间/秒
+code:
+  expiration: 300
+
+#密码加密传输,前端公钥加密,后端私钥解密
+rsa:
+  private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
+
+#MinIO配置
+minio:
+  #endpoint: http://152.136.191.250:2304
+  #accessKey: root
+  #secretKey: llmllmllm
+  bucketName: create-default
+  #ragUrl: http://rag.yangzhiqiang.tech/rag/index/{knowledegeId}/file/{fileId}?chunk_size={cs}&chunk_overlap={co}
+  #numHitUrl: http://rag.yangzhiqiang.tech/rag/retrieve/{knowledegeId}?query={q}&topk={t}

+ 1076 - 0
xs/config/car_credit_template.json

@@ -0,0 +1,1076 @@
+{
+    "name": "一汽金融信贷助手",
+    "debug": "true",
+    "env": {
+      "question": "一汽金融信贷助手根据模板生成html文件流程"
+    },
+    "nodes": [
+      {
+        "id": "__start__",
+        "type": "__start__",
+        "name": "开始"
+      },
+      {
+        "id": "InitConstant_1",
+        "type": "InitConstant",
+        "name": "初始化常量",
+        "config": {
+          "credit_constant": "{{__cfg.env.cfg.credit_constant}}"
+        }
+      },
+      {
+        "id": "MinioClient_1",
+        "type": "CreditMinioClient",
+        "name": "模板与源文件",
+        "config": {
+          "server_url": "{{__cfg.env.cfg.minio.server_url}}",
+          "access_key": "{{__cfg.env.cfg.minio.access_key}}",
+          "secret_key": "{{__cfg.env.cfg.minio.secret_key}}",
+          "files": "{{__cfg.env.cfg.files}}"
+        }
+      },
+      {
+        "id": "TemplateVariablesExtractor_1",
+        "type": "VariablesExtractor",
+        "name": "模板变量提取(docx) vars",
+        "config": {
+        }
+      },
+      {
+        "id": "CreditPlanner_1",
+        "type": "CreditPlanner",
+        "name": "信审报告计划",
+        "config": {
+          "plans": [
+            "根据输入的文件列表从minio下载文件",
+            "关键词提取目标变量 #E0 = retrieval_keyword(tmplateVars)",
+            "多模态从图片列表中提取模板变量列表中值  v_前缀的vars #E1 = multiLlm([1,2,3],'$Vxxx*') 返回json示例{} ",
+            "金融行业信贷报告的基本结构和所需信息 #E1 = 通过关键词 ${keyword-} 提取 ",
+            "借款人近12个月批发业务余额趋势图 #E2 = 使用#E1 批发业务余额数据,生成趋势图",
+            "表格数据提取 #E3 = 通过关键词或语义检索 retrieval [ 提取数据]",
+            "行业数据 #E4 = tavily_search[汽车行业趋势]",
+            "财务指标数据 #E5 = 使用#E3 通过大模型提问提取",
+            "汇总说明 #E6 = 使用#E3 通过大模型提问提取",
+            "根据提取的目标变量 #E0 的值和信审报告模板(template.docx),生成初始报告 # E7(reportid.docx)",
+            "根据初始报告 #E7, 按照分页符解析拆分为 html 文件内容"
+          ],
+          "tools": [
+            "tavily_search"
+          ]
+        }
+      },
+      {
+        "id": "CreditWorker_1",
+        "type": "CreditWorker",
+        "name": "计划并行执行",
+        "config": {
+        }
+      },
+      {
+        "id": "ExtractorWorker_1",
+        "type": "ExtractorWorker",
+        "name": "原数据提取",
+        "config": {
+          "chat_base_url": "http://qwen72b.192.168.107.2.nip.io/v1/chat/completions",
+          "chat_model": "Qwen/Qwen2.5-72B-Instruct-AWQ",
+          "vl_base_url": "http://qw2vl72b.192.168.107.2.nip.io/v1",
+          "vl_model": "Qwen/Qwen2-VL-72B-Instruct-AWQ",
+          "bisheng_url": "http://49.232.200.84:9000/api/v1/etl4llm/predict",
+          "tavily_api_key": "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",
+          "offline": false,
+          "datas": {
+            "Affiliate_Table": {
+              "type": "excelToImage",
+              "data": {
+                "keyWord": "集团关联公司调查表"
+              }
+            },
+            "Sales_Table": {
+              "type": "excelToImage",
+              "data": {
+                "keyWord": "销售数据"
+              }
+            },
+            "Income_Table": {
+              "type": "excelToImage",
+              "data": {
+                "keyWord": "收益数据"
+              }
+            },
+            "Cust_Name_kb": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "营业执照",
+                "question": "名称",
+                "prompt": "首先阅读如下的文档片段: \"\"\" {context} \"\"\" 然后寻找如下问题的答案: \"\"\" 数据提取营业执照{question}, 仅提取名称,不要有多余的描述 \"\"\" ,找不到请直接回答`无法找到答案`。 你的回答:"
+              }
+            },
+            "Cust_Name_multi": {
+              "type": "multi",
+              "data": {
+                "keyWord": "营业执照",
+                "prompt": "提取图片中的公司名称,只输出公司名称,不要其他信息。"
+              }
+            },
+            "Cust_Name": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "Cust_Name_kb",
+                  "Cust_Name_multi"
+                ],
+                "type": "cal",
+                "cal": "nested_map[\"Cust_Name_multi\"].data if nested_map[\"Cust_Name_kb\"].data is None else nested_map[\"Cust_Name_kb\"].data"
+              }
+            },
+            "License_Check_date_kb": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "营业执照",
+                "question": "期限",
+                "prompt": "首先阅读如下的文档片段: \"\"\" {context} \"\"\" 然后寻找如下问题的答案: \"\"\" 数据提取营业执照有效截止{question}, 不要有多余的描述 \"\"\" ,找不到请直接回答`无法找到答案`。 你的回答:"
+              }
+            },
+            "License_Check_date_multi": {
+              "type": "multi",
+              "data": {
+                "keyWord": "营业执照",
+                "prompt": "提取营业执照有效截止日期,以yyyy-MM-dd展示。若有效期为长期,则回答\"长期\"两个字。严格按照要求输出,你的回答是:"
+              }
+            },
+            "License_Check_choose": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "License_Check_date_kb",
+                  "License_Check_date_multi"
+                ],
+                "type": "cal",
+                "cal": "nested_map[\"License_Check_date_multi\"].data if nested_map[\"License_Check_date_kb\"].data is None else nested_map[\"License_Check_date_kb\"].data"
+              }
+            },
+            "License_Check": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "License_Check_choose"
+                ],
+                "type": "cal",
+                "cal": "\"是\" if \"长期\" in nested_map[\"License_Check_choose\"].data or datetime.strptime(nested_map[\"License_Check_choose\"].data, \"%Y-%m-%d\").date() > (datetime.now().date() - timedelta(days=60)) else \"否\""
+              }
+            },
+            "CRM_Check": {
+              "type": "mock",
+              "data": {
+                "text": [
+                  "是",
+                  "否"
+                ]
+              }
+            },
+            "UC_Check": {
+              "type": "mock",
+              "data": {
+                "text": "是"
+              }
+            },
+            "Check_Discribe2": {
+              "type": "mock",
+              "data": {
+                "text": "短期借款比对不一致"
+              }
+            },
+            "Balance_Graph_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "批发业务余额"
+              }
+            },
+            "Balance_Graph_labels": {
+              "type": "tableByModel",
+              "data": {
+                "source": "Balance_Graph_md",
+                "type": "list",
+                "item": [
+                  "日期"
+                ]
+              }
+            },
+            "Balance_Graph_data": {
+              "type": "tableByModel",
+              "data": {
+                "source": "Balance_Graph_md",
+                "type": "list",
+                "item": [
+                  "金额"
+                ]
+              }
+            },
+            "Balance_Graph": {
+              "type": "linechart",
+              "data": {
+                "title": "贷款余额",
+                "data": "${Balance_Graph_data}",
+                "labels": "${Balance_Graph_labels}",
+                "x_size": 10,
+                "y_size": 6
+              }
+            },
+            "Discribe3_w": {
+              "type": "webspider",
+              "data": {
+                "text": "北京宇信科技股份有限公司 百度百科"
+              }
+            },
+            "Discribe3": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "Discribe3_w"
+                ],
+                "question": "${Discribe3_w}, \n\n从上文中简单总结该公司的介绍信息,200字左右,按照事实回答"
+              }
+            },
+            "RiskInfo_Search_w": {
+              "type": "webspider",
+              "data": {
+                "text": "北京宇信科技股份有限公司 风险信息(最不利)新闻"
+              }
+            },
+            "RiskInfo_Search": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "RiskInfo_Search_w"
+                ],
+                "question": "#Action:\n阅读以下内容,并形成300字内容总结\n\n#内容 \n\"\"\" ${RiskInfo_Search_w} \"\"\" \n\n\n然后寻找如下问题的答案:  \"\"\" 总结上文信息,分析公司风险以及利好信息 \"\"\""
+              }
+            },
+            "Commerce_Table_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "合作情况调查"
+              }
+            },
+            "Commerce_Table": {
+              "type": "todo_mdtolist",
+              "data": {
+                "source": "Commerce_Table_md",
+                "variable": [
+                  "real_company",
+                  "product",
+                  "coo_date",
+                  "edu_new",
+                  "edu_old",
+                  "pts_yue",
+                  "zsh_yue",
+                  "rj_yue"
+                ]
+              }
+            },
+            "sum_edu_new": {
+              "type": "calculate",
+              "data": {
+                "type": "list_sum",
+                "sources": [
+                  "Commerce_Table"
+                ],
+                "variable": "edu_new",
+                "cal": ""
+              }
+            },
+            "sum_edu_old": {
+              "type": "calculate",
+              "data": {
+                "type": "list_sum",
+                "sources": [
+                  "Commerce_Table"
+                ],
+                "variable": "edu_old",
+                "cal": ""
+              }
+            },
+            "sum_pts_yue": {
+              "type": "calculate",
+              "data": {
+                "type": "list_sum",
+                "sources": [
+                  "Commerce_Table"
+                ],
+                "variable": "pts_yue",
+                "cal": ""
+              }
+            },
+            "sum_zsh_yue": {
+              "type": "calculate",
+              "data": {
+                "type": "list_sum",
+                "sources": [
+                  "Commerce_Table"
+                ],
+                "variable": "zsh_yue",
+                "cal": ""
+              }
+            },
+            "sum_rj_yue": {
+              "type": "calculate",
+              "data": {
+                "type": "list_sum",
+                "sources": [
+                  "Commerce_Table"
+                ],
+                "variable": "rj_yue",
+                "cal": ""
+              }
+            },
+            "Discribe2_now": {
+              "type": "calculate",
+              "data": {
+                "sources": [],
+                "type": "cal",
+                "cal": "datetime.now().strftime('%Y-%m-%d')"
+              }
+            },
+            "Discribe2": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "Commerce_Table_md"
+                ],
+                "question": "${Commerce_Table_md}\n根据提供的表格将以下内容补充完整 \"\"\" \n 借款人集团在我司准时化新车授信   万,准时化二手车授信  万,普通式余额  万;截止到${Discribe2_now},在我司总余额  万。 \n\"\"\",(我司总余额=${sum_pts_yue}+${sum_zsh_yue})仅返回内容本身,不要有多余描述。你的回答:"
+              }
+            },
+            "Base_Check_md": {
+              "type": "pdfToMd",
+              "data": {
+                "keyWord": "文件清单"
+              }
+            },
+            "Base_Check_1": {
+              "type": "questionByModel",
+              "data": {
+                "sources": ["Base_Check_md"],
+                "question": "${Base_Check_md} \n\n\n 提取上文文件清单,以逗号分隔,找不到请直接回答`无法找到答案`。 你的回答:"
+              }
+            },
+            "Base_Check": {
+              "type": "fileExist",
+              "data": {
+                "fileList": "${Base_Check_1}"
+              }
+            },
+            "IDCard_Check1_date": {
+              "type": "multi",
+              "data": {
+                "keyWord": "实际控制人身份证",
+                "prompt": "提取身份证有效截止日期,以yyyy-MM-dd展示。严格按照要求输出,你的回答是:"
+              }
+            },
+            "IDCard_Check1": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "IDCard_Check1_date"
+                ],
+                "type": "cal",
+                "cal": "\"是\" if \"长期\" in nested_map[\"IDCard_Check1_date\"].data or datetime.strptime(nested_map[\"IDCard_Check1_date\"].data, \"%Y-%m-%d\").date() > (datetime.now().date() - timedelta(days=60)) else \"否\"",
+                "default": "否"
+              }
+            },
+            "IDCard_Check2_date": {
+              "type": "multi",
+              "data": {
+                "keyWord": "实际经营人身份证",
+                "prompt": "提取身份证有效截止日期,以yyyy-MM-dd展示。严格按照要求输出,你的回答是:"
+              }
+            },
+            "IDCard_Check2": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "IDCard_Check2_date"
+                ],
+                "type": "cal",
+                "cal": "\"是\" if \"长期\" in nested_map[\"IDCard_Check2_date\"].data or datetime.strptime(nested_map[\"IDCard_Check2_date\"].data, \"%Y-%m-%d\").date() > (datetime.now().date() - timedelta(days=60)) else \"否\"",
+                "default": "否"
+              }
+            },
+            "IDCard_Check3_date": {
+              "type": "multi",
+              "data": {
+                "keyWord": "法人代表身份证",
+                "prompt": "提取身份证有效截止日期,以yyyy-MM-dd展示。严格按照要求输出,你的回答是:"
+              }
+            },
+            "IDCard_Check3": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "IDCard_Check3_date"
+                ],
+                "type": "cal",
+                "cal": "\"是\" if \"长期\" in nested_map[\"IDCard_Check3_date\"].data or datetime.strptime(nested_map[\"IDCard_Check3_date\"].data, \"%Y-%m-%d\").date() > (datetime.now().date() - timedelta(days=60)) else \"否\"",
+                "default": "否"
+              }
+            },
+            "Guarantee_Check_kb": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "公司章程",
+                "question": "担保",
+                "prompt": "\"\"\" {context} \"\"\" \n 提取上文中对外担提供保条款,找不到请直接回答`无法找到答案`。 你的回答:"
+              }
+            },
+            "Guarantee_Check_kb_1": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "Guarantee_Check_kb"
+                ],
+                "type": "cal",
+                "cal": "\"否\" if nested_map[\"Guarantee_Check_kb\"].data is None else \"是\""
+              }
+            },
+            "Guarantee_Check_multi": {
+              "type": "multi",
+              "data": {
+                "keyWord": "公司章程",
+                "prompt": "判断图片中是否存在对外担保的限制性条款信息,如果存在则返回是,如果不存在则返回否。严格回答:是 或 否,仅输出一个字, 你的回答是:"
+              }
+            },
+            "Guarantee_Check_multi1": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "Guarantee_Check_multi"
+                ],
+                "type": "cal",
+                "cal": "\"是\" if any(\"是\" in element for element in nested_map[\"Guarantee_Check_multi\"].data) else \"否\"",
+                "default": "否"
+              }
+            },
+            "Guarantee_Check": {
+              "type": "calculate",
+              "data": {
+                "sources": [
+                  "Guarantee_Check_kb_1",
+                  "Guarantee_Check_multi1"
+                ],
+                "type": "cal",
+                "cal": "\"是\" if \"是\" in nested_map[\"Guarantee_Check_multi1\"].data or \"是\" in nested_map[\"Guarantee_Check_kb\"].data else \"否\"",
+                "default": "否"
+              }
+            },
+            "Sales_Check_kb": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "品牌",
+                "question": "品牌",
+                "prompt": "首先阅读如下的文档片段:\n \"\"\" \n {context} \n\"\"\" \n数据提取{question}名称,仅提取单一名称,不要有多余的描述,严格回答:品牌名称,找不到请直接回答`无法找到答案`。你的回答:"
+              }
+            },
+            "Sales_Check_kb_1": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "品牌",
+                "question": "有效期",
+                "prompt": "首先阅读如下的文档片段:\n \"\"\" \n {context} \n\"\"\" \n数据提取{question}截止日期,以yyyy-MM-dd展示。若未找到,则回答\"长期\"两个字。严格按照要求输出,找不到请直接回答`无法找到答案`。你的回答:"
+              }
+            },
+            "Sales_Check_multi": {
+              "type": "multi",
+              "data": {
+                "keyWord": "品牌",
+                "prompt": "数据提取品牌名称,仅提取单一名称,不要有多余的描述,严格回答:品牌名称,你的回答是:"
+              }
+            },
+            "Sales_Check_multi_2": {
+              "type": "multi",
+              "data": {
+                "keyWord": "品牌",
+                "prompt": "数据提取有效截止日期,以yyyy-MM-dd展示。若未找到长期,则回答\"长期\"两个字。严格按照要求输出,你的回答是:"
+              }
+            },
+            "Sales_Check_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "申请信息"
+              }
+            },
+            "Sales_Check_multi_3": {
+              "type": "tableByModel",
+              "data": {
+                "source": "Sales_Check_md",
+                "type": "list",
+                "item": [
+                  "品牌"
+                ]
+              }
+            },
+            "Sales_Check_pinpai": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Sales_Check_kb",
+                  "Sales_Check_multi"
+                ],
+                "cal": "nested_map[\"Sales_Check_multi\"].data if nested_map[\"Sales_Check_kb\"].data is None else nested_map[\"Sales_Check_kb\"].data",
+                "default": "否"
+              }
+            },
+            "Sales_Check_riqi": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Sales_Check_kb_1",
+                  "Sales_Check_multi_2"
+                ],
+                "cal": "nested_map[\"Sales_Check_multi_2\"].data if nested_map[\"Sales_Check_kb_1\"].data is None else nested_map[\"Sales_Check_kb_1\"].data",
+                "default": "否"
+              }
+            },
+            "Sales_Check_1": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Sales_Check_pinpai",
+                  "Sales_Check_multi_3"
+                ],
+                "cal": "\"是\" if nested_map[\"Sales_Check_pinpai\"].data in nested_map[\"Sales_Check_multi_3\"].data else \"否\"",
+                "default": "否"
+              }
+            },
+            "Sales_Check_2": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Sales_Check_riqi"
+                ],
+                "cal": "\"是\" if \"长期\" in nested_map[\"Sales_Check_riqi\"].data or datetime.strptime(nested_map[\"Sales_Check_riqi\"].data, \"%Y-%m-%d\").date() > (datetime.now().date() - timedelta(days=60)) else \"否\"",
+                "default": "否"
+              }
+            },
+            "Sales_Check": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Sales_Check_1",
+                  "Sales_Check_2"
+                ],
+                "cal": "\"是\" if \"是\" == nested_map[\"Sales_Check_1\"].data and \"是\" == nested_map[\"Sales_Check_2\"].data else \"否\"",
+                "default": "否"
+              }
+            },
+            "zcfz_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "资产负债表"
+              }
+            },
+            "lirun_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "利润表"
+              }
+            },
+            "debt_hbzj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "货币资金",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_yiszk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "应收账款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_qtysk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "其他应收款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_yufzk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "预付账款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_ch": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "存货",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_ldzc": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "流动资产",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_cqtz": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "长期投资",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_gdzcyz": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "固定资产原值",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_gdzchj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "固定资产合计",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_wxzc": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "无形资产",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_qtzc": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "其他非流动资产",
+                  "期末余额"
+                ]
+              }
+            },
+            "debt_wxzcjqtzchj": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "debt_wxzc",
+                  "debt_qtzc"
+                ],
+                "cal": "nested_map[\"debt_wxzc\"].data + nested_map[\"debt_qtzc\"].data"
+              }
+            },
+            "debt_zchj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "资产合计",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_dqjk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "短期借款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_yfpj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "应付票据",
+                  "期末余额"
+                ]
+              }
+            },
+            "debt_yifzk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "应付账款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_yuszk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "预收账款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_qtyfk": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "其他应付款",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_ldfz": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "流动负债",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_cqfzhj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "长期负债合计",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_fzhj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "负债合计",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_sszb": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "实收资本",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_wfplr": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "未分配利润",
+                  "期末数"
+                ]
+              }
+            },
+            "debt_syzqyhj": {
+              "type": "tableByModel",
+              "data": {
+                "source": "zcfz_md",
+                "item": [
+                  "所有者权益合计",
+                  "期末数"
+                ]
+              }
+            },
+            "profit_zyyysr": {
+              "type": "tableByModel",
+              "data": {
+                "source": "lirun_md",
+                "item": [
+                  "主营业务收入",
+                  "本年累计数"
+                ]
+              }
+            },
+            "profit_yyfy": {
+              "type": "tableByModel",
+              "data": {
+                "source": "lirun_md",
+                "item": [
+                  "营业费用",
+                  "本年累计数"
+                ]
+              }
+            },
+            "profit_yylr": {
+              "type": "tableByModel",
+              "data": {
+                "source": "lirun_md",
+                "item": [
+                  "营业利润",
+                  "本年累计数"
+                ]
+              }
+            },
+            "profit_glfy": {
+              "type": "tableByModel",
+              "data": {
+                "source": "lirun_md",
+                "item": [
+                  "管理费用",
+                  "本年累计数"
+                ]
+              }
+            },
+            "profit_cwfy": {
+              "type": "tableByModel",
+              "data": {
+                "source": "lirun_md",
+                "item": [
+                  "财务费用",
+                  "本年金额"
+                ]
+              }
+            },
+            "profit_jlr": {
+              "type": "tableByModel",
+              "data": {
+                "source": "lirun_md",
+                "item": [
+                  "净利润",
+                  "本年累计数"
+                ]
+              }
+            },
+            "Check_Discribe1_multi": {
+              "type": "multi",
+              "data": {
+                "keyWord": "对账单",
+                "prompt": "数据提取最新余额,仅提取最新余额数据。严格回答:余额数字,不要有多余的描述, 你的回答是:"
+              }
+            },
+            "Check_Discribe1_1": {
+              "type": "calculate",
+              "data": {
+                "type": "sum",
+                "sources": [
+                  "Check_Discribe1_multi"
+                ],
+                "list": "Check_Discribe1_multi",
+                "cal": ""
+              }
+            },
+            "Check_Discribe_keyu_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "科余"
+              }
+            },
+            "Check_Discribe_yhck": {
+              "type": "tableByModel",
+              "data": {
+                "source": "Check_Discribe_keyu_md",
+                "item": [
+                  "银行存款",
+                  "期末余额"
+                ]
+              }
+            },
+            "Check_Discribe1": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Check_Discribe1_1",
+                  "debt_hbzj",
+                  "Check_Discribe_yhck"
+                ],
+                "cal": "\"货币资金比对一致\" + str(nested_map[\"Check_Discribe1_1\"].data) + \"万元\" if float(nested_map[\"Check_Discribe1_1\"].data) == float(nested_map[\"Check_Discribe_yhck\"].data) else \"货币资金比对不一致, 银行对账单核对金额为\" + str(nested_map[\"Check_Discribe1_1\"].data) + \"万,货币资金\" + str(nested_map[\"debt_hbzj\"].data) + \"万元,其中银行存款\" + str(nested_map[\"Check_Discribe_yhck\"].data) + \"万元,差异为\" + str(round(float(nested_map[\"Check_Discribe1_1\"].data) - float(nested_map[\"Check_Discribe_yhck\"].data), 2)) + \"万元\""
+              }
+            },
+            "Discribe1_x_kb": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "授信额度",
+                "question": "新车",
+                "prompt": "首先阅读如下的文档片段:\n \"\"\" \n {context} \n\"\"\" \n数据提取{question}授信额度数值,仅提取单一金额数值,不带单位,不要有多余的描述,严格按要求回答,找不到请直接回答`无法找到答案`。你的回答:"
+              }
+            },
+            "Discribe1_e_kb": {
+              "type": "knowledge",
+              "data": {
+                "keyWord": "授信额度",
+                "question": "二手车",
+                "prompt": "首先阅读如下的文档片段:\n \"\"\" \n {context} \n\"\"\" \n数据提取{question}授信额度数值,仅提取单一金额数值,不带单位,不要有多余的描述,严格按要求回答,找不到请直接回答`无法找到答案`。你的回答:"
+              }
+            },
+            "Discribe1_md": {
+              "type": "exCelToMd",
+              "data": {
+                "keyWord": "申请信息"
+              }
+            },
+            "Discribe1": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "Discribe1_md",
+                  "Discribe1_x_kb",
+                  "Discribe1_e_kb"
+                ],
+                "question": "${Discribe1_md}, 新车授信额度老数据为${Discribe1_x_kb}万,二手车授信额度老数据为${Discribe1_e_kb}万,现根据上表得处结论:新车授信额度从  万增加(或减少)至   万,二手车授信额度从  万增加(或减少)至  万。仅输出结论,你的回答是:"
+              }
+            },
+            "Debet_Rate1": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "zcfz_md"
+                ],
+                "question": "${zcfz_md}, 从上表中获取年初资产负债率,仅回答数据,你的回答是:"
+              }
+            },
+            "Debet_Rate2": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "zcfz_md"
+                ],
+                "question": "${zcfz_md}, 从上表中获取最近一期资产负债率,仅回答数据,你的回答是"
+              }
+            },
+            "Current_Rate1": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "zcfz_md"
+                ],
+                "question": "${zcfz_md}, 从上表中获取年初流动比率,仅回答数据,正确的答案是1.12,你的回答是"
+              }
+            },
+            "Current_Rate2": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "zcfz_md"
+                ],
+                "question": "${zcfz_md}, 从上表中获取最近一期流动比率,仅回答数据,你的回答是"
+              }
+            },
+            "Finacial_Describe_1": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "zcfz_md"
+                ],
+                "question": "${zcfz_md}, \n\n从上表中分析,\n最近一期的流动比率是否正常;\n不要有多余的描述,总结分析"
+              }
+            },
+            "Finacial_Describe_2": {
+              "type": "questionByModel",
+              "data": {
+                "sources": [
+                  "zcfz_md"
+                ],
+                "question": "${zcfz_md}, \n\n从上表中分析,\n最近一期资产负债率是否较高(超70%),如较高请给出原因,否则资产负债率正常;\n最近一期报表数值较年初报表是否发生较大变动(超过30%),如发生较大变动请给出的原因;\n不要有多余的描述,简短总结"
+              }
+            },
+            "Finacial_Describe": {
+              "type": "calculate",
+              "data": {
+                "type": "cal",
+                "sources": [
+                  "Finacial_Describe_1",
+                  "Finacial_Describe_2"
+                ],
+                "cal": "nested_map[\"Finacial_Describe_1\"].data + \"\\n\\n\" + nested_map[\"Finacial_Describe_2\"].data"
+              }
+            }
+          }
+        }
+      },
+      {
+        "id": "CreditSolver_1",
+        "type": "CreditSolver",
+        "name": "信审报告数据整合验证",
+        "config": {
+        }
+      },
+      {
+        "id": "GenWord_1",
+        "type": "GenReport",
+        "name": "报告生成",
+        "config": {
+        }
+      }
+    ],
+    "edges": [
+      {
+        "__start__": "InitConstant_1"
+      },
+      {
+        "InitConstant_1": "MinioClient_1"
+      },
+      {
+        "MinioClient_1": "TemplateVariablesExtractor_1"
+      },
+      {
+        "TemplateVariablesExtractor_1": "CreditPlanner_1"
+      },
+      {
+        "CreditPlanner_1": "ExtractorWorker_1"
+      },
+      {
+        "ExtractorWorker_1": "CreditWorker_1"
+      },
+      {
+        "CreditSolver_1": "GenWord_1"
+      },
+      {
+        "GenWord_1": "__end__"
+      }
+    ],
+    "conditionalEdges": {
+      "CreditWorker_1": {
+        "multiple": "CreditSolver_1",
+        "normal": "GenWord_1"
+      }
+    }
+  }

+ 8 - 0
xs/config/cfg.json

@@ -0,0 +1,8 @@
+{
+    "redis": {
+        "host": "redis",
+        "port": 6379,
+        "db": 0,
+        "password": "llmllmllm"
+    }
+}

+ 117 - 0
xs/docker-compose.yml

@@ -0,0 +1,117 @@
+services:
+  llm-app-frontend:
+    image: 192.168.107.2:5000/yusyscloud/llm-app-frontend:develop-16
+    depends_on:
+      llm-app-backend:
+        condition: service_healthy
+    container_name: llm-app-frontend
+    ports:
+      - ${FRONTEND_PORT}:80
+    environment:
+      - TZ=${TIMEZONE}
+    networks:
+      - yusys-xs
+    restart: always
+
+  llm-app-backend:
+    depends_on:
+      mysql:
+        condition: service_healthy
+    image: 192.168.107.2:5000/yusyscloud/llm-app-backend:develop-6
+    container_name: llm-app-backend
+    ports:
+      - ${BACKEND_PORT}:8000
+    volumes:
+      - ./config/application.yaml:/app/application.yml
+    environment:
+      - TZ=${TIMEZONE}
+    healthcheck:
+      test: ["CMD", "curl", "-f", "http://localhost:8000"]
+      interval: 10s
+      timeout: 10s
+      retries: 5
+      start_period: 20s
+    networks:
+      - yusys-xs
+    restart: always
+
+  llm-agent:
+    container_name: llm-agent
+    image: 192.168.107.2:5000/yusyscloud/llm-llmops:credit_report-49
+    volumes:
+      - ./config/cfg.json:/app/llmops/cfg.json
+      - ./config/car_credit_template.json:/app/tests/workflow/example/car_credit_template.json
+      - ./data:/app/.tmp_llmops
+    ports:
+      - ${AGENT_API_PORT}:9000
+      - ${AGENT_FILE_PORT}:9001
+    networks:
+      - yusys-xs
+    restart: always
+
+  mysql:
+    image: docker.byai.uk/library/mysql:8.4.3
+    container_name: llm-mysql
+    environment:
+      - MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD}
+      - TZ=${TIMEZONE}
+    command:
+      --max_connections=1000
+      --character-set-server=utf8mb4
+      --collation-server=utf8mb4_general_ci
+      --tls_version="TLSv1.2,TLSv1.3"
+      --init-file /data/application/init.sql
+    ports:
+      - ${MYSQL_PORT}:3306
+    volumes:
+      - mysql_data:/var/lib/mysql
+      - ./init.sql:/data/application/init.sql
+    networks:
+      - yusys-xs
+    healthcheck:
+      test: ["CMD", "mysqladmin" ,"ping", "-uroot", "-p${MYSQL_PASSWORD}"]
+      interval: 10s
+      timeout: 10s
+      retries: 3
+    restart: always
+
+  minio:
+    image: quay.io/minio/minio:RELEASE.2024-09-22T00-33-43Z
+    container_name: llm-minio
+    command: server --console-address ":9001" /data
+    ports:
+      - ${MINIO_PORT}:9000
+      - ${MINIO_CONSOLE_PORT}:9001
+    environment:
+      - MINIO_ROOT_USER=${MINIO_USER}
+      - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
+      - TZ=${TIMEZONE}
+    volumes:
+      - minio_data:/data
+    networks:
+      - yusys-xs
+    restart: always
+
+  redis:
+    image: docker.byai.uk/library/redis:7.2.4
+    container_name: llm-redis
+    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 128mb --maxmemory-policy allkeys-lru
+    ports:
+      - ${REDIS_PORT}:6379
+    volumes:
+      - redis_data:/data
+    networks:
+      - yusys-xs
+    restart: always
+
+volumes:
+  mysql_data:
+    driver: local
+  minio_data:
+    driver: local
+  redis_data:
+    driver: local
+
+networks:
+  yusys-xs:
+    driver: bridge

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1351 - 0
xs/init.sql


Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov