Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_方案B实施总结_2025-12-09.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

8.4 KiB
Raw Blame History

撌亙<EFBFBD>C - <20><EFBFBD>B摰墧鴌<E5A2A7><EFBFBD><EFBFBD><E59A97><EFBFBD>滨鸌畾𠰴<E795BE>蝚西圾<E8A5BF>單䲮獢<E4B2AE><E78DA2>

<EFBFBD><EFBFBD>: 2025-12-09
<EFBFBD><EFBFBD>𧋦: v1.0
摰墧鴌<EFBFBD><EFBFBD>: <20><EFBFBD>B - Python韐蠘提<E8A098><EFBFBD><E5A092>踵揢


<EFBFBD><EFBFBD> <20><EFBFBD><E6A185>峕艶

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

<EFBFBD><EFBFBD>銝𠹺<EFBFBD><EFBFBD><EFBFBD>xcel<EFBFBD><EFBFBD>辣銵典仍<EFBFBD><EFBFBD><EFBFBD><EFBFBD>摮㛖泵嚗<EFBFBD><EFBFBD>渲恣蝞堒<EFBFBD><EFBFBD><EFBFBD>憭梯揖嚗?

蝷箔<EFBFBD>銵典仍:

  • `雿㯄<E99BBF>ɑg嚗头
  • `1.擃䁅<E69383><E48185><EFBFBD><EFBFBD><E59A97>=0嚗峕<E59A97>=1嚗䔶<E59A97><E494B6>仿<EFBFBD>=2嚗头
  • `頨恍<E9A0A8>嚗Ếm嚗头

<EFBFBD>仿<EFBFBD>靽⊥<EFBFBD>:

霈∠<EFBFBD><EFBFBD>堒仃韐伐<EFBFBD><EFBFBD><EFBFBD>撉諹<EFBFBD>憭梯揖: <20><EFBFBD><E7A08D><EFBFBD>鉄銝滚<E98A9D>霈貊<E99C88>摮㛖泵

<EFBFBD><20><EFBFBD><E5AF9E>㗇𥋘

<EFBFBD><EFBFBD>撖寞<EFBFBD>

<EFBFBD><EFBFBD> <EFBFBD>讛膩 隡条<EFBFBD> 蝻箇<EFBFBD> <EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>A <EFBFBD><EFBFBD>雿輻鍂摨誩噡撘閧鍂嚗Ếol_0, col_1嚗? <EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰匧<EFBFBD> <EFBFBD><EFBFBD>雿㯄<EFBFBD>撌殷<EFBFBD>銝滨凒閫? 潃鐥<EFBFBD>
<EFBFBD><EFBFBD>B <EFBFBD><EFBFBD>雿輻鍂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Python韐蠘提<EFBFBD>踵揢 <EFBFBD><EFBFBD>雿㯄<EFBFBD>憟踝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>臬虾<EFBFBD>? <EFBFBD><EFBFBD>摰䂿緵<EFBFBD>踵揢<EFBFBD><EFBFBD> 潃鐥<EFBFBD>潃鐥<EFBFBD>潃?
<EFBFBD><EFBFBD>C <EFBFBD>滨垢<EFBFBD>踵揢<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>蝵𤑳<EFBFBD>隡㰘<EFBFBD> 颲寧<EFBFBD><EFBFBD><EFBFBD><EFBFBD>圈𠗕嚗䔶<EFBFBD><EFBFBD><EFBFBD> 潃鐥<EFBFBD>潃?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>㗇𥋘: <EFBFBD><EFBFBD>B <20>?


<EFBFBD><EFBFBD>儭?<3F><EFBFBD>霈曇恣

<EFBFBD>唳旿瘚?

<EFBFBD><EFBFBD>颲枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
    <20>?
<0A>滨垢嚗帋<E59A97><E5B88B><EFBFBD>kg嚗?/ (頨恍<E9A0A8>嚗Ếm嚗?100)**2
    <20>?
<0A>𡒊垢嚗朞繮<E69C9E>?columnMapping
    <20>?
隡𣳇<E99AA1><EFBFBD>Python: {
  formula: "雿㯄<E99BBF>ɑg嚗?/ (頨恍<E9A0A8>嚗Ếm嚗?100)**2",
  column_mapping: [
    {"originalName": "雿㯄<E99BBF>ɑg嚗?, "safeName": "col_0"},
    {"originalName": "頨恍<E9A0A8>嚗Ếm嚗?, "safeName": "col_1"}
  ]
}
    <20>?
Python<6F>踵揢: col_0 / (col_1/100)**2
    <20>?
<0A><EFBFBD>霈∠<E99C88> <20>?

<EFBFBD>諹提<EFBFBD><EFBFBD>

<EFBFBD> <EFBFBD>諹提 <EFBFBD>喲睸<EFBFBD>?
<EFBFBD>滨垢 UI鈭支<EFBFBD><EFBFBD><EFBFBD><EFBFBD>格𤣰<EFBFBD>? <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>𡒊垢 <EFBFBD><EFBFBD>columnMapping<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Python 隞燑ession<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Python <EFBFBD><EFBFBD><EFBFBD>踵揢<EFBFBD><EFBFBD><EFBFBD>撘𤩺<EFBFBD>銵? <EFBFBD>厰鵭摨行<EFBFBD>摨譌<EFBFBD><EFBFBD>移蝖格𤜯<EFBFBD>?

<EFBFBD>凃 摰墧鴌蝏<E9B48C><E89D8F>

1. <20>滨垢嚗㇃omputeDialog.tsx嚗?

靽脲<EFBFBD>銝滚<EFBFBD> - 撌脩<E6928C>雿輻鍂<E8BCBB><EFBFBD><E7AC94>齿䲮撘?

// <20><EFBFBD><E586BD>孵稬<E5ADB5><EFBFBD><E5A092><EFBFBD>倌嚗峕<E59A97><E5B395><EFBFBD><E4BA99><EFBFBD>獢?
<Tag onClick={() => setFormula(formula + col.name)}>
  {col.name}  {/* <20>曄內<E69B84><EFBFBD><E7AC94><EFBFBD>雿㯄<E99BBF>ɑg嚗?*/}
</Tag>

// <20>𣂷漱<F0A382B7>嗥凒<E597A5><EFBFBD><E4B9A9><EFBFBD><E98DA6><EFBFBD>
onApply({
  newColumnName: "BMI",
  formula: "雿㯄<E99BBF>ɑg嚗?/ (頨恍<E9A0A8>嚗Ếm嚗?100)**2",  // <20><EFBFBD><E7AC94>?
});

2. <20>𡒊垢嚗㇋uickActionController.ts嚗?

靽格㺿: <20><EFBFBD>session撟嗡<E6929F><E597A1>𠸍olumnMapping

// <20><EFBFBD>session嚗<6E><E59A97><EFBFBD>剃olumnMapping嚗?
session = await sessionService.getSession(sessionId);

// 隡𣳇<E99AA1><EFBFBD>QuickActionService
executeResult = await quickActionService.executeCompute(
  fullData, 
  params, 
  session.columnMapping  // <20>?隡𣳇<E99AA1><EFBFBD>撠?
);

3. <20>𡒊垢嚗㇋uickActionService.ts嚗?

靽格㺿: <20>交𤣰撟嗡<E6929F><E597A1>𠸍olumnMapping蝏筢ython

async executeCompute(
  data: any[], 
  params: ComputeParams, 
  columnMapping?: any[]  // <20>?<3F><EFBFBD><E595A3><EFBFBD>): Promise<OperationResult> {
  const response = await axios.post(`${PYTHON_SERVICE_URL}/api/operations/compute`, {
    data,
    new_column_name: params.newColumnName,
    formula: params.formula,
    column_mapping: columnMapping || [],  // <20>?隡𣳇<E99AA1><EFBFBD>撠?
  });
  
  return response.data;
}

4. Python嚗éain.py嚗?

靽格㺿: <20>湔鰵霂瑟<E99C82><E79285>

class ComputeRequest(BaseModel):
    data: List[Dict[str, Any]]
    new_column_name: str
    formula: str
    column_mapping: List[Dict[str, str]] = []  # <20>?<3F><EFBFBD>摮埈挾

@app.post("/api/operations/compute")
async def operation_compute(request: ComputeRequest):
    result_df = compute_column(
        df,
        request.new_column_name,
        request.formula,
        request.column_mapping  # <20>?隡𣳇<E99AA1><EFBFBD>撠?
    )

5. Python嚗Ếompute.py嚗?

<EFBFBD><EFBFBD>摰䂿緵: <20><EFBFBD><E5A092>踵揢<E8B8B5><EFBFBD>

def replace_column_names_in_formula(
    formula: str, 
    column_mapping: List[Dict[str, str]]
) -> str:
    """
    <20>?<3F><EFBFBD>蝞埈<E89D9E>嚗𡁜虾<F0A1819C><EFBFBD><E588A0><EFBFBD><E5A092>踵揢
    """
    safe_formula = formula
    
    # <20>喲睸1嚗𡁏<E59A97><F0A1818F><EFBFBD><E5A092>踹漲<E8B8B9><EFBFBD><E98DA6><EFBFBD>
    # <20><EFBFBD>摮𣂷葡<F0A382B7><EFBFBD>嚗𡁜<E59A97><F0A1819C>踵揢"擃䁅<E69383><E48185><EFBFBD><E8AEA0>?嚗<><E59A97><EFBFBD>踵揢"擃䁅<E69383><E48185>?
    sorted_mapping = sorted(
        column_mapping,
        key=lambda x: len(x['originalName']),
        reverse=True
    )
    
    # <20>喲睸2嚗𡁻<E59A97>𣂷葵蝎曄<E69B84>踵揢嚗<E68FA2><E59A97>雿輻鍂甇<E98D82><E79487>嚗?
    for item in sorted_mapping:
        original = item['originalName']
        safe = item['safeName']
        
        if original in safe_formula:
            safe_formula = safe_formula.replace(original, safe)
    
    return safe_formula

def compute_column(
    df: pd.DataFrame,
    new_column_name: str,
    formula: str,
    column_mapping: Optional[List[Dict[str, str]]] = None
) -> pd.DataFrame:
    """
    <20>?<3F><EFBFBD>B嚗䥪ython韐蠘提<E8A098>踵揢
    """
    # 1. <20>踵揢<E8B8B5><EFBFBD>
    if column_mapping:
        safe_formula = replace_column_names_in_formula(formula, column_mapping)
    else:
        safe_formula = formula
    
    # 2. <20><><EFBFBD><EFBFBD><EFBFBD><E689AF><EFBFBD>
    env = {}
    for item in column_mapping:
        env[item['safeName']] = df[item['originalName']]
    env.update(ALLOWED_FUNCTIONS)
    
    # 3. <20><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><E996AC>蝚阡<E89D9A><EFBFBD><E99C82>嚗?
    result = eval(safe_formula, {"__builtins__": {}}, env)
    
    return df.assign(**{new_column_name: result})

<EFBFBD>?閫<><E996AB><EFBFBD><EFBFBD>䔮憸?

1. <20><EFBFBD>摮㛖泵<E39B96><EFBFBD> <20>?

  • <EFBFBD><EFBFBD>: `雿㯄<E99BBF>ɑg嚗头 <20><>鉄銝剜<E98A9D><E5899C>砍噡
  • <EFBFBD><EFBFBD>: Python雿輻鍂摰匧<E691B0><E58CA7><EFBFBD> col_0嚗䔶<EFBFBD><EFBFBD>㛖鸌畾𠰴<EFBFBD>蝚血蔣<EFBFBD>?

