Files
AIclinicalresearch/docs/05-部署文档/07-关键配置补充说明.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

25 KiB
Raw Blame History

<EFBFBD>喲睸<EFBFBD>滨蔭銵亙<EFBFBD>霂湔<EFBFBD> - <20>函蔡<E587BD><E894A1><EFBFBD>䁅秤銝𤾸<E98A9D>撘?

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗? v1.0
*<EFBFBD>𥕦遣<EFBFBD><EFBFBD>嚗? 2025-12-14
*<EFBFBD><EFBFBD><EFBFBD>扯捶嚗? 撖?銝芰𡠺蝡钅<E89DA1>蝵脫<E89DB5><EFBFBD><E78DA2><EFBFBD>喲睸銵亙<E98AB5>
隡睃<EFBFBD>蝥改<EFBFBD> 潃鐥<E6BD83>潃鐥<E6BD83>潃?敹<>粉嚗<E7B289><E59A97><EFBFBD>?銝枉0/P1<50>游𦶢<E6B8B8><EFBFBD>嚗?


<EFBFBD><EFBFBD> <20><>﹝霂湔<E99C82>

<EFBFBD><EFBFBD><EFBFBD>抅鈭𤾸笆5銝芰𡠺蝡钅<EFBFBD>蝵脫<EFBFBD><EFBFBD><EFBFBD>瘛勗漲摰⊥䰻嚗諹<EFBFBD><EFBFBD><EFBFBD>**3銝芾稲<E88ABE>賡䔮憸?<EFBFBD>?<EFBFBD>亙僕<EFBFBD><EFBFBD>雿喳<EFBFBD>頝?*<2A><><EFBFBD>鈭𥕦<E988AD>摰孵銁<E5ADB5><E98A81><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59F88>𡝗𧊋<F0A19D97><F0A78A8B><EFBFBD>撘箄<E69298>嚗䔶<E59A97>撖寧<E69296>鈭抒㴓憓<E3B493><E68693>蝵脰秐<E884B0><EFBFBD><EFBFBD><E996AC>? *霂瑕銁<EFBFBD>函蔡<EFBFBD>滚𦛚敹<EFBFBD><EFBFBD>霂餅𧋦<EFBFBD><EFBFBD>﹝嚗?


<EFBFBD><20>游𦶢<E6B8B8><EFBFBD>靽格迤嚗㇊0/P1嚗?

1. SAE摮文<E691AE><E69687><EFBFBD><EFBFBD> - NAT蝵穃<E89DB5><E7A983>滨蔭 潃鐥<E6BD83>潃鐥<E6BD83>潃?

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P0嚗<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

SAE<EFBFBD>函蔡<EFBFBD>汲PC<EFBFBD><EFBFBD><EFBFBD>暺䁅恕瘝⊥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>箏藁嚗?
敶勗<E695B6><E58B97>箸艶嚗?<3F>?<3F>𡒊垢靚<E59EA2>鍂 DeepSeek/OpenAI API <20>?頞<>𧒄
<0A>?Python銝贝蝸<E8B49D><EFBFBD>PDF <20>?頞<>𧒄
<0A>?npm install<6C><EFBFBD>靘肽<E99D98><EFBFBD><E59A97>撱箸𧒄嚗争<E59A97> 憭梯揖

蝏𤘪<E89D8F>嚗𡁏<E59A97><F0A1818F>𡅅I<F0A18585><EFBFBD>銝滚虾<E6BB9A><EFBFBD>蝟餌<E89D9F><E9A48C>箸𧋦<E7AEB8>怎緾嚗?```

#### 閫<><E996AB><EFBFBD><EFBFBD>

**<2A><EFBFBD>A嚗鐭AT蝵穃<E89DB5><EFBFBD><EFBFBD><EFBFBD><E7909C>煺漣<E785BA><EFBFBD>嚗?*

```bash
# 甇仿炊1嚗𡁜<E59A97>撱摸AT蝵穃<E89DB5>
<0A><EFBFBD>鈭烐綉<E78390>嗅蝱 > VPC > NAT蝵穃<E89DB5> > <20>𥕦遣NAT蝵穃<E89DB5>
<0A><EFBFBD> VPC嚗𡁻<E59A97>㗇𥋘SAE<41><45><EFBFBD><EFBFBD>VPC
<0A><EFBFBD> 鈭斗揢<E69697><EFBFBD><E7B6BD>㗇𥋘SAE<41><45><EFBFBD><EFBFBD>鈭斗揢<E69697>?<3F><EFBFBD><>聢嚗𡁜<E59A97><F0A1819C><EFBFBD>憭毺鍂嚗?<3F><EFBFBD> 霈∟晶<E2889F><EFBFBD>嚗𡁏<E59A97>雿輻鍂<E8BCBB>讛恣韐?
# 甇仿炊2嚗𡁜<E59A97>撱箏僎蝏穃<E89D8F>EIP
NAT蝵穃<E89DB5>霂行<E99C82> > 撘寞<E69298><EFBFBD>蝵飡P > 蝏穃<E89D8F>撘寞<E69298><EFBFBD>蝵飡P
<0A><EFBFBD> <20>𥕦遣<F0A595A6>蚩IP<49><EFBFBD>㗇𥋘撌脫<E6928C>EIP
<0A><EFBFBD> 撣血捐嚗𡁏<E59A97>雿輻鍂瘚<E98D82><E7989A><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?<3F><EFBFBD> 蝖株恕蝏穃<E89D8F>

# 甇仿炊3嚗𡁻<E59A97>蝵娟NAT<41>∠𤌍
NAT蝵穃<E89DB5>霂行<E99C82> > SNAT蝞∠<E89D9E> > <20>𥕦遣SNAT<41>∠𤌍
<0A><EFBFBD> <20>㗇𥋘鈭斗揢<E69697><EFBFBD>SAE<41><45><EFBFBD><EFBFBD>鈭斗揢<E69697><EFBFBD>憒?vsw-xxxxx嚗?<3F><EFBFBD> <20>㗇𥋘<E39787><EFBFBD>IP嚗𡁜<E59A97><F0A1819C><EFBFBD>摰𡁶<E691B0>EIP
<0A><EFBFBD> 蝖株恕<E6A0AA>𥕦遣

<0A>鞉𧋦嚗鐭AT蝵穃<E89DB5>瞼60/<2F>?+ EIP瘚<50><E7989A>韐嗽?0-50/<2F>?= 瞼90-110/<2F>?```

**<2A><EFBFBD>B嚗锭AE蝏穃<E89D8F><E7A983><EFBFBD>IP嚗<50><E59A97><EFBFBD><EFBFBD>𧑐<EFBFBD><F0A79190>𣈲<EFBFBD><F0A388B2><EFBFBD>**

```bash
SAE<41><EFBFBD><E689B9>?> 摨𠉛鍂<F0A0899B>滨蔭 > 蝵𤑳<E89DB5><F0A491B3>滨蔭
<0A><EFBFBD> <20><EFBFBD><E4BAA6>臬炏<E887AC>?<3F><EFBFBD>霈輸䔮"<22>?蝏穃<E89D8F>EIP"<22>厰★

<0A>𩤃<EFBFBD> 瘜冽<E7989C>嚗?- 撟園<E6929F><E59C92><EFBFBD><EFBFBD>匧𧑐<E58CA7><EFBFBD><E7BDB8><EFBFBD>
- 隡睃<E99AA1>雿輻鍂<E8BCBB><EFBFBD>A嚗<41>凒蝔喳<E89D94>嚗?```

#### 撉諹<E69289>NAT蝵穃<E89DB5><E7A983>臬炏<E887AC><E7828F><EFBFBD>

```bash
# <20><EFBFBD>1嚗𡁜銁SAE摨𠉛鍂<F0A0899B><EFBFBD>銝剜䰻<E5899C>?# 摨𠉛鍂<F0A0899B>臬𢆡<E887AC>𠬍<EFBFBD><F0A0AC8D><EFBFBD><E4BAA6>臬炏<E887AC><E7828F>eepSeek API靚<49><EFBFBD>𣂼<EFBFBD><F0A382BC><EFBFBD>𠯫敹?
# <20><EFBFBD>2嚗𡁻<E59A97><EFBFBD>鈭穃𨭌<E7A983>𧢲<EFBFBD><EFBFBD>𦶢隞歹<E99A9E>SAE<41><EFBFBD><E689B9>?> 摰硺<E691B0><E7A1BA>𡑒” > <20><EFBFBD>摰硺<E691B0>嚗?curl -I https://api.deepseek.com
# 摨磰砲餈𥪜<E9A488> 200 OK嚗諹<E59A97><EFBFBD><E494B6><EFBFBD><E888AA>?
# <20><EFBFBD>3嚗𡁏<E59A97>霂𠠬ython銝贝蝸<E8B49D><EFBFBD>PDF
curl -I https://arxiv.org/pdf/2301.00001.pdf
# 摨磰砲餈𥪜<E9A488> 200 OK