2. 摮𣂷葡<F0A382B7><E891A1><EFBFBD><EFBFBD> <20>?

  • <EFBFBD><EFBFBD>: "擃䁅<E69383><E48185>? <20>?"擃䁅<E69383><E48185><EFBFBD><E8AEA0>? <20><EFBFBD>霂舀𤜯<E88880>?
  • <EFBFBD><EFBFBD>: <20>厰鵭摨血<E691A8><EFBFBD><E98DA6><EFBFBD><EFBFBD><E59A97><EFBFBD>踵揢<E8B8B5><EFBFBD><E8B8B9>?

3. 颲寧<E9A2B2><EFBFBD><E99C82><EFBFBD><EFBFBD> <20>?

  • <EFBFBD><EFBFBD>: 甇<><E79487>\b撖嫣葉<EFBFBD><EFBFBD><EFBFBD>蝚虫<EFBFBD><EFBFBD><EFBFBD>
  • <EFBFBD><EFBFBD>: 雿輻鍂Python摮㛖泵銝深replace`嚗𣬚<E59A97><F0A3AC9A>訫虾<E8A8AB>?

4. 摮㛖泵<E39B96><EFBFBD><E8B3A2>閖䔮憸?<3F>?

  • <EFBFBD><EFBFBD>: <20><><EFBFBD><E996AC>銝暹<E98A9D><E69AB9><EFBFBD>霈貊<E99C88>摮㛖泵
  • <EFBFBD><EFBFBD>: 銝漤<E98A9D><EFBFBD><E996AC><EFBFBD><E99C82>Python<6F><EFBFBD><E88AB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E585B8>?

<EFBFBD>妒 瘚贝<E7989A><E8B49D><EFBFBD>

瘚贝<EFBFBD>1嚗𡁜抅<EFBFBD><EFBFBD><EFBFBD>?

column_mapping = [
    {"originalName": "雿㯄<E99BBF>ɑg嚗?, "safeName": "col_0"},
    {"originalName": "頨恍<E9A0A8>嚗Ếm嚗?, "safeName": "col_1"}
]
formula = "雿㯄<E99BBF>ɑg嚗?/ (頨恍<E9A0A8>嚗Ếm嚗?100)**2"
# 憸<><E686B8>: col_0 / (col_1/100)**2 <20>?

瘚贝<EFBFBD>2嚗𡁜<EFBFBD>銝脣<EFBFBD><EFBFBD>?

column_mapping = [
    {"originalName": "擃䁅<E69383><E48185>?, "safeName": "col_0"},
    {"originalName": "擃䁅<E69383><E48185><EFBFBD><E8AEA0>?, "safeName": "col_1"}
]
formula = "擃䁅<E69383><E48185><EFBFBD><E8AEA0>?+ 擃䁅<E69383><E48185>?
# 憸<><E686B8>: col_1 + col_0 <20><><EFBFBD><EFBFBD>牐蛹<E78990>厰鵭摨行<E691A8>摨𧶏<E691A8>

瘚贝<EFBFBD>3嚗𡁜<EFBFBD><EFBFBD><EFBFBD>鸌畾𠰴<EFBFBD>蝚?

column_mapping = [
    {"originalName": "1.擃䁅<E69383><E48185><EFBFBD><EFBFBD><E59A97>=0嚗峕<E59A97>=1嚗䔶<E59A97><E494B6>仿<EFBFBD>=2嚗?, "safeName": "col_0"}
]
formula = "1.擃䁅<E69383><E48185><EFBFBD><EFBFBD><E59A97>=0嚗峕<E59A97>=1嚗䔶<E59A97><E494B6>仿<EFBFBD>=2嚗?* 2"
# 憸<><E686B8>: col_0 * 2 <20>?

瘚贝<EFBFBD>4嚗𡁜<EFBFBD>憟埈𡠺<EFBFBD>?

column_mapping = [
    {"originalName": "FMA<4D><EFBFBD>嚗?-100嚗?, "safeName": "col_0"}
]
formula = "FMA<4D><EFBFBD>嚗?-100嚗?/ 100"
# 憸<><E686B8>: col_0 / 100 <20>?

<EFBFBD><EFBFBD> <20><EFBFBD>敶勗<E695B6>

<EFBFBD><EFBFBD><EFBFBD> 敶勗<EFBFBD> 霂湔<EFBFBD>
蝵𤑳<EFBFBD>隡㰘<EFBFBD> +5KB columnMapping蝥?KB嚗?00<30><EFBFBD>
<EFBFBD>踵揢<EFBFBD>園𡢿 <1ms 摮㛖泵銝脫𤜯<EFBFBD><EFBFBD>撣詨翰
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>臬蕭<EFBFBD>? <EFBFBD><EFBFBD><EFBFBD>唳旿憭<EFBFBD><EFBFBD><EFBFBD>園𡢿嚗<EFBFBD><EFBFBD>蝥改<EFBFBD><EFBFBD>臬蕭<EFBFBD>?

<EFBFBD>㴓 隡睃飵<E79D83><EFBFBD>

<EFBFBD><EFBFBD>雿㯄<EFBFBD> 潃鐥<E6BD83>潃鐥<E6BD83>潃?

  • <EFBFBD>?<3F><EFBFBD><E586BD><EFBFBD><E8A781><EFBFBD><E8ABB9><EFBFBD><E4BA99><EFBFBD>
  • <EFBFBD>?<3F><EFBFBD><E7A08D><EFBFBD><E6B8B2>𤘪<EFBFBD>
  • <EFBFBD>?<3F><>蟮霈啣<E99C88><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>臬虾<EFBFBD><EFBFBD>?潃鐥<E6BD83>潃鐥<E6BD83>潃?

  • <EFBFBD>?銝滢<E98A9D>韏𡝗迤<F0A19D97>躰器<E8BAB0><EFBFBD><E8ABB9>?
  • <EFBFBD>?<3F>厰鵭摨行<E691A8>摨誯<E691A8><E8AAAF><EFBFBD>銝脤䔮憸?
  • <EFBFBD>?Python摮㛖泵銝脫<E98A9D>雿𦦵<E99BBF><F0A6A6B5>訫虾<E8A8AB>?

<EFBFBD>舐輕<EFBFBD><EFBFBD>?潃鐥<E6BD83>潃鐥<E6BD83>潃?

  • <EFBFBD>?<3F>諹提皜<E68F90>苊嚗<E88B8A><E59A97>蝡狹I<E78BB9><49>ython<6F><EFBFBD>嚗?
  • <EFBFBD>?<3F><EFBFBD><EFBFBD><E99D9A><EFBFBD><EFBFBD>枏㫲<E69E8F>踵揢<E8B8B5><EFBFBD>嚗?
  • <EFBFBD>?<3F>芣䔉銝滢<E98A9D><E6BBA2>齿<EFBFBD>摮㛖泵<E39B96><EFBFBD>

<EFBFBD><EFBFBD> <20>𡒊賒撌乩<E6928C>

撌脣<EFBFBD><EFBFBD>?<3F>?

  • <EFBFBD>滨垢靽脲<EFBFBD>雿輻鍂<EFBFBD><EFBFBD><EFBFBD>?
  • <EFBFBD>𡒊垢隡𣳇<EFBFBD>𠸍olumnMapping
  • Python摰䂿緵<EFBFBD>踵揢<EFBFBD><EFBFBD>
  • 蝘駁膄摮㛖泵撉諹<EFBFBD>
  • <EFBFBD>湔鰵Pivot<EFBFBD><EFBFBD>

<EFBFBD><EFBFBD>霂?<3F>?

  • <EFBFBD><EFBFBD>摰鮋<EFBFBD>瘚贝<EFBFBD>
  • 颲寧<EFBFBD><EFBFBD><EFBFBD><EFBFBD>撉諹<EFBFBD>
  • <EFBFBD><EFBFBD>瘚贝<EFBFBD>

<EFBFBD>芣䔉隡睃<EFBFBD> <20>

  • 瘛餃<EFBFBD><EFBFBD><EFBFBD>霂剜<EFBFBD>擃䀝漁
  • <EFBFBD><EFBFBD><EFBFBD>芸𢆡銵亙<EFBFBD>
  • <EFBFBD><EFBFBD><EFBFBD>躰秤<EFBFBD>鞟內隡睃<EFBFBD>

<EFBFBD><EFBFBD> <20><EFBFBD><E8A9A8><EFBFBD>

靽格㺿<EFBFBD><EFBFBD><EFBFBD>隞?

  1. backend/src/modules/dc/tool-c/controllers/QuickActionController.ts
  2. backend/src/modules/dc/tool-c/services/QuickActionService.ts
  3. extraction_service/main.py
  4. extraction_service/operations/compute.py
  5. extraction_service/operations/pivot.py

<EFBFBD><EFBFBD>

  • <EFBFBD><EFBFBD><EFBFBD><EFBFBD>撌亙<EFBFBD>C_<EFBFBD><EFBFBD>B摰墧鴌<EFBFBD><EFBFBD>_2025-12-09.md
  • <EFBFBD>埞ug<EFBFBD><EFBFBD>嚗䫤撌亙<EFBFBD>C_Bug靽桀<EFBFBD><EFBFBD><EFBFBD>_2025-12-08.md`

<EFBFBD>?<3F><EFBFBD>

<EFBFBD><EFBFBD>B<EFBFBD>𣂼<EFBFBD>摰䂿緵鈭<EFBFBD><EFBFBD>

  1. <EFBFBD><EFBFBD>雿㯄<EFBFBD>隡条<EFBFBD> - 雿輻鍂<E8BCBB><EFBFBD><E7AC94><EFBFBD><E3B5AA><EFBFBD><E6B8B2>𤘪<EFBFBD>
  2. *<EFBFBD><EFBFBD><EFBFBD>臬虾<EFBFBD>? - Python<6F>踵揢嚗𣬚<E59A97><F0A3AC9A>訫虾<E8A8AB>?
  3. 敶餃<EFBFBD><EFBFBD><EFBFBD> - 銝滚<E98A9D><E6BB9A>厩鸌畾𠰴<E795BE>蝚阡䔮憸?

**銝衤<E98A9D>甇?*: 蝑匧<E89D91><E58CA7><EFBFBD>瘚贝<E7989A>撉諹<E69289> <20>?