<EFBFBD>湔鰵<EFBFBD><EFBFBD><EFBFBD>獢?

  • <EFBFBD>?00-<2D>函蔡<E587BD><EFBFBD><E59786><EFBFBD>.md嚗𡁶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㦛撌脣<EFBFBD><EFBFBD>賫AT蝵穃<EFBFBD>
  • <EFBFBD>?00-<2D>函蔡<E587BD><EFBFBD><E59786><EFBFBD>.md嚗𡁏<EFBFBD><EFBFBD>砌摯蝞堒歇<EFBFBD>湔鰵嚗<EFBFBD>?,200-1,250/<2F><><EFBFBD>
  • <EFBFBD>𩤃<EFBFBD> 05-Node.js<6A>𡒊垢-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md嚗𡁻<EFBFBD><EFBFBD>銁"SAE摨𠉛鍂<F0A0899B>滨蔭"蝡㰘<E89DA1>憓𧼮<E68693>蝵𤑳<E89DB5><F0A491B3>滨蔭霂湔<E99C82>
  • <EFBFBD>𩤃<EFBFBD> 04-Python敺格<E695BA><E6A0BC>?SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md嚗𡁜<EFBFBD>銝?

2. <20>函蔡靘肽<E99D98>甇駁<E79487> - Dify API Key曏∠<E69B8F><E288A0>钅䔮憸?潃鐥<E6BD83>潃鐥<E6BD83>潃?

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P1嚗<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

甇駁<EFBFBD><EFBFBD><EFBFBD>
1. <20>𡒊垢<F0A1928A>臬𢆡<E887AC><F0A286A1>閬?DIFY_API_KEY
2. DIFY_API_KEY <20><>閬?Dify <20>臬𢆡撟嗡犖撌亦蒈敶訫<E695B6><E8A8AB><EFBFBD><E6BBA9><EFBFBD><EFBFBD>
3. <20>𡒊垢憒<E59EA2><E68692><EFBFBD>亙熒璉<E78692><E79289>亙仃韐伐<E99F90>隡𡁏<E99AA1><F0A1818F><EFBFBD><E99EBE>?
蝏𤘪<E89D8F>嚗𡁜<E59A97>蝡舀<E89DA1>瘜訫鍳<E8A8AB><EFBFBD><E58981>硋鍳<E7A18B><EFBFBD>PKB璅<E79285>銝滚虾<E6BB9A>?```

#### 閫<><E996AB><EFBFBD><EFBFBD><EFBFBD><E59A97><EFBFBD>嗆挾<E59786>函蔡嚗?
**<2A>嗆挾1嚗𡁻<E59A97>甈⊿<E79488>蝵脣<E89DB5>蝡荔<E89DA1>銝湔𧒄<E6B994>滨蔭嚗?*

```bash
# SAE<41><EFBFBD><E887AC><EFBFBD><E3979B>滨蔭
DIFY_API_KEY=temp_placeholder_will_update_later

# <20>𩤃<EFBFBD> <20><EFBFBD>嚗𡁜<E59A97>蝡臭誨<E887AD><E8AAA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59D94>?# backend/src/common/rag/DifyClient.ts
constructor() {
  const apiKey = process.env.DIFY_API_KEY
  
  if (!apiKey || apiKey === 'temp' || apiKey.startsWith('temp_')) {
    console.warn('<27>𩤃<EFBFBD> Dify API Key<65><EFBFBD>蝵殷<E89DB5>PKB璅<E79285><EFBFBD><E692A0><EFBFBD>舐鍂')
    this.enabled = false
    return
  }
  
  this.client = new DifySDK(apiKey)
  this.enabled = true
}

// <20><><EFBFBD><EFBFBD>ify靚<79><EFBFBD>齿<EFBFBD><E9BDBF>?async createDataset(name: string) {
  if (!this.enabled) {
    throw new Error('Dify<66>滚𦛚<E6BB9A><EFBFBD>蝵殷<E89DB5>霂瑕<E99C82><E79195>滨蔭DIFY_API_KEY<45><EFBFBD><E887AC><EFBFBD>')
  }
  // ... 甇<><EFBFBD><EFBFBD>
}

<EFBFBD>嗆挾2嚗𡁻<EFBFBD>蝵涼ify撟嗉繮<EFBFBD>𣇉<EFBFBD>摰揼ey

# 1. <20>函蔡Dify<66>蚩CS嚗<53><E59A97><EFBFBD>?03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md嚗?cd /opt/dify
docker-compose up -d

# 2. 蝑匧<E89D91><E58CA7>滚𦛚<E6BB9A>臬𢆡嚗<F0A286A1>漲2-3<><33><EFBFBD>嚗?docker-compose logs -f api

# 3. 瘚讛<E7989A><E8AE9B>刻挪<E588BB>?http://ECS<43><EFBFBD>IP
# 4. 瘜典<E7989C>蝞∠<E89D9E><E288A0>䁅揭<E48185><EFBFBD>擐𡝗活霈輸䔮隡𡁏<E99AA1>蝷綽<E89DB7>
# 5. <20>𥕦遣API Key
#    霈曄蔭 > API撖<49>𤨎 > <20>𥕦遣撖<E981A3>𤨎 > 憭滚<E686AD>
#    <20><EFBFBD>嚗惨pp-xxxxxxxxxxxxxxxxxxxxx

# 6. 霈啣<E99C88>API Key嚗<79><EFBFBD><E6888E><EFBFBD>摮矋<E691AE>
DIFY_API_KEY=app-xxxxxxxxxxxxxxxxxxxxx

*<EFBFBD>嗆挾3嚗𡁏凒<EFBFBD><EFBFBD>蝡舫<EFBFBD>蝵?

# SAE<41><EFBFBD><E689B9>?> 摨𠉛鍂霂行<E99C82> > <20><EFBFBD><E887AC><EFBFBD>
# <20><EFBFBD> DIFY_API_KEY嚗䔶耨<E494B6>嫣蛹<E5ABA3><EFBFBD><E7AC94>?DIFY_API_KEY=app-xxxxxxxxxxxxxxxxxxxxx

# 靽嘥<E99DBD> > <20>滚鍳摨𠉛鍂
# SAE隡𡁏<E99AA1>銵峕<E98AB5><E5B395><EFBFBD><E588B8><EFBFBD><E88D94><EFBFBD><E59785><EFBFBD>

<EFBFBD>嗆挾4嚗𡁻<EFBFBD><EFBFBD>KB<EFBFBD><EFBFBD>

# 瘚贝<E7989A><E8B49D><EFBFBD>摨枏<E691A8>撱?curl -X POST https://your-api.com/api/v1/pkb/knowledge-bases \
  -H "Authorization: Bearer YOUR_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"瘚贝<E7989A><E8B49D><EFBFBD>摨?,"description":"瘚贝<E7989A>"}'

# 摨磰砲餈𥪜<E9A488> 200 OK嚗諹<E59A97><EFBFBD><E494B6>?"Dify<66>滚𦛚<E6BB9A><EFBFBD>蝵? <20>躰秤

<EFBFBD>湔鰵<EFBFBD><EFBFBD><EFBFBD>獢?

  • <EFBFBD>?00-<2D>函蔡<E587BD><EFBFBD><E59786><EFBFBD>.md嚗𡁻<EFBFBD>蝵脤◇摨誩歇<EFBFBD>湔鰵嚗峕<EFBFBD>蝖桀<EFBFBD><EFBFBD>嗆挾<EFBFBD>函蔡
  • <EFBFBD>𩤃<EFBFBD> 05-Node.js<6A>𡒊垢-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md嚗𡁻<EFBFBD><EFBFBD>銁"<22><EFBFBD><E887AC><EFBFBD><E3979B>滨蔭"蝡㰘<E89DA1>憓𧼮<E68693>銝湔𧒄<E6B994>滨蔭霂湔<E99C82>
  • <EFBFBD>𩤃<EFBFBD> 03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md嚗𡁻<EFBFBD><EFBFBD>銁"擐𡝗活霈輸䔮"蝡㰘<E89DA1>憓𧼮<E68693>API Key<65><79><EFBFBD>甇仿炊

3. HTTP Client頞<74>𧒄<EFBFBD>滨蔭 - <20>脫迫餈墧𦻖瘜<F0A6BB96><E7989C> 潃鐥<E6BD83>潃鐥<E6BD83>

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P1嚗<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

Python<EFBFBD>滚𦛚憭<EFBFBD><EFBFBD>PDF/OCR<43><EFBFBD><E888AA><EFBFBD>閬?0-120蝘?憒<><E68692><EFBFBD>𡒊垢HTTP Client瘝⊥<E7989D>霈曄蔭頞<E894AD>𧒄嚗䔶<E59A97>撖潸稲嚗?<3F>?餈墧𦻖<E5A2A7><EFBFBD>蝘?<3F>?<3F>𡒊垢摰硺<E691B0><E7A1BA><EFBFBD><EFBFBD><EFBFBD>堒偷
<0A>?<3F>唳旿摨栞<E691A8><E6A09E><EFBFBD><E4BAA4>堒偷

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD>𡒊垢HTTP Client<6E>滨蔭

// backend/src/common/http/httpClient.ts
import axios from 'axios'

export const pythonServiceClient = axios.create({
  baseURL: process.env.EXTRACTION_SERVICE_URL || 'http://localhost:8000',
  timeout: 120000,  // <20>𩤃<EFBFBD> 120蝘𡜐<E89D98>2<EFBFBD><32><EFBFBD>嚗?  timeoutErrorMessage: 'Python敺格<E695BA><E6A0BC><EFBFBD>摨磰<E691A8><E7A3B0><EFBFBD>>2<><32><EFBFBD>嚗?,
  headers: {
    'Content-Type': 'application/json'
  }
})

// 霂瑟<E99C82><E7919F>行⏛<E8A18C><EFBFBD><E58981><EFBFBD><EFBFBD><E39A81><EFBFBD><E585B6><EFBFBD>嚗?pythonServiceClient.interceptors.request.use(
  (config) => {
    console.log(`[HTTP] 靚<>鍂Python<6F>滚𦛚: ${config.method?.toUpperCase()} ${config.url}`)
    return config
  },
  (error) => Promise.reject(error)
)

// <20><EFBFBD><E6BB9A>行⏛<E8A18C><EFBFBD><E58981>躰秤憭<E7A7A4><E686AD>嚗?pythonServiceClient.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.code === 'ECONNABORTED') {
      console.error('[HTTP] Python<6F>滚𦛚頞<F0A69B9A>𧒄:', error.message)
    }
    return Promise.reject(error)
  }
)

Dify Client<6E>滨蔭

// backend/src/common/rag/DifyClient.ts
import axios from 'axios'

const difyHttpClient = axios.create({
  baseURL: process.env.DIFY_API_URL || 'http://localhost/v1',
  timeout: 60000,  // <20>𩤃<EFBFBD> 60蝘𡜐<E89D98>Dify<66><EFBFBD><EFBFBD>翰嚗?  headers: {
    'Authorization': `Bearer ${process.env.DIFY_API_KEY}`,
    'Content-Type': 'application/json'
  }
})

<EFBFBD>𧒄<EFBFBD>園𡢿撱箄悅

<EFBFBD>滚𦛚 <EFBFBD>𧒄<EFBFBD>園𡢿 <EFBFBD><EFBFBD>
*Python敺格<EFBFBD><EFBFBD>? 120蝘? PDF閫<EFBFBD><EFBFBD>嚗𠃊ougat OCR嚗匧虾<E58CA7><EFBFBD>閬?0-120蝘?
Dify API 60蝘? RAG璉<EFBFBD><EFBFBD>𡁜虜<10蝘𡜐<E89D98>60蝘坿雲憭?
憭㚚<EFBFBD>LLM API 60蝘? DeepSeek/OpenAI瘚<49><E7989A><EFBFBD><EFBFBD>嚗?0蝘坿雲憭?
*<EFBFBD>唳旿摨𤘪䰻霂? 30蝘? Prisma暺䁅恕嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>䰻霂<EFBFBD><EFBFBD>閬?0-20蝘?

<EFBFBD>湔鰵<EFBFBD><EFBFBD><EFBFBD>獢?

  • <EFBFBD>𩤃<EFBFBD> 05-Node.js<6A>𡒊垢-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md嚗𡁻<EFBFBD><EFBFBD>銁"隞<><E99A9E><EFBFBD><EFBFBD><EFBFBD>"蝡㰘<E89DA1>憓𧼮<E68693>HTTP Client<6E>滨蔭

<EFBFBD>𩤃<EFBFBD> <20><EFBFBD>摰匧<E691B0><E58CA7>滨蔭

4. ECS蝡臬藁摰匧<E691B0> - Redis/Weaviate銝滚笆憭硋<E686AD><E7A18B>?潃鐥<E6BD83>潃鐥<E6BD83>潃?

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P0嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

Dify<EFBFBD><EFBFBD>edis嚗?379嚗匧<E59A97>Weaviate嚗?080嚗匧<E59A97><E58CA7>𨅯笆<F0A885AF><EFBFBD><EFBFBD><E69298><EFBFBD>
<0A>?Redis<69><EFBFBD><E683A9><EFBFBD><EFBFBD><EFBFBD>航◤<E888AA>餃稬<E9A483><E7A8AC><EFBFBD>亥挪<E4BAA5>?<3F>?Weaviate<74><65><EFBFBD>𤩺<EFBFBD><F0A4A9BA><EFBFBD><EFBFBD><EFBFBD>𤩺㺭<F0A4A9BA>?<3F>?<3F><EFBFBD>鋡怎鍂鈭𥟠DoS<6F>餃稬<E9A483><E7A8AC><EFBFBD>?```

#### 甇<><EFBFBD>滨蔭

**docker-compose.yaml 蝡臬藁<E887AC>滨蔭**

```yaml
services:
  # <20>?<3F>躰秤蝷箔<E89DB7><EFBFBD><EFBFBD><EFBFBD>
  redis:
    ports:
      - "6379:6379"  # 撖寞<E69296><E5AF9E><EFBFBD><E58EA9><EFBFBD><E288AA><EFBFBD><E6A998><EFBFBD>𡠺<EFBFBD><EFBFBD>嚗?  
  # <20>?甇<><EFBFBD>滨蔭
  redis:
    image: redis:6-alpine
    ports:
      - "127.0.0.1:6379:6379"  # <20><EFBFBD><E88AB0>?localhost
    restart: always
    volumes:
      - ./volumes/redis/data:/data
    command: redis-server --save 60 1 --loglevel warning
  
  # <20>?甇<><EFBFBD>滨蔭
  weaviate:
    image: semitechnologies/weaviate:1.19.0
    ports:
      - "127.0.0.1:8080:8080"  # <20><EFBFBD><E88AB0>?localhost
    restart: always
    environment:
      - QUERY_DEFAULTS_LIMIT=25
      - AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true
      - PERSISTENCE_DATA_PATH=/var/lib/weaviate
  
  # <20>?<3F><EFBFBD>Nginx<6E><78><EFBFBD>笆憭吔<E686AD>VPC<50><43><EFBFBD>嚗?  nginx:
    image: nginx:latest
    ports:
      - "80:80"  # 撖釉PC<50><43><EFBFBD><EFBFBD><E69298><EFBFBD>銝齿糓<E9BDBF><EFBFBD>嚗?    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - api
      - web

ECS摰匧<EFBFBD><EFBFBD><EFBFBD>蝵?

# 摰匧<E691B0><EFBFBD><E89D8F><EFBFBD><EFBFBD>ECS<43><EFBFBD><E689B9>?> 摰匧<E691B0>蝏?> <20>滨蔭閫<E894AD><E996AB>嚗?
<0A>交䲮<E4BAA4>𤏸<EFBFBD><F0A48FB8><EFBFBD>
<0A><EFBFBD> <20><>捂 80/TCP    <20><EFBFBD>嚗间PC蝵烐挾嚗?72.16.0.0/12嚗? # Nginx
<0A><EFBFBD> <20><>捂 22/TCP    <20><EFBFBD>嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD><EFBFBD>砍恕IP             # SSH蝞∠<E89D9E>
<0A><EFBFBD> <20><EFBFBD> <20><><EFBFBD>?      <20><EFBFBD>嚗?.0.0.0/0                # 暺䁅恕<E48185><EFBFBD>

<0A>箸䲮<E7AEB8>𤏸<EFBFBD><F0A48FB8><EFBFBD>
<0A><EFBFBD> <20><><20><><EFBFBD>?      <20><EFBFBD>嚗?.0.0.0/0                # <20><>捂霈輸䔮<E8BCB8><EFBFBD>

撉諹<EFBFBD>摰匧<EFBFBD><EFBFBD>滨蔭

# 隞𤾸<E99A9E>蝵烐<E89DB5>霂𤏪<E99C82>摨磰砲憭梯揖嚗?telnet ECS<43><EFBFBD>IP 6379
# 摨磰砲頞<E7A0B2>𧒄<EFBFBD>𡝗<EFBFBD>蝏肽<E89D8F><E882BD>?
telnet ECS<43><EFBFBD>IP 8080
# 摨磰砲頞<E7A0B2>𧒄<EFBFBD>𡝗<EFBFBD>蝏肽<E89D8F><E882BD>?
# 隞竚PC<50><43><EFBFBD>霂𤏪<E99C82>摨磰砲<E7A3B0>𣂼<EFBFBD>嚗?# <20>沒AE摨𠉛鍂銝剜<E98A9D>銵?curl http://172.16.x.x  # Dify<66><79><EFBFBD><EFBFBD><EFBFBD>
# 摨磰砲餈𥪜<E9A488> Dify <20><><EFBFBD>摨?```

#### <20>湔鰵<E6B994><E9B0B5><EFBFBD>獢?
- <20>𩤃<EFBFBD> `03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md`嚗𡁻<EFBFBD><EFBFBD>"docker-compose.yaml<6D>滨蔭"蝡㰘<EFBFBD>撘箄<EFBFBD>蝡臬藁摰匧<EFBFBD>

---

### 5. Nginx client_max_body_size - <20><EFBFBD>憭扳<E686AD>隞嗡<E99A9E>隡?潃鐥<E6BD83>潃鐥<E6BD83>

**<2A><EFBFBD>銝仿<E98A9D>摨佗<E691A8>P2嚗<32><E59A97><EFBFBD>穿<EFBFBD>**

#### <20><EFBFBD><E6A185>讛膩

<EFBFBD><EFBFBD>PDF<EFBFBD><EFBFBD><EFBFBD>之嚗?0-50MB嚗?Nginx暺䁅恕<E48185>𣂼<EFBFBD>嚗?MB 蝏𤘪<E89D8F>嚗𡁶鍂<F0A181B6><EFBFBD>隡惩之<E683A9><E4B98B><EFBFBD><EFBFBD><E59789>?413 Request Entity Too Large


#### 閫<><E996AB><EFBFBD><EFBFBD>

**<2A>滨垢Nginx<6E>滨蔭**

```nginx
# frontend-v2/nginx.conf.template
http {
    # <20>𩤃<EFBFBD> <20><EFBFBD>嚗𡁏𣈲<F0A1818F><F0A388B2><EFBFBD><E4B98B>辣銝𠹺<E98A9D>
    client_max_body_size 50M;
    
    # <20>𩤃<EFBFBD> <20><EFBFBD>嚗𡁜<E59A97><F0A1819C>症zip嚗㇌eact憭找<E686AD>蝘浥S嚗?    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;
    gzip_comp_level 6;
    
    server {
        listen 8080;
        server_name _;
        
        # <20>寧𤌍敶?        root /usr/share/nginx/html;
        index index.html;
        
        # API<50><EFBFBD><EFBFBD><E99A9E>
        location /api/ {
            proxy_pass http://${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT}/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            
            # <20>𩤃<EFBFBD> <20><EFBFBD>嚗帋誨<E5B88B><E8AAA8><EFBFBD><EFBFBD><EFBFBD>蝵?            proxy_connect_timeout 120s;
            proxy_send_timeout 120s;
            proxy_read_timeout 120s;
        }
        
        # SPA頝舐眏
        location / {
            try_files $uri $uri/ /index.html;
        }
        
        # <20>亙熒璉<E78692><E79289>?        location /health {
            access_log off;
            return 200 "healthy\n";
            add_header Content-Type text/plain;
        }
    }
}

<EFBFBD>湔鰵<EFBFBD><EFBFBD><EFBFBD>獢?

  • <EFBFBD>𩤃<EFBFBD> 06-<2D>滨垢Nginx-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md嚗𡁻<EFBFBD><EFBFBD>銁"nginx.conf.template"蝡㰘<E89DA1>憓𧼮<E68693><F0A7BCAE>滨蔭

6. Python Workers<72>𣂼<EFBFBD> - <20>脫迫OOM 潃鐥<E6BD83>潃鐥<E6BD83>潃?

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P1嚗<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

PyMuPDF/Nougat OCR<43>𧼮虜<F0A7BCAE><E8999C><EFBFBD>摮矋<E691AE><E79F8B>蓥葵霂瑟<E99C82><E7919F><EFBFBD><E888AA>删鍂500MB-1GB嚗?SAE<41>滨蔭嚗?GB<47><42><EFBFBD><><E68692>Gunicorn workers餈<73><E9A488>嚗䔶<E59A97>撖潸稲OOM嚗㇉ut of Memory嚗?```

#### 閫<><E996AB><EFBFBD><EFBFBD>

**Dockerfile<6C>滨蔭**

```dockerfile
# extraction_service/Dockerfile

# 餈鞱<E9A488><E99EB1>嗆挾
FROM python:3.11-slim

# ... <20><EFBFBD><E597A1>滨蔭 ...

# <20>𩤃<EFBFBD> <20>喲睸嚗𡁻<E59A97><F0A181BB>鈍orkers<72>脫迫OOM
CMD ["gunicorn", "app.main:app", \
     "--workers", "2", \
     "--worker-class", "uvicorn.workers.UvicornWorker", \
     "--bind", "0.0.0.0:8000", \
     "--timeout", "120", \
     "--max-requests", "100", \
     "--max-requests-jitter", "10", \
     "--access-logfile", "-", \
     "--error-logfile", "-"]

# workers=2: <20><>憭?銝泡orker嚗?GB<47><42><EFBFBD><EFBFBD>𣂼<EFBFBD>嚗?# timeout=120: <20>蓥葵霂瑟<E99C82><E7919F><EFBFBD>憭?20蝘𡜐<E89D98>OCR<43><EFBFBD><EFBFBD><E695BA>嚗?# max-requests=100: 100銝芾窈瘙<E7AA88><E79899><EFBFBD>滚鍳worker嚗<72>俈甇<E79487>摮䀹<E691AE>瞍𧶏<E79E8D>

SAE<EFBFBD>滨蔭

# SAE<41><EFBFBD><E689B9>?> 摨𠉛鍂<F0A0899B>滨蔭 > 摰硺<E691B0><EFBFBD>
CPU: 1<>?<3F><><EFBFBD>: 2GB  # <20>𩤃<EFBFBD> 銝滩<E98A9D>雿𦒘<E99BBF>2GB

# 摰硺<E691B0><E7A1BA><EFBFBD>
<0A><>撠誩<E692A0>靘𧢲㺭: 1
<0A><>憭批<E686AD>靘𧢲㺭: 3嚗<33><EFBFBD><EFBFBD><E6A0BC>讛䌊<E8AE9B><EFBFBD>摰對<E691B0>

Workers<EFBFBD><EFBFBD>霈∠<EFBFBD><EFBFBD><EFBFBD>

# 蝏誯<E89D8F><E8AAAF><EFBFBD>
workers = (CPU<EFBFBD>豢㺭 <EFBFBD> 2) + 1

# 雿<>笆鈭𤾸<E988AD>摮睃<E691AE><E79D83><EFBFBD><EFBFBD>摨𠉛鍂嚗<E98D82><E59A97>PDF閫<46><E996AB>嚗?workers = min((<28><><EFBFBD>GB / <20>嫤orker<65><72><EFBFBD>GB), (CPU<50>豢㺭 <20> 2) + 1)

# 蝷箔<E89DB7>嚗锭AE 1<>?GB
<EFBFBD>嫤orker<EFBFBD><EFBFBD><EFBFBD> <EFBFBD>?800MB嚗yMuPDF + Nougat嚗?workers = min(2GB / 0.8GB, 1<EFBFBD>2+1) = min(2.5, 3) = 2

# 蝏栞捏嚗鯱orkers=2 <20><EFBFBD><E887AC><EFBFBD>?```

#### <20>烐綉OOM

```bash
# SAE<41><EFBFBD><E689B9>?> <20>烐綉 > <20><><EFBFBD>雿輻鍂<E8BCBB>?# 憒<><E68692>蝏誩虜颲曉<E9A2B2>90%+嚗諹秩<E8ABB9>𡡞<EFBFBD><EFBFBD><E996AC>
# 1. <20><EFBFBD>workers嚗<73><E59A97>2<EFBFBD><EFBFBD>1嚗?# 2. 憓𧼮<E68693><F0A7BCAE><EFBFBD><EFBFBD><EFBFBD><E59A97>2GB<47><42><EFBFBD>4GB嚗?# 3. 隡睃<E99AA1><EFBFBD><E99A9E><EFBFBD><E59A97>撠穃<E692A0>摮睃<E691AE><E79D83><EFBFBD>

<EFBFBD>湔鰵<EFBFBD><EFBFBD><EFBFBD>獢?

  • <EFBFBD>𩤃<EFBFBD> 04-Python敺格<E695BA><E6A0BC>?SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md嚗𡁻<EFBFBD><EFBFBD>銁"Dockerfile"蝡㰘<E89DA1>撘箄<E69298>workers<72>𣂼<EFBFBD>

<EFBFBD><EFBFBD><><E69298>𤏸<EFBFBD>霂閙<E99C82>雿喳<E99BBF>頝?

7. SSH<53><EFBFBD> - <20>砍𧑐<E7A08D><EFBFBD>RDS<44>唳旿摨?潃鐥<E6BD83>潃鐥<E6BD83>

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>睲噶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧼮<EFBFBD><EFBFBD><EFBFBD>嚗䔶<EFBFBD>撘箇<EFBFBD><EFBFBD><EFBFBD>嚗?

<EFBFBD>箸艶

<EFBFBD><EFBFBD>睲犖<EFBFBD><EFBFBD><EFBFBD>鍂Navicat/DBeaver<65><EFBFBD>RDS<44>唳旿
雿<>DS<44><EFBFBD>霈禽PC<50><43><EFBFBD>霈輸䔮
閫<><E996AB>嚗𡁻<E59A97><EFBFBD>ECS雿靝蛹頝單踎<E596AE><EFBFBD>撱箇<E692B1>SSH<53><EFBFBD>

<EFBFBD><EFBFBD>甇仿炊

甇仿炊1嚗𡁶靽𨎊CS<EFBFBD>农SH霈輸䔮<EFBFBD><EFBFBD><EFBFBD>

# <20>砍𧑐<E7A08D><F0A79190><EFBFBD>SSH撖<48>𤨎嚗<F0A4A88E><E59A97><EFBFBD>𡏭<EFBFBD>瘝⊥<E7989D>嚗?ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 撠<><E692A0><EFBFBD>交溶<E4BAA4><EFBFBD>ECS
# ECS<43><EFBFBD><E689B9>?> 摰硺<E691B0> > 餈𦦵<E9A488>餈墧𦻖 > <20>滨蔭撖<E894AD>𤨎撖?# <20>𤥁<EFBFBD><F0A4A581><EFBFBD><EFBFBD>冽溶<E586BD><EFBFBD> ~/.ssh/authorized_keys

甇仿炊2嚗𡁜遣蝡喹SH<EFBFBD><EFBFBD>

# <20><EFBFBD>
ssh -N -L <20>砍𧑐蝡臬藁:RDS<44><53><EFBFBD><EFBFBD><EFBFBD>:RDS蝡臬藁 root@ECS<43><EFBFBD>IP -i 撖<>𤨎<EFBFBD><F0A4A88E># 蝷箔<E89DB7>
ssh -N -L 5433:rm-bp1xxxxx.pg.rds.aliyuncs.com:5432 \
    root@120.55.xx.xx \
    -i ~/.ssh/dify-ecs.pem

# <20><>㺭霂湔<E99C82>嚗?# -N: 銝齿<E98A9D>銵諹<E98AB5>蝔见𦶢隞歹<E99A9E><E6ADB9>芸遣蝡钅银<E99285>?# -L: <20>砍𧑐蝡臬藁頧砍<E9A0A7>
# 5433: <20>砍𧑐<E7A08D>穃𨯬蝡臬藁嚗<E89781><E59A97><EFBFBD><EFBFBD><E6BBA2>砍𧑐PostgreSQL 5432<33><EFBFBD>嚗?# rm-bp1xxxxx...: RDS<44><53><EFBFBD><EFBFBD><EFBFBD>
# 5432: RDS蝡臬藁

甇仿炊3嚗鐭avicat餈墧𦻖

餈墧𦻖蝐餃<EFBFBD>嚗䥪ostgreSQL
銝餅㦤嚗饝ocalhost
蝡臬藁嚗?433
<0A><EFBFBD><E586BD><EFBFBD>aiclinical_rw
撖<><E69296>嚗𡄯<E59A97>RDS撖<53><E69296>嚗?<3F>唳旿摨橒<E691A8>ai_clinical_research

瘚贝<E7989A>餈墧𦻖 <20>?<3F>𣂼<EFBFBD>嚗?```

**甇仿炊4嚗𡁜<E59A97><F0A1819C><EFBFBD>銵屸银<E5B1B8><EFBFBD><E6A992><EFBFBD><EFBFBD>**

```bash
# <20><EFBFBD>1嚗䭰ohup<75>𤾸蝱餈鞱<E9A488>
nohup ssh -N -L 5433:rm-xxxxx.pg.rds.aliyuncs.com:5432 \
    root@ECS-IP -i key.pem > /dev/null 2>&1 &

# <20><EFBFBD>2嚗𡁜<E59A97>撱漳ystemd<6D>滚𦛚嚗𡿨inux嚗?# /etc/systemd/system/rds-tunnel.service
[Unit]
Description=SSH Tunnel to RDS
After=network.target

[Service]
Type=simple
User=your-user
ExecStart=/usr/bin/ssh -N -L 5433:rm-xxxxx.pg.rds.aliyuncs.com:5432 root@ECS-IP -i /home/your-user/.ssh/key.pem
Restart=always

[Install]
WantedBy=multi-user.target

# <20>臬𢆡<E887AC>滚𦛚
sudo systemctl start rds-tunnel
sudo systemctl enable rds-tunnel

摰匧<EFBFBD>瘜冽<EFBFBD>鈭钅★

<EFBFBD>𩤃<EFBFBD> 銝滩<E98A9D><EFBFBD>SH撖<48>𤨎<EFBFBD>𣂷漱<F0A382B7>蚣it
<0A>𩤃<EFBFBD> 摰𡁏<E691B0>頧格揢ECS<43><53>SH撖<48>𤨎
<0A>𩤃<EFBFBD> <20>芸銁撘<E98A81><E69298>𤑳㴓憓<E3B493><EFBFBD><EFBFBD><E58981>煺漣<E785BA><EFBFBD><E887AC><EFBFBD>VPN霈輸䔮

8. <20>嗅躹蝏煺<E89D8F><E785BA>滨蔭 - <20>脫迫<E884AB><EFBFBD><E4BA99>園𡢿瘛瑚僚 潃鐥<E6BD83>潃鐥<E6BD83>潃?

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P2嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

銝滚<EFBFBD><EFBFBD>滚𦛚<EFBFBD><EFBFBD>𧒄<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>撖潸稲嚗?<3F>?<3F><EFBFBD><E4BA99>園𡢿撖嫣<E69296>銝𠺪<E98A9D><F0A0BAAA>滨垢14:00嚗<30><E59A97>蝡?6:00嚗?<3F>?pg-boss摰𡁏𧒄隞餃𦛚<E9A483><EFBFBD>霂舀𧒄<E88880>渲圻<E6B8B2>?<3F>?<3F><EFBFBD><E586BD><EFBFBD><E8A781><EFBFBD>𧒄<EFBFBD><EFBFBD><E6B994>躰秤
<0A>?<3F>埝䰻<E59F9D><E4B0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𥡝㜃

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>雿輻鍂 Asia/Shanghai <20>嗅躹

# backend/Dockerfile - Node.js<6A>𡒊垢
FROM node:22-alpine
RUN apk add --no-cache tzdata
ENV TZ=Asia/Shanghai
# ... <20><EFBFBD><E597A1>滨蔭

# extraction_service/Dockerfile - Python敺格<E695BA><E6A0BC>?FROM python:3.11-slim
RUN apt-get update && apt-get install -y tzdata
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# ... <20><EFBFBD><E597A1>滨蔭

# frontend-v2/Dockerfile - <20>滨垢嚗<E59EA2><EFBFBD>滨蔭嚗?FROM nginx:1.25-alpine
RUN apk add --no-cache tzdata
ENV TZ=Asia/Shanghai
# ... <20><EFBFBD><E597A1>滨蔭
-- RDS PostgreSQL <20>嗅躹<E59785>滨蔭
-- RDS<44><EFBFBD><E689B9>?> <20><>㺭霈曄蔭 > timezone
timezone = Asia/Shanghai

*撉諹<EFBFBD><EFBFBD>嗅躹嚗?

# <20><EFBFBD>摰孵膥<E5ADB5>嗅躹
docker exec <container-id> date
# 摨磰砲<E7A3B0>曄內嚗锭at Dec 14 14:30:00 CST 2024

# <20><EFBFBD>RDS<44>嗅躹
psql -c "SHOW timezone;"
# 摨磰砲<E7A3B0>曄內嚗鋫sia/Shanghai

敶勗<EFBFBD><EFBFBD><EFBFBD>

  • <EFBFBD>?Node.js<6A>𡒊垢嚗𡁻<E59A97><EFBFBD><EFBFBD>蚤ockerfile
  • <EFBFBD>?Python敺格<E695BA><E6A0BC><EFBFBD><E288B4><EFBFBD><EFBFBD><EFBFBD>蚤ockerfile
  • <EFBFBD>?<3F>滨垢Nginx嚗𡁜歇甇<E6AD87><EFBFBD>滨蔭
  • <EFBFBD>?RDS PostgreSQL嚗𡁻<E59A97><EFBFBD><EFBFBD><EFBFBD><E5ADB5>?

靽桀<EFBFBD>甇仿炊

# 1. 靽格㺿Node.js<6A>𡒊垢Dockerfile
cd backend
# <20>求ockerfile銝剜溶<E5899C>䭾𧒄<E4ADBE><EFBFBD>蝵殷<E89DB5><EFBFBD><E996AB><EFBFBD>寧內靘页<E99D98>

# 2. 靽格㺿Python敺格<E695BA><E6A0BC>ockerfile
cd extraction_service
# <20>求ockerfile銝剜溶<E5899C>䭾𧒄<E4ADBE><EFBFBD>蝵殷<E89DB5><EFBFBD><E996AB><EFBFBD>寧內靘页<E99D98>

# 3. 靽格㺿RDS<44>嗅躹
# RDS<44><EFBFBD><E689B9>?> <20><>㺭霈曄蔭 > timezone > Asia/Shanghai
# <20><><EFBFBD><E996AC><EFBFBD>爹DS摰硺<E691B0>

# 4. 撉諹<E69289>
docker exec backend-container date
docker exec python-container date
psql -h rds-host -c "SHOW timezone;"

9. <20>𨅯<EFBFBD><F0A885AF><EFBFBD>蝑𣇉裦 - <20>脫迫隞<E8BFAB><E99A9E>銝齿凒<E9BDBF>?潃鐥<E6BD83>潃鐥<E6BD83>潃?

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P2嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

<EFBFBD>箸艶嚗?撘<><E69298>𤏸<EFBFBD><F0A48FB8><EFBFBD>嫣誨<E5ABA3>?<3F>?<3F><><EFBFBD>𨅯<EFBFBD> <20>?<3F><EFBFBD><E588B8><EFBFBD>ACR嚗<52><E59A97><EFBFBD>𩥈1.0.0嚗?<3F>?SAE<41>函蔡 <20>?<3F>𤑳緵隞<E7B7B5><E99A9E>瘝⊥凒<E28AA5><EFBFBD><EFBFBD><E59A97>

<0A><EFBFBD>嚗?SAE暺䁅恕<E48185>𨅯<EFBFBD><F0A885AF><EFBFBD>蝑𣇉裦<F0A38789><EFBFBD><E888AA>?IfNotPresent
憒<><E68692><EFBFBD>砍𧑐撌脫<E6928C> v1.0.0嚗䔶<EFBFBD>隡𡁻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?```

#### 閫<><E996AB><EFBFBD><EFBFBD>

**<2A><EFBFBD>A嚗𡁏<E59A97>甈⊿<E79488>蝵脖蝙<E88496>冽鰵<E586BD><E9B0B5>𧋦<EFBFBD><EFBFBD>撘箇<E69298><E7AE87><EFBFBD>嚗?*

```bash
# 雿輻鍂霂凋<E99C82><E5878B>𣇉<EFBFBD><F0A38789>砍噡
v1.0.0 <20>?v1.0.1 <20>?v1.0.2 ...

# <20>碶蝙<E7A2B6>冽𧒄<E586BD><EFBFBD>
v20251214-1430 <20>?v20251214-1530 ...

# <20>碶蝙<E7A2B6>沁it SHA
v-a1b2c3d <20>?v-b2c3d4e ...

# <20><>遣蝷箔<E89DB7>
docker build -t backend:v1.0.1 .
docker tag backend:v1.0.1 registry.cn-hangzhou.aliyuncs.com/aiclinical/backend:v1.0.1
docker push registry.cn-hangzhou.aliyuncs.com/aiclinical/backend:v1.0.1

# SAE<41>函蔡<E587BD><EFBFBD>㗇𥋘<E39787><EFBFBD><E59581>砍噡

<EFBFBD><EFBFBD>B嚗𡁻<EFBFBD>蝵娟AE<EFBFBD>𨅯<EFBFBD><EFBFBD><EFBFBD>蝑𣇉裦嚗<EFBFBD><EFBFBD>霂閧㴓憓<EFBFBD><EFBFBD>

# SAE<41><EFBFBD><E689B9>?> 摨𠉛鍂<F0A0899B>滨蔭 > <20>𨅯<EFBFBD>霈曄蔭
<0A>𨅯<EFBFBD><F0A885AF><EFBFBD>蝑𣇉裦嚗鋫lways

# <20>𩤃<EFBFBD> 瘜冽<E7989C>嚗?# - 瘥𤩺活<F0A4A9BA>滚鍳<E6BB9A><EFBFBD><E8B3AD><EFBFBD><E58CA7>𨅯<EFBFBD><EFBFBD><EFBFBD><EFBFBD><E587BD><EFBFBD>
# - <20><><EFBFBD>瘚贝<E7989A><E8B49D><EFBFBD>嚗䔶<E59A97><E494B6><EFBFBD><E588BB>煺漣<E785BA><EFBFBD>

<EFBFBD><EFBFBD>雿喳<EFBFBD>頝?

<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>
<EFBFBD>煺漣<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>A嚗<EFBFBD><EFBFBD><EFBFBD>砍噡蝞∠<EFBFBD>嚗? <EFBFBD><EFBFBD>𧋦<EFBFBD>航蕭皞荔<EFBFBD>蝔喳<EFBFBD>
瘚贝<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>B嚗㇁lways<EFBFBD><EFBFBD>嚗? 憪讠<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嫣噶
*<EFBFBD><EFBFBD>𤑳㴓憓? <EFBFBD><EFBFBD>A <EFBFBD><EFBFBD>瘛瑚僚

*<EFBFBD>?銝滩<E98A9D>嚗?

# 憪讠<E686AA>雿輻鍂 latest <20><>倌嚗<E5808C><E59A97>瘜閗蕭皞舐<E79A9E><E88890>穿<EFBFBD>
docker tag backend:latest ...

10. Python<6F>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>蝞∠<E89D9E> - <20>脫迫OOM 潃鐥<E6BD83>潃鐥<E6BD83>

<EFBFBD><EFBFBD>銝仿<EFBFBD>摨佗<EFBFBD>P2嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

Python<EFBFBD>滚𦛚嚗㇊yMuPDF/Nougat嚗匧<E59A97>摮睃<E691AE><E79D83><EFBFBD><EFBFBD>摰寞<E691B0>OOM
<0A>?<3F>蓥葵PDF OCR<43><EFBFBD><E888AA>删鍂500MB-1GB<47><42><EFBFBD>
<0A>?憭帋葵撟嗅<E6929F>霂瑟<E99C82>隡𡁜紡<F0A1819C><EFBFBD>摮䀹滯<E480B9>?<3F>?SAE暺䁅恕2GB<47><42><EFBFBD><EFBFBD><EFBFBD>銝滚<E98A9D>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

*<EFBFBD>聢撱箄悅嚗?

<EFBFBD>箸艶 CPU <EFBFBD><EFBFBD><EFBFBD> Workers <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*<EFBFBD><EFBFBD><EFBFBD>? 1<EFBFBD>? 2GB 2 <EFBFBD><EFBFBD>𠠬DF閫<EFBFBD><EFBFBD>
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>? 2<EFBFBD>? 4GB 3 <EFBFBD><EFBFBD>鉄OCR嚗𠃊ougat嚗?
*憓𧼮撩<EFBFBD>? 2<EFBFBD>? 8GB 4 憭折<EFBFBD>OCR + 擃睃僎<E79D83>?

Dockerfile隡睃<EFBFBD><EFBFBD>歇摨𠉛鍂嚗㚁<EFBFBD>

# extraction_service/Dockerfile
CMD ["gunicorn", "main:app", \
     "--bind", "0.0.0.0:8000", \
     "--workers", "2", \              # <20>𩤃<EFBFBD> <20>𣂼<EFBFBD>撟嗅<E6929F>
     "--timeout", "120", \             # <20>𩤃<EFBFBD> 2<><32><EFBFBD><EFBFBD>𧒄
     "--max-requests", "100", \        # <20>𩤃<EFBFBD><><E686AD>100銝芾窈瘙<E7AA88><E79899><EFBFBD>滚鍳worker
     "--max-requests-jitter", "10"]    # <20>𩤃<EFBFBD> <20>𤩺㦤<F0A4A9BA>硋𢆡嚗屸<E59A97><E5B1B8><EFBFBD><E6BB9A><EFBFBD><E59C92>?```

**<2A>烐綉銝𤾸<E98A9D>霅佗<E99C85>**

```bash
# SAE<41><EFBFBD><E689B9>?> <20>烐綉<E78390>𡃏郎 > <20>𥕦遣<F0A595A6>𡃏郎閫<E9838E><E996AB>
<EFBFBD><EFBFBD><EFBFBD>嚗𡁜<EFBFBD>摮䀝蝙<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>> 80%
<EFBFBD><EFBFBD>嚗𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡁶䰻 + <20>芸𢆡<E88AB8>拙捆嚗<E68D86><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>OOM

*<EFBFBD><EFBFBD>1嚗𡁜<EFBFBD>蝥批<EFBFBD>摮矋<EFBFBD><EFBFBD><EFBFBD>嚗?

# SAE<41><EFBFBD><E689B9>?> 摨𠉛鍂<F0A0899B>滨蔭 > 閫<>聢靚<E881A2>
1<>?GB <20>?2<>?GB嚗<42><E59A97><EFBFBD>覉?00/<2F><><EFBFBD>

*<EFBFBD><EFBFBD>2嚗𡁻<EFBFBD><EFBFBD>嗅僎<EFBFBD>𡢅<EFBFBD>銝湔𧒄嚗?

# 靽格㺿Dockerfile
CMD ["gunicorn", "main:app", \
     "--workers", "1", \      # <20><EFBFBD>撟嗅<E6929F>
     "--threads", "2"]        # 雿輻鍂蝥輻<E89DA5><E8BCBB><EFBFBD>餈𤤿<E9A488>

11. OSS蝑曉<E89D91>URL - 摰匧<E691B0><E58CA7><EFBFBD><EFBFBD>隞嗉挪<E59789>?潃鐥<E6BD83>潃鐥<E6BD83>

*<EFBFBD><EFBFBD><EFBFBD>摰匧<EFBFBD><EFBFBD><EFBFBD>雿喳<EFBFBD>頝?

<EFBFBD><EFBFBD>

<EFBFBD><EFBFBD>OSS Bucket霈曄蔭銝摺ublic嚗?<3F>?隞颱<E99A9E>鈭粹<E988AD><E7B2B9>臭誑霈輸䔮<E8BCB8><E494AE><EFBFBD><EFBFBD>隞?<3F>?<3F><EFBFBD>餈質葵靚<E891B5><EFBFBD><EFBFBD><E6A190><EFBFBD><E88AAF><EFBFBD><0A>?<3F><EFBFBD><E4ADBE><EFBFBD>霈輸䔮<E8BCB8><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

OSS Bucket<65>滨蔭

# OSS<53><EFBFBD><E689B9>?> Bucket<65>𡑒” > aiclinical-data-prod
# 霂餃<E99C82><E9A483><EFBFBD><EFBFBD>嚗𡁶<E59A97><F0A181B6><EFBFBD>Private嚗?```

**<2A>𡒊垢<F0A1928A><E59EA2><EFBFBD>蝑曉<E89D91>URL**

```typescript
// backend/src/common/storage/OSSAdapter.ts
import OSS from 'ali-oss'

export class OSSAdapter {
  private client: OSS
  
  constructor() {
    this.client = new OSS({
      region: process.env.OSS_REGION!,
      accessKeyId: process.env.OSS_ACCESS_KEY_ID!,
      accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET!,
      bucket: process.env.OSS_BUCKET!
    })
  }
  
  /**
   * <20><><EFBFBD>蝑曉<E89D91>URL嚗?撠𤩺𧒄<F0A4A9BA><EFBFBD><E39787><EFBFBD><EFBFBD>
   */
  async getSignedUrl(objectKey: string, expiresIn: number = 3600): Promise<string> {
    try {
      const url = this.client.signatureUrl(objectKey, {
        expires: expiresIn,  // 蝘𡜐<E89D98>暺䁅恕1撠𤩺𧒄
        method: 'GET'
      })
      
      return url
    } catch (error) {
      console.error('[OSS] <20><><EFBFBD>蝑曉<E89D91>URL憭梯揖:', error)
      throw error
    }
  }
  
  /**
   * 銝𠹺<E98A9D><F0A0B9BA><EFBFBD>辣
   */
  async uploadFile(objectKey: string, filePath: string): Promise<string> {
    try {
      const result = await this.client.put(objectKey, filePath)
      console.log(`[OSS] <20><>辣銝𠹺<E98A9D><F0A0B9BA>𣂼<EFBFBD>: ${objectKey}`)
      
      // 餈𥪜<E9A488>蝑曉<E89D91>URL嚗<4C><E59A97><EFBFBD><EFBFBD><EFBFBD>URL嚗?      return this.getSignedUrl(objectKey)
    } catch (error) {
      console.error('[OSS] <20><>辣銝𠹺<E98A9D>憭梯揖:', error)
      throw error
    }
  }
}

API餈𥪜<EFBFBD>蝑曉<EFBFBD>URL

// backend/src/modules/pkb/documentController.ts
router.get('/documents/:id/download', async (req, res) => {
  const { id } = req.params
  
  // 1. <20>亥砭<E4BAA5><E7A0AD><EFBFBD><EFB99D><EFBFBD>?  const document = await prisma.document.findUnique({
    where: { id }
  })
  
  if (!document) {
    return res.status(404).json({ error: '<27><>﹝銝滚<E98A9D><E6BB9A>? })
  }
  
  // 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>靽萘鍂<E89098><EFBFBD><E7919F><EFBFBD><EFBFBD><EFBFBD>
  if (document.userId !== req.user.id) {
    return res.status(403).json({ error: '<EFBFBD><EFBFBD>霈輸䔮甇斗<EFBFBD>? })
  }
  
  // 3. <20><><EFBFBD>蝑曉<E89D91>URL嚗?撠𤩺𧒄<F0A4A9BA><EFBFBD>嚗?  const ossAdapter = new OSSAdapter()
  const signedUrl = await ossAdapter.getSignedUrl(document.ossKey, 3600)
  
  // 4. 餈𥪜<E9A488>蝑曉<E89D91>URL
  res.json({
    url: signedUrl,
    expiresIn: 3600,
    filename: document.filename
  })
})

<EFBFBD>滨垢雿輻鍂蝑曉<EFBFBD>URL

// frontend-v2/src/api/documents.ts
export async function downloadDocument(documentId: string) {
  // 1. 靚<><EFBFBD>𡒊垢API<50><EFBFBD>蝑曉<E89D91>URL
  const response = await fetch(`/api/v1/pkb/documents/${documentId}/download`, {
    headers: {
      'Authorization': `Bearer ${getToken()}`
    }
  })
  
  const { url, filename } = await response.json()
  
  // 2. 雿輻鍂蝑曉<E89D91>URL銝贝蝸<E8B49D><E89DB8>  const link = document.createElement('a')
  link.href = url  // 蝑曉<E89D91>URL嚗?撠𤩺𧒄<F0A4A9BA><EFBFBD>
  link.download = filename
  link.click()
}

隡睃飵

<EFBFBD>?摰匧<E691B0>嚗𡁜蘨<F0A1819C><EFBFBD><E39787><EFBFBD><EFBFBD><EFBFBD><E7919F>質繮<E8B3AA>𣇉倌<F0A38789>䔛RL
<0A>?<3F><EFBFBD>嚗䦧RL<52>芸𢆡餈<F0A286A1><E9A488>嚗?撠𤩺𧒄<F0A4A9BA>𤾸仃<F0A4BEB8><E4BB83><EFBFBD>
<0A>?摰∟恣嚗𡁜虾隞亥扇敶閗<E695B6>霈輸䔮鈭<E494AE>𪑛鈭𥟇<E988AD>隞?<3F>?<3F>菜暑嚗𡁜虾隞亙𢆡<E4BA99><F0A286A1><EFBFBD><EFBFBD><EFBFBD><E6B8B2><EFBFBD>𧒄<EFBFBD>?```

---

## <20><> <20><EFBFBD>

### 敹<>◆蝡见朖靽桀<E99DBD><E6A180><EFBFBD>䔮憸?
| # | <20><EFBFBD> | 銝仿<E98A9D>摨?| 敶勗<E695B6> | 靽桀<E99DBD><E6A180>園𡢿 |
|---|------|--------|------|---------|
| 1 | **NAT蝵穃<E89DB5>蝻箏仃** | P0 | <20><><EFBFBD>𡅅I<F0A18585><EFBFBD>銝滚虾<E6BB9A>?| 15<31><35><EFBFBD> |
| 2 | **Dify API Key甇駁<E79487>** | P1 | PKB璅<E79285>銝滚虾<E6BB9A>?| 10<31><30><EFBFBD><EFBFBD><E59A97><EFBFBD>嗆挾<E59786>函蔡嚗?|
| 3 | **HTTP頞<50>𧒄<EFBFBD><EFBFBD>蝵?* | P1 | 餈墧𦻖瘜<F0A6BB96><E7989C>嚗𣬚頂蝏笔援皞?| 5<><35><EFBFBD><EFBFBD><EFBFBD><E8AAA8><EFBFBD><EFBFBD> |
| 4 | **ECS蝡臬藁撖孵<E69296><EFBFBD><E69298>?* | P0 | 摰匧<E691B0>憌𡡞埯嚗<E59FAF>虾鋡急𤫇<E680A5>?| 5<><35><EFBFBD>嚗Ê̌ocker-compose靽格㺿嚗?|
| 5 | **Python Workers餈<73><E9A488>** | P1 | OOM嚗峕<E59A97><E5B395>援皞?| 2<><32><EFBFBD>嚗㇄ockerfile靽格㺿嚗?|
| 6 | **Nginx<6E><78>辣憭批<E686AD><E689B9>𣂼<EFBFBD>** | P2 | 憭扳<E686AD>隞嗡<E99A9E>隡惩仃韐?| 2<><32><EFBFBD>嚗ěginx.conf靽格㺿嚗?|

### <20><EFBFBD><EFBFBD><E99BBF><EFBFBD><E695B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
| # | 隡睃<E99AA1> | 隞瑕<E99A9E>?| 摰墧鴌<E5A2A7>園𡢿 |
|---|------|------|---------|
| 7 | **SSH<53><EFBFBD>** | 撘<><E69298>睲噶<E79DB2><EFBFBD>?| 10<31><30><EFBFBD> |
| 8 | **OSS蝑曉<E89D91>URL** | 摰匧<E691B0><E58CA7><EFBFBD>雿喳<E99BBF>頝?| 30<33><30><EFBFBD><EFBFBD><EFBFBD><E8AAA8><EFBFBD><EFBFBD> |

### 銝衤<E98A9D>甇亥<E79487><E4BAA5>?

<EFBFBD>?1. <20>𥕦遣NAT蝵穃<E89DB5><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?5<><35><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃鐥<E6BD83> <0A>?2. 靽格㺿docker-compose.yaml嚗𠄌CS蝡臬藁摰匧<E691B0>嚗?<3F><><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃鐥<E6BD83> <0A>?3. 靽格㺿Dockerfile嚗㇊ython workers<72>𣂼<EFBFBD>嚗?<3F><><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃?<3F>?4. 靽格㺿nginx.conf嚗<66><E59A97>隞嗅之撠誯<E692A0><E8AAAF><EFBFBD>2<EFBFBD><32><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃?<3F>?5. 靽格㺿<E6A0BC>𡒊垢隞<E59EA2><E99A9E>嚗𠃍TTP頞<50>𧒄嚗?<3F><><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃?<3F>?6. 靽格㺿<E6A0BC>𡒊垢隞<E59EA2><E99A9E>嚗㇄ify摰寥<E691B0>嚗?<3F><><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃?<3F>?7. <20>湔鰵<E6B994>函蔡瘚<E894A1><E7989A><EFBFBD><E59A97><EFBFBD>嗆挾<E59786>函蔡嚗峕<E59A97><EFBFBD><EFBFBD><EFBFBD>潃鐥<E6BD83>潃鐥<E6BD83> <0A>?8. 蝏煺<E89D8F><E785BA>嗅躹<E59785>滨蔭嚗<E894AD><E59A97><EFBFBD><EFBFBD>嚗?5<><35><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃鐥<E6BD83> <0A>?9. <20>滨蔭<E6BBA8>𨅯<EFBFBD><F0A885AF><EFBFBD>蝑𣇉裦嚗<E8A3A6><E59A97><EFBFBD><EFBFBD>嚗?<3F><><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃鐥<E6BD83> <0A>?10. Python<6F><6E><EFBFBD>蝞∠<E89D9E><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?0<><30><EFBFBD>嚗争<E59A97>潃鐥<E6BD83>潃?<3F>?11. 嚗<><EFBFBD><EFBFBD><E39A81>滨蔭SSH<53><EFBFBD><EFBFBD><E59A97><EFBFBD>睲噶<E79DB2><EFBFBD>10<31><30><EFBFBD>嚗?<3F>?12. 嚗<><EFBFBD><EFBFBD>摰䂿緵OSS蝑曉<E89D91>URL嚗<4C><E59A97><EFBFBD><EFBFBD>30<33><30><EFBFBD>嚗? <0A>餉恣嚗𡁜<E59A97><F0A1819C><EFBFBD>靽桀<E99DBD>蝥?0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E58A90>𣇉漲40<34><30><EFBFBD>


---

**<2A><><EFBFBD>𥕦遣鈭綽<E988AD>** AI<41><EFBFBD>  
**<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-12-14  
**<2A><>𧋦嚗?* v1.0  

**<2A><EFBFBD><E8A9A8><EFBFBD>艙嚗𡁜<E59A97><F0A1819C>函洵銝<E6B4B5><E98A9D><EFBFBD>迅摰𡁶洵鈭䎚<E988AD><E48E9A><EFBFBD>拍洵銝?* 潃鐥<E6BD83>潃